mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
refactor: rename Ai* database identifiers to AI* (AIGOV-369) (#26327)
Adds `ai` to sqlc's `gen.go.initialisms` in `coderd/database/sqlc.yaml` so the generated DB code follows Go's initialism convention. Adds the matching `ai` -> `AI` case to the dbgen PascalCase helper (`scripts/dbgen/main.go`) so the corresponding `dbmem` / mock identifiers stay in sync. `make gen` regenerates the rest; hand-written call sites that consume DB-generated identifiers (`enterprise/audit/table.go`, `coderd/database/modelmethods.go`, `enterprise/coderd/aigatewaykeys.go`, `coderd/database/dbauthz/*`, etc.) are updated to match. Scope is deliberately limited to the database layer: - `coderd/rbac/*` (resource and scope generators) is untouched — `ResourceAi*` / `ScopeAi*` constants stay on main's casing. - `codersdk/*` (Go SDK) is untouched — `codersdk.ResourceAi*` / `codersdk.APIKeyScopeAi*` constants stay on main's casing, so external Go SDK consumers see no source-level break. - `Aibridge*` identifiers (one SQL token `aibridge`, not `ai_bridge`) are out of scope. On-the-wire values are unchanged: enum strings, RBAC resource type strings, API key scope strings, and JSON tags all stay the same. The HTTP/JSON surface is unaffected. Refs: [AIGOV-369](https://linear.app/codercom/issue/AIGOV-369/change-ai-references-in-coderddatabasemodelsgo-to-ai) 🤖 Generated with [Coder Agents](https://coder.com)
This commit is contained in:
@@ -325,8 +325,8 @@ func (api *API) aiProvidersUpdate(rw http.ResponseWriter, r *http.Request) {
|
||||
// misconfiguration from sitting silently in the encrypted
|
||||
// blob.
|
||||
if existing.Bedrock != nil &&
|
||||
old.Type != database.AiProviderTypeAnthropic &&
|
||||
old.Type != database.AiProviderTypeBedrock {
|
||||
old.Type != database.AIProviderTypeAnthropic &&
|
||||
old.Type != database.AIProviderTypeBedrock {
|
||||
return errAIProviderBedrockTypeMismatch
|
||||
}
|
||||
settings, err := encodeAIProviderSettings(existing)
|
||||
@@ -340,7 +340,7 @@ func (api *API) aiProvidersUpdate(rw http.ResponseWriter, r *http.Request) {
|
||||
return errBedrockRejectsAPIKeys
|
||||
}
|
||||
|
||||
if req.APIKeys != nil && old.Type == database.AiProviderTypeCopilot && len(*req.APIKeys) > 0 {
|
||||
if req.APIKeys != nil && old.Type == database.AIProviderTypeCopilot && len(*req.APIKeys) > 0 {
|
||||
return errCopilotRejectsAPIKeys
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ func BackfillBedrockProviderType(ctx context.Context, db database.Store, logger
|
||||
}
|
||||
var promoted int
|
||||
for _, provider := range providers {
|
||||
if provider.Type != database.AiProviderTypeAnthropic {
|
||||
if provider.Type != database.AIProviderTypeAnthropic {
|
||||
continue
|
||||
}
|
||||
settings, err := db2sdk.AIProviderSettings(provider.Settings)
|
||||
@@ -46,7 +46,7 @@ func BackfillBedrockProviderType(ctx context.Context, db database.Store, logger
|
||||
}
|
||||
_, err = db.UpdateAIProvider(sysCtx, database.UpdateAIProviderParams{
|
||||
ID: provider.ID,
|
||||
Type: database.AiProviderTypeBedrock,
|
||||
Type: database.AIProviderTypeBedrock,
|
||||
DisplayName: provider.DisplayName,
|
||||
Enabled: provider.Enabled,
|
||||
BaseUrl: provider.BaseUrl,
|
||||
|
||||
@@ -49,16 +49,16 @@ func TestBackfillBedrockProviderType(t *testing.T) {
|
||||
|
||||
t.Run("PromotesLegacyRow", func(t *testing.T) {
|
||||
legacy := dbgen.AIProvider(t, db, database.AIProvider{
|
||||
Type: database.AiProviderTypeAnthropic,
|
||||
Type: database.AIProviderTypeAnthropic,
|
||||
Settings: bedrockSettings,
|
||||
})
|
||||
require.Equal(t, database.AiProviderTypeAnthropic, legacy.Type, "pre-condition: row must start as anthropic")
|
||||
require.Equal(t, database.AIProviderTypeAnthropic, legacy.Type, "pre-condition: row must start as anthropic")
|
||||
|
||||
coderd.BackfillBedrockProviderType(ctx, db, logger)
|
||||
|
||||
row, err := db.GetAIProviderByName(ctx, legacy.Name)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, database.AiProviderTypeBedrock, row.Type)
|
||||
require.Equal(t, database.AIProviderTypeBedrock, row.Type)
|
||||
})
|
||||
|
||||
t.Run("Idempotent", func(t *testing.T) {
|
||||
@@ -70,7 +70,7 @@ func TestBackfillBedrockProviderType(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
for _, r := range before {
|
||||
require.Equal(t, database.AiProviderTypeBedrock, r.Type,
|
||||
require.Equal(t, database.AIProviderTypeBedrock, r.Type,
|
||||
"pre-condition: all rows must already be promoted before testing idempotency")
|
||||
}
|
||||
|
||||
@@ -89,37 +89,37 @@ func TestBackfillBedrockProviderType(t *testing.T) {
|
||||
|
||||
t.Run("PreservesNativeAnthropicRow", func(t *testing.T) {
|
||||
native := dbgen.AIProvider(t, db, database.AIProvider{
|
||||
Type: database.AiProviderTypeAnthropic,
|
||||
Type: database.AIProviderTypeAnthropic,
|
||||
})
|
||||
require.Equal(t, database.AiProviderTypeAnthropic, native.Type, "pre-condition")
|
||||
require.Equal(t, database.AIProviderTypeAnthropic, native.Type, "pre-condition")
|
||||
|
||||
coderd.BackfillBedrockProviderType(ctx, db, logger)
|
||||
|
||||
row, err := db.GetAIProviderByName(ctx, native.Name)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, database.AiProviderTypeAnthropic, row.Type)
|
||||
require.Equal(t, database.AIProviderTypeAnthropic, row.Type)
|
||||
})
|
||||
|
||||
t.Run("PreservesNativeBedrockRow", func(t *testing.T) {
|
||||
native := dbgen.AIProvider(t, db, database.AIProvider{
|
||||
Type: database.AiProviderTypeBedrock,
|
||||
Type: database.AIProviderTypeBedrock,
|
||||
Settings: bedrockSettings,
|
||||
})
|
||||
require.Equal(t, database.AiProviderTypeBedrock, native.Type, "pre-condition")
|
||||
require.Equal(t, database.AIProviderTypeBedrock, native.Type, "pre-condition")
|
||||
|
||||
coderd.BackfillBedrockProviderType(ctx, db, logger)
|
||||
|
||||
row, err := db.GetAIProviderByName(ctx, native.Name)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, database.AiProviderTypeBedrock, row.Type)
|
||||
require.Equal(t, database.AIProviderTypeBedrock, row.Type)
|
||||
})
|
||||
|
||||
t.Run("SkipsDeletedRows", func(t *testing.T) {
|
||||
deleted := dbgen.AIProvider(t, db, database.AIProvider{
|
||||
Type: database.AiProviderTypeAnthropic,
|
||||
Type: database.AIProviderTypeAnthropic,
|
||||
Settings: bedrockSettings,
|
||||
})
|
||||
require.Equal(t, database.AiProviderTypeAnthropic, deleted.Type, "pre-condition")
|
||||
require.Equal(t, database.AIProviderTypeAnthropic, deleted.Type, "pre-condition")
|
||||
require.NoError(t, db.DeleteAIProviderByID(ctx, deleted.ID))
|
||||
|
||||
coderd.BackfillBedrockProviderType(ctx, db, logger)
|
||||
@@ -133,7 +133,7 @@ func TestBackfillBedrockProviderType(t *testing.T) {
|
||||
for _, r := range row {
|
||||
if r.ID == deleted.ID {
|
||||
found = true
|
||||
require.Equal(t, database.AiProviderTypeAnthropic, r.Type, "deleted row must not be promoted")
|
||||
require.Equal(t, database.AIProviderTypeAnthropic, r.Type, "deleted row must not be promoted")
|
||||
}
|
||||
}
|
||||
require.True(t, found, "deleted row must appear in IncludeDeleted result set")
|
||||
@@ -141,17 +141,17 @@ func TestBackfillBedrockProviderType(t *testing.T) {
|
||||
|
||||
t.Run("IncludesDisabledRows", func(t *testing.T) {
|
||||
disabled := dbgen.AIProvider(t, db, database.AIProvider{
|
||||
Type: database.AiProviderTypeAnthropic,
|
||||
Type: database.AIProviderTypeAnthropic,
|
||||
Enabled: false,
|
||||
Settings: bedrockSettings,
|
||||
})
|
||||
require.Equal(t, database.AiProviderTypeAnthropic, disabled.Type, "pre-condition")
|
||||
require.Equal(t, database.AIProviderTypeAnthropic, disabled.Type, "pre-condition")
|
||||
|
||||
coderd.BackfillBedrockProviderType(ctx, db, logger)
|
||||
|
||||
row, err := db.GetAIProviderByName(ctx, disabled.Name)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, database.AiProviderTypeBedrock, row.Type, "disabled legacy row must be promoted")
|
||||
require.Equal(t, database.AIProviderTypeBedrock, row.Type, "disabled legacy row must be promoted")
|
||||
})
|
||||
|
||||
t.Run("PreservesAnthropicRowWithNonBedrockSettings", func(t *testing.T) {
|
||||
@@ -159,39 +159,39 @@ func TestBackfillBedrockProviderType(t *testing.T) {
|
||||
// and the row is skipped via the unparsable-settings path, not the
|
||||
// settings.Bedrock == nil guard. Either way the row must stay anthropic.
|
||||
nonBedrock := dbgen.AIProvider(t, db, database.AIProvider{
|
||||
Type: database.AiProviderTypeAnthropic,
|
||||
Type: database.AIProviderTypeAnthropic,
|
||||
Settings: sql.NullString{String: "{}", Valid: true},
|
||||
})
|
||||
require.Equal(t, database.AiProviderTypeAnthropic, nonBedrock.Type, "pre-condition")
|
||||
require.Equal(t, database.AIProviderTypeAnthropic, nonBedrock.Type, "pre-condition")
|
||||
|
||||
coderd.BackfillBedrockProviderType(ctx, db, logger)
|
||||
|
||||
row, err := db.GetAIProviderByName(ctx, nonBedrock.Name)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, database.AiProviderTypeAnthropic, row.Type, "anthropic row with non-bedrock settings must not be promoted")
|
||||
require.Equal(t, database.AIProviderTypeAnthropic, row.Type, "anthropic row with non-bedrock settings must not be promoted")
|
||||
})
|
||||
|
||||
t.Run("SkipsUnparsableSettings", func(t *testing.T) {
|
||||
malformed := dbgen.AIProvider(t, db, database.AIProvider{
|
||||
Type: database.AiProviderTypeAnthropic,
|
||||
Type: database.AIProviderTypeAnthropic,
|
||||
Settings: sql.NullString{String: "{", Valid: true},
|
||||
})
|
||||
require.Equal(t, database.AiProviderTypeAnthropic, malformed.Type, "pre-condition")
|
||||
require.Equal(t, database.AIProviderTypeAnthropic, malformed.Type, "pre-condition")
|
||||
good := dbgen.AIProvider(t, db, database.AIProvider{
|
||||
Type: database.AiProviderTypeAnthropic,
|
||||
Type: database.AIProviderTypeAnthropic,
|
||||
Settings: bedrockSettings,
|
||||
})
|
||||
require.Equal(t, database.AiProviderTypeAnthropic, good.Type, "pre-condition")
|
||||
require.Equal(t, database.AIProviderTypeAnthropic, good.Type, "pre-condition")
|
||||
|
||||
coderd.BackfillBedrockProviderType(ctx, db, logger)
|
||||
|
||||
malformedRow, err := db.GetAIProviderByName(ctx, malformed.Name)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, database.AiProviderTypeAnthropic, malformedRow.Type, "row with unparsable settings must not be touched")
|
||||
require.Equal(t, database.AIProviderTypeAnthropic, malformedRow.Type, "row with unparsable settings must not be touched")
|
||||
|
||||
goodRow, err := db.GetAIProviderByName(ctx, good.Name)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, database.AiProviderTypeBedrock, goodRow.Type, "valid row alongside unparsable one must still be promoted")
|
||||
require.Equal(t, database.AIProviderTypeBedrock, goodRow.Type, "valid row alongside unparsable one must still be promoted")
|
||||
})
|
||||
|
||||
// --- chat_model_configs.provider backfill ---
|
||||
@@ -203,7 +203,7 @@ func TestBackfillBedrockProviderType(t *testing.T) {
|
||||
// type=anthropic. The stored provider string is "anthropic" but the
|
||||
// linked provider row now has type=bedrock.
|
||||
bedrockProvider := dbgen.AIProvider(t, db, database.AIProvider{
|
||||
Type: database.AiProviderTypeBedrock,
|
||||
Type: database.AIProviderTypeBedrock,
|
||||
Settings: bedrockSettings,
|
||||
})
|
||||
staleConfig := dbgen.ChatModelConfig(t, db, database.ChatModelConfig{
|
||||
@@ -240,7 +240,7 @@ func TestBackfillBedrockProviderType(t *testing.T) {
|
||||
// A model config with provider="openai" linked to a Bedrock provider
|
||||
// must not be touched. Only "anthropic" → "bedrock" is in scope.
|
||||
bedrockProvider := dbgen.AIProvider(t, db, database.AIProvider{
|
||||
Type: database.AiProviderTypeBedrock,
|
||||
Type: database.AIProviderTypeBedrock,
|
||||
Settings: bedrockSettings,
|
||||
})
|
||||
openAIConfig := dbgen.ChatModelConfig(t, db, database.ChatModelConfig{
|
||||
@@ -261,7 +261,7 @@ func TestBackfillBedrockProviderType(t *testing.T) {
|
||||
// the linked provider is deleted and therefore excluded by the
|
||||
// AND deleted = FALSE condition in the query.
|
||||
deletedProvider := dbgen.AIProvider(t, db, database.AIProvider{
|
||||
Type: database.AiProviderTypeBedrock,
|
||||
Type: database.AIProviderTypeBedrock,
|
||||
Settings: bedrockSettings,
|
||||
})
|
||||
staleConfig := dbgen.ChatModelConfig(t, db, database.ChatModelConfig{
|
||||
@@ -281,7 +281,7 @@ func TestBackfillBedrockProviderType(t *testing.T) {
|
||||
// The SQL query guards on deleted = FALSE. Capture the config ID
|
||||
// before deletion so we delete the right row regardless of ordering.
|
||||
bedrockProvider := dbgen.AIProvider(t, db, database.AIProvider{
|
||||
Type: database.AiProviderTypeBedrock,
|
||||
Type: database.AIProviderTypeBedrock,
|
||||
Settings: bedrockSettings,
|
||||
})
|
||||
cfg := dbgen.ChatModelConfig(t, db, database.ChatModelConfig{
|
||||
@@ -323,7 +323,7 @@ func TestBackfillBedrockProviderType(t *testing.T) {
|
||||
db.EXPECT().
|
||||
GetAIProviders(gomock.Any(), gomock.Any()).
|
||||
Return([]database.AIProvider{{
|
||||
Type: database.AiProviderTypeAnthropic,
|
||||
Type: database.AIProviderTypeAnthropic,
|
||||
Settings: bedrockSettings,
|
||||
}}, nil)
|
||||
db.EXPECT().
|
||||
@@ -342,7 +342,7 @@ func TestBackfillBedrockProviderType(t *testing.T) {
|
||||
db.EXPECT().
|
||||
GetAIProviders(gomock.Any(), gomock.Any()).
|
||||
Return([]database.AIProvider{{
|
||||
Type: database.AiProviderTypeAnthropic,
|
||||
Type: database.AIProviderTypeAnthropic,
|
||||
Settings: bedrockSettings,
|
||||
}}, nil)
|
||||
db.EXPECT().
|
||||
|
||||
@@ -130,8 +130,8 @@ func SeedAIProvidersFromEnv(
|
||||
// type=anthropic to type=bedrock by the startup backfill
|
||||
// is not mistaken for drift on the next startup.
|
||||
existingType := existing.Type
|
||||
if existingSettings.Bedrock != nil && existing.Type == database.AiProviderTypeAnthropic {
|
||||
existingType = database.AiProviderTypeBedrock
|
||||
if existingSettings.Bedrock != nil && existing.Type == database.AIProviderTypeAnthropic {
|
||||
existingType = database.AIProviderTypeBedrock
|
||||
}
|
||||
existingDP := desiredAIProvider{
|
||||
Type: existingType,
|
||||
@@ -309,7 +309,7 @@ func providersFromEnv(ctx context.Context, cfg codersdk.AIBridgeConfig, logger s
|
||||
if cfg.LegacyOpenAI.Key.String() != "" {
|
||||
dp := desiredAIProvider{
|
||||
Name: aibridge.ProviderOpenAI,
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
BaseURL: cfg.LegacyOpenAI.BaseURL.String(),
|
||||
Keys: []string{cfg.LegacyOpenAI.Key.String()},
|
||||
}
|
||||
@@ -334,10 +334,10 @@ func providersFromEnv(ctx context.Context, cfg codersdk.AIBridgeConfig, logger s
|
||||
if hasAnthropicKey || hasLegacyBedrock {
|
||||
dp := desiredAIProvider{
|
||||
Name: aibridge.ProviderAnthropic,
|
||||
Type: database.AiProviderTypeAnthropic,
|
||||
Type: database.AIProviderTypeAnthropic,
|
||||
}
|
||||
if hasLegacyBedrock {
|
||||
dp.Type = database.AiProviderTypeBedrock
|
||||
dp.Type = database.AIProviderTypeBedrock
|
||||
if hasAnthropicKey {
|
||||
logger.Warn(ctx, "ignoring legacy Anthropic API key because Bedrock credentials are configured; Bedrock authenticates via access keys or credential chain",
|
||||
slog.F("provider", aibridge.ProviderAnthropic),
|
||||
@@ -389,7 +389,7 @@ func providersFromEnv(ctx context.Context, cfg codersdk.AIBridgeConfig, logger s
|
||||
// AIProviderBedrockSettings.IsConfigured() so the legacy and
|
||||
// indexed paths agree on what counts as a Bedrock provider.
|
||||
isBedrock := false
|
||||
if dp.Type == database.AiProviderTypeAnthropic || dp.Type == database.AiProviderTypeBedrock {
|
||||
if dp.Type == database.AIProviderTypeAnthropic || dp.Type == database.AIProviderTypeBedrock {
|
||||
var accessKey, accessKeySecret string
|
||||
if len(p.BedrockAccessKeys) > 0 {
|
||||
accessKey = p.BedrockAccessKeys[0]
|
||||
@@ -426,7 +426,7 @@ func providersFromEnv(ctx context.Context, cfg codersdk.AIBridgeConfig, logger s
|
||||
slog.F("ignored_key_count", len(p.Keys)),
|
||||
)
|
||||
}
|
||||
case dp.Type == database.AiProviderTypeCopilot:
|
||||
case dp.Type == database.AIProviderTypeCopilot:
|
||||
if len(p.Keys) > 0 {
|
||||
logger.Warn(ctx, "ignoring bearer keys configured on Copilot AI provider; Copilot authenticates via request-time GitHub OAuth tokens",
|
||||
slog.F("name", name),
|
||||
|
||||
@@ -47,7 +47,7 @@ func TestSeedAIProvidersFromEnv(t *testing.T) {
|
||||
// One row exists for "openai".
|
||||
row, err := db.GetAIProviderByName(ctx, "openai")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, database.AiProviderTypeOpenai, row.Type)
|
||||
require.Equal(t, database.AIProviderTypeOpenai, row.Type)
|
||||
require.Equal(t, "https://api.openai.com/v1", row.BaseUrl)
|
||||
require.True(t, row.Enabled)
|
||||
|
||||
@@ -161,7 +161,7 @@ func TestSeedAIProvidersFromEnv(t *testing.T) {
|
||||
|
||||
row, err := db.GetAIProviderByName(ctx, "anthropic")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, database.AiProviderTypeBedrock, row.Type)
|
||||
require.Equal(t, database.AIProviderTypeBedrock, row.Type)
|
||||
require.Contains(t, row.Settings.String, "us-west-2")
|
||||
require.Contains(t, row.Settings.String, "anthropic.claude-3-5-sonnet")
|
||||
require.Contains(t, row.Settings.String, "anthropic.claude-3-5-haiku")
|
||||
@@ -280,7 +280,7 @@ func TestSeedAIProvidersFromEnv(t *testing.T) {
|
||||
|
||||
oa, err := db.GetAIProviderByName(ctx, "primary-openai")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, database.AiProviderTypeOpenai, oa.Type)
|
||||
require.Equal(t, database.AIProviderTypeOpenai, oa.Type)
|
||||
oaKeys, err := db.GetAIProviderKeysByProviderID(ctx, oa.ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, oaKeys, 2)
|
||||
@@ -289,7 +289,7 @@ func TestSeedAIProvidersFromEnv(t *testing.T) {
|
||||
|
||||
an, err := db.GetAIProviderByName(ctx, "primary-anthropic")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, database.AiProviderTypeAnthropic, an.Type)
|
||||
require.Equal(t, database.AIProviderTypeAnthropic, an.Type)
|
||||
// Plain bearer-token Anthropic with no Bedrock fields: no
|
||||
// settings blob, one bearer key.
|
||||
require.False(t, an.Settings.Valid, "no settings blob for bearer-token Anthropic")
|
||||
@@ -625,7 +625,7 @@ func TestSeedAIProvidersFromEnv(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
_, err = db.UpdateAIProvider(ctx, database.UpdateAIProviderParams{
|
||||
ID: row.ID,
|
||||
Type: database.AiProviderTypeAnthropic,
|
||||
Type: database.AIProviderTypeAnthropic,
|
||||
DisplayName: row.DisplayName,
|
||||
Enabled: row.Enabled,
|
||||
BaseUrl: row.BaseUrl,
|
||||
@@ -635,7 +635,7 @@ func TestSeedAIProvidersFromEnv(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
row, err = db.GetAIProviderByName(ctx, "anthropic")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, database.AiProviderTypeAnthropic, row.Type, "pre-condition: row must be anthropic before seed runs")
|
||||
require.Equal(t, database.AIProviderTypeAnthropic, row.Type, "pre-condition: row must be anthropic before seed runs")
|
||||
|
||||
require.NoError(t, coderd.SeedAIProvidersFromEnv(ctx, db, cfg, testLogger(t)))
|
||||
})
|
||||
|
||||
@@ -11,18 +11,18 @@ import (
|
||||
)
|
||||
|
||||
type Reason struct {
|
||||
EventType database.AiSeatUsageReason
|
||||
EventType database.AISeatUsageReason
|
||||
Description string
|
||||
}
|
||||
|
||||
// ReasonAIBridge constructs a reason for usage originating from AI Bridge.
|
||||
func ReasonAIBridge(description string) Reason {
|
||||
return Reason{EventType: database.AiSeatUsageReasonAibridge, Description: description}
|
||||
return Reason{EventType: database.AISeatUsageReasonAibridge, Description: description}
|
||||
}
|
||||
|
||||
// ReasonTask constructs a reason for usage originating from tasks.
|
||||
func ReasonTask(description string) Reason {
|
||||
return Reason{EventType: database.AiSeatUsageReasonTask, Description: description}
|
||||
return Reason{EventType: database.AISeatUsageReasonTask, Description: description}
|
||||
}
|
||||
|
||||
// SeatTracker records AI seat consumption state.
|
||||
|
||||
+2
-2
@@ -608,7 +608,7 @@ func (api *API) auditLogResourceLink(ctx context.Context, alog database.GetAudit
|
||||
// TODO(PLAT-102): point at the user secrets management page once
|
||||
// it ships. Until then, the audit row links nowhere.
|
||||
return ""
|
||||
case database.ResourceTypeGroupAiBudget:
|
||||
case database.ResourceTypeGroupAIBudget:
|
||||
// The resource_id is the group's UUID; link to the group's
|
||||
// settings page.
|
||||
group, err := api.Database.GetGroupByID(ctx, alog.AuditLog.ResourceID)
|
||||
@@ -620,7 +620,7 @@ func (api *API) auditLogResourceLink(ctx context.Context, alog database.GetAudit
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("/organizations/%s/groups/%s", org.Name, group.Name)
|
||||
case database.ResourceTypeUserAiBudgetOverride:
|
||||
case database.ResourceTypeUserAIBudgetOverride:
|
||||
// TODO: point at the user's AI budget override management page
|
||||
// once it ships. Until then, the audit row links nowhere.
|
||||
return ""
|
||||
|
||||
@@ -33,13 +33,13 @@ type Auditable interface {
|
||||
idpsync.GroupSyncSettings |
|
||||
idpsync.RoleSyncSettings |
|
||||
database.TaskTable |
|
||||
database.AiSeatState |
|
||||
database.AISeatState |
|
||||
database.AIProvider |
|
||||
database.AIProviderKey |
|
||||
database.AIGatewayKey |
|
||||
database.Chat |
|
||||
database.AuditableGroupAiBudget |
|
||||
database.AuditableUserAiBudgetOverride |
|
||||
database.AuditableGroupAIBudget |
|
||||
database.AuditableUserAIBudgetOverride |
|
||||
database.UserSecret |
|
||||
database.UserSkill
|
||||
}
|
||||
|
||||
+15
-15
@@ -132,7 +132,7 @@ func ResourceTarget[T Auditable](tgt T) string {
|
||||
return "Organization Role Sync"
|
||||
case database.TaskTable:
|
||||
return typed.Name
|
||||
case database.AiSeatState:
|
||||
case database.AISeatState:
|
||||
return "AI Seat"
|
||||
case database.AIProvider:
|
||||
return typed.Name
|
||||
@@ -140,9 +140,9 @@ func ResourceTarget[T Auditable](tgt T) string {
|
||||
return typed.ID.String()
|
||||
case database.AIGatewayKey:
|
||||
return typed.Name
|
||||
case database.AuditableGroupAiBudget:
|
||||
case database.AuditableGroupAIBudget:
|
||||
return typed.GroupName
|
||||
case database.AuditableUserAiBudgetOverride:
|
||||
case database.AuditableUserAIBudgetOverride:
|
||||
return typed.Username
|
||||
case database.Chat:
|
||||
// Chat titles can contain sensitive content (secrets, internal
|
||||
@@ -220,7 +220,7 @@ func ResourceID[T Auditable](tgt T) uuid.UUID {
|
||||
return noID // Org field on audit log has org id
|
||||
case database.TaskTable:
|
||||
return typed.ID
|
||||
case database.AiSeatState:
|
||||
case database.AISeatState:
|
||||
return typed.UserID
|
||||
case database.AIProvider:
|
||||
return typed.ID
|
||||
@@ -228,9 +228,9 @@ func ResourceID[T Auditable](tgt T) uuid.UUID {
|
||||
return typed.ID
|
||||
case database.AIGatewayKey:
|
||||
return typed.ID
|
||||
case database.AuditableGroupAiBudget:
|
||||
case database.AuditableGroupAIBudget:
|
||||
return typed.GroupID
|
||||
case database.AuditableUserAiBudgetOverride:
|
||||
case database.AuditableUserAIBudgetOverride:
|
||||
return typed.UserID
|
||||
case database.Chat:
|
||||
return typed.ID
|
||||
@@ -293,18 +293,18 @@ func ResourceType[T Auditable](tgt T) database.ResourceType {
|
||||
return database.ResourceTypeIdpSyncSettingsGroup
|
||||
case database.TaskTable:
|
||||
return database.ResourceTypeTask
|
||||
case database.AiSeatState:
|
||||
return database.ResourceTypeAiSeat
|
||||
case database.AISeatState:
|
||||
return database.ResourceTypeAISeat
|
||||
case database.AIProvider:
|
||||
return database.ResourceTypeAIProvider
|
||||
case database.AIProviderKey:
|
||||
return database.ResourceTypeAIProviderKey
|
||||
case database.AIGatewayKey:
|
||||
return database.ResourceTypeAIGatewayKey
|
||||
case database.AuditableGroupAiBudget:
|
||||
return database.ResourceTypeGroupAiBudget
|
||||
case database.AuditableUserAiBudgetOverride:
|
||||
return database.ResourceTypeUserAiBudgetOverride
|
||||
case database.AuditableGroupAIBudget:
|
||||
return database.ResourceTypeGroupAIBudget
|
||||
case database.AuditableUserAIBudgetOverride:
|
||||
return database.ResourceTypeUserAIBudgetOverride
|
||||
case database.Chat:
|
||||
return database.ResourceTypeChat
|
||||
case database.UserSecret:
|
||||
@@ -369,7 +369,7 @@ func ResourceRequiresOrgID[T Auditable]() bool {
|
||||
return true
|
||||
case database.TaskTable:
|
||||
return true
|
||||
case database.AiSeatState:
|
||||
case database.AISeatState:
|
||||
return false
|
||||
case database.AIProvider:
|
||||
// AI providers are deployment-scoped, not org-scoped.
|
||||
@@ -381,10 +381,10 @@ func ResourceRequiresOrgID[T Auditable]() bool {
|
||||
case database.AIGatewayKey:
|
||||
// AI Gateway keys are deployment-scoped, not org-scoped.
|
||||
return false
|
||||
case database.AuditableGroupAiBudget:
|
||||
case database.AuditableGroupAIBudget:
|
||||
// Group AI budgets are org-scoped through their parent group.
|
||||
return true
|
||||
case database.AuditableUserAiBudgetOverride:
|
||||
case database.AuditableUserAIBudgetOverride:
|
||||
// User AI budget overrides are org-scoped through their
|
||||
// attributed group.
|
||||
return true
|
||||
|
||||
Generated
+12
-12
@@ -6,17 +6,17 @@ type CheckConstraint string
|
||||
|
||||
// CheckConstraint enums.
|
||||
const (
|
||||
CheckAiGatewayKeysHashedSecretCheck CheckConstraint = "ai_gateway_keys_hashed_secret_check" // ai_gateway_keys
|
||||
CheckAiGatewayKeysNameCheck CheckConstraint = "ai_gateway_keys_name_check" // ai_gateway_keys
|
||||
CheckAiGatewayKeysSecretPrefixCheck CheckConstraint = "ai_gateway_keys_secret_prefix_check" // ai_gateway_keys
|
||||
CheckAiModelPricesCacheReadPriceCheck CheckConstraint = "ai_model_prices_cache_read_price_check" // ai_model_prices
|
||||
CheckAiModelPricesCacheWritePriceCheck CheckConstraint = "ai_model_prices_cache_write_price_check" // ai_model_prices
|
||||
CheckAiModelPricesInputPriceCheck CheckConstraint = "ai_model_prices_input_price_check" // ai_model_prices
|
||||
CheckAiModelPricesOutputPriceCheck CheckConstraint = "ai_model_prices_output_price_check" // ai_model_prices
|
||||
CheckAiProvidersNameCheck CheckConstraint = "ai_providers_name_check" // ai_providers
|
||||
CheckAIGatewayKeysHashedSecretCheck CheckConstraint = "ai_gateway_keys_hashed_secret_check" // ai_gateway_keys
|
||||
CheckAIGatewayKeysNameCheck CheckConstraint = "ai_gateway_keys_name_check" // ai_gateway_keys
|
||||
CheckAIGatewayKeysSecretPrefixCheck CheckConstraint = "ai_gateway_keys_secret_prefix_check" // ai_gateway_keys
|
||||
CheckAIModelPricesCacheReadPriceCheck CheckConstraint = "ai_model_prices_cache_read_price_check" // ai_model_prices
|
||||
CheckAIModelPricesCacheWritePriceCheck CheckConstraint = "ai_model_prices_cache_write_price_check" // ai_model_prices
|
||||
CheckAIModelPricesInputPriceCheck CheckConstraint = "ai_model_prices_input_price_check" // ai_model_prices
|
||||
CheckAIModelPricesOutputPriceCheck CheckConstraint = "ai_model_prices_output_price_check" // ai_model_prices
|
||||
CheckAIProvidersNameCheck CheckConstraint = "ai_providers_name_check" // ai_providers
|
||||
CheckAPIKeysAllowListNotEmpty CheckConstraint = "api_keys_allow_list_not_empty" // api_keys
|
||||
CheckBoundaryLogsSequenceNumberCheck CheckConstraint = "boundary_logs_sequence_number_check" // boundary_logs
|
||||
CheckChatModelConfigsAiProviderRequiredWhenActive CheckConstraint = "chat_model_configs_ai_provider_required_when_active" // chat_model_configs
|
||||
CheckChatModelConfigsAIProviderRequiredWhenActive CheckConstraint = "chat_model_configs_ai_provider_required_when_active" // chat_model_configs
|
||||
CheckChatModelConfigsCompressionThresholdCheck CheckConstraint = "chat_model_configs_compression_threshold_check" // chat_model_configs
|
||||
CheckChatModelConfigsContextLimitCheck CheckConstraint = "chat_model_configs_context_limit_check" // chat_model_configs
|
||||
CheckChatUsageLimitConfigDefaultLimitMicrosCheck CheckConstraint = "chat_usage_limit_config_default_limit_micros_check" // chat_usage_limit_config
|
||||
@@ -33,7 +33,7 @@ const (
|
||||
CheckUsersServiceAccountLoginType CheckConstraint = "users_service_account_login_type" // users
|
||||
CheckUsersUsernameMinLength CheckConstraint = "users_username_min_length" // users
|
||||
CheckOrganizationIDNotZero CheckConstraint = "organization_id_not_zero" // custom_roles
|
||||
CheckGroupAiBudgetsSpendLimitMicrosCheck CheckConstraint = "group_ai_budgets_spend_limit_micros_check" // group_ai_budgets
|
||||
CheckGroupAIBudgetsSpendLimitMicrosCheck CheckConstraint = "group_ai_budgets_spend_limit_micros_check" // group_ai_budgets
|
||||
CheckGroupsChatSpendLimitMicrosCheck CheckConstraint = "groups_chat_spend_limit_micros_check" // groups
|
||||
CheckMcpServerConfigsAuthTypeCheck CheckConstraint = "mcp_server_configs_auth_type_check" // mcp_server_configs
|
||||
CheckMcpServerConfigsAvailabilityCheck CheckConstraint = "mcp_server_configs_availability_check" // mcp_server_configs
|
||||
@@ -47,8 +47,8 @@ const (
|
||||
CheckTelemetryLockEventTypeConstraint CheckConstraint = "telemetry_lock_event_type_constraint" // telemetry_locks
|
||||
CheckValidationMonotonicOrder CheckConstraint = "validation_monotonic_order" // template_version_parameters
|
||||
CheckUsageEventTypeCheck CheckConstraint = "usage_event_type_check" // usage_events
|
||||
CheckUserAiBudgetOverridesSpendLimitMicrosCheck CheckConstraint = "user_ai_budget_overrides_spend_limit_micros_check" // user_ai_budget_overrides
|
||||
CheckUserAiProviderKeysAPIKeyCheck CheckConstraint = "user_ai_provider_keys_api_key_check" // user_ai_provider_keys
|
||||
CheckUserAIBudgetOverridesSpendLimitMicrosCheck CheckConstraint = "user_ai_budget_overrides_spend_limit_micros_check" // user_ai_budget_overrides
|
||||
CheckUserAIProviderKeysAPIKeyCheck CheckConstraint = "user_ai_provider_keys_api_key_check" // user_ai_provider_keys
|
||||
CheckUserSkillsContentSize CheckConstraint = "user_skills_content_size" // user_skills
|
||||
CheckUserSkillsDescriptionSize CheckConstraint = "user_skills_description_size" // user_skills
|
||||
CheckUserSkillsNameFormat CheckConstraint = "user_skills_name_format" // user_skills
|
||||
|
||||
@@ -1421,7 +1421,7 @@ func flattenAndSum(sums map[string]int64, prefix string, m map[string]json.RawMe
|
||||
}
|
||||
}
|
||||
|
||||
func GroupAIBudget(b database.GroupAiBudget) codersdk.GroupAIBudget {
|
||||
func GroupAIBudget(b database.GroupAIBudget) codersdk.GroupAIBudget {
|
||||
return codersdk.GroupAIBudget{
|
||||
GroupID: b.GroupID,
|
||||
SpendLimitMicros: b.SpendLimitMicros,
|
||||
@@ -1430,7 +1430,7 @@ func GroupAIBudget(b database.GroupAiBudget) codersdk.GroupAIBudget {
|
||||
}
|
||||
}
|
||||
|
||||
func UserAIBudgetOverride(o database.UserAiBudgetOverride) codersdk.UserAIBudgetOverride {
|
||||
func UserAIBudgetOverride(o database.UserAIBudgetOverride) codersdk.UserAIBudgetOverride {
|
||||
return codersdk.UserAIBudgetOverride{
|
||||
UserID: o.UserID,
|
||||
GroupID: o.GroupID,
|
||||
|
||||
@@ -2171,14 +2171,14 @@ func (q *querier) DeleteExternalAuthLink(ctx context.Context, arg database.Delet
|
||||
}, q.db.DeleteExternalAuthLink)(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) DeleteGroupAIBudget(ctx context.Context, groupID uuid.UUID) (database.GroupAiBudget, error) {
|
||||
func (q *querier) DeleteGroupAIBudget(ctx context.Context, groupID uuid.UUID) (database.GroupAIBudget, error) {
|
||||
// Removing a group's AI budget counts as updating the group.
|
||||
group, err := q.db.GetGroupByID(ctx, groupID)
|
||||
if err != nil {
|
||||
return database.GroupAiBudget{}, err
|
||||
return database.GroupAIBudget{}, err
|
||||
}
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, group); err != nil {
|
||||
return database.GroupAiBudget{}, err
|
||||
return database.GroupAIBudget{}, err
|
||||
}
|
||||
return q.db.DeleteGroupAIBudget(ctx, groupID)
|
||||
}
|
||||
@@ -2439,28 +2439,28 @@ func (q *querier) DeleteTask(ctx context.Context, arg database.DeleteTaskParams)
|
||||
return q.db.DeleteTask(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) DeleteUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (database.UserAiBudgetOverride, error) {
|
||||
func (q *querier) DeleteUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (database.UserAIBudgetOverride, error) {
|
||||
// Removing a user's AI budget override affects both the user (clearing
|
||||
// their per-user spend cap) and the group it was attributed to.
|
||||
u, err := q.db.GetUserByID(ctx, userID)
|
||||
if err != nil {
|
||||
return database.UserAiBudgetOverride{}, err
|
||||
return database.UserAIBudgetOverride{}, err
|
||||
}
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, u); err != nil {
|
||||
return database.UserAiBudgetOverride{}, err
|
||||
return database.UserAIBudgetOverride{}, err
|
||||
}
|
||||
// Fetch the existing override to learn which group it attributes spend to,
|
||||
// so we can authorize the caller against that group as well.
|
||||
userOverride, err := q.db.GetUserAIBudgetOverride(ctx, userID)
|
||||
if err != nil {
|
||||
return database.UserAiBudgetOverride{}, err
|
||||
return database.UserAIBudgetOverride{}, err
|
||||
}
|
||||
g, err := q.db.GetGroupByID(ctx, userOverride.GroupID)
|
||||
if err != nil {
|
||||
return database.UserAiBudgetOverride{}, err
|
||||
return database.UserAIBudgetOverride{}, err
|
||||
}
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, g); err != nil {
|
||||
return database.UserAiBudgetOverride{}, err
|
||||
return database.UserAIBudgetOverride{}, err
|
||||
}
|
||||
return q.db.DeleteUserAIBudgetOverride(ctx, userID)
|
||||
}
|
||||
@@ -2727,9 +2727,9 @@ func (q *querier) GetAIBridgeUserPromptsByInterceptionID(ctx context.Context, in
|
||||
return q.db.GetAIBridgeUserPromptsByInterceptionID(ctx, interceptionID)
|
||||
}
|
||||
|
||||
func (q *querier) GetAIModelPriceByProviderModel(ctx context.Context, arg database.GetAIModelPriceByProviderModelParams) (database.AiModelPrice, error) {
|
||||
func (q *querier) GetAIModelPriceByProviderModel(ctx context.Context, arg database.GetAIModelPriceByProviderModelParams) (database.AIModelPrice, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceAiModelPrice); err != nil {
|
||||
return database.AiModelPrice{}, err
|
||||
return database.AIModelPrice{}, err
|
||||
}
|
||||
return q.db.GetAIModelPriceByProviderModel(ctx, arg)
|
||||
}
|
||||
@@ -3737,14 +3737,14 @@ func (q *querier) GetGitSSHKey(ctx context.Context, userID uuid.UUID) (database.
|
||||
return fetchWithAction(q.log, q.auth, policy.ActionReadPersonal, q.db.GetGitSSHKey)(ctx, userID)
|
||||
}
|
||||
|
||||
func (q *querier) GetGroupAIBudget(ctx context.Context, groupID uuid.UUID) (database.GroupAiBudget, error) {
|
||||
func (q *querier) GetGroupAIBudget(ctx context.Context, groupID uuid.UUID) (database.GroupAIBudget, error) {
|
||||
// Reading a group's AI budget requires read on the parent group.
|
||||
group, err := q.db.GetGroupByID(ctx, groupID)
|
||||
if err != nil {
|
||||
return database.GroupAiBudget{}, err
|
||||
return database.GroupAIBudget{}, err
|
||||
}
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, group); err != nil {
|
||||
return database.GroupAiBudget{}, err
|
||||
return database.GroupAIBudget{}, err
|
||||
}
|
||||
return q.db.GetGroupAIBudget(ctx, groupID)
|
||||
}
|
||||
@@ -4794,32 +4794,32 @@ func (q *querier) GetUnexpiredLicenses(ctx context.Context) ([]database.License,
|
||||
return q.db.GetUnexpiredLicenses(ctx)
|
||||
}
|
||||
|
||||
func (q *querier) GetUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (database.UserAiBudgetOverride, error) {
|
||||
func (q *querier) GetUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (database.UserAIBudgetOverride, error) {
|
||||
if _, err := q.GetUserByID(ctx, userID); err != nil { // AuthZ check
|
||||
return database.UserAiBudgetOverride{}, err
|
||||
return database.UserAIBudgetOverride{}, err
|
||||
}
|
||||
return q.db.GetUserAIBudgetOverride(ctx, userID)
|
||||
}
|
||||
|
||||
func (q *querier) GetUserAIProviderKeyByProviderID(ctx context.Context, arg database.GetUserAIProviderKeyByProviderIDParams) (database.UserAiProviderKey, error) {
|
||||
func (q *querier) GetUserAIProviderKeyByProviderID(ctx context.Context, arg database.GetUserAIProviderKeyByProviderIDParams) (database.UserAIProviderKey, error) {
|
||||
u, err := q.db.GetUserByID(ctx, arg.UserID)
|
||||
if err != nil {
|
||||
return database.UserAiProviderKey{}, err
|
||||
return database.UserAIProviderKey{}, err
|
||||
}
|
||||
if err := q.authorizeContext(ctx, policy.ActionReadPersonal, u); err != nil {
|
||||
return database.UserAiProviderKey{}, err
|
||||
return database.UserAIProviderKey{}, err
|
||||
}
|
||||
return q.db.GetUserAIProviderKeyByProviderID(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) GetUserAIProviderKeys(ctx context.Context) ([]database.UserAiProviderKey, error) {
|
||||
func (q *querier) GetUserAIProviderKeys(ctx context.Context) ([]database.UserAIProviderKey, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceAIProvider); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetUserAIProviderKeys(ctx)
|
||||
}
|
||||
|
||||
func (q *querier) GetUserAIProviderKeysByUserID(ctx context.Context, userID uuid.UUID) ([]database.UserAiProviderKey, error) {
|
||||
func (q *querier) GetUserAIProviderKeysByUserID(ctx context.Context, userID uuid.UUID) ([]database.UserAIProviderKey, error) {
|
||||
u, err := q.db.GetUserByID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -7295,12 +7295,12 @@ func (q *querier) UpdateEncryptedAIProviderSettings(ctx context.Context, arg dat
|
||||
return q.db.UpdateEncryptedAIProviderSettings(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) UpdateEncryptedUserAIProviderKey(ctx context.Context, arg database.UpdateEncryptedUserAIProviderKeyParams) (database.UserAiProviderKey, error) {
|
||||
func (q *querier) UpdateEncryptedUserAIProviderKey(ctx context.Context, arg database.UpdateEncryptedUserAIProviderKeyParams) (database.UserAIProviderKey, error) {
|
||||
// Encrypted user-owned provider keys can be rewritten on any row so
|
||||
// dbcrypt rotation can move every key to a new digest. This is a
|
||||
// maintenance path, not the self-service user key API.
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceAIProvider); err != nil {
|
||||
return database.UserAiProviderKey{}, err
|
||||
return database.UserAIProviderKey{}, err
|
||||
}
|
||||
return q.db.UpdateEncryptedUserAIProviderKey(ctx, arg)
|
||||
}
|
||||
@@ -7831,13 +7831,13 @@ func (q *querier) UpdateUsageEventsPostPublish(ctx context.Context, arg database
|
||||
return q.db.UpdateUsageEventsPostPublish(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) UpdateUserAIProviderKey(ctx context.Context, arg database.UpdateUserAIProviderKeyParams) (database.UserAiProviderKey, error) {
|
||||
func (q *querier) UpdateUserAIProviderKey(ctx context.Context, arg database.UpdateUserAIProviderKeyParams) (database.UserAIProviderKey, error) {
|
||||
u, err := q.db.GetUserByID(ctx, arg.UserID)
|
||||
if err != nil {
|
||||
return database.UserAiProviderKey{}, err
|
||||
return database.UserAIProviderKey{}, err
|
||||
}
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdatePersonal, u); err != nil {
|
||||
return database.UserAiProviderKey{}, err
|
||||
return database.UserAIProviderKey{}, err
|
||||
}
|
||||
return q.db.UpdateUserAIProviderKey(ctx, arg)
|
||||
}
|
||||
@@ -8645,14 +8645,14 @@ func (q *querier) UpsertDefaultProxy(ctx context.Context, arg database.UpsertDef
|
||||
return q.db.UpsertDefaultProxy(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) UpsertGroupAIBudget(ctx context.Context, arg database.UpsertGroupAIBudgetParams) (database.GroupAiBudget, error) {
|
||||
func (q *querier) UpsertGroupAIBudget(ctx context.Context, arg database.UpsertGroupAIBudgetParams) (database.GroupAIBudget, error) {
|
||||
// Setting a group's AI budget counts as updating the group.
|
||||
group, err := q.db.GetGroupByID(ctx, arg.GroupID)
|
||||
if err != nil {
|
||||
return database.GroupAiBudget{}, err
|
||||
return database.GroupAIBudget{}, err
|
||||
}
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, group); err != nil {
|
||||
return database.GroupAiBudget{}, err
|
||||
return database.GroupAIBudget{}, err
|
||||
}
|
||||
return q.db.UpsertGroupAIBudget(ctx, arg)
|
||||
}
|
||||
@@ -8792,33 +8792,33 @@ func (q *querier) UpsertTemplateUsageStats(ctx context.Context) error {
|
||||
return q.db.UpsertTemplateUsageStats(ctx)
|
||||
}
|
||||
|
||||
func (q *querier) UpsertUserAIBudgetOverride(ctx context.Context, arg database.UpsertUserAIBudgetOverrideParams) (database.UserAiBudgetOverride, error) {
|
||||
func (q *querier) UpsertUserAIBudgetOverride(ctx context.Context, arg database.UpsertUserAIBudgetOverrideParams) (database.UserAIBudgetOverride, error) {
|
||||
// Setting a user's AI budget override affects both the user (their
|
||||
// per-user spend cap) and the group (spend attribution).
|
||||
u, err := q.db.GetUserByID(ctx, arg.UserID)
|
||||
if err != nil {
|
||||
return database.UserAiBudgetOverride{}, err
|
||||
return database.UserAIBudgetOverride{}, err
|
||||
}
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, u); err != nil {
|
||||
return database.UserAiBudgetOverride{}, err
|
||||
return database.UserAIBudgetOverride{}, err
|
||||
}
|
||||
g, err := q.db.GetGroupByID(ctx, arg.GroupID)
|
||||
if err != nil {
|
||||
return database.UserAiBudgetOverride{}, err
|
||||
return database.UserAIBudgetOverride{}, err
|
||||
}
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, g); err != nil {
|
||||
return database.UserAiBudgetOverride{}, err
|
||||
return database.UserAIBudgetOverride{}, err
|
||||
}
|
||||
return q.db.UpsertUserAIBudgetOverride(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) UpsertUserAIProviderKey(ctx context.Context, arg database.UpsertUserAIProviderKeyParams) (database.UserAiProviderKey, error) {
|
||||
func (q *querier) UpsertUserAIProviderKey(ctx context.Context, arg database.UpsertUserAIProviderKeyParams) (database.UserAIProviderKey, error) {
|
||||
u, err := q.db.GetUserByID(ctx, arg.UserID)
|
||||
if err != nil {
|
||||
return database.UserAiProviderKey{}, err
|
||||
return database.UserAIProviderKey{}, err
|
||||
}
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdatePersonal, u); err != nil {
|
||||
return database.UserAiProviderKey{}, err
|
||||
return database.UserAIProviderKey{}, err
|
||||
}
|
||||
return q.db.UpsertUserAIProviderKey(ctx, arg)
|
||||
}
|
||||
|
||||
@@ -3134,17 +3134,17 @@ func (s *MethodTestSuite) TestUser() {
|
||||
s.Run("GetUserAIProviderKeyByProviderID", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
|
||||
u := testutil.Fake(s.T(), faker, database.User{})
|
||||
arg := database.GetUserAIProviderKeyByProviderIDParams{UserID: u.ID, AIProviderID: uuid.New()}
|
||||
key := testutil.Fake(s.T(), faker, database.UserAiProviderKey{UserID: u.ID, AIProviderID: arg.AIProviderID})
|
||||
key := testutil.Fake(s.T(), faker, database.UserAIProviderKey{UserID: u.ID, AIProviderID: arg.AIProviderID})
|
||||
dbm.EXPECT().GetUserByID(gomock.Any(), u.ID).Return(u, nil).AnyTimes()
|
||||
dbm.EXPECT().GetUserAIProviderKeyByProviderID(gomock.Any(), arg).Return(key, nil).AnyTimes()
|
||||
check.Args(arg).Asserts(u, policy.ActionReadPersonal).Returns(key)
|
||||
}))
|
||||
s.Run("GetUserAIProviderKeysByUserID", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
|
||||
u := testutil.Fake(s.T(), faker, database.User{})
|
||||
key := testutil.Fake(s.T(), faker, database.UserAiProviderKey{UserID: u.ID})
|
||||
key := testutil.Fake(s.T(), faker, database.UserAIProviderKey{UserID: u.ID})
|
||||
dbm.EXPECT().GetUserByID(gomock.Any(), u.ID).Return(u, nil).AnyTimes()
|
||||
dbm.EXPECT().GetUserAIProviderKeysByUserID(gomock.Any(), u.ID).Return([]database.UserAiProviderKey{key}, nil).AnyTimes()
|
||||
check.Args(u.ID).Asserts(u, policy.ActionReadPersonal).Returns([]database.UserAiProviderKey{key})
|
||||
dbm.EXPECT().GetUserAIProviderKeysByUserID(gomock.Any(), u.ID).Return([]database.UserAIProviderKey{key}, nil).AnyTimes()
|
||||
check.Args(u.ID).Asserts(u, policy.ActionReadPersonal).Returns([]database.UserAIProviderKey{key})
|
||||
}))
|
||||
s.Run("DeleteUserAIProviderKeysByProviderID", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
|
||||
providerID := uuid.New()
|
||||
@@ -3161,7 +3161,7 @@ func (s *MethodTestSuite) TestUser() {
|
||||
s.Run("UpdateUserAIProviderKey", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
|
||||
u := testutil.Fake(s.T(), faker, database.User{})
|
||||
arg := database.UpdateUserAIProviderKeyParams{UserID: u.ID, AIProviderID: uuid.New(), APIKey: "updated-api-key"}
|
||||
key := testutil.Fake(s.T(), faker, database.UserAiProviderKey{UserID: u.ID, AIProviderID: arg.AIProviderID, APIKey: arg.APIKey})
|
||||
key := testutil.Fake(s.T(), faker, database.UserAIProviderKey{UserID: u.ID, AIProviderID: arg.AIProviderID, APIKey: arg.APIKey})
|
||||
dbm.EXPECT().GetUserByID(gomock.Any(), u.ID).Return(u, nil).AnyTimes()
|
||||
dbm.EXPECT().UpdateUserAIProviderKey(gomock.Any(), arg).Return(key, nil).AnyTimes()
|
||||
check.Args(arg).Asserts(u, policy.ActionUpdatePersonal).Returns(key)
|
||||
@@ -3169,7 +3169,7 @@ func (s *MethodTestSuite) TestUser() {
|
||||
s.Run("UpsertUserAIProviderKey", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
|
||||
u := testutil.Fake(s.T(), faker, database.User{})
|
||||
arg := database.UpsertUserAIProviderKeyParams{UserID: u.ID, AIProviderID: uuid.New(), APIKey: "upserted-api-key"}
|
||||
key := testutil.Fake(s.T(), faker, database.UserAiProviderKey{UserID: u.ID, AIProviderID: arg.AIProviderID, APIKey: arg.APIKey})
|
||||
key := testutil.Fake(s.T(), faker, database.UserAIProviderKey{UserID: u.ID, AIProviderID: arg.AIProviderID, APIKey: arg.APIKey})
|
||||
dbm.EXPECT().GetUserByID(gomock.Any(), u.ID).Return(u, nil).AnyTimes()
|
||||
dbm.EXPECT().UpsertUserAIProviderKey(gomock.Any(), arg).Return(key, nil).AnyTimes()
|
||||
check.Args(arg).Asserts(u, policy.ActionUpdatePersonal).Returns(key)
|
||||
@@ -6681,13 +6681,13 @@ func (s *MethodTestSuite) TestAIBridge() {
|
||||
}))
|
||||
|
||||
s.Run("GetAIModelPriceByProviderModel", s.Mocked(func(db *dbmock.MockStore, _ *gofakeit.Faker, check *expects) {
|
||||
db.EXPECT().GetAIModelPriceByProviderModel(gomock.Any(), gomock.Any()).Return(database.AiModelPrice{}, nil).AnyTimes()
|
||||
db.EXPECT().GetAIModelPriceByProviderModel(gomock.Any(), gomock.Any()).Return(database.AIModelPrice{}, nil).AnyTimes()
|
||||
check.Args(database.GetAIModelPriceByProviderModelParams{}).Asserts(rbac.ResourceAiModelPrice, policy.ActionRead)
|
||||
}))
|
||||
|
||||
s.Run("GetGroupAIBudget", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
|
||||
g := testutil.Fake(s.T(), faker, database.Group{})
|
||||
b := testutil.Fake(s.T(), faker, database.GroupAiBudget{GroupID: g.ID})
|
||||
b := testutil.Fake(s.T(), faker, database.GroupAIBudget{GroupID: g.ID})
|
||||
dbm.EXPECT().GetGroupByID(gomock.Any(), g.ID).Return(g, nil).AnyTimes()
|
||||
dbm.EXPECT().GetGroupAIBudget(gomock.Any(), g.ID).Return(b, nil).AnyTimes()
|
||||
check.Args(g.ID).Asserts(g, policy.ActionRead).Returns(b)
|
||||
@@ -6695,7 +6695,7 @@ func (s *MethodTestSuite) TestAIBridge() {
|
||||
|
||||
s.Run("UpsertGroupAIBudget", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
|
||||
g := testutil.Fake(s.T(), faker, database.Group{})
|
||||
b := testutil.Fake(s.T(), faker, database.GroupAiBudget{GroupID: g.ID})
|
||||
b := testutil.Fake(s.T(), faker, database.GroupAIBudget{GroupID: g.ID})
|
||||
arg := database.UpsertGroupAIBudgetParams{GroupID: g.ID, SpendLimitMicros: b.SpendLimitMicros}
|
||||
dbm.EXPECT().GetGroupByID(gomock.Any(), g.ID).Return(g, nil).AnyTimes()
|
||||
dbm.EXPECT().UpsertGroupAIBudget(gomock.Any(), arg).Return(b, nil).AnyTimes()
|
||||
@@ -6704,7 +6704,7 @@ func (s *MethodTestSuite) TestAIBridge() {
|
||||
|
||||
s.Run("DeleteGroupAIBudget", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
|
||||
g := testutil.Fake(s.T(), faker, database.Group{})
|
||||
b := testutil.Fake(s.T(), faker, database.GroupAiBudget{GroupID: g.ID})
|
||||
b := testutil.Fake(s.T(), faker, database.GroupAIBudget{GroupID: g.ID})
|
||||
dbm.EXPECT().GetGroupByID(gomock.Any(), g.ID).Return(g, nil).AnyTimes()
|
||||
dbm.EXPECT().DeleteGroupAIBudget(gomock.Any(), g.ID).Return(b, nil).AnyTimes()
|
||||
check.Args(g.ID).Asserts(g, policy.ActionUpdate).Returns(b)
|
||||
@@ -6712,7 +6712,7 @@ func (s *MethodTestSuite) TestAIBridge() {
|
||||
|
||||
s.Run("GetUserAIBudgetOverride", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
|
||||
user := testutil.Fake(s.T(), faker, database.User{})
|
||||
override := testutil.Fake(s.T(), faker, database.UserAiBudgetOverride{UserID: user.ID})
|
||||
override := testutil.Fake(s.T(), faker, database.UserAIBudgetOverride{UserID: user.ID})
|
||||
dbm.EXPECT().GetUserByID(gomock.Any(), user.ID).Return(user, nil).AnyTimes()
|
||||
dbm.EXPECT().GetUserAIBudgetOverride(gomock.Any(), user.ID).Return(override, nil).AnyTimes()
|
||||
check.Args(user.ID).Asserts(user, policy.ActionRead).Returns(override)
|
||||
@@ -6729,7 +6729,7 @@ func (s *MethodTestSuite) TestAIBridge() {
|
||||
s.Run("UpsertUserAIBudgetOverride", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
|
||||
user := testutil.Fake(s.T(), faker, database.User{})
|
||||
group := testutil.Fake(s.T(), faker, database.Group{})
|
||||
override := testutil.Fake(s.T(), faker, database.UserAiBudgetOverride{UserID: user.ID, GroupID: group.ID})
|
||||
override := testutil.Fake(s.T(), faker, database.UserAIBudgetOverride{UserID: user.ID, GroupID: group.ID})
|
||||
arg := database.UpsertUserAIBudgetOverrideParams{UserID: user.ID, GroupID: group.ID, SpendLimitMicros: override.SpendLimitMicros}
|
||||
dbm.EXPECT().GetUserByID(gomock.Any(), user.ID).Return(user, nil).AnyTimes()
|
||||
dbm.EXPECT().GetGroupByID(gomock.Any(), group.ID).Return(group, nil).AnyTimes()
|
||||
@@ -6740,7 +6740,7 @@ func (s *MethodTestSuite) TestAIBridge() {
|
||||
s.Run("DeleteUserAIBudgetOverride", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
|
||||
user := testutil.Fake(s.T(), faker, database.User{})
|
||||
group := testutil.Fake(s.T(), faker, database.Group{})
|
||||
override := testutil.Fake(s.T(), faker, database.UserAiBudgetOverride{UserID: user.ID, GroupID: group.ID})
|
||||
override := testutil.Fake(s.T(), faker, database.UserAIBudgetOverride{UserID: user.ID, GroupID: group.ID})
|
||||
dbm.EXPECT().GetUserByID(gomock.Any(), user.ID).Return(user, nil).AnyTimes()
|
||||
dbm.EXPECT().GetUserAIBudgetOverride(gomock.Any(), user.ID).Return(override, nil).AnyTimes()
|
||||
dbm.EXPECT().GetGroupByID(gomock.Any(), group.ID).Return(group, nil).AnyTimes()
|
||||
@@ -6773,7 +6773,7 @@ func (s *MethodTestSuite) TestAIBridge() {
|
||||
s.Run("InsertAIProvider", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
|
||||
arg := database.InsertAIProviderParams{
|
||||
ID: uuid.New(),
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
Name: "test-provider",
|
||||
Enabled: true,
|
||||
BaseUrl: "https://api.example.com/",
|
||||
@@ -6876,13 +6876,13 @@ func (s *MethodTestSuite) TestAIBridge() {
|
||||
check.Args(arg).Asserts(rbac.ResourceAIProvider, policy.ActionUpdate).Returns(key)
|
||||
}))
|
||||
s.Run("GetUserAIProviderKeys", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
|
||||
keyA := testutil.Fake(s.T(), faker, database.UserAiProviderKey{})
|
||||
keyB := testutil.Fake(s.T(), faker, database.UserAiProviderKey{})
|
||||
dbm.EXPECT().GetUserAIProviderKeys(gomock.Any()).Return([]database.UserAiProviderKey{keyA, keyB}, nil).AnyTimes()
|
||||
check.Args().Asserts(rbac.ResourceAIProvider, policy.ActionRead).Returns([]database.UserAiProviderKey{keyA, keyB})
|
||||
keyA := testutil.Fake(s.T(), faker, database.UserAIProviderKey{})
|
||||
keyB := testutil.Fake(s.T(), faker, database.UserAIProviderKey{})
|
||||
dbm.EXPECT().GetUserAIProviderKeys(gomock.Any()).Return([]database.UserAIProviderKey{keyA, keyB}, nil).AnyTimes()
|
||||
check.Args().Asserts(rbac.ResourceAIProvider, policy.ActionRead).Returns([]database.UserAIProviderKey{keyA, keyB})
|
||||
}))
|
||||
s.Run("UpdateEncryptedUserAIProviderKey", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
|
||||
key := testutil.Fake(s.T(), faker, database.UserAiProviderKey{})
|
||||
key := testutil.Fake(s.T(), faker, database.UserAIProviderKey{})
|
||||
arg := database.UpdateEncryptedUserAIProviderKeyParams{
|
||||
ID: key.ID,
|
||||
APIKey: "encrypted-api-key",
|
||||
|
||||
@@ -210,7 +210,7 @@ func AIProvider(t testing.TB, db database.Store, seed database.AIProvider, munge
|
||||
}
|
||||
provType := seed.Type
|
||||
if provType == "" {
|
||||
provType = database.AiProviderTypeOpenai
|
||||
provType = database.AIProviderTypeOpenai
|
||||
}
|
||||
name := takeFirst(seed.Name, testutil.GetRandomNameHyphenated(t))
|
||||
displayName := seed.DisplayName
|
||||
|
||||
+13
-13
@@ -594,7 +594,7 @@ func (m queryMetricsStore) DeleteExternalAuthLink(ctx context.Context, arg datab
|
||||
return r0
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) DeleteGroupAIBudget(ctx context.Context, groupID uuid.UUID) (database.GroupAiBudget, error) {
|
||||
func (m queryMetricsStore) DeleteGroupAIBudget(ctx context.Context, groupID uuid.UUID) (database.GroupAIBudget, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.DeleteGroupAIBudget(ctx, groupID)
|
||||
m.queryLatencies.WithLabelValues("DeleteGroupAIBudget").Observe(time.Since(start).Seconds())
|
||||
@@ -866,7 +866,7 @@ func (m queryMetricsStore) DeleteTask(ctx context.Context, arg database.DeleteTa
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) DeleteUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (database.UserAiBudgetOverride, error) {
|
||||
func (m queryMetricsStore) DeleteUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (database.UserAIBudgetOverride, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.DeleteUserAIBudgetOverride(ctx, userID)
|
||||
m.queryLatencies.WithLabelValues("DeleteUserAIBudgetOverride").Observe(time.Since(start).Seconds())
|
||||
@@ -1106,7 +1106,7 @@ func (m queryMetricsStore) GetAIBridgeUserPromptsByInterceptionID(ctx context.Co
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) GetAIModelPriceByProviderModel(ctx context.Context, arg database.GetAIModelPriceByProviderModelParams) (database.AiModelPrice, error) {
|
||||
func (m queryMetricsStore) GetAIModelPriceByProviderModel(ctx context.Context, arg database.GetAIModelPriceByProviderModelParams) (database.AIModelPrice, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.GetAIModelPriceByProviderModel(ctx, arg)
|
||||
m.queryLatencies.WithLabelValues("GetAIModelPriceByProviderModel").Observe(time.Since(start).Seconds())
|
||||
@@ -2082,7 +2082,7 @@ func (m queryMetricsStore) GetGitSSHKey(ctx context.Context, userID uuid.UUID) (
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) GetGroupAIBudget(ctx context.Context, groupID uuid.UUID) (database.GroupAiBudget, error) {
|
||||
func (m queryMetricsStore) GetGroupAIBudget(ctx context.Context, groupID uuid.UUID) (database.GroupAIBudget, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.GetGroupAIBudget(ctx, groupID)
|
||||
m.queryLatencies.WithLabelValues("GetGroupAIBudget").Observe(time.Since(start).Seconds())
|
||||
@@ -3106,7 +3106,7 @@ func (m queryMetricsStore) GetUnexpiredLicenses(ctx context.Context) ([]database
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) GetUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (database.UserAiBudgetOverride, error) {
|
||||
func (m queryMetricsStore) GetUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (database.UserAIBudgetOverride, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.GetUserAIBudgetOverride(ctx, userID)
|
||||
m.queryLatencies.WithLabelValues("GetUserAIBudgetOverride").Observe(time.Since(start).Seconds())
|
||||
@@ -3114,7 +3114,7 @@ func (m queryMetricsStore) GetUserAIBudgetOverride(ctx context.Context, userID u
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) GetUserAIProviderKeyByProviderID(ctx context.Context, arg database.GetUserAIProviderKeyByProviderIDParams) (database.UserAiProviderKey, error) {
|
||||
func (m queryMetricsStore) GetUserAIProviderKeyByProviderID(ctx context.Context, arg database.GetUserAIProviderKeyByProviderIDParams) (database.UserAIProviderKey, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.GetUserAIProviderKeyByProviderID(ctx, arg)
|
||||
m.queryLatencies.WithLabelValues("GetUserAIProviderKeyByProviderID").Observe(time.Since(start).Seconds())
|
||||
@@ -3122,7 +3122,7 @@ func (m queryMetricsStore) GetUserAIProviderKeyByProviderID(ctx context.Context,
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) GetUserAIProviderKeys(ctx context.Context) ([]database.UserAiProviderKey, error) {
|
||||
func (m queryMetricsStore) GetUserAIProviderKeys(ctx context.Context) ([]database.UserAIProviderKey, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.GetUserAIProviderKeys(ctx)
|
||||
m.queryLatencies.WithLabelValues("GetUserAIProviderKeys").Observe(time.Since(start).Seconds())
|
||||
@@ -3130,7 +3130,7 @@ func (m queryMetricsStore) GetUserAIProviderKeys(ctx context.Context) ([]databas
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) GetUserAIProviderKeysByUserID(ctx context.Context, userID uuid.UUID) ([]database.UserAiProviderKey, error) {
|
||||
func (m queryMetricsStore) GetUserAIProviderKeysByUserID(ctx context.Context, userID uuid.UUID) ([]database.UserAIProviderKey, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.GetUserAIProviderKeysByUserID(ctx, userID)
|
||||
m.queryLatencies.WithLabelValues("GetUserAIProviderKeysByUserID").Observe(time.Since(start).Seconds())
|
||||
@@ -5234,7 +5234,7 @@ func (m queryMetricsStore) UpdateEncryptedAIProviderSettings(ctx context.Context
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) UpdateEncryptedUserAIProviderKey(ctx context.Context, arg database.UpdateEncryptedUserAIProviderKeyParams) (database.UserAiProviderKey, error) {
|
||||
func (m queryMetricsStore) UpdateEncryptedUserAIProviderKey(ctx context.Context, arg database.UpdateEncryptedUserAIProviderKeyParams) (database.UserAIProviderKey, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.UpdateEncryptedUserAIProviderKey(ctx, arg)
|
||||
m.queryLatencies.WithLabelValues("UpdateEncryptedUserAIProviderKey").Observe(time.Since(start).Seconds())
|
||||
@@ -5570,7 +5570,7 @@ func (m queryMetricsStore) UpdateUsageEventsPostPublish(ctx context.Context, arg
|
||||
return r0
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) UpdateUserAIProviderKey(ctx context.Context, arg database.UpdateUserAIProviderKeyParams) (database.UserAiProviderKey, error) {
|
||||
func (m queryMetricsStore) UpdateUserAIProviderKey(ctx context.Context, arg database.UpdateUserAIProviderKeyParams) (database.UserAIProviderKey, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.UpdateUserAIProviderKey(ctx, arg)
|
||||
m.queryLatencies.WithLabelValues("UpdateUserAIProviderKey").Observe(time.Since(start).Seconds())
|
||||
@@ -6226,7 +6226,7 @@ func (m queryMetricsStore) UpsertDefaultProxy(ctx context.Context, arg database.
|
||||
return r0
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) UpsertGroupAIBudget(ctx context.Context, arg database.UpsertGroupAIBudgetParams) (database.GroupAiBudget, error) {
|
||||
func (m queryMetricsStore) UpsertGroupAIBudget(ctx context.Context, arg database.UpsertGroupAIBudgetParams) (database.GroupAIBudget, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.UpsertGroupAIBudget(ctx, arg)
|
||||
m.queryLatencies.WithLabelValues("UpsertGroupAIBudget").Observe(time.Since(start).Seconds())
|
||||
@@ -6370,7 +6370,7 @@ func (m queryMetricsStore) UpsertTemplateUsageStats(ctx context.Context) error {
|
||||
return r0
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) UpsertUserAIBudgetOverride(ctx context.Context, arg database.UpsertUserAIBudgetOverrideParams) (database.UserAiBudgetOverride, error) {
|
||||
func (m queryMetricsStore) UpsertUserAIBudgetOverride(ctx context.Context, arg database.UpsertUserAIBudgetOverrideParams) (database.UserAIBudgetOverride, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.UpsertUserAIBudgetOverride(ctx, arg)
|
||||
m.queryLatencies.WithLabelValues("UpsertUserAIBudgetOverride").Observe(time.Since(start).Seconds())
|
||||
@@ -6378,7 +6378,7 @@ func (m queryMetricsStore) UpsertUserAIBudgetOverride(ctx context.Context, arg d
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m queryMetricsStore) UpsertUserAIProviderKey(ctx context.Context, arg database.UpsertUserAIProviderKeyParams) (database.UserAiProviderKey, error) {
|
||||
func (m queryMetricsStore) UpsertUserAIProviderKey(ctx context.Context, arg database.UpsertUserAIProviderKeyParams) (database.UserAIProviderKey, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.UpsertUserAIProviderKey(ctx, arg)
|
||||
m.queryLatencies.WithLabelValues("UpsertUserAIProviderKey").Observe(time.Since(start).Seconds())
|
||||
|
||||
Generated
+26
-26
@@ -978,10 +978,10 @@ func (mr *MockStoreMockRecorder) DeleteExternalAuthLink(ctx, arg any) *gomock.Ca
|
||||
}
|
||||
|
||||
// DeleteGroupAIBudget mocks base method.
|
||||
func (m *MockStore) DeleteGroupAIBudget(ctx context.Context, groupID uuid.UUID) (database.GroupAiBudget, error) {
|
||||
func (m *MockStore) DeleteGroupAIBudget(ctx context.Context, groupID uuid.UUID) (database.GroupAIBudget, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DeleteGroupAIBudget", ctx, groupID)
|
||||
ret0, _ := ret[0].(database.GroupAiBudget)
|
||||
ret0, _ := ret[0].(database.GroupAIBudget)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@@ -1468,10 +1468,10 @@ func (mr *MockStoreMockRecorder) DeleteTask(ctx, arg any) *gomock.Call {
|
||||
}
|
||||
|
||||
// DeleteUserAIBudgetOverride mocks base method.
|
||||
func (m *MockStore) DeleteUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (database.UserAiBudgetOverride, error) {
|
||||
func (m *MockStore) DeleteUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (database.UserAIBudgetOverride, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DeleteUserAIBudgetOverride", ctx, userID)
|
||||
ret0, _ := ret[0].(database.UserAiBudgetOverride)
|
||||
ret0, _ := ret[0].(database.UserAIBudgetOverride)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@@ -1904,10 +1904,10 @@ func (mr *MockStoreMockRecorder) GetAIBridgeUserPromptsByInterceptionID(ctx, int
|
||||
}
|
||||
|
||||
// GetAIModelPriceByProviderModel mocks base method.
|
||||
func (m *MockStore) GetAIModelPriceByProviderModel(ctx context.Context, arg database.GetAIModelPriceByProviderModelParams) (database.AiModelPrice, error) {
|
||||
func (m *MockStore) GetAIModelPriceByProviderModel(ctx context.Context, arg database.GetAIModelPriceByProviderModelParams) (database.AIModelPrice, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetAIModelPriceByProviderModel", ctx, arg)
|
||||
ret0, _ := ret[0].(database.AiModelPrice)
|
||||
ret0, _ := ret[0].(database.AIModelPrice)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@@ -3854,10 +3854,10 @@ func (mr *MockStoreMockRecorder) GetGitSSHKey(ctx, userID any) *gomock.Call {
|
||||
}
|
||||
|
||||
// GetGroupAIBudget mocks base method.
|
||||
func (m *MockStore) GetGroupAIBudget(ctx context.Context, groupID uuid.UUID) (database.GroupAiBudget, error) {
|
||||
func (m *MockStore) GetGroupAIBudget(ctx context.Context, groupID uuid.UUID) (database.GroupAIBudget, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetGroupAIBudget", ctx, groupID)
|
||||
ret0, _ := ret[0].(database.GroupAiBudget)
|
||||
ret0, _ := ret[0].(database.GroupAIBudget)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@@ -5804,10 +5804,10 @@ func (mr *MockStoreMockRecorder) GetUnexpiredLicenses(ctx any) *gomock.Call {
|
||||
}
|
||||
|
||||
// GetUserAIBudgetOverride mocks base method.
|
||||
func (m *MockStore) GetUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (database.UserAiBudgetOverride, error) {
|
||||
func (m *MockStore) GetUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (database.UserAIBudgetOverride, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetUserAIBudgetOverride", ctx, userID)
|
||||
ret0, _ := ret[0].(database.UserAiBudgetOverride)
|
||||
ret0, _ := ret[0].(database.UserAIBudgetOverride)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@@ -5819,10 +5819,10 @@ func (mr *MockStoreMockRecorder) GetUserAIBudgetOverride(ctx, userID any) *gomoc
|
||||
}
|
||||
|
||||
// GetUserAIProviderKeyByProviderID mocks base method.
|
||||
func (m *MockStore) GetUserAIProviderKeyByProviderID(ctx context.Context, arg database.GetUserAIProviderKeyByProviderIDParams) (database.UserAiProviderKey, error) {
|
||||
func (m *MockStore) GetUserAIProviderKeyByProviderID(ctx context.Context, arg database.GetUserAIProviderKeyByProviderIDParams) (database.UserAIProviderKey, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetUserAIProviderKeyByProviderID", ctx, arg)
|
||||
ret0, _ := ret[0].(database.UserAiProviderKey)
|
||||
ret0, _ := ret[0].(database.UserAIProviderKey)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@@ -5834,10 +5834,10 @@ func (mr *MockStoreMockRecorder) GetUserAIProviderKeyByProviderID(ctx, arg any)
|
||||
}
|
||||
|
||||
// GetUserAIProviderKeys mocks base method.
|
||||
func (m *MockStore) GetUserAIProviderKeys(ctx context.Context) ([]database.UserAiProviderKey, error) {
|
||||
func (m *MockStore) GetUserAIProviderKeys(ctx context.Context) ([]database.UserAIProviderKey, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetUserAIProviderKeys", ctx)
|
||||
ret0, _ := ret[0].([]database.UserAiProviderKey)
|
||||
ret0, _ := ret[0].([]database.UserAIProviderKey)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@@ -5849,10 +5849,10 @@ func (mr *MockStoreMockRecorder) GetUserAIProviderKeys(ctx any) *gomock.Call {
|
||||
}
|
||||
|
||||
// GetUserAIProviderKeysByUserID mocks base method.
|
||||
func (m *MockStore) GetUserAIProviderKeysByUserID(ctx context.Context, userID uuid.UUID) ([]database.UserAiProviderKey, error) {
|
||||
func (m *MockStore) GetUserAIProviderKeysByUserID(ctx context.Context, userID uuid.UUID) ([]database.UserAIProviderKey, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetUserAIProviderKeysByUserID", ctx, userID)
|
||||
ret0, _ := ret[0].([]database.UserAiProviderKey)
|
||||
ret0, _ := ret[0].([]database.UserAIProviderKey)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@@ -9862,10 +9862,10 @@ func (mr *MockStoreMockRecorder) UpdateEncryptedAIProviderSettings(ctx, arg any)
|
||||
}
|
||||
|
||||
// UpdateEncryptedUserAIProviderKey mocks base method.
|
||||
func (m *MockStore) UpdateEncryptedUserAIProviderKey(ctx context.Context, arg database.UpdateEncryptedUserAIProviderKeyParams) (database.UserAiProviderKey, error) {
|
||||
func (m *MockStore) UpdateEncryptedUserAIProviderKey(ctx context.Context, arg database.UpdateEncryptedUserAIProviderKeyParams) (database.UserAIProviderKey, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "UpdateEncryptedUserAIProviderKey", ctx, arg)
|
||||
ret0, _ := ret[0].(database.UserAiProviderKey)
|
||||
ret0, _ := ret[0].(database.UserAIProviderKey)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@@ -10468,10 +10468,10 @@ func (mr *MockStoreMockRecorder) UpdateUsageEventsPostPublish(ctx, arg any) *gom
|
||||
}
|
||||
|
||||
// UpdateUserAIProviderKey mocks base method.
|
||||
func (m *MockStore) UpdateUserAIProviderKey(ctx context.Context, arg database.UpdateUserAIProviderKeyParams) (database.UserAiProviderKey, error) {
|
||||
func (m *MockStore) UpdateUserAIProviderKey(ctx context.Context, arg database.UpdateUserAIProviderKeyParams) (database.UserAIProviderKey, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "UpdateUserAIProviderKey", ctx, arg)
|
||||
ret0, _ := ret[0].(database.UserAiProviderKey)
|
||||
ret0, _ := ret[0].(database.UserAIProviderKey)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@@ -11651,10 +11651,10 @@ func (mr *MockStoreMockRecorder) UpsertDefaultProxy(ctx, arg any) *gomock.Call {
|
||||
}
|
||||
|
||||
// UpsertGroupAIBudget mocks base method.
|
||||
func (m *MockStore) UpsertGroupAIBudget(ctx context.Context, arg database.UpsertGroupAIBudgetParams) (database.GroupAiBudget, error) {
|
||||
func (m *MockStore) UpsertGroupAIBudget(ctx context.Context, arg database.UpsertGroupAIBudgetParams) (database.GroupAIBudget, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "UpsertGroupAIBudget", ctx, arg)
|
||||
ret0, _ := ret[0].(database.GroupAiBudget)
|
||||
ret0, _ := ret[0].(database.GroupAIBudget)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@@ -11910,10 +11910,10 @@ func (mr *MockStoreMockRecorder) UpsertTemplateUsageStats(ctx any) *gomock.Call
|
||||
}
|
||||
|
||||
// UpsertUserAIBudgetOverride mocks base method.
|
||||
func (m *MockStore) UpsertUserAIBudgetOverride(ctx context.Context, arg database.UpsertUserAIBudgetOverrideParams) (database.UserAiBudgetOverride, error) {
|
||||
func (m *MockStore) UpsertUserAIBudgetOverride(ctx context.Context, arg database.UpsertUserAIBudgetOverrideParams) (database.UserAIBudgetOverride, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "UpsertUserAIBudgetOverride", ctx, arg)
|
||||
ret0, _ := ret[0].(database.UserAiBudgetOverride)
|
||||
ret0, _ := ret[0].(database.UserAIBudgetOverride)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
@@ -11925,10 +11925,10 @@ func (mr *MockStoreMockRecorder) UpsertUserAIBudgetOverride(ctx, arg any) *gomoc
|
||||
}
|
||||
|
||||
// UpsertUserAIProviderKey mocks base method.
|
||||
func (m *MockStore) UpsertUserAIProviderKey(ctx context.Context, arg database.UpsertUserAIProviderKeyParams) (database.UserAiProviderKey, error) {
|
||||
func (m *MockStore) UpsertUserAIProviderKey(ctx context.Context, arg database.UpsertUserAIProviderKeyParams) (database.UserAIProviderKey, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "UpsertUserAIProviderKey", ctx, arg)
|
||||
ret0, _ := ret[0].(database.UserAiProviderKey)
|
||||
ret0, _ := ret[0].(database.UserAIProviderKey)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
+11
-11
@@ -6,10 +6,10 @@ type ForeignKeyConstraint string
|
||||
|
||||
// ForeignKeyConstraint enums.
|
||||
const (
|
||||
ForeignKeyAiProviderKeysAPIKeyKeyID ForeignKeyConstraint = "ai_provider_keys_api_key_key_id_fkey" // ALTER TABLE ONLY ai_provider_keys ADD CONSTRAINT ai_provider_keys_api_key_key_id_fkey FOREIGN KEY (api_key_key_id) REFERENCES dbcrypt_keys(active_key_digest);
|
||||
ForeignKeyAiProviderKeysProviderID ForeignKeyConstraint = "ai_provider_keys_provider_id_fkey" // ALTER TABLE ONLY ai_provider_keys ADD CONSTRAINT ai_provider_keys_provider_id_fkey FOREIGN KEY (provider_id) REFERENCES ai_providers(id) ON DELETE CASCADE;
|
||||
ForeignKeyAiProvidersSettingsKeyID ForeignKeyConstraint = "ai_providers_settings_key_id_fkey" // ALTER TABLE ONLY ai_providers ADD CONSTRAINT ai_providers_settings_key_id_fkey FOREIGN KEY (settings_key_id) REFERENCES dbcrypt_keys(active_key_digest);
|
||||
ForeignKeyAiSeatStateUserID ForeignKeyConstraint = "ai_seat_state_user_id_fkey" // ALTER TABLE ONLY ai_seat_state ADD CONSTRAINT ai_seat_state_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
ForeignKeyAIProviderKeysAPIKeyKeyID ForeignKeyConstraint = "ai_provider_keys_api_key_key_id_fkey" // ALTER TABLE ONLY ai_provider_keys ADD CONSTRAINT ai_provider_keys_api_key_key_id_fkey FOREIGN KEY (api_key_key_id) REFERENCES dbcrypt_keys(active_key_digest);
|
||||
ForeignKeyAIProviderKeysProviderID ForeignKeyConstraint = "ai_provider_keys_provider_id_fkey" // ALTER TABLE ONLY ai_provider_keys ADD CONSTRAINT ai_provider_keys_provider_id_fkey FOREIGN KEY (provider_id) REFERENCES ai_providers(id) ON DELETE CASCADE;
|
||||
ForeignKeyAIProvidersSettingsKeyID ForeignKeyConstraint = "ai_providers_settings_key_id_fkey" // ALTER TABLE ONLY ai_providers ADD CONSTRAINT ai_providers_settings_key_id_fkey FOREIGN KEY (settings_key_id) REFERENCES dbcrypt_keys(active_key_digest);
|
||||
ForeignKeyAISeatStateUserID ForeignKeyConstraint = "ai_seat_state_user_id_fkey" // ALTER TABLE ONLY ai_seat_state ADD CONSTRAINT ai_seat_state_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
ForeignKeyAibridgeInterceptionsInitiatorID ForeignKeyConstraint = "aibridge_interceptions_initiator_id_fkey" // ALTER TABLE ONLY aibridge_interceptions ADD CONSTRAINT aibridge_interceptions_initiator_id_fkey FOREIGN KEY (initiator_id) REFERENCES users(id);
|
||||
ForeignKeyAPIKeysUserIDUUID ForeignKeyConstraint = "api_keys_user_id_uuid_fkey" // ALTER TABLE ONLY api_keys ADD CONSTRAINT api_keys_user_id_uuid_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
ForeignKeyBoundarySessionsOwnerID ForeignKeyConstraint = "boundary_sessions_owner_id_fkey" // ALTER TABLE ONLY boundary_sessions ADD CONSTRAINT boundary_sessions_owner_id_fkey FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE SET NULL;
|
||||
@@ -25,7 +25,7 @@ const (
|
||||
ForeignKeyChatMessagesAPIKeyID ForeignKeyConstraint = "chat_messages_api_key_id_fkey" // ALTER TABLE ONLY chat_messages ADD CONSTRAINT chat_messages_api_key_id_fkey FOREIGN KEY (api_key_id) REFERENCES api_keys(id) ON DELETE SET NULL;
|
||||
ForeignKeyChatMessagesChatID ForeignKeyConstraint = "chat_messages_chat_id_fkey" // ALTER TABLE ONLY chat_messages ADD CONSTRAINT chat_messages_chat_id_fkey FOREIGN KEY (chat_id) REFERENCES chats(id) ON DELETE CASCADE;
|
||||
ForeignKeyChatMessagesModelConfigID ForeignKeyConstraint = "chat_messages_model_config_id_fkey" // ALTER TABLE ONLY chat_messages ADD CONSTRAINT chat_messages_model_config_id_fkey FOREIGN KEY (model_config_id) REFERENCES chat_model_configs(id);
|
||||
ForeignKeyChatModelConfigsAiProviderID ForeignKeyConstraint = "chat_model_configs_ai_provider_id_fkey" // ALTER TABLE ONLY chat_model_configs ADD CONSTRAINT chat_model_configs_ai_provider_id_fkey FOREIGN KEY (ai_provider_id) REFERENCES ai_providers(id);
|
||||
ForeignKeyChatModelConfigsAIProviderID ForeignKeyConstraint = "chat_model_configs_ai_provider_id_fkey" // ALTER TABLE ONLY chat_model_configs ADD CONSTRAINT chat_model_configs_ai_provider_id_fkey FOREIGN KEY (ai_provider_id) REFERENCES ai_providers(id);
|
||||
ForeignKeyChatModelConfigsCreatedBy ForeignKeyConstraint = "chat_model_configs_created_by_fkey" // ALTER TABLE ONLY chat_model_configs ADD CONSTRAINT chat_model_configs_created_by_fkey FOREIGN KEY (created_by) REFERENCES users(id);
|
||||
ForeignKeyChatModelConfigsUpdatedBy ForeignKeyConstraint = "chat_model_configs_updated_by_fkey" // ALTER TABLE ONLY chat_model_configs ADD CONSTRAINT chat_model_configs_updated_by_fkey FOREIGN KEY (updated_by) REFERENCES users(id);
|
||||
ForeignKeyChatQueuedMessagesAPIKeyID ForeignKeyConstraint = "chat_queued_messages_api_key_id_fkey" // ALTER TABLE ONLY chat_queued_messages ADD CONSTRAINT chat_queued_messages_api_key_id_fkey FOREIGN KEY (api_key_id) REFERENCES api_keys(id) ON DELETE SET NULL;
|
||||
@@ -48,7 +48,7 @@ const (
|
||||
ForeignKeyGitAuthLinksOauthRefreshTokenKeyID ForeignKeyConstraint = "git_auth_links_oauth_refresh_token_key_id_fkey" // ALTER TABLE ONLY external_auth_links ADD CONSTRAINT git_auth_links_oauth_refresh_token_key_id_fkey FOREIGN KEY (oauth_refresh_token_key_id) REFERENCES dbcrypt_keys(active_key_digest);
|
||||
ForeignKeyGitSSHKeysPrivateKeyKeyID ForeignKeyConstraint = "gitsshkeys_private_key_key_id_fkey" // ALTER TABLE ONLY gitsshkeys ADD CONSTRAINT gitsshkeys_private_key_key_id_fkey FOREIGN KEY (private_key_key_id) REFERENCES dbcrypt_keys(active_key_digest);
|
||||
ForeignKeyGitSSHKeysUserID ForeignKeyConstraint = "gitsshkeys_user_id_fkey" // ALTER TABLE ONLY gitsshkeys ADD CONSTRAINT gitsshkeys_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id);
|
||||
ForeignKeyGroupAiBudgetsGroupID ForeignKeyConstraint = "group_ai_budgets_group_id_fkey" // ALTER TABLE ONLY group_ai_budgets ADD CONSTRAINT group_ai_budgets_group_id_fkey FOREIGN KEY (group_id) REFERENCES groups(id) ON DELETE CASCADE;
|
||||
ForeignKeyGroupAIBudgetsGroupID ForeignKeyConstraint = "group_ai_budgets_group_id_fkey" // ALTER TABLE ONLY group_ai_budgets ADD CONSTRAINT group_ai_budgets_group_id_fkey FOREIGN KEY (group_id) REFERENCES groups(id) ON DELETE CASCADE;
|
||||
ForeignKeyGroupMembersGroupID ForeignKeyConstraint = "group_members_group_id_fkey" // ALTER TABLE ONLY group_members ADD CONSTRAINT group_members_group_id_fkey FOREIGN KEY (group_id) REFERENCES groups(id) ON DELETE CASCADE;
|
||||
ForeignKeyGroupMembersUserID ForeignKeyConstraint = "group_members_user_id_fkey" // ALTER TABLE ONLY group_members ADD CONSTRAINT group_members_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
ForeignKeyGroupsOrganizationID ForeignKeyConstraint = "groups_organization_id_fkey" // ALTER TABLE ONLY groups ADD CONSTRAINT groups_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
|
||||
@@ -106,11 +106,11 @@ const (
|
||||
ForeignKeyTemplateVersionsTemplateID ForeignKeyConstraint = "template_versions_template_id_fkey" // ALTER TABLE ONLY template_versions ADD CONSTRAINT template_versions_template_id_fkey FOREIGN KEY (template_id) REFERENCES templates(id) ON DELETE CASCADE;
|
||||
ForeignKeyTemplatesCreatedBy ForeignKeyConstraint = "templates_created_by_fkey" // ALTER TABLE ONLY templates ADD CONSTRAINT templates_created_by_fkey FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE RESTRICT;
|
||||
ForeignKeyTemplatesOrganizationID ForeignKeyConstraint = "templates_organization_id_fkey" // ALTER TABLE ONLY templates ADD CONSTRAINT templates_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
|
||||
ForeignKeyUserAiBudgetOverridesGroupID ForeignKeyConstraint = "user_ai_budget_overrides_group_id_fkey" // ALTER TABLE ONLY user_ai_budget_overrides ADD CONSTRAINT user_ai_budget_overrides_group_id_fkey FOREIGN KEY (group_id) REFERENCES groups(id) ON DELETE CASCADE;
|
||||
ForeignKeyUserAiBudgetOverridesUserID ForeignKeyConstraint = "user_ai_budget_overrides_user_id_fkey" // ALTER TABLE ONLY user_ai_budget_overrides ADD CONSTRAINT user_ai_budget_overrides_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
ForeignKeyUserAiProviderKeysAiProviderID ForeignKeyConstraint = "user_ai_provider_keys_ai_provider_id_fkey" // ALTER TABLE ONLY user_ai_provider_keys ADD CONSTRAINT user_ai_provider_keys_ai_provider_id_fkey FOREIGN KEY (ai_provider_id) REFERENCES ai_providers(id) ON DELETE CASCADE;
|
||||
ForeignKeyUserAiProviderKeysAPIKeyKeyID ForeignKeyConstraint = "user_ai_provider_keys_api_key_key_id_fkey" // ALTER TABLE ONLY user_ai_provider_keys ADD CONSTRAINT user_ai_provider_keys_api_key_key_id_fkey FOREIGN KEY (api_key_key_id) REFERENCES dbcrypt_keys(active_key_digest);
|
||||
ForeignKeyUserAiProviderKeysUserID ForeignKeyConstraint = "user_ai_provider_keys_user_id_fkey" // ALTER TABLE ONLY user_ai_provider_keys ADD CONSTRAINT user_ai_provider_keys_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
ForeignKeyUserAIBudgetOverridesGroupID ForeignKeyConstraint = "user_ai_budget_overrides_group_id_fkey" // ALTER TABLE ONLY user_ai_budget_overrides ADD CONSTRAINT user_ai_budget_overrides_group_id_fkey FOREIGN KEY (group_id) REFERENCES groups(id) ON DELETE CASCADE;
|
||||
ForeignKeyUserAIBudgetOverridesUserID ForeignKeyConstraint = "user_ai_budget_overrides_user_id_fkey" // ALTER TABLE ONLY user_ai_budget_overrides ADD CONSTRAINT user_ai_budget_overrides_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
ForeignKeyUserAIProviderKeysAIProviderID ForeignKeyConstraint = "user_ai_provider_keys_ai_provider_id_fkey" // ALTER TABLE ONLY user_ai_provider_keys ADD CONSTRAINT user_ai_provider_keys_ai_provider_id_fkey FOREIGN KEY (ai_provider_id) REFERENCES ai_providers(id) ON DELETE CASCADE;
|
||||
ForeignKeyUserAIProviderKeysAPIKeyKeyID ForeignKeyConstraint = "user_ai_provider_keys_api_key_key_id_fkey" // ALTER TABLE ONLY user_ai_provider_keys ADD CONSTRAINT user_ai_provider_keys_api_key_key_id_fkey FOREIGN KEY (api_key_key_id) REFERENCES dbcrypt_keys(active_key_digest);
|
||||
ForeignKeyUserAIProviderKeysUserID ForeignKeyConstraint = "user_ai_provider_keys_user_id_fkey" // ALTER TABLE ONLY user_ai_provider_keys ADD CONSTRAINT user_ai_provider_keys_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
ForeignKeyUserConfigsUserID ForeignKeyConstraint = "user_configs_user_id_fkey" // ALTER TABLE ONLY user_configs ADD CONSTRAINT user_configs_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
ForeignKeyUserDeletedUserID ForeignKeyConstraint = "user_deleted_user_id_fkey" // ALTER TABLE ONLY user_deleted ADD CONSTRAINT user_deleted_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id);
|
||||
ForeignKeyUserLinksOauthAccessTokenKeyID ForeignKeyConstraint = "user_links_oauth_access_token_key_id_fkey" // ALTER TABLE ONLY user_links ADD CONSTRAINT user_links_oauth_access_token_key_id_fkey FOREIGN KEY (oauth_access_token_key_id) REFERENCES dbcrypt_keys(active_key_digest);
|
||||
|
||||
@@ -84,38 +84,38 @@ type AuditableGroup struct {
|
||||
Members []GroupMemberTable `json:"members"`
|
||||
}
|
||||
|
||||
// AuditableGroupAiBudget is the audit-log representation of GroupAiBudget.
|
||||
// AuditableGroupAIBudget is the audit-log representation of GroupAIBudget.
|
||||
// It enriches the raw record with the group's name and a human-readable
|
||||
// spend limit so audit entries can display meaningful values instead of
|
||||
// UUIDs and micros.
|
||||
type AuditableGroupAiBudget struct {
|
||||
GroupAiBudget
|
||||
type AuditableGroupAIBudget struct {
|
||||
GroupAIBudget
|
||||
GroupName string `json:"group_name"`
|
||||
SpendLimit string `json:"spend_limit"`
|
||||
}
|
||||
|
||||
func (b GroupAiBudget) Auditable(groupName string) AuditableGroupAiBudget {
|
||||
return AuditableGroupAiBudget{
|
||||
GroupAiBudget: b,
|
||||
func (b GroupAIBudget) Auditable(groupName string) AuditableGroupAIBudget {
|
||||
return AuditableGroupAIBudget{
|
||||
GroupAIBudget: b,
|
||||
GroupName: groupName,
|
||||
SpendLimit: fmt.Sprintf("$%.2f", float64(b.SpendLimitMicros)/1_000_000),
|
||||
}
|
||||
}
|
||||
|
||||
// AuditableUserAiBudgetOverride is the audit-log representation of
|
||||
// UserAiBudgetOverride. It enriches the raw record with the username, the
|
||||
// AuditableUserAIBudgetOverride is the audit-log representation of
|
||||
// UserAIBudgetOverride. It enriches the raw record with the username, the
|
||||
// attributed group's name, and a human-readable spend limit so audit
|
||||
// entries can display meaningful values instead of UUIDs and micros.
|
||||
type AuditableUserAiBudgetOverride struct {
|
||||
UserAiBudgetOverride
|
||||
type AuditableUserAIBudgetOverride struct {
|
||||
UserAIBudgetOverride
|
||||
Username string `json:"username"`
|
||||
GroupName string `json:"group_name"`
|
||||
SpendLimit string `json:"spend_limit"`
|
||||
}
|
||||
|
||||
func (o UserAiBudgetOverride) Auditable(username, groupName string) AuditableUserAiBudgetOverride {
|
||||
return AuditableUserAiBudgetOverride{
|
||||
UserAiBudgetOverride: o,
|
||||
func (o UserAIBudgetOverride) Auditable(username, groupName string) AuditableUserAIBudgetOverride {
|
||||
return AuditableUserAIBudgetOverride{
|
||||
UserAIBudgetOverride: o,
|
||||
Username: username,
|
||||
GroupName: groupName,
|
||||
SpendLimit: fmt.Sprintf("$%.2f", float64(o.SpendLimitMicros)/1_000_000),
|
||||
|
||||
Generated
+163
-163
@@ -19,15 +19,15 @@ import (
|
||||
type AIProviderType string
|
||||
|
||||
const (
|
||||
AiProviderTypeOpenai AIProviderType = "openai"
|
||||
AiProviderTypeAnthropic AIProviderType = "anthropic"
|
||||
AiProviderTypeAzure AIProviderType = "azure"
|
||||
AiProviderTypeBedrock AIProviderType = "bedrock"
|
||||
AiProviderTypeGoogle AIProviderType = "google"
|
||||
AiProviderTypeOpenaiCompat AIProviderType = "openai-compat"
|
||||
AiProviderTypeOpenrouter AIProviderType = "openrouter"
|
||||
AiProviderTypeVercel AIProviderType = "vercel"
|
||||
AiProviderTypeCopilot AIProviderType = "copilot"
|
||||
AIProviderTypeOpenai AIProviderType = "openai"
|
||||
AIProviderTypeAnthropic AIProviderType = "anthropic"
|
||||
AIProviderTypeAzure AIProviderType = "azure"
|
||||
AIProviderTypeBedrock AIProviderType = "bedrock"
|
||||
AIProviderTypeGoogle AIProviderType = "google"
|
||||
AIProviderTypeOpenaiCompat AIProviderType = "openai-compat"
|
||||
AIProviderTypeOpenrouter AIProviderType = "openrouter"
|
||||
AIProviderTypeVercel AIProviderType = "vercel"
|
||||
AIProviderTypeCopilot AIProviderType = "copilot"
|
||||
)
|
||||
|
||||
func (e *AIProviderType) Scan(src interface{}) error {
|
||||
@@ -67,15 +67,15 @@ func (ns NullAIProviderType) Value() (driver.Value, error) {
|
||||
|
||||
func (e AIProviderType) Valid() bool {
|
||||
switch e {
|
||||
case AiProviderTypeOpenai,
|
||||
AiProviderTypeAnthropic,
|
||||
AiProviderTypeAzure,
|
||||
AiProviderTypeBedrock,
|
||||
AiProviderTypeGoogle,
|
||||
AiProviderTypeOpenaiCompat,
|
||||
AiProviderTypeOpenrouter,
|
||||
AiProviderTypeVercel,
|
||||
AiProviderTypeCopilot:
|
||||
case AIProviderTypeOpenai,
|
||||
AIProviderTypeAnthropic,
|
||||
AIProviderTypeAzure,
|
||||
AIProviderTypeBedrock,
|
||||
AIProviderTypeGoogle,
|
||||
AIProviderTypeOpenaiCompat,
|
||||
AIProviderTypeOpenrouter,
|
||||
AIProviderTypeVercel,
|
||||
AIProviderTypeCopilot:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -83,15 +83,73 @@ func (e AIProviderType) Valid() bool {
|
||||
|
||||
func AllAIProviderTypeValues() []AIProviderType {
|
||||
return []AIProviderType{
|
||||
AiProviderTypeOpenai,
|
||||
AiProviderTypeAnthropic,
|
||||
AiProviderTypeAzure,
|
||||
AiProviderTypeBedrock,
|
||||
AiProviderTypeGoogle,
|
||||
AiProviderTypeOpenaiCompat,
|
||||
AiProviderTypeOpenrouter,
|
||||
AiProviderTypeVercel,
|
||||
AiProviderTypeCopilot,
|
||||
AIProviderTypeOpenai,
|
||||
AIProviderTypeAnthropic,
|
||||
AIProviderTypeAzure,
|
||||
AIProviderTypeBedrock,
|
||||
AIProviderTypeGoogle,
|
||||
AIProviderTypeOpenaiCompat,
|
||||
AIProviderTypeOpenrouter,
|
||||
AIProviderTypeVercel,
|
||||
AIProviderTypeCopilot,
|
||||
}
|
||||
}
|
||||
|
||||
type AISeatUsageReason string
|
||||
|
||||
const (
|
||||
AISeatUsageReasonAibridge AISeatUsageReason = "aibridge"
|
||||
AISeatUsageReasonTask AISeatUsageReason = "task"
|
||||
)
|
||||
|
||||
func (e *AISeatUsageReason) Scan(src interface{}) error {
|
||||
switch s := src.(type) {
|
||||
case []byte:
|
||||
*e = AISeatUsageReason(s)
|
||||
case string:
|
||||
*e = AISeatUsageReason(s)
|
||||
default:
|
||||
return fmt.Errorf("unsupported scan type for AISeatUsageReason: %T", src)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type NullAISeatUsageReason struct {
|
||||
AISeatUsageReason AISeatUsageReason `json:"ai_seat_usage_reason"`
|
||||
Valid bool `json:"valid"` // Valid is true if AISeatUsageReason is not NULL
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (ns *NullAISeatUsageReason) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
ns.AISeatUsageReason, ns.Valid = "", false
|
||||
return nil
|
||||
}
|
||||
ns.Valid = true
|
||||
return ns.AISeatUsageReason.Scan(value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (ns NullAISeatUsageReason) Value() (driver.Value, error) {
|
||||
if !ns.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return string(ns.AISeatUsageReason), nil
|
||||
}
|
||||
|
||||
func (e AISeatUsageReason) Valid() bool {
|
||||
switch e {
|
||||
case AISeatUsageReasonAibridge,
|
||||
AISeatUsageReasonTask:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func AllAISeatUsageReasonValues() []AISeatUsageReason {
|
||||
return []AISeatUsageReason{
|
||||
AISeatUsageReasonAibridge,
|
||||
AISeatUsageReasonTask,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,17 +361,17 @@ const (
|
||||
ApiKeyScopeChatUpdate APIKeyScope = "chat:update"
|
||||
ApiKeyScopeChatDelete APIKeyScope = "chat:delete"
|
||||
ApiKeyScopeChat APIKeyScope = "chat:*"
|
||||
ApiKeyScopeAiSeat APIKeyScope = "ai_seat:*"
|
||||
ApiKeyScopeAiSeatCreate APIKeyScope = "ai_seat:create"
|
||||
ApiKeyScopeAiSeatRead APIKeyScope = "ai_seat:read"
|
||||
ApiKeyScopeAiModelPrice APIKeyScope = "ai_model_price:*"
|
||||
ApiKeyScopeAiModelPriceRead APIKeyScope = "ai_model_price:read"
|
||||
ApiKeyScopeAiModelPriceUpdate APIKeyScope = "ai_model_price:update"
|
||||
ApiKeyScopeAiProvider APIKeyScope = "ai_provider:*"
|
||||
ApiKeyScopeAiProviderCreate APIKeyScope = "ai_provider:create"
|
||||
ApiKeyScopeAiProviderDelete APIKeyScope = "ai_provider:delete"
|
||||
ApiKeyScopeAiProviderRead APIKeyScope = "ai_provider:read"
|
||||
ApiKeyScopeAiProviderUpdate APIKeyScope = "ai_provider:update"
|
||||
ApiKeyScopeAISeat APIKeyScope = "ai_seat:*"
|
||||
ApiKeyScopeAISeatCreate APIKeyScope = "ai_seat:create"
|
||||
ApiKeyScopeAISeatRead APIKeyScope = "ai_seat:read"
|
||||
ApiKeyScopeAIModelPrice APIKeyScope = "ai_model_price:*"
|
||||
ApiKeyScopeAIModelPriceRead APIKeyScope = "ai_model_price:read"
|
||||
ApiKeyScopeAIModelPriceUpdate APIKeyScope = "ai_model_price:update"
|
||||
ApiKeyScopeAIProvider APIKeyScope = "ai_provider:*"
|
||||
ApiKeyScopeAIProviderCreate APIKeyScope = "ai_provider:create"
|
||||
ApiKeyScopeAIProviderDelete APIKeyScope = "ai_provider:delete"
|
||||
ApiKeyScopeAIProviderRead APIKeyScope = "ai_provider:read"
|
||||
ApiKeyScopeAIProviderUpdate APIKeyScope = "ai_provider:update"
|
||||
ApiKeyScopeChatShare APIKeyScope = "chat:share"
|
||||
ApiKeyScopeUserSkillCreate APIKeyScope = "user_skill:create"
|
||||
ApiKeyScopeUserSkillRead APIKeyScope = "user_skill:read"
|
||||
@@ -324,10 +382,10 @@ const (
|
||||
ApiKeyScopeBoundaryLogCreate APIKeyScope = "boundary_log:create"
|
||||
ApiKeyScopeBoundaryLogDelete APIKeyScope = "boundary_log:delete"
|
||||
ApiKeyScopeBoundaryLogRead APIKeyScope = "boundary_log:read"
|
||||
ApiKeyScopeAiGatewayKey APIKeyScope = "ai_gateway_key:*"
|
||||
ApiKeyScopeAiGatewayKeyCreate APIKeyScope = "ai_gateway_key:create"
|
||||
ApiKeyScopeAiGatewayKeyDelete APIKeyScope = "ai_gateway_key:delete"
|
||||
ApiKeyScopeAiGatewayKeyRead APIKeyScope = "ai_gateway_key:read"
|
||||
ApiKeyScopeAIGatewayKey APIKeyScope = "ai_gateway_key:*"
|
||||
ApiKeyScopeAIGatewayKeyCreate APIKeyScope = "ai_gateway_key:create"
|
||||
ApiKeyScopeAIGatewayKeyDelete APIKeyScope = "ai_gateway_key:delete"
|
||||
ApiKeyScopeAIGatewayKeyRead APIKeyScope = "ai_gateway_key:read"
|
||||
)
|
||||
|
||||
func (e *APIKeyScope) Scan(src interface{}) error {
|
||||
@@ -572,17 +630,17 @@ func (e APIKeyScope) Valid() bool {
|
||||
ApiKeyScopeChatUpdate,
|
||||
ApiKeyScopeChatDelete,
|
||||
ApiKeyScopeChat,
|
||||
ApiKeyScopeAiSeat,
|
||||
ApiKeyScopeAiSeatCreate,
|
||||
ApiKeyScopeAiSeatRead,
|
||||
ApiKeyScopeAiModelPrice,
|
||||
ApiKeyScopeAiModelPriceRead,
|
||||
ApiKeyScopeAiModelPriceUpdate,
|
||||
ApiKeyScopeAiProvider,
|
||||
ApiKeyScopeAiProviderCreate,
|
||||
ApiKeyScopeAiProviderDelete,
|
||||
ApiKeyScopeAiProviderRead,
|
||||
ApiKeyScopeAiProviderUpdate,
|
||||
ApiKeyScopeAISeat,
|
||||
ApiKeyScopeAISeatCreate,
|
||||
ApiKeyScopeAISeatRead,
|
||||
ApiKeyScopeAIModelPrice,
|
||||
ApiKeyScopeAIModelPriceRead,
|
||||
ApiKeyScopeAIModelPriceUpdate,
|
||||
ApiKeyScopeAIProvider,
|
||||
ApiKeyScopeAIProviderCreate,
|
||||
ApiKeyScopeAIProviderDelete,
|
||||
ApiKeyScopeAIProviderRead,
|
||||
ApiKeyScopeAIProviderUpdate,
|
||||
ApiKeyScopeChatShare,
|
||||
ApiKeyScopeUserSkillCreate,
|
||||
ApiKeyScopeUserSkillRead,
|
||||
@@ -593,10 +651,10 @@ func (e APIKeyScope) Valid() bool {
|
||||
ApiKeyScopeBoundaryLogCreate,
|
||||
ApiKeyScopeBoundaryLogDelete,
|
||||
ApiKeyScopeBoundaryLogRead,
|
||||
ApiKeyScopeAiGatewayKey,
|
||||
ApiKeyScopeAiGatewayKeyCreate,
|
||||
ApiKeyScopeAiGatewayKeyDelete,
|
||||
ApiKeyScopeAiGatewayKeyRead:
|
||||
ApiKeyScopeAIGatewayKey,
|
||||
ApiKeyScopeAIGatewayKeyCreate,
|
||||
ApiKeyScopeAIGatewayKeyDelete,
|
||||
ApiKeyScopeAIGatewayKeyRead:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -809,17 +867,17 @@ func AllAPIKeyScopeValues() []APIKeyScope {
|
||||
ApiKeyScopeChatUpdate,
|
||||
ApiKeyScopeChatDelete,
|
||||
ApiKeyScopeChat,
|
||||
ApiKeyScopeAiSeat,
|
||||
ApiKeyScopeAiSeatCreate,
|
||||
ApiKeyScopeAiSeatRead,
|
||||
ApiKeyScopeAiModelPrice,
|
||||
ApiKeyScopeAiModelPriceRead,
|
||||
ApiKeyScopeAiModelPriceUpdate,
|
||||
ApiKeyScopeAiProvider,
|
||||
ApiKeyScopeAiProviderCreate,
|
||||
ApiKeyScopeAiProviderDelete,
|
||||
ApiKeyScopeAiProviderRead,
|
||||
ApiKeyScopeAiProviderUpdate,
|
||||
ApiKeyScopeAISeat,
|
||||
ApiKeyScopeAISeatCreate,
|
||||
ApiKeyScopeAISeatRead,
|
||||
ApiKeyScopeAIModelPrice,
|
||||
ApiKeyScopeAIModelPriceRead,
|
||||
ApiKeyScopeAIModelPriceUpdate,
|
||||
ApiKeyScopeAIProvider,
|
||||
ApiKeyScopeAIProviderCreate,
|
||||
ApiKeyScopeAIProviderDelete,
|
||||
ApiKeyScopeAIProviderRead,
|
||||
ApiKeyScopeAIProviderUpdate,
|
||||
ApiKeyScopeChatShare,
|
||||
ApiKeyScopeUserSkillCreate,
|
||||
ApiKeyScopeUserSkillRead,
|
||||
@@ -830,10 +888,10 @@ func AllAPIKeyScopeValues() []APIKeyScope {
|
||||
ApiKeyScopeBoundaryLogCreate,
|
||||
ApiKeyScopeBoundaryLogDelete,
|
||||
ApiKeyScopeBoundaryLogRead,
|
||||
ApiKeyScopeAiGatewayKey,
|
||||
ApiKeyScopeAiGatewayKeyCreate,
|
||||
ApiKeyScopeAiGatewayKeyDelete,
|
||||
ApiKeyScopeAiGatewayKeyRead,
|
||||
ApiKeyScopeAIGatewayKey,
|
||||
ApiKeyScopeAIGatewayKeyCreate,
|
||||
ApiKeyScopeAIGatewayKeyDelete,
|
||||
ApiKeyScopeAIGatewayKeyRead,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -895,64 +953,6 @@ func AllAgentKeyScopeEnumValues() []AgentKeyScopeEnum {
|
||||
}
|
||||
}
|
||||
|
||||
type AiSeatUsageReason string
|
||||
|
||||
const (
|
||||
AiSeatUsageReasonAibridge AiSeatUsageReason = "aibridge"
|
||||
AiSeatUsageReasonTask AiSeatUsageReason = "task"
|
||||
)
|
||||
|
||||
func (e *AiSeatUsageReason) Scan(src interface{}) error {
|
||||
switch s := src.(type) {
|
||||
case []byte:
|
||||
*e = AiSeatUsageReason(s)
|
||||
case string:
|
||||
*e = AiSeatUsageReason(s)
|
||||
default:
|
||||
return fmt.Errorf("unsupported scan type for AiSeatUsageReason: %T", src)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type NullAiSeatUsageReason struct {
|
||||
AiSeatUsageReason AiSeatUsageReason `json:"ai_seat_usage_reason"`
|
||||
Valid bool `json:"valid"` // Valid is true if AiSeatUsageReason is not NULL
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (ns *NullAiSeatUsageReason) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
ns.AiSeatUsageReason, ns.Valid = "", false
|
||||
return nil
|
||||
}
|
||||
ns.Valid = true
|
||||
return ns.AiSeatUsageReason.Scan(value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (ns NullAiSeatUsageReason) Value() (driver.Value, error) {
|
||||
if !ns.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return string(ns.AiSeatUsageReason), nil
|
||||
}
|
||||
|
||||
func (e AiSeatUsageReason) Valid() bool {
|
||||
switch e {
|
||||
case AiSeatUsageReasonAibridge,
|
||||
AiSeatUsageReasonTask:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func AllAiSeatUsageReasonValues() []AiSeatUsageReason {
|
||||
return []AiSeatUsageReason{
|
||||
AiSeatUsageReasonAibridge,
|
||||
AiSeatUsageReasonTask,
|
||||
}
|
||||
}
|
||||
|
||||
type AppSharingLevel string
|
||||
|
||||
const (
|
||||
@@ -3361,15 +3361,15 @@ const (
|
||||
ResourceTypeWorkspaceApp ResourceType = "workspace_app"
|
||||
ResourceTypePrebuildsSettings ResourceType = "prebuilds_settings"
|
||||
ResourceTypeTask ResourceType = "task"
|
||||
ResourceTypeAiSeat ResourceType = "ai_seat"
|
||||
ResourceTypeAISeat ResourceType = "ai_seat"
|
||||
ResourceTypeChat ResourceType = "chat"
|
||||
ResourceTypeUserSecret ResourceType = "user_secret"
|
||||
ResourceTypeAIProvider ResourceType = "ai_provider"
|
||||
ResourceTypeAIProviderKey ResourceType = "ai_provider_key"
|
||||
ResourceTypeGroupAiBudget ResourceType = "group_ai_budget"
|
||||
ResourceTypeGroupAIBudget ResourceType = "group_ai_budget"
|
||||
ResourceTypeUserSkill ResourceType = "user_skill"
|
||||
ResourceTypeAIGatewayKey ResourceType = "ai_gateway_key"
|
||||
ResourceTypeUserAiBudgetOverride ResourceType = "user_ai_budget_override"
|
||||
ResourceTypeUserAIBudgetOverride ResourceType = "user_ai_budget_override"
|
||||
)
|
||||
|
||||
func (e *ResourceType) Scan(src interface{}) error {
|
||||
@@ -3435,15 +3435,15 @@ func (e ResourceType) Valid() bool {
|
||||
ResourceTypeWorkspaceApp,
|
||||
ResourceTypePrebuildsSettings,
|
||||
ResourceTypeTask,
|
||||
ResourceTypeAiSeat,
|
||||
ResourceTypeAISeat,
|
||||
ResourceTypeChat,
|
||||
ResourceTypeUserSecret,
|
||||
ResourceTypeAIProvider,
|
||||
ResourceTypeAIProviderKey,
|
||||
ResourceTypeGroupAiBudget,
|
||||
ResourceTypeGroupAIBudget,
|
||||
ResourceTypeUserSkill,
|
||||
ResourceTypeAIGatewayKey,
|
||||
ResourceTypeUserAiBudgetOverride:
|
||||
ResourceTypeUserAIBudgetOverride:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -3477,15 +3477,15 @@ func AllResourceTypeValues() []ResourceType {
|
||||
ResourceTypeWorkspaceApp,
|
||||
ResourceTypePrebuildsSettings,
|
||||
ResourceTypeTask,
|
||||
ResourceTypeAiSeat,
|
||||
ResourceTypeAISeat,
|
||||
ResourceTypeChat,
|
||||
ResourceTypeUserSecret,
|
||||
ResourceTypeAIProvider,
|
||||
ResourceTypeAIProviderKey,
|
||||
ResourceTypeGroupAiBudget,
|
||||
ResourceTypeGroupAIBudget,
|
||||
ResourceTypeUserSkill,
|
||||
ResourceTypeAIGatewayKey,
|
||||
ResourceTypeUserAiBudgetOverride,
|
||||
ResourceTypeUserAIBudgetOverride,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4614,6 +4614,18 @@ type AIGatewayKey struct {
|
||||
LastUsedAt sql.NullTime `db:"last_used_at" json:"last_used_at"`
|
||||
}
|
||||
|
||||
// Per-model token prices used by AI Bridge to compute interception cost.
|
||||
type AIModelPrice struct {
|
||||
Provider string `db:"provider" json:"provider"`
|
||||
Model string `db:"model" json:"model"`
|
||||
InputPrice sql.NullInt64 `db:"input_price" json:"input_price"`
|
||||
OutputPrice sql.NullInt64 `db:"output_price" json:"output_price"`
|
||||
CacheReadPrice sql.NullInt64 `db:"cache_read_price" json:"cache_read_price"`
|
||||
CacheWritePrice sql.NullInt64 `db:"cache_write_price" json:"cache_write_price"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
}
|
||||
|
||||
// Runtime configuration for AI providers. Authoritative source for the provider set served by aibridged. Replaces deployment-time CODER_AIBRIDGE_* environment variables.
|
||||
type AIProvider struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
@@ -4645,6 +4657,15 @@ type AIProviderKey struct {
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
}
|
||||
|
||||
type AISeatState struct {
|
||||
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
||||
FirstUsedAt time.Time `db:"first_used_at" json:"first_used_at"`
|
||||
LastUsedAt time.Time `db:"last_used_at" json:"last_used_at"`
|
||||
LastEventType AISeatUsageReason `db:"last_event_type" json:"last_event_type"`
|
||||
LastEventDescription string `db:"last_event_description" json:"last_event_description"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
}
|
||||
|
||||
type APIKey struct {
|
||||
ID string `db:"id" json:"id"`
|
||||
// hashed_secret contains a SHA256 hash of the key secret. This is considered a secret and MUST NOT be returned from the API as it is used for API key encryption in app proxying code.
|
||||
@@ -4662,27 +4683,6 @@ type APIKey struct {
|
||||
AllowList AllowList `db:"allow_list" json:"allow_list"`
|
||||
}
|
||||
|
||||
// Per-model token prices used by AI Bridge to compute interception cost.
|
||||
type AiModelPrice struct {
|
||||
Provider string `db:"provider" json:"provider"`
|
||||
Model string `db:"model" json:"model"`
|
||||
InputPrice sql.NullInt64 `db:"input_price" json:"input_price"`
|
||||
OutputPrice sql.NullInt64 `db:"output_price" json:"output_price"`
|
||||
CacheReadPrice sql.NullInt64 `db:"cache_read_price" json:"cache_read_price"`
|
||||
CacheWritePrice sql.NullInt64 `db:"cache_write_price" json:"cache_write_price"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
}
|
||||
|
||||
type AiSeatState struct {
|
||||
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
||||
FirstUsedAt time.Time `db:"first_used_at" json:"first_used_at"`
|
||||
LastUsedAt time.Time `db:"last_used_at" json:"last_used_at"`
|
||||
LastEventType AiSeatUsageReason `db:"last_event_type" json:"last_event_type"`
|
||||
LastEventDescription string `db:"last_event_description" json:"last_event_description"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
}
|
||||
|
||||
type AuditLog struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
Time time.Time `db:"time" json:"time"`
|
||||
@@ -5126,7 +5126,7 @@ type Group struct {
|
||||
}
|
||||
|
||||
// Per-group AI spend limit applied to each member of the group. No row means no budget is enforced.
|
||||
type GroupAiBudget struct {
|
||||
type GroupAIBudget struct {
|
||||
GroupID uuid.UUID `db:"group_id" json:"group_id"`
|
||||
SpendLimitMicros int64 `db:"spend_limit_micros" json:"spend_limit_micros"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
@@ -5955,7 +5955,7 @@ type User struct {
|
||||
}
|
||||
|
||||
// Per-user AI spend override that supersedes group budget resolution.
|
||||
type UserAiBudgetOverride struct {
|
||||
type UserAIBudgetOverride struct {
|
||||
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
||||
GroupID uuid.UUID `db:"group_id" json:"group_id"`
|
||||
SpendLimitMicros int64 `db:"spend_limit_micros" json:"spend_limit_micros"`
|
||||
@@ -5964,7 +5964,7 @@ type UserAiBudgetOverride struct {
|
||||
}
|
||||
|
||||
// User-owned API keys associated with AI providers. These keys are used only when BYOK is enabled.
|
||||
type UserAiProviderKey struct {
|
||||
type UserAIProviderKey struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
||||
AIProviderID uuid.UUID `db:"ai_provider_id" json:"ai_provider_id"`
|
||||
|
||||
Generated
+13
-13
@@ -153,7 +153,7 @@ type sqlcQuerier interface {
|
||||
DeleteCustomRole(ctx context.Context, arg DeleteCustomRoleParams) error
|
||||
DeleteExpiredAPIKeys(ctx context.Context, arg DeleteExpiredAPIKeysParams) (int64, error)
|
||||
DeleteExternalAuthLink(ctx context.Context, arg DeleteExternalAuthLinkParams) error
|
||||
DeleteGroupAIBudget(ctx context.Context, groupID uuid.UUID) (GroupAiBudget, error)
|
||||
DeleteGroupAIBudget(ctx context.Context, groupID uuid.UUID) (GroupAIBudget, error)
|
||||
DeleteGroupByID(ctx context.Context, id uuid.UUID) error
|
||||
DeleteGroupMemberFromGroup(ctx context.Context, arg DeleteGroupMemberFromGroupParams) error
|
||||
DeleteLicense(ctx context.Context, id int32) (int32, error)
|
||||
@@ -223,7 +223,7 @@ type sqlcQuerier interface {
|
||||
DeleteTailnetPeer(ctx context.Context, arg DeleteTailnetPeerParams) (DeleteTailnetPeerRow, error)
|
||||
DeleteTailnetTunnel(ctx context.Context, arg DeleteTailnetTunnelParams) (DeleteTailnetTunnelRow, error)
|
||||
DeleteTask(ctx context.Context, arg DeleteTaskParams) (uuid.UUID, error)
|
||||
DeleteUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (UserAiBudgetOverride, error)
|
||||
DeleteUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (UserAIBudgetOverride, error)
|
||||
DeleteUserAIProviderKey(ctx context.Context, arg DeleteUserAIProviderKeyParams) error
|
||||
DeleteUserAIProviderKeysByProviderID(ctx context.Context, aiProviderID uuid.UUID) error
|
||||
DeleteUserChatCompactionThreshold(ctx context.Context, arg DeleteUserChatCompactionThresholdParams) error
|
||||
@@ -290,7 +290,7 @@ type sqlcQuerier interface {
|
||||
GetAIBridgeTokenUsagesByInterceptionID(ctx context.Context, interceptionID uuid.UUID) ([]AIBridgeTokenUsage, error)
|
||||
GetAIBridgeToolUsagesByInterceptionID(ctx context.Context, interceptionID uuid.UUID) ([]AIBridgeToolUsage, error)
|
||||
GetAIBridgeUserPromptsByInterceptionID(ctx context.Context, interceptionID uuid.UUID) ([]AIBridgeUserPrompt, error)
|
||||
GetAIModelPriceByProviderModel(ctx context.Context, arg GetAIModelPriceByProviderModelParams) (AiModelPrice, error)
|
||||
GetAIModelPriceByProviderModel(ctx context.Context, arg GetAIModelPriceByProviderModelParams) (AIModelPrice, error)
|
||||
GetAIProviderByID(ctx context.Context, id uuid.UUID) (AIProvider, error)
|
||||
// Lock the provider row until the model-config write completes. The
|
||||
// transaction alone does not stop a concurrent soft-delete or disable
|
||||
@@ -552,7 +552,7 @@ type sqlcQuerier interface {
|
||||
GetFilteredInboxNotificationsByUserID(ctx context.Context, arg GetFilteredInboxNotificationsByUserIDParams) ([]InboxNotification, error)
|
||||
GetForcedMCPServerConfigs(ctx context.Context) ([]MCPServerConfig, error)
|
||||
GetGitSSHKey(ctx context.Context, userID uuid.UUID) (GitSSHKey, error)
|
||||
GetGroupAIBudget(ctx context.Context, groupID uuid.UUID) (GroupAiBudget, error)
|
||||
GetGroupAIBudget(ctx context.Context, groupID uuid.UUID) (GroupAIBudget, error)
|
||||
GetGroupByID(ctx context.Context, id uuid.UUID) (Group, error)
|
||||
GetGroupByOrgAndName(ctx context.Context, arg GetGroupByOrgAndNameParams) (Group, error)
|
||||
GetGroupMembers(ctx context.Context, includeSystem bool) ([]GroupMember, error)
|
||||
@@ -824,12 +824,12 @@ type sqlcQuerier interface {
|
||||
// inclusive.
|
||||
GetTotalUsageDCManagedAgentsV1(ctx context.Context, arg GetTotalUsageDCManagedAgentsV1Params) (int64, error)
|
||||
GetUnexpiredLicenses(ctx context.Context) ([]License, error)
|
||||
GetUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (UserAiBudgetOverride, error)
|
||||
GetUserAIProviderKeyByProviderID(ctx context.Context, arg GetUserAIProviderKeyByProviderIDParams) (UserAiProviderKey, error)
|
||||
GetUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (UserAIBudgetOverride, error)
|
||||
GetUserAIProviderKeyByProviderID(ctx context.Context, arg GetUserAIProviderKeyByProviderIDParams) (UserAIProviderKey, error)
|
||||
// GetUserAIProviderKeys is used by dbcrypt key rotation. Request paths should use
|
||||
// user-scoped lookups instead of this bulk accessor.
|
||||
GetUserAIProviderKeys(ctx context.Context) ([]UserAiProviderKey, error)
|
||||
GetUserAIProviderKeysByUserID(ctx context.Context, userID uuid.UUID) ([]UserAiProviderKey, error)
|
||||
GetUserAIProviderKeys(ctx context.Context) ([]UserAIProviderKey, error)
|
||||
GetUserAIProviderKeysByUserID(ctx context.Context, userID uuid.UUID) ([]UserAIProviderKey, error)
|
||||
// Returns user IDs from the provided list that are consuming an AI seat.
|
||||
// Filters to active, non-deleted, non-system users to match the canonical
|
||||
// seat count query (GetActiveAISeatCount).
|
||||
@@ -1377,7 +1377,7 @@ type sqlcQuerier interface {
|
||||
// Used by the dbcrypt key rotation utility to re-encrypt or decrypt
|
||||
// rows in place.
|
||||
UpdateEncryptedAIProviderSettings(ctx context.Context, arg UpdateEncryptedAIProviderSettingsParams) (AIProvider, error)
|
||||
UpdateEncryptedUserAIProviderKey(ctx context.Context, arg UpdateEncryptedUserAIProviderKeyParams) (UserAiProviderKey, error)
|
||||
UpdateEncryptedUserAIProviderKey(ctx context.Context, arg UpdateEncryptedUserAIProviderKeyParams) (UserAIProviderKey, error)
|
||||
UpdateExternalAuthLink(ctx context.Context, arg UpdateExternalAuthLinkParams) (ExternalAuthLink, error)
|
||||
// Optimistic lock: only update the row if the refresh token in the database
|
||||
// still matches the one we read before attempting the refresh. This prevents
|
||||
@@ -1426,7 +1426,7 @@ type sqlcQuerier interface {
|
||||
UpdateTemplateVersionFlagsByJobID(ctx context.Context, arg UpdateTemplateVersionFlagsByJobIDParams) error
|
||||
UpdateTemplateWorkspacesLastUsedAt(ctx context.Context, arg UpdateTemplateWorkspacesLastUsedAtParams) error
|
||||
UpdateUsageEventsPostPublish(ctx context.Context, arg UpdateUsageEventsPostPublishParams) error
|
||||
UpdateUserAIProviderKey(ctx context.Context, arg UpdateUserAIProviderKeyParams) (UserAiProviderKey, error)
|
||||
UpdateUserAIProviderKey(ctx context.Context, arg UpdateUserAIProviderKeyParams) (UserAIProviderKey, error)
|
||||
UpdateUserAgentChatSendShortcut(ctx context.Context, arg UpdateUserAgentChatSendShortcutParams) (string, error)
|
||||
UpdateUserChatCompactionThreshold(ctx context.Context, arg UpdateUserChatCompactionThresholdParams) (UserConfig, error)
|
||||
UpdateUserChatCustomPrompt(ctx context.Context, arg UpdateUserChatCustomPromptParams) (UserConfig, error)
|
||||
@@ -1532,7 +1532,7 @@ type sqlcQuerier interface {
|
||||
// So we need to store it's configuration here for display purposes.
|
||||
// The functional values are immutable and controlled implicitly.
|
||||
UpsertDefaultProxy(ctx context.Context, arg UpsertDefaultProxyParams) error
|
||||
UpsertGroupAIBudget(ctx context.Context, arg UpsertGroupAIBudgetParams) (GroupAiBudget, error)
|
||||
UpsertGroupAIBudget(ctx context.Context, arg UpsertGroupAIBudgetParams) (GroupAIBudget, error)
|
||||
UpsertHealthSettings(ctx context.Context, value string) error
|
||||
UpsertLastUpdateCheck(ctx context.Context, value string) error
|
||||
UpsertLogoURL(ctx context.Context, value string) error
|
||||
@@ -1555,11 +1555,11 @@ type sqlcQuerier interface {
|
||||
// used to store the data, and the minutes are summed for each user and template
|
||||
// combination. The result is stored in the template_usage_stats table.
|
||||
UpsertTemplateUsageStats(ctx context.Context) error
|
||||
UpsertUserAIBudgetOverride(ctx context.Context, arg UpsertUserAIBudgetOverrideParams) (UserAiBudgetOverride, error)
|
||||
UpsertUserAIBudgetOverride(ctx context.Context, arg UpsertUserAIBudgetOverrideParams) (UserAIBudgetOverride, error)
|
||||
// UpsertUserAIProviderKey preserves the original id and created_at when the
|
||||
// user/provider pair already exists. On conflict, callers provide id and
|
||||
// created_at for the insert path only.
|
||||
UpsertUserAIProviderKey(ctx context.Context, arg UpsertUserAIProviderKeyParams) (UserAiProviderKey, error)
|
||||
UpsertUserAIProviderKey(ctx context.Context, arg UpsertUserAIProviderKeyParams) (UserAIProviderKey, error)
|
||||
UpsertUserChatDebugLoggingEnabled(ctx context.Context, arg UpsertUserChatDebugLoggingEnabledParams) error
|
||||
UpsertUserChatPersonalModelOverride(ctx context.Context, arg UpsertUserChatPersonalModelOverrideParams) error
|
||||
UpsertWebpushVAPIDKeys(ctx context.Context, arg UpsertWebpushVAPIDKeysParams) error
|
||||
|
||||
@@ -11087,11 +11087,11 @@ func TestGetEnabledChatModelConfigsUsesAIProviders(t *testing.T) {
|
||||
ctx := testutil.Context(t, testutil.WaitMedium)
|
||||
|
||||
enabledProvider := dbgen.AIProvider(t, store, database.AIProvider{
|
||||
Type: database.AiProviderTypeOpenrouter,
|
||||
Type: database.AIProviderTypeOpenrouter,
|
||||
Name: "openrouter-" + uuid.NewString(),
|
||||
})
|
||||
disabledProvider := dbgen.AIProvider(t, store, database.AIProvider{
|
||||
Type: database.AiProviderTypeVercel,
|
||||
Type: database.AIProviderTypeVercel,
|
||||
Name: "vercel-" + uuid.NewString(),
|
||||
}, func(params *database.InsertAIProviderParams) {
|
||||
params.Enabled = false
|
||||
@@ -11400,7 +11400,7 @@ func TestGetChatMessagesForPromptByChatID(t *testing.T) {
|
||||
|
||||
// An AI provider row is required as a FK for model configs.
|
||||
provider := dbgen.AIProvider(t, db, database.AIProvider{
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
Name: "test-" + uuid.NewString(),
|
||||
DisplayName: sql.NullString{String: "OpenAI", Valid: true},
|
||||
Enabled: true,
|
||||
@@ -11739,7 +11739,7 @@ func TestUpsertAISeats(t *testing.T) {
|
||||
newRow, err := db.UpsertAISeatState(ctx, database.UpsertAISeatStateParams{
|
||||
UserID: user.ID,
|
||||
FirstUsedAt: now.Add(time.Hour * -24),
|
||||
LastEventType: database.AiSeatUsageReasonTask,
|
||||
LastEventType: database.AISeatUsageReasonTask,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.True(t, newRow)
|
||||
@@ -11747,7 +11747,7 @@ func TestUpsertAISeats(t *testing.T) {
|
||||
alreadyExists, err := db.UpsertAISeatState(ctx, database.UpsertAISeatStateParams{
|
||||
UserID: user.ID,
|
||||
FirstUsedAt: now.Add(time.Hour * -23),
|
||||
LastEventType: database.AiSeatUsageReasonTask,
|
||||
LastEventType: database.AISeatUsageReasonTask,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.False(t, alreadyExists)
|
||||
@@ -11755,7 +11755,7 @@ func TestUpsertAISeats(t *testing.T) {
|
||||
alreadyExists, err = db.UpsertAISeatState(ctx, database.UpsertAISeatStateParams{
|
||||
UserID: user.ID,
|
||||
FirstUsedAt: now,
|
||||
LastEventType: database.AiSeatUsageReasonTask,
|
||||
LastEventType: database.AISeatUsageReasonTask,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.False(t, alreadyExists)
|
||||
@@ -14604,7 +14604,7 @@ func TestGetChatsFilter(t *testing.T) {
|
||||
dbgen.OrganizationMember(t, store, database.OrganizationMember{UserID: user.ID, OrganizationID: org.ID})
|
||||
|
||||
provider := dbgen.AIProviderWithOptionalKey(t, store, database.AIProvider{
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
}, "test-key")
|
||||
|
||||
modelCfg, err := store.InsertChatModelConfig(ctx, database.InsertChatModelConfigParams{
|
||||
@@ -15395,67 +15395,67 @@ func TestAIGatewayKeysTableConstraints(t *testing.T) {
|
||||
{
|
||||
name: "duplicate name",
|
||||
params: aiGatewayKeyParams(preExisting.Name, "key_test002"),
|
||||
expectUniqueErr: database.UniqueAiGatewayKeysNameIndex,
|
||||
expectUniqueErr: database.UniqueAIGatewayKeysNameIndex,
|
||||
},
|
||||
{
|
||||
name: "duplicate secret prefix",
|
||||
params: aiGatewayKeyParams("different-key", preExisting.SecretPrefix),
|
||||
expectUniqueErr: database.UniqueAiGatewayKeysSecretPrefixIndex,
|
||||
expectUniqueErr: database.UniqueAIGatewayKeysSecretPrefixIndex,
|
||||
},
|
||||
{
|
||||
name: "duplicate hashed secret",
|
||||
params: database.InsertAIGatewayKeyParams{ID: uuid.New(), Name: "other-name", SecretPrefix: "key_1234567", HashedSecret: preExisting.HashedSecret},
|
||||
expectUniqueErr: database.UniqueAiGatewayKeysHashedSecretIndex,
|
||||
expectUniqueErr: database.UniqueAIGatewayKeysHashedSecretIndex,
|
||||
},
|
||||
{
|
||||
name: "empty name",
|
||||
params: aiGatewayKeyParams("", "key_empty__"),
|
||||
expectCheckErr: database.CheckAiGatewayKeysNameCheck,
|
||||
expectCheckErr: database.CheckAIGatewayKeysNameCheck,
|
||||
},
|
||||
{
|
||||
name: "name with trailing dash",
|
||||
params: aiGatewayKeyParams("other-name-", "key_trail__"),
|
||||
expectCheckErr: database.CheckAiGatewayKeysNameCheck,
|
||||
expectCheckErr: database.CheckAIGatewayKeysNameCheck,
|
||||
},
|
||||
{
|
||||
name: "name with consecutive dashes",
|
||||
params: aiGatewayKeyParams("other--name", "key_consec_"),
|
||||
expectCheckErr: database.CheckAiGatewayKeysNameCheck,
|
||||
expectCheckErr: database.CheckAIGatewayKeysNameCheck,
|
||||
},
|
||||
{
|
||||
name: "name with underscore",
|
||||
params: aiGatewayKeyParams("other_name", "key_undersc"),
|
||||
expectCheckErr: database.CheckAiGatewayKeysNameCheck,
|
||||
expectCheckErr: database.CheckAIGatewayKeysNameCheck,
|
||||
},
|
||||
{
|
||||
name: "name with space",
|
||||
params: aiGatewayKeyParams("other name", "key_spacen_"),
|
||||
expectCheckErr: database.CheckAiGatewayKeysNameCheck,
|
||||
expectCheckErr: database.CheckAIGatewayKeysNameCheck,
|
||||
},
|
||||
{
|
||||
name: "name with leading dash",
|
||||
params: aiGatewayKeyParams("-other-name", "key_leadng_"),
|
||||
expectCheckErr: database.CheckAiGatewayKeysNameCheck,
|
||||
expectCheckErr: database.CheckAIGatewayKeysNameCheck,
|
||||
},
|
||||
{
|
||||
name: "name longer than 64 characters",
|
||||
params: aiGatewayKeyParams(strings.Repeat("a", 65), "key_longna_"),
|
||||
expectCheckErr: database.CheckAiGatewayKeysNameCheck,
|
||||
expectCheckErr: database.CheckAIGatewayKeysNameCheck,
|
||||
},
|
||||
{
|
||||
name: "empty secret prefix",
|
||||
params: aiGatewayKeyParams("check-empty-pfx", ""),
|
||||
expectCheckErr: database.CheckAiGatewayKeysSecretPrefixCheck,
|
||||
expectCheckErr: database.CheckAIGatewayKeysSecretPrefixCheck,
|
||||
},
|
||||
{
|
||||
name: "invalid secret prefix length",
|
||||
params: aiGatewayKeyParams("check-short-pfx", "key_short"),
|
||||
expectCheckErr: database.CheckAiGatewayKeysSecretPrefixCheck,
|
||||
expectCheckErr: database.CheckAIGatewayKeysSecretPrefixCheck,
|
||||
},
|
||||
{
|
||||
name: "empty hashed secret",
|
||||
params: database.InsertAIGatewayKeyParams{ID: uuid.New(), Name: "check-empty-hash", SecretPrefix: "key_ehash__", HashedSecret: []byte{}},
|
||||
expectCheckErr: database.CheckAiGatewayKeysHashedSecretCheck,
|
||||
expectCheckErr: database.CheckAIGatewayKeysHashedSecretCheck,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Generated
+29
-29
@@ -2346,9 +2346,9 @@ const deleteGroupAIBudget = `-- name: DeleteGroupAIBudget :one
|
||||
DELETE FROM group_ai_budgets WHERE group_id = $1 RETURNING group_id, spend_limit_micros, created_at, updated_at
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) DeleteGroupAIBudget(ctx context.Context, groupID uuid.UUID) (GroupAiBudget, error) {
|
||||
func (q *sqlQuerier) DeleteGroupAIBudget(ctx context.Context, groupID uuid.UUID) (GroupAIBudget, error) {
|
||||
row := q.db.QueryRowContext(ctx, deleteGroupAIBudget, groupID)
|
||||
var i GroupAiBudget
|
||||
var i GroupAIBudget
|
||||
err := row.Scan(
|
||||
&i.GroupID,
|
||||
&i.SpendLimitMicros,
|
||||
@@ -2362,9 +2362,9 @@ const deleteUserAIBudgetOverride = `-- name: DeleteUserAIBudgetOverride :one
|
||||
DELETE FROM user_ai_budget_overrides WHERE user_id = $1 RETURNING user_id, group_id, spend_limit_micros, created_at, updated_at
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) DeleteUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (UserAiBudgetOverride, error) {
|
||||
func (q *sqlQuerier) DeleteUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (UserAIBudgetOverride, error) {
|
||||
row := q.db.QueryRowContext(ctx, deleteUserAIBudgetOverride, userID)
|
||||
var i UserAiBudgetOverride
|
||||
var i UserAIBudgetOverride
|
||||
err := row.Scan(
|
||||
&i.UserID,
|
||||
&i.GroupID,
|
||||
@@ -2386,9 +2386,9 @@ type GetAIModelPriceByProviderModelParams struct {
|
||||
Model string `db:"model" json:"model"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) GetAIModelPriceByProviderModel(ctx context.Context, arg GetAIModelPriceByProviderModelParams) (AiModelPrice, error) {
|
||||
func (q *sqlQuerier) GetAIModelPriceByProviderModel(ctx context.Context, arg GetAIModelPriceByProviderModelParams) (AIModelPrice, error) {
|
||||
row := q.db.QueryRowContext(ctx, getAIModelPriceByProviderModel, arg.Provider, arg.Model)
|
||||
var i AiModelPrice
|
||||
var i AIModelPrice
|
||||
err := row.Scan(
|
||||
&i.Provider,
|
||||
&i.Model,
|
||||
@@ -2408,9 +2408,9 @@ FROM group_ai_budgets
|
||||
WHERE group_id = $1
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) GetGroupAIBudget(ctx context.Context, groupID uuid.UUID) (GroupAiBudget, error) {
|
||||
func (q *sqlQuerier) GetGroupAIBudget(ctx context.Context, groupID uuid.UUID) (GroupAIBudget, error) {
|
||||
row := q.db.QueryRowContext(ctx, getGroupAIBudget, groupID)
|
||||
var i GroupAiBudget
|
||||
var i GroupAIBudget
|
||||
err := row.Scan(
|
||||
&i.GroupID,
|
||||
&i.SpendLimitMicros,
|
||||
@@ -2461,9 +2461,9 @@ FROM user_ai_budget_overrides
|
||||
WHERE user_id = $1
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) GetUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (UserAiBudgetOverride, error) {
|
||||
func (q *sqlQuerier) GetUserAIBudgetOverride(ctx context.Context, userID uuid.UUID) (UserAIBudgetOverride, error) {
|
||||
row := q.db.QueryRowContext(ctx, getUserAIBudgetOverride, userID)
|
||||
var i UserAiBudgetOverride
|
||||
var i UserAIBudgetOverride
|
||||
err := row.Scan(
|
||||
&i.UserID,
|
||||
&i.GroupID,
|
||||
@@ -2516,9 +2516,9 @@ type UpsertGroupAIBudgetParams struct {
|
||||
SpendLimitMicros int64 `db:"spend_limit_micros" json:"spend_limit_micros"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) UpsertGroupAIBudget(ctx context.Context, arg UpsertGroupAIBudgetParams) (GroupAiBudget, error) {
|
||||
func (q *sqlQuerier) UpsertGroupAIBudget(ctx context.Context, arg UpsertGroupAIBudgetParams) (GroupAIBudget, error) {
|
||||
row := q.db.QueryRowContext(ctx, upsertGroupAIBudget, arg.GroupID, arg.SpendLimitMicros)
|
||||
var i GroupAiBudget
|
||||
var i GroupAIBudget
|
||||
err := row.Scan(
|
||||
&i.GroupID,
|
||||
&i.SpendLimitMicros,
|
||||
@@ -2544,9 +2544,9 @@ type UpsertUserAIBudgetOverrideParams struct {
|
||||
SpendLimitMicros int64 `db:"spend_limit_micros" json:"spend_limit_micros"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) UpsertUserAIBudgetOverride(ctx context.Context, arg UpsertUserAIBudgetOverrideParams) (UserAiBudgetOverride, error) {
|
||||
func (q *sqlQuerier) UpsertUserAIBudgetOverride(ctx context.Context, arg UpsertUserAIBudgetOverrideParams) (UserAIBudgetOverride, error) {
|
||||
row := q.db.QueryRowContext(ctx, upsertUserAIBudgetOverride, arg.UserID, arg.GroupID, arg.SpendLimitMicros)
|
||||
var i UserAiBudgetOverride
|
||||
var i UserAIBudgetOverride
|
||||
err := row.Scan(
|
||||
&i.UserID,
|
||||
&i.GroupID,
|
||||
@@ -2604,7 +2604,7 @@ RETURNING
|
||||
type UpsertAISeatStateParams struct {
|
||||
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
||||
FirstUsedAt time.Time `db:"first_used_at" json:"first_used_at"`
|
||||
LastEventType AiSeatUsageReason `db:"last_event_type" json:"last_event_type"`
|
||||
LastEventType AISeatUsageReason `db:"last_event_type" json:"last_event_type"`
|
||||
LastEventDescription string `db:"last_event_description" json:"last_event_description"`
|
||||
}
|
||||
|
||||
@@ -28593,9 +28593,9 @@ type GetUserAIProviderKeyByProviderIDParams struct {
|
||||
AIProviderID uuid.UUID `db:"ai_provider_id" json:"ai_provider_id"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) GetUserAIProviderKeyByProviderID(ctx context.Context, arg GetUserAIProviderKeyByProviderIDParams) (UserAiProviderKey, error) {
|
||||
func (q *sqlQuerier) GetUserAIProviderKeyByProviderID(ctx context.Context, arg GetUserAIProviderKeyByProviderIDParams) (UserAIProviderKey, error) {
|
||||
row := q.db.QueryRowContext(ctx, getUserAIProviderKeyByProviderID, arg.UserID, arg.AIProviderID)
|
||||
var i UserAiProviderKey
|
||||
var i UserAIProviderKey
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
@@ -28622,15 +28622,15 @@ ORDER BY
|
||||
|
||||
// GetUserAIProviderKeys is used by dbcrypt key rotation. Request paths should use
|
||||
// user-scoped lookups instead of this bulk accessor.
|
||||
func (q *sqlQuerier) GetUserAIProviderKeys(ctx context.Context) ([]UserAiProviderKey, error) {
|
||||
func (q *sqlQuerier) GetUserAIProviderKeys(ctx context.Context) ([]UserAIProviderKey, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getUserAIProviderKeys)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []UserAiProviderKey
|
||||
var items []UserAIProviderKey
|
||||
for rows.Next() {
|
||||
var i UserAiProviderKey
|
||||
var i UserAIProviderKey
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
@@ -28666,15 +28666,15 @@ ORDER BY
|
||||
id ASC
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) GetUserAIProviderKeysByUserID(ctx context.Context, userID uuid.UUID) ([]UserAiProviderKey, error) {
|
||||
func (q *sqlQuerier) GetUserAIProviderKeysByUserID(ctx context.Context, userID uuid.UUID) ([]UserAIProviderKey, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getUserAIProviderKeysByUserID, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []UserAiProviderKey
|
||||
var items []UserAIProviderKey
|
||||
for rows.Next() {
|
||||
var i UserAiProviderKey
|
||||
var i UserAIProviderKey
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
@@ -28716,9 +28716,9 @@ type UpdateEncryptedUserAIProviderKeyParams struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) UpdateEncryptedUserAIProviderKey(ctx context.Context, arg UpdateEncryptedUserAIProviderKeyParams) (UserAiProviderKey, error) {
|
||||
func (q *sqlQuerier) UpdateEncryptedUserAIProviderKey(ctx context.Context, arg UpdateEncryptedUserAIProviderKeyParams) (UserAIProviderKey, error) {
|
||||
row := q.db.QueryRowContext(ctx, updateEncryptedUserAIProviderKey, arg.APIKey, arg.ApiKeyKeyID, arg.ID)
|
||||
var i UserAiProviderKey
|
||||
var i UserAIProviderKey
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
@@ -28752,14 +28752,14 @@ type UpdateUserAIProviderKeyParams struct {
|
||||
AIProviderID uuid.UUID `db:"ai_provider_id" json:"ai_provider_id"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) UpdateUserAIProviderKey(ctx context.Context, arg UpdateUserAIProviderKeyParams) (UserAiProviderKey, error) {
|
||||
func (q *sqlQuerier) UpdateUserAIProviderKey(ctx context.Context, arg UpdateUserAIProviderKeyParams) (UserAIProviderKey, error) {
|
||||
row := q.db.QueryRowContext(ctx, updateUserAIProviderKey,
|
||||
arg.APIKey,
|
||||
arg.ApiKeyKeyID,
|
||||
arg.UserID,
|
||||
arg.AIProviderID,
|
||||
)
|
||||
var i UserAiProviderKey
|
||||
var i UserAIProviderKey
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
@@ -28812,7 +28812,7 @@ type UpsertUserAIProviderKeyParams struct {
|
||||
// UpsertUserAIProviderKey preserves the original id and created_at when the
|
||||
// user/provider pair already exists. On conflict, callers provide id and
|
||||
// created_at for the insert path only.
|
||||
func (q *sqlQuerier) UpsertUserAIProviderKey(ctx context.Context, arg UpsertUserAIProviderKeyParams) (UserAiProviderKey, error) {
|
||||
func (q *sqlQuerier) UpsertUserAIProviderKey(ctx context.Context, arg UpsertUserAIProviderKeyParams) (UserAIProviderKey, error) {
|
||||
row := q.db.QueryRowContext(ctx, upsertUserAIProviderKey,
|
||||
arg.ID,
|
||||
arg.UserID,
|
||||
@@ -28822,7 +28822,7 @@ func (q *sqlQuerier) UpsertUserAIProviderKey(ctx context.Context, arg UpsertUser
|
||||
arg.CreatedAt,
|
||||
arg.UpdatedAt,
|
||||
)
|
||||
var i UserAiProviderKey
|
||||
var i UserAIProviderKey
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.UserID,
|
||||
|
||||
@@ -27,6 +27,11 @@ sql:
|
||||
emit_db_tags: true
|
||||
emit_enum_valid_method: true
|
||||
emit_all_enum_values: true
|
||||
initialisms:
|
||||
# Keep the sqlc default initialism and add AI so generated
|
||||
# identifiers follow Go naming conventions.
|
||||
- id
|
||||
- ai
|
||||
overrides:
|
||||
- column: "api_keys.scopes"
|
||||
go_type:
|
||||
|
||||
Generated
+13
-13
@@ -7,11 +7,11 @@ type UniqueConstraint string
|
||||
// UniqueConstraint enums.
|
||||
const (
|
||||
UniqueAgentStatsPkey UniqueConstraint = "agent_stats_pkey" // ALTER TABLE ONLY workspace_agent_stats ADD CONSTRAINT agent_stats_pkey PRIMARY KEY (id);
|
||||
UniqueAiGatewayKeysPkey UniqueConstraint = "ai_gateway_keys_pkey" // ALTER TABLE ONLY ai_gateway_keys ADD CONSTRAINT ai_gateway_keys_pkey PRIMARY KEY (id);
|
||||
UniqueAiModelPricesPkey UniqueConstraint = "ai_model_prices_pkey" // ALTER TABLE ONLY ai_model_prices ADD CONSTRAINT ai_model_prices_pkey PRIMARY KEY (provider, model);
|
||||
UniqueAiProviderKeysPkey UniqueConstraint = "ai_provider_keys_pkey" // ALTER TABLE ONLY ai_provider_keys ADD CONSTRAINT ai_provider_keys_pkey PRIMARY KEY (id);
|
||||
UniqueAiProvidersPkey UniqueConstraint = "ai_providers_pkey" // ALTER TABLE ONLY ai_providers ADD CONSTRAINT ai_providers_pkey PRIMARY KEY (id);
|
||||
UniqueAiSeatStatePkey UniqueConstraint = "ai_seat_state_pkey" // ALTER TABLE ONLY ai_seat_state ADD CONSTRAINT ai_seat_state_pkey PRIMARY KEY (user_id);
|
||||
UniqueAIGatewayKeysPkey UniqueConstraint = "ai_gateway_keys_pkey" // ALTER TABLE ONLY ai_gateway_keys ADD CONSTRAINT ai_gateway_keys_pkey PRIMARY KEY (id);
|
||||
UniqueAIModelPricesPkey UniqueConstraint = "ai_model_prices_pkey" // ALTER TABLE ONLY ai_model_prices ADD CONSTRAINT ai_model_prices_pkey PRIMARY KEY (provider, model);
|
||||
UniqueAIProviderKeysPkey UniqueConstraint = "ai_provider_keys_pkey" // ALTER TABLE ONLY ai_provider_keys ADD CONSTRAINT ai_provider_keys_pkey PRIMARY KEY (id);
|
||||
UniqueAIProvidersPkey UniqueConstraint = "ai_providers_pkey" // ALTER TABLE ONLY ai_providers ADD CONSTRAINT ai_providers_pkey PRIMARY KEY (id);
|
||||
UniqueAISeatStatePkey UniqueConstraint = "ai_seat_state_pkey" // ALTER TABLE ONLY ai_seat_state ADD CONSTRAINT ai_seat_state_pkey PRIMARY KEY (user_id);
|
||||
UniqueAibridgeInterceptionsPkey UniqueConstraint = "aibridge_interceptions_pkey" // ALTER TABLE ONLY aibridge_interceptions ADD CONSTRAINT aibridge_interceptions_pkey PRIMARY KEY (id);
|
||||
UniqueAibridgeTokenUsagesPkey UniqueConstraint = "aibridge_token_usages_pkey" // ALTER TABLE ONLY aibridge_token_usages ADD CONSTRAINT aibridge_token_usages_pkey PRIMARY KEY (id);
|
||||
UniqueAibridgeToolUsagesPkey UniqueConstraint = "aibridge_tool_usages_pkey" // ALTER TABLE ONLY aibridge_tool_usages ADD CONSTRAINT aibridge_tool_usages_pkey PRIMARY KEY (id);
|
||||
@@ -43,7 +43,7 @@ const (
|
||||
UniqueFilesPkey UniqueConstraint = "files_pkey" // ALTER TABLE ONLY files ADD CONSTRAINT files_pkey PRIMARY KEY (id);
|
||||
UniqueGitAuthLinksProviderIDUserIDKey UniqueConstraint = "git_auth_links_provider_id_user_id_key" // ALTER TABLE ONLY external_auth_links ADD CONSTRAINT git_auth_links_provider_id_user_id_key UNIQUE (provider_id, user_id);
|
||||
UniqueGitSSHKeysPkey UniqueConstraint = "gitsshkeys_pkey" // ALTER TABLE ONLY gitsshkeys ADD CONSTRAINT gitsshkeys_pkey PRIMARY KEY (user_id);
|
||||
UniqueGroupAiBudgetsPkey UniqueConstraint = "group_ai_budgets_pkey" // ALTER TABLE ONLY group_ai_budgets ADD CONSTRAINT group_ai_budgets_pkey PRIMARY KEY (group_id);
|
||||
UniqueGroupAIBudgetsPkey UniqueConstraint = "group_ai_budgets_pkey" // ALTER TABLE ONLY group_ai_budgets ADD CONSTRAINT group_ai_budgets_pkey PRIMARY KEY (group_id);
|
||||
UniqueGroupMembersUserIDGroupIDKey UniqueConstraint = "group_members_user_id_group_id_key" // ALTER TABLE ONLY group_members ADD CONSTRAINT group_members_user_id_group_id_key UNIQUE (user_id, group_id);
|
||||
UniqueGroupsNameOrganizationIDKey UniqueConstraint = "groups_name_organization_id_key" // ALTER TABLE ONLY groups ADD CONSTRAINT groups_name_organization_id_key UNIQUE (name, organization_id);
|
||||
UniqueGroupsPkey UniqueConstraint = "groups_pkey" // ALTER TABLE ONLY groups ADD CONSTRAINT groups_pkey PRIMARY KEY (id);
|
||||
@@ -99,9 +99,9 @@ const (
|
||||
UniqueTemplatesPkey UniqueConstraint = "templates_pkey" // ALTER TABLE ONLY templates ADD CONSTRAINT templates_pkey PRIMARY KEY (id);
|
||||
UniqueUsageEventsDailyPkey UniqueConstraint = "usage_events_daily_pkey" // ALTER TABLE ONLY usage_events_daily ADD CONSTRAINT usage_events_daily_pkey PRIMARY KEY (day, event_type);
|
||||
UniqueUsageEventsPkey UniqueConstraint = "usage_events_pkey" // ALTER TABLE ONLY usage_events ADD CONSTRAINT usage_events_pkey PRIMARY KEY (id);
|
||||
UniqueUserAiBudgetOverridesPkey UniqueConstraint = "user_ai_budget_overrides_pkey" // ALTER TABLE ONLY user_ai_budget_overrides ADD CONSTRAINT user_ai_budget_overrides_pkey PRIMARY KEY (user_id);
|
||||
UniqueUserAiProviderKeysPkey UniqueConstraint = "user_ai_provider_keys_pkey" // ALTER TABLE ONLY user_ai_provider_keys ADD CONSTRAINT user_ai_provider_keys_pkey PRIMARY KEY (id);
|
||||
UniqueUserAiProviderKeysUserIDAiProviderIDKey UniqueConstraint = "user_ai_provider_keys_user_id_ai_provider_id_key" // ALTER TABLE ONLY user_ai_provider_keys ADD CONSTRAINT user_ai_provider_keys_user_id_ai_provider_id_key UNIQUE (user_id, ai_provider_id);
|
||||
UniqueUserAIBudgetOverridesPkey UniqueConstraint = "user_ai_budget_overrides_pkey" // ALTER TABLE ONLY user_ai_budget_overrides ADD CONSTRAINT user_ai_budget_overrides_pkey PRIMARY KEY (user_id);
|
||||
UniqueUserAIProviderKeysPkey UniqueConstraint = "user_ai_provider_keys_pkey" // ALTER TABLE ONLY user_ai_provider_keys ADD CONSTRAINT user_ai_provider_keys_pkey PRIMARY KEY (id);
|
||||
UniqueUserAIProviderKeysUserIDAIProviderIDKey UniqueConstraint = "user_ai_provider_keys_user_id_ai_provider_id_key" // ALTER TABLE ONLY user_ai_provider_keys ADD CONSTRAINT user_ai_provider_keys_user_id_ai_provider_id_key UNIQUE (user_id, ai_provider_id);
|
||||
UniqueUserConfigsPkey UniqueConstraint = "user_configs_pkey" // ALTER TABLE ONLY user_configs ADD CONSTRAINT user_configs_pkey PRIMARY KEY (user_id, key);
|
||||
UniqueUserDeletedPkey UniqueConstraint = "user_deleted_pkey" // ALTER TABLE ONLY user_deleted ADD CONSTRAINT user_deleted_pkey PRIMARY KEY (id);
|
||||
UniqueUserLinksPkey UniqueConstraint = "user_links_pkey" // ALTER TABLE ONLY user_links ADD CONSTRAINT user_links_pkey PRIMARY KEY (user_id, login_type);
|
||||
@@ -139,10 +139,10 @@ const (
|
||||
UniqueWorkspaceResourceMetadataPkey UniqueConstraint = "workspace_resource_metadata_pkey" // ALTER TABLE ONLY workspace_resource_metadata ADD CONSTRAINT workspace_resource_metadata_pkey PRIMARY KEY (id);
|
||||
UniqueWorkspaceResourcesPkey UniqueConstraint = "workspace_resources_pkey" // ALTER TABLE ONLY workspace_resources ADD CONSTRAINT workspace_resources_pkey PRIMARY KEY (id);
|
||||
UniqueWorkspacesPkey UniqueConstraint = "workspaces_pkey" // ALTER TABLE ONLY workspaces ADD CONSTRAINT workspaces_pkey PRIMARY KEY (id);
|
||||
UniqueAiGatewayKeysHashedSecretIndex UniqueConstraint = "ai_gateway_keys_hashed_secret_idx" // CREATE UNIQUE INDEX ai_gateway_keys_hashed_secret_idx ON ai_gateway_keys USING btree (hashed_secret);
|
||||
UniqueAiGatewayKeysNameIndex UniqueConstraint = "ai_gateway_keys_name_idx" // CREATE UNIQUE INDEX ai_gateway_keys_name_idx ON ai_gateway_keys USING btree (lower(name));
|
||||
UniqueAiGatewayKeysSecretPrefixIndex UniqueConstraint = "ai_gateway_keys_secret_prefix_idx" // CREATE UNIQUE INDEX ai_gateway_keys_secret_prefix_idx ON ai_gateway_keys USING btree (secret_prefix);
|
||||
UniqueAiProvidersNameUnique UniqueConstraint = "ai_providers_name_unique" // CREATE UNIQUE INDEX ai_providers_name_unique ON ai_providers USING btree (name) WHERE (deleted = false);
|
||||
UniqueAIGatewayKeysHashedSecretIndex UniqueConstraint = "ai_gateway_keys_hashed_secret_idx" // CREATE UNIQUE INDEX ai_gateway_keys_hashed_secret_idx ON ai_gateway_keys USING btree (hashed_secret);
|
||||
UniqueAIGatewayKeysNameIndex UniqueConstraint = "ai_gateway_keys_name_idx" // CREATE UNIQUE INDEX ai_gateway_keys_name_idx ON ai_gateway_keys USING btree (lower(name));
|
||||
UniqueAIGatewayKeysSecretPrefixIndex UniqueConstraint = "ai_gateway_keys_secret_prefix_idx" // CREATE UNIQUE INDEX ai_gateway_keys_secret_prefix_idx ON ai_gateway_keys USING btree (secret_prefix);
|
||||
UniqueAIProvidersNameUnique UniqueConstraint = "ai_providers_name_unique" // CREATE UNIQUE INDEX ai_providers_name_unique ON ai_providers USING btree (name) WHERE (deleted = false);
|
||||
UniqueIndexAPIKeyName UniqueConstraint = "idx_api_key_name" // CREATE UNIQUE INDEX idx_api_key_name ON api_keys USING btree (user_id, token_name) WHERE (login_type = 'token'::login_type);
|
||||
UniqueIndexChatDebugRunsIDChat UniqueConstraint = "idx_chat_debug_runs_id_chat" // CREATE UNIQUE INDEX idx_chat_debug_runs_id_chat ON chat_debug_runs USING btree (id, chat_id);
|
||||
UniqueIndexChatDebugStepsRunStep UniqueConstraint = "idx_chat_debug_steps_run_step" // CREATE UNIQUE INDEX idx_chat_debug_steps_run_step ON chat_debug_steps USING btree (run_id, step_number);
|
||||
|
||||
@@ -60,7 +60,7 @@ func TestValidateChatModelConfigProviderModel(t *testing.T) {
|
||||
model: "anthropic/claude-opus-4.6",
|
||||
provider: database.AIProvider{
|
||||
Name: "openrouter",
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
},
|
||||
wantErr: true,
|
||||
wantDetail: "Change the AI provider type to openrouter or openai-compat.",
|
||||
@@ -70,7 +70,7 @@ func TestValidateChatModelConfigProviderModel(t *testing.T) {
|
||||
model: "anthropic/claude-opus-4.6",
|
||||
provider: database.AIProvider{
|
||||
Name: " OpenRouter ",
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
},
|
||||
wantErr: true,
|
||||
wantDetail: "Change the AI provider type to openrouter or openai-compat.",
|
||||
@@ -80,7 +80,7 @@ func TestValidateChatModelConfigProviderModel(t *testing.T) {
|
||||
model: "anthropic/claude-opus-4.6",
|
||||
provider: database.AIProvider{
|
||||
Name: "private-relay",
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
BaseUrl: "https://openrouter.ai/api/v1",
|
||||
},
|
||||
wantErr: true,
|
||||
@@ -91,7 +91,7 @@ func TestValidateChatModelConfigProviderModel(t *testing.T) {
|
||||
model: "anthropic/claude-opus-4.6",
|
||||
provider: database.AIProvider{
|
||||
Name: "private-relay",
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
BaseUrl: "https://openrouter.ai:443/api/v1",
|
||||
},
|
||||
wantErr: true,
|
||||
@@ -102,7 +102,7 @@ func TestValidateChatModelConfigProviderModel(t *testing.T) {
|
||||
model: "anthropic/claude-opus-4.6",
|
||||
provider: database.AIProvider{
|
||||
Name: "private-relay",
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
BaseUrl: "https://api.openrouter.ai/v1",
|
||||
},
|
||||
wantErr: true,
|
||||
@@ -113,7 +113,7 @@ func TestValidateChatModelConfigProviderModel(t *testing.T) {
|
||||
model: "anthropic/claude-opus-4.6",
|
||||
provider: database.AIProvider{
|
||||
Name: "openrouter",
|
||||
Type: database.AiProviderTypeOpenrouter,
|
||||
Type: database.AIProviderTypeOpenrouter,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -121,7 +121,7 @@ func TestValidateChatModelConfigProviderModel(t *testing.T) {
|
||||
model: "anthropic/claude-opus-4.6",
|
||||
provider: database.AIProvider{
|
||||
Name: "openrouter",
|
||||
Type: database.AiProviderTypeOpenaiCompat,
|
||||
Type: database.AIProviderTypeOpenaiCompat,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -129,7 +129,7 @@ func TestValidateChatModelConfigProviderModel(t *testing.T) {
|
||||
model: "anthropic/claude-opus-4.6",
|
||||
provider: database.AIProvider{
|
||||
Name: "private-relay",
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
BaseUrl: "https://llm-relay.internal/v1",
|
||||
},
|
||||
},
|
||||
@@ -138,7 +138,7 @@ func TestValidateChatModelConfigProviderModel(t *testing.T) {
|
||||
model: "gpt-4.1",
|
||||
provider: database.AIProvider{
|
||||
Name: "openrouter",
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1749,7 +1749,7 @@ func TestListChatModels(t *testing.T) {
|
||||
client := newChatClient(t)
|
||||
_ = coderdtest.CreateFirstUser(t, client.Client)
|
||||
|
||||
providerType := database.AiProviderTypeAnthropic
|
||||
providerType := database.AIProviderTypeAnthropic
|
||||
provider := createAIProviderForTest(t, client, string(providerType), "")
|
||||
|
||||
contextLimit := int64(4096)
|
||||
@@ -3997,7 +3997,7 @@ func TestUpdateChatModelConfig(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
modelConfig := dbgen.ChatModelConfig(t, db, database.ChatModelConfig{
|
||||
Provider: string(database.AiProviderTypeOpenai),
|
||||
Provider: string(database.AIProviderTypeOpenai),
|
||||
Model: "anthropic/claude-opus-4.6",
|
||||
AIProviderID: uuid.NullUUID{UUID: aiProvider.ID, Valid: true},
|
||||
})
|
||||
|
||||
@@ -98,7 +98,7 @@ func insertAgentChatTestModelConfig(
|
||||
createdBy := uuid.NullUUID{UUID: userID, Valid: true}
|
||||
|
||||
provider := dbgen.AIProvider(t, db, database.AIProvider{
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
Name: "test-openai",
|
||||
DisplayName: sql.NullString{String: "OpenAI", Valid: true},
|
||||
})
|
||||
|
||||
@@ -294,7 +294,7 @@ func TestResolveAdvisorModelOverride(t *testing.T) {
|
||||
getAIProviders: func(context.Context, database.GetAIProvidersParams) ([]database.AIProvider, error) {
|
||||
return []database.AIProvider{{
|
||||
ID: providerID,
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
Enabled: true,
|
||||
}}, nil
|
||||
},
|
||||
@@ -385,7 +385,7 @@ func TestResolveAdvisorModelOverride(t *testing.T) {
|
||||
getAIProviderByID: func(context.Context, uuid.UUID) (database.AIProvider, error) {
|
||||
return database.AIProvider{
|
||||
ID: providerID,
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
Enabled: true,
|
||||
}, nil
|
||||
},
|
||||
@@ -434,7 +434,7 @@ func TestResolveAdvisorModelOverridePromotesAIBridgeErrors(t *testing.T) {
|
||||
}, nil
|
||||
},
|
||||
getAIProviderByID: func(context.Context, uuid.UUID) (database.AIProvider, error) {
|
||||
return database.AIProvider{ID: providerID, Type: database.AiProviderTypeOpenai, Name: "primary-openai", Enabled: true}, nil
|
||||
return database.AIProvider{ID: providerID, Type: database.AIProviderTypeOpenai, Name: "primary-openai", Enabled: true}, nil
|
||||
},
|
||||
getAIProviderKeysByProviderID: func(context.Context, uuid.UUID) ([]database.AIProviderKey, error) {
|
||||
return []database.AIProviderKey{{ProviderID: providerID, APIKey: "sk-selected"}}, nil
|
||||
|
||||
@@ -321,7 +321,7 @@ func seedAnthropicChatDependencies(t *testing.T, db database.Store, baseURL stri
|
||||
_ = testAPIKeyID(t, db, user.ID)
|
||||
org := dbgen.Organization(t, db, database.Organization{})
|
||||
dbgen.OrganizationMember(t, db, database.OrganizationMember{UserID: user.ID, OrganizationID: org.ID})
|
||||
provider := dbgen.AIProvider(t, db, database.AIProvider{Type: database.AiProviderTypeAnthropic}, func(params *database.InsertAIProviderParams) {
|
||||
provider := dbgen.AIProvider(t, db, database.AIProvider{Type: database.AIProviderTypeAnthropic}, func(params *database.InsertAIProviderParams) {
|
||||
params.BaseUrl = baseURL
|
||||
})
|
||||
dbgen.AIProviderKey(t, db, database.AIProviderKey{ProviderID: provider.ID})
|
||||
|
||||
@@ -182,8 +182,8 @@ func TestResolveUserProviderAPIKeysAndProviderForProviderTypeProviderMatch(t *te
|
||||
providerID := uuid.New()
|
||||
|
||||
db.EXPECT().GetAIProviders(gomock.Any(), database.GetAIProvidersParams{}).Return([]database.AIProvider{
|
||||
{ID: uuid.New(), Type: database.AiProviderTypeAnthropic, Enabled: true},
|
||||
{ID: providerID, Type: database.AiProviderTypeOpenai, Enabled: true},
|
||||
{ID: uuid.New(), Type: database.AIProviderTypeAnthropic, Enabled: true},
|
||||
{ID: providerID, Type: database.AIProviderTypeOpenai, Enabled: true},
|
||||
}, nil)
|
||||
db.EXPECT().GetAIProviderKeysByProviderID(gomock.Any(), providerID).Return([]database.AIProviderKey{{
|
||||
ProviderID: providerID,
|
||||
@@ -200,7 +200,7 @@ func TestResolveUserProviderAPIKeysAndProviderForProviderTypeProviderMatch(t *te
|
||||
require.Equal(t, "test-key", keys.APIKey(chattool.ComputerUseProviderOpenAI))
|
||||
require.NotNil(t, aiProvider)
|
||||
require.Equal(t, providerID, aiProvider.ID)
|
||||
require.Equal(t, database.AiProviderTypeOpenai, aiProvider.Type)
|
||||
require.Equal(t, database.AIProviderTypeOpenai, aiProvider.Type)
|
||||
}
|
||||
|
||||
func TestResolveModelRouteForProviderTypeAIGatewayRequiresProvider(t *testing.T) {
|
||||
@@ -864,7 +864,7 @@ func TestRegenerateChatTitle_PersistsAndBroadcasts(t *testing.T) {
|
||||
providerID := uuid.New()
|
||||
db.EXPECT().GetAIProviders(gomock.Any(), gomock.Any()).Return([]database.AIProvider{{
|
||||
ID: providerID,
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
Enabled: true,
|
||||
BaseUrl: serverURL,
|
||||
}}, nil)
|
||||
@@ -1030,7 +1030,7 @@ func TestRegenerateChatTitle_PersistsAndBroadcasts_IdleChatReleasesManualLock(t
|
||||
providerID := uuid.New()
|
||||
db.EXPECT().GetAIProviders(gomock.Any(), gomock.Any()).Return([]database.AIProvider{{
|
||||
ID: providerID,
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
Enabled: true,
|
||||
BaseUrl: serverURL,
|
||||
}}, nil)
|
||||
@@ -1181,7 +1181,7 @@ func TestResolveUserProviderAPIKeys_StripsDisabledFallbackKeys(t *testing.T) {
|
||||
providerID := uuid.New()
|
||||
db.EXPECT().GetAIProviders(gomock.Any(), gomock.Any()).Return([]database.AIProvider{{
|
||||
ID: providerID,
|
||||
Type: database.AiProviderTypeAnthropic,
|
||||
Type: database.AIProviderTypeAnthropic,
|
||||
Enabled: true,
|
||||
}}, nil)
|
||||
db.EXPECT().GetAIProviderKeysByProviderIDs(gomock.Any(), []uuid.UUID{providerID}).Return(nil, nil)
|
||||
@@ -1219,7 +1219,7 @@ func TestResolveUserProviderAPIKeys_SelectedAIProviderDoesNotUseDeploymentFallba
|
||||
|
||||
db.EXPECT().GetAIProviderByID(gomock.Any(), providerID).Return(database.AIProvider{
|
||||
ID: providerID,
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
Name: "agents-openai",
|
||||
Enabled: true,
|
||||
}, nil)
|
||||
@@ -1258,7 +1258,7 @@ func TestResolveUserProviderAPIKeys_SkipsUserKeyLookupWhenNoProviderAllowsUserKe
|
||||
providerID := uuid.New()
|
||||
db.EXPECT().GetAIProviders(gomock.Any(), gomock.Any()).Return([]database.AIProvider{{
|
||||
ID: providerID,
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
Enabled: true,
|
||||
}}, nil)
|
||||
db.EXPECT().GetAIProviderKeysByProviderIDs(gomock.Any(), []uuid.UUID{providerID}).Return(nil, nil)
|
||||
|
||||
@@ -8698,7 +8698,7 @@ func setOpenAIProviderBaseURL(
|
||||
providers, err := db.GetAIProviders(ctx, database.GetAIProvidersParams{IncludeDisabled: true})
|
||||
require.NoError(t, err)
|
||||
for _, provider := range providers {
|
||||
if provider.Type != database.AiProviderTypeOpenai {
|
||||
if provider.Type != database.AIProviderTypeOpenai {
|
||||
continue
|
||||
}
|
||||
_, err = db.UpdateAIProvider(ctx, database.UpdateAIProviderParams{
|
||||
@@ -9785,12 +9785,12 @@ func seedAIGatewayOpenAITestDependencies(
|
||||
OrganizationID: org.ID,
|
||||
})
|
||||
provider := dbgen.AIProvider(t, db, database.AIProvider{
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
Name: "primary-openai-" + uuid.NewString(),
|
||||
BaseUrl: openAIURL,
|
||||
})
|
||||
model := dbgen.ChatModelConfig(t, db, database.ChatModelConfig{
|
||||
Provider: string(database.AiProviderTypeOpenai),
|
||||
Provider: string(database.AIProviderTypeOpenai),
|
||||
Model: "gpt-4o-mini",
|
||||
IsDefault: true,
|
||||
AIProviderID: uuid.NullUUID{UUID: provider.ID, Valid: true},
|
||||
|
||||
@@ -231,7 +231,7 @@ func TestDeriveFinalTurnRunResult(t *testing.T) {
|
||||
})
|
||||
// A disabled AI provider makes resolveChatModel fail, exercising the
|
||||
// degraded path that still returns the re-derived text and IDs.
|
||||
provider := insertInternalAIProvider(t, db, database.AiProviderTypeOpenai, "provider-api-key", false)
|
||||
provider := insertInternalAIProvider(t, db, database.AIProviderTypeOpenai, "provider-api-key", false)
|
||||
modelCfg := dbgen.ChatModelConfig(t, db, database.ChatModelConfig{
|
||||
Provider: "openai",
|
||||
Model: "gpt-4o-mini",
|
||||
|
||||
@@ -91,7 +91,7 @@ func (t *aiGatewayRoundTripper) RoundTrip(req *http.Request) (*http.Response, er
|
||||
// OpenRouter-like providers typed as openai, where the provider type
|
||||
// strips the vendor prefix.
|
||||
func ValidateAIGatewayProviderModel(provider database.AIProvider, model string) error {
|
||||
if provider.Type != database.AiProviderTypeOpenai {
|
||||
if provider.Type != database.AIProviderTypeOpenai {
|
||||
return nil
|
||||
}
|
||||
if !isSlashNamespacedAIGatewayModel(model) || !isOpenRouterLikeAIGatewayProvider(provider) {
|
||||
@@ -188,10 +188,10 @@ func fantasyConfigForAIBridge(providerType database.AIProviderType) aibridgeFant
|
||||
var fantasyProvider string
|
||||
baseURL := aibridgeLocalBaseURL + "/v1"
|
||||
switch providerType {
|
||||
case database.AiProviderTypeAnthropic, database.AiProviderTypeBedrock:
|
||||
case database.AIProviderTypeAnthropic, database.AIProviderTypeBedrock:
|
||||
fantasyProvider = fantasyanthropic.Name
|
||||
baseURL = aibridgeLocalBaseURL
|
||||
case database.AiProviderTypeOpenai:
|
||||
case database.AIProviderTypeOpenai:
|
||||
fantasyProvider = fantasyopenai.Name
|
||||
default:
|
||||
fantasyProvider = fantasyopenaicompat.Name
|
||||
@@ -211,7 +211,7 @@ func fantasyConfigForAIBridge(providerType database.AIProviderType) aibridgeFant
|
||||
|
||||
func aiGatewayRequestFormatForProviderType(providerType database.AIProviderType) aiGatewayRequestFormat {
|
||||
switch providerType {
|
||||
case database.AiProviderTypeAnthropic, database.AiProviderTypeBedrock:
|
||||
case database.AIProviderTypeAnthropic, database.AIProviderTypeBedrock:
|
||||
return aiGatewayRequestFormatAnthropic
|
||||
default:
|
||||
return aiGatewayRequestFormatOpenAI
|
||||
|
||||
@@ -85,10 +85,10 @@ func TestAIBridgeProviderFormatMapping(t *testing.T) {
|
||||
wantProvider string
|
||||
wantBaseURL string
|
||||
}{
|
||||
{name: "OpenAI", providerType: database.AiProviderTypeOpenai, wantProvider: "openai", wantBaseURL: "http://coder-aibridge/v1"},
|
||||
{name: "Anthropic", providerType: database.AiProviderTypeAnthropic, wantProvider: "anthropic", wantBaseURL: "http://coder-aibridge"},
|
||||
{name: "Bedrock", providerType: database.AiProviderTypeBedrock, wantProvider: "anthropic", wantBaseURL: "http://coder-aibridge"},
|
||||
{name: "Google", providerType: database.AiProviderTypeGoogle, wantProvider: "openai-compat", wantBaseURL: "http://coder-aibridge/v1"},
|
||||
{name: "OpenAI", providerType: database.AIProviderTypeOpenai, wantProvider: "openai", wantBaseURL: "http://coder-aibridge/v1"},
|
||||
{name: "Anthropic", providerType: database.AIProviderTypeAnthropic, wantProvider: "anthropic", wantBaseURL: "http://coder-aibridge"},
|
||||
{name: "Bedrock", providerType: database.AIProviderTypeBedrock, wantProvider: "anthropic", wantBaseURL: "http://coder-aibridge"},
|
||||
{name: "Google", providerType: database.AIProviderTypeGoogle, wantProvider: "openai-compat", wantBaseURL: "http://coder-aibridge/v1"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@@ -113,7 +113,7 @@ func TestResolveModelRouteForConfigPreservesBaseURL(t *testing.T) {
|
||||
|
||||
db.EXPECT().GetAIProviderByID(gomock.Any(), providerID).Return(database.AIProvider{
|
||||
ID: providerID,
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
Name: "primary-openai",
|
||||
Enabled: true,
|
||||
BaseUrl: baseURL,
|
||||
@@ -141,7 +141,7 @@ func TestAIGatewayProviderAuthForUser(t *testing.T) {
|
||||
ctx := t.Context()
|
||||
ownerID := uuid.New()
|
||||
providerID := uuid.New()
|
||||
provider := database.AIProvider{ID: providerID, Type: database.AiProviderTypeOpenai, Enabled: true}
|
||||
provider := database.AIProvider{ID: providerID, Type: database.AIProviderTypeOpenai, Enabled: true}
|
||||
|
||||
t.Run("OpenAIUserKey", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
@@ -151,7 +151,7 @@ func TestAIGatewayProviderAuthForUser(t *testing.T) {
|
||||
db.EXPECT().GetUserAIProviderKeyByProviderID(gomock.Any(), database.GetUserAIProviderKeyByProviderIDParams{
|
||||
UserID: ownerID,
|
||||
AIProviderID: providerID,
|
||||
}).Return(database.UserAiProviderKey{APIKey: "sk-user"}, nil)
|
||||
}).Return(database.UserAIProviderKey{APIKey: "sk-user"}, nil)
|
||||
|
||||
server := &Server{db: db, allowBYOK: true}
|
||||
auth, err := server.aiGatewayProviderAuthForUser(ctx, ownerID, provider, aiGatewayRequestFormatOpenAI)
|
||||
@@ -168,7 +168,7 @@ func TestAIGatewayProviderAuthForUser(t *testing.T) {
|
||||
db.EXPECT().GetUserAIProviderKeyByProviderID(gomock.Any(), database.GetUserAIProviderKeyByProviderIDParams{
|
||||
UserID: ownerID,
|
||||
AIProviderID: providerID,
|
||||
}).Return(database.UserAiProviderKey{APIKey: "sk-user"}, nil)
|
||||
}).Return(database.UserAIProviderKey{APIKey: "sk-user"}, nil)
|
||||
|
||||
server := &Server{db: db, allowBYOK: true}
|
||||
auth, err := server.aiGatewayProviderAuthForUser(ctx, ownerID, provider, aiGatewayRequestFormatAnthropic)
|
||||
@@ -185,7 +185,7 @@ func TestAIGatewayProviderAuthForUser(t *testing.T) {
|
||||
db.EXPECT().GetUserAIProviderKeyByProviderID(gomock.Any(), database.GetUserAIProviderKeyByProviderIDParams{
|
||||
UserID: ownerID,
|
||||
AIProviderID: providerID,
|
||||
}).Return(database.UserAiProviderKey{}, sql.ErrNoRows)
|
||||
}).Return(database.UserAIProviderKey{}, sql.ErrNoRows)
|
||||
|
||||
server := &Server{db: db, allowBYOK: true}
|
||||
auth, err := server.aiGatewayProviderAuthForUser(ctx, ownerID, provider, aiGatewayRequestFormatOpenAI)
|
||||
@@ -231,7 +231,7 @@ func TestResolveModelRouteForConfigAIGatewayProviderAuth(t *testing.T) {
|
||||
providerID := uuid.New()
|
||||
provider := database.AIProvider{
|
||||
ID: providerID,
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
Name: "primary-openai",
|
||||
Enabled: true,
|
||||
}
|
||||
@@ -251,7 +251,7 @@ func TestResolveModelRouteForConfigAIGatewayProviderAuth(t *testing.T) {
|
||||
db.EXPECT().GetUserAIProviderKeyByProviderID(gomock.Any(), database.GetUserAIProviderKeyByProviderIDParams{
|
||||
UserID: ownerID,
|
||||
AIProviderID: providerID,
|
||||
}).Return(database.UserAiProviderKey{APIKey: "sk-user"}, nil)
|
||||
}).Return(database.UserAIProviderKey{APIKey: "sk-user"}, nil)
|
||||
|
||||
server := &Server{db: db, aiGatewayRoutingEnabled: true, allowBYOK: true}
|
||||
route, err := server.resolveModelRouteForConfig(ctx, ownerID, modelConfig, chatprovider.ProviderAPIKeys{})
|
||||
@@ -296,7 +296,7 @@ func TestAIGatewayModelForwardsProviderAuth(t *testing.T) {
|
||||
path: req.URL.Path,
|
||||
}
|
||||
body := `{"id":"resp_test","object":"response","created_at":0,"status":"completed","model":"gpt-4","output":[{"id":"msg_test","type":"message","role":"assistant","content":[{"type":"output_text","text":"hello"}]}],"usage":{"input_tokens":1,"output_tokens":1,"total_tokens":2}}`
|
||||
if provider.Type == database.AiProviderTypeAnthropic {
|
||||
if provider.Type == database.AIProviderTypeAnthropic {
|
||||
body = `{"id":"msg_test","type":"message","role":"assistant","model":"claude-haiku-4-5","content":[{"type":"text","text":"hello"}],"stop_reason":"end_turn","stop_sequence":null,"usage":{"input_tokens":1,"output_tokens":1}}`
|
||||
}
|
||||
return &http.Response{
|
||||
@@ -318,7 +318,7 @@ func TestAIGatewayModelForwardsProviderAuth(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
seen := make(chan seenRequest, 1)
|
||||
provider := aibridgeTestAIProvider(uuid.New(), "primary-openai", database.AiProviderTypeOpenai)
|
||||
provider := aibridgeTestAIProvider(uuid.New(), "primary-openai", database.AIProviderTypeOpenai)
|
||||
server, route := newServer(t, provider, aiGatewayProviderAuth{
|
||||
Headers: map[string]string{"Authorization": "Bearer sk-user"},
|
||||
}, seen)
|
||||
@@ -340,7 +340,7 @@ func TestAIGatewayModelForwardsProviderAuth(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
seen := make(chan seenRequest, 1)
|
||||
provider := aibridgeTestAIProvider(uuid.New(), "primary-anthropic", database.AiProviderTypeAnthropic)
|
||||
provider := aibridgeTestAIProvider(uuid.New(), "primary-anthropic", database.AIProviderTypeAnthropic)
|
||||
server, route := newServer(t, provider, aiGatewayProviderAuth{
|
||||
Headers: map[string]string{"X-Api-Key": "sk-user"},
|
||||
}, seen)
|
||||
@@ -361,7 +361,7 @@ func TestAIGatewayModelForwardsProviderAuth(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
seen := make(chan seenRequest, 1)
|
||||
provider := aibridgeTestAIProvider(uuid.New(), "primary-openai", database.AiProviderTypeOpenai)
|
||||
provider := aibridgeTestAIProvider(uuid.New(), "primary-openai", database.AIProviderTypeOpenai)
|
||||
server, route := newServer(t, provider, aiGatewayProviderAuth{}, seen)
|
||||
apiKeyID := uuid.NewString()
|
||||
model, err := server.newModel(t.Context(), aibridgeTestRequest(database.Chat{ID: uuid.New(), OwnerID: uuid.New()}, "gpt-4"), route, modelBuildOptions{ActiveAPIKeyID: apiKeyID})
|
||||
@@ -595,7 +595,7 @@ func TestAIBridgeRoutingFailClosed(t *testing.T) {
|
||||
|
||||
providerID := uuid.New()
|
||||
chat := database.Chat{ID: uuid.New(), OwnerID: uuid.New()}
|
||||
aiProvider := aibridgeTestAIProvider(providerID, "primary-openai", database.AiProviderTypeOpenai)
|
||||
aiProvider := aibridgeTestAIProvider(providerID, "primary-openai", database.AIProviderTypeOpenai)
|
||||
|
||||
t.Run("NilFactory", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
@@ -618,7 +618,7 @@ func TestAIBridgeRoutingFailClosed(t *testing.T) {
|
||||
t.Run("MissingProviderName", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
server := &Server{aiGatewayRoutingEnabled: true}
|
||||
missingNameProvider := aibridgeTestAIProvider(providerID, "", database.AiProviderTypeOpenai)
|
||||
missingNameProvider := aibridgeTestAIProvider(providerID, "", database.AIProviderTypeOpenai)
|
||||
_, err := server.newModel(t.Context(), aibridgeTestRequest(chat, "gpt-4"), aibridgeTestRoute(missingNameProvider), modelBuildOptions{ActiveAPIKeyID: uuid.NewString()})
|
||||
require.ErrorContains(t, err, "AI provider name")
|
||||
})
|
||||
@@ -652,7 +652,7 @@ func TestAIBridgeRoutingFailClosed(t *testing.T) {
|
||||
aiGatewayRoutingEnabled: true,
|
||||
aibridgeTransportFactory: aibridgeTestFactoryPointer(factory),
|
||||
}
|
||||
provider := aibridgeTestAIProvider(providerID, "openrouter", database.AiProviderTypeOpenai)
|
||||
provider := aibridgeTestAIProvider(providerID, "openrouter", database.AIProviderTypeOpenai)
|
||||
_, err := server.newModel(
|
||||
t.Context(),
|
||||
aibridgeTestRequest(chat, "anthropic/claude-opus-4.6"),
|
||||
@@ -685,12 +685,12 @@ func TestAIBridgeGatewayProviderTypesPreserveSlashModelID(t *testing.T) {
|
||||
{
|
||||
name: "OpenRouter",
|
||||
providerName: "openrouter",
|
||||
providerType: database.AiProviderTypeOpenrouter,
|
||||
providerType: database.AIProviderTypeOpenrouter,
|
||||
},
|
||||
{
|
||||
name: "OpenAICompat",
|
||||
providerName: "openai-compatible-relay",
|
||||
providerType: database.AiProviderTypeOpenaiCompat,
|
||||
providerType: database.AIProviderTypeOpenaiCompat,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -814,7 +814,7 @@ func TestAIBridgeComputerUseModelUsesRoute(t *testing.T) {
|
||||
model, debugEnabled, resolvedProvider, resolvedModel, err := server.resolveComputerUseModel(
|
||||
ctx,
|
||||
chat,
|
||||
aibridgeTestRoute(aibridgeTestAIProvider(providerID, "primary-openai", database.AiProviderTypeOpenai)),
|
||||
aibridgeTestRoute(aibridgeTestAIProvider(providerID, "primary-openai", database.AIProviderTypeOpenai)),
|
||||
provider,
|
||||
modelProvider,
|
||||
modelName,
|
||||
@@ -862,7 +862,7 @@ func TestAIBridgeDelegatedContextPropagation(t *testing.T) {
|
||||
}
|
||||
|
||||
ctx := aibridge.WithDelegatedAPIKeyID(t.Context(), "context-key-must-be-ignored")
|
||||
model, err := server.newModel(ctx, aibridgeTestRequest(chat, "gpt-4"), aibridgeTestRoute(aibridgeTestAIProvider(providerID, "primary-openai", database.AiProviderTypeOpenai)), modelBuildOptions{ActiveAPIKeyID: apiKeyID, RecordHTTP: true})
|
||||
model, err := server.newModel(ctx, aibridgeTestRequest(chat, "gpt-4"), aibridgeTestRoute(aibridgeTestAIProvider(providerID, "primary-openai", database.AIProviderTypeOpenai)), modelBuildOptions{ActiveAPIKeyID: apiKeyID, RecordHTTP: true})
|
||||
require.NoError(t, err)
|
||||
_, err = model.Generate(t.Context(), fantasy.Call{Prompt: []fantasy.Message{{
|
||||
Role: fantasy.MessageRoleUser,
|
||||
|
||||
@@ -476,7 +476,7 @@ func TestResolveUserProviderAPIKeys_AIProvider(t *testing.T) {
|
||||
server := newInternalTestServer(t, db, ps, chatprovider.ProviderAPIKeys{})
|
||||
ctx := chatdTestContext(t)
|
||||
user, _, _ := seedInternalChatDeps(t, db)
|
||||
provider := insertInternalAIProvider(t, db, database.AiProviderTypeOpenai, "provider-api-key", true)
|
||||
provider := insertInternalAIProvider(t, db, database.AIProviderTypeOpenai, "provider-api-key", true)
|
||||
now := time.Now()
|
||||
_, err := db.UpsertUserAIProviderKey(ctx, database.UpsertUserAIProviderKeyParams{
|
||||
ID: uuid.New(),
|
||||
@@ -502,7 +502,7 @@ func TestResolveUserProviderAPIKeys_AIProvider(t *testing.T) {
|
||||
server.allowBYOK = false
|
||||
ctx := chatdTestContext(t)
|
||||
user, _, _ := seedInternalChatDeps(t, db)
|
||||
provider := insertInternalAIProvider(t, db, database.AiProviderTypeOpenai, "provider-api-key", true)
|
||||
provider := insertInternalAIProvider(t, db, database.AIProviderTypeOpenai, "provider-api-key", true)
|
||||
now := time.Now()
|
||||
_, err := db.UpsertUserAIProviderKey(ctx, database.UpsertUserAIProviderKeyParams{
|
||||
ID: uuid.New(),
|
||||
@@ -526,7 +526,7 @@ func TestResolveUserProviderAPIKeys_AIProvider(t *testing.T) {
|
||||
server := newInternalTestServer(t, db, ps, chatprovider.ProviderAPIKeys{})
|
||||
ctx := chatdTestContext(t)
|
||||
user, _, _ := seedInternalChatDeps(t, db)
|
||||
insertInternalAIProvider(t, db, database.AiProviderTypeAzure, "provider-api-key", true)
|
||||
insertInternalAIProvider(t, db, database.AIProviderTypeAzure, "provider-api-key", true)
|
||||
|
||||
keys, err := server.resolveUserProviderAPIKeysForProviderType(ctx, user.ID, "azure")
|
||||
require.NoError(t, err)
|
||||
@@ -540,7 +540,7 @@ func TestResolveUserProviderAPIKeys_AIProvider(t *testing.T) {
|
||||
server := newInternalTestServer(t, db, ps, chatprovider.ProviderAPIKeys{})
|
||||
ctx := chatdTestContext(t)
|
||||
user, _, _ := seedInternalChatDeps(t, db)
|
||||
provider := insertInternalAIProvider(t, db, database.AiProviderTypeBedrock, "", true)
|
||||
provider := insertInternalAIProvider(t, db, database.AIProviderTypeBedrock, "", true)
|
||||
|
||||
keys, err := server.resolveUserProviderAPIKeys(ctx, user.ID, provider.ID)
|
||||
require.NoError(t, err)
|
||||
@@ -555,8 +555,8 @@ func TestResolveUserProviderAPIKeys_AIProvider(t *testing.T) {
|
||||
server := newInternalTestServer(t, db, ps, chatprovider.ProviderAPIKeys{})
|
||||
ctx := chatdTestContext(t)
|
||||
user, _, _ := seedInternalChatDeps(t, db)
|
||||
insertInternalAIProvider(t, db, database.AiProviderTypeOpenai, "first-provider-api-key", true)
|
||||
insertInternalAIProvider(t, db, database.AiProviderTypeOpenai, "second-provider-api-key", true)
|
||||
insertInternalAIProvider(t, db, database.AIProviderTypeOpenai, "first-provider-api-key", true)
|
||||
insertInternalAIProvider(t, db, database.AIProviderTypeOpenai, "second-provider-api-key", true)
|
||||
|
||||
keys, err := server.resolveUserProviderAPIKeys(ctx, user.ID, uuid.Nil)
|
||||
require.ErrorContains(t, err, "multiple enabled AI providers use provider type")
|
||||
@@ -570,7 +570,7 @@ func TestResolveChatModel_AIProviderDisabled(t *testing.T) {
|
||||
ctx := chatdTestContext(t)
|
||||
db, ps := dbtestutil.NewDB(t)
|
||||
user, org, _ := seedInternalChatDeps(t, db)
|
||||
provider := insertInternalAIProvider(t, db, database.AiProviderTypeOpenai, "provider-api-key", false)
|
||||
provider := insertInternalAIProvider(t, db, database.AIProviderTypeOpenai, "provider-api-key", false)
|
||||
modelConfig := dbgen.ChatModelConfig(t, db, database.ChatModelConfig{
|
||||
Provider: "openai",
|
||||
Model: "gpt-4o-mini",
|
||||
|
||||
@@ -253,7 +253,7 @@ func TestMaybeGenerateChatTitle_TitleGenerationOverrideSetUsable(t *testing.T) {
|
||||
})
|
||||
provider := database.AIProvider{
|
||||
ID: providerID,
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
Enabled: true,
|
||||
BaseUrl: serverURL,
|
||||
}
|
||||
@@ -365,7 +365,7 @@ func TestMaybeGenerateChatTitle_TitleGenerationOverrideCallFailureSkipsFallback(
|
||||
|
||||
db.EXPECT().GetChatTitleGenerationModelOverride(gomock.Any()).Return(overrideConfig.ID.String(), nil)
|
||||
db.EXPECT().GetChatModelConfigByID(gomock.Any(), overrideConfig.ID).Return(overrideConfig, nil)
|
||||
db.EXPECT().GetAIProviders(gomock.Any(), gomock.Any()).Return([]database.AIProvider{{Type: database.AiProviderTypeOpenai, Enabled: true}}, nil)
|
||||
db.EXPECT().GetAIProviders(gomock.Any(), gomock.Any()).Return([]database.AIProvider{{Type: database.AIProviderTypeOpenai, Enabled: true}}, nil)
|
||||
db.EXPECT().GetAIProviderKeysByProviderIDs(gomock.Any(), []uuid.UUID{uuid.Nil}).Return(nil, nil)
|
||||
|
||||
generated := &generatedChatTitle{}
|
||||
@@ -446,7 +446,7 @@ func TestResolveManualTitleModel_TitleGenerationOverrideUnsetAIProvider(t *testi
|
||||
})
|
||||
provider := database.AIProvider{
|
||||
ID: providerID,
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
Enabled: true,
|
||||
BaseUrl: serverURL,
|
||||
}
|
||||
@@ -521,7 +521,7 @@ func TestResolveManualTitleModel_TitleGenerationOverrideSetUsable(t *testing.T)
|
||||
|
||||
db.EXPECT().GetChatTitleGenerationModelOverride(gomock.Any()).Return(overrideConfig.ID.String(), nil)
|
||||
db.EXPECT().GetChatModelConfigByID(gomock.Any(), overrideConfig.ID).Return(overrideConfig, nil)
|
||||
db.EXPECT().GetAIProviders(gomock.Any(), gomock.Any()).Return([]database.AIProvider{{Type: database.AiProviderTypeOpenai, Enabled: true}}, nil)
|
||||
db.EXPECT().GetAIProviders(gomock.Any(), gomock.Any()).Return([]database.AIProvider{{Type: database.AIProviderTypeOpenai, Enabled: true}}, nil)
|
||||
db.EXPECT().GetAIProviderKeysByProviderIDs(gomock.Any(), gomock.Any()).Return(nil, nil).AnyTimes()
|
||||
|
||||
server := titleOverrideTestServer(db, logger)
|
||||
@@ -549,7 +549,7 @@ func TestResolveManualTitleModel_TitleGenerationOverrideMissingCredentials(t *te
|
||||
|
||||
db.EXPECT().GetChatTitleGenerationModelOverride(gomock.Any()).Return(overrideConfig.ID.String(), nil)
|
||||
db.EXPECT().GetChatModelConfigByID(gomock.Any(), overrideConfig.ID).Return(overrideConfig, nil)
|
||||
db.EXPECT().GetAIProviders(gomock.Any(), gomock.Any()).Return([]database.AIProvider{{Type: database.AiProviderTypeOpenai, Enabled: true}}, nil)
|
||||
db.EXPECT().GetAIProviders(gomock.Any(), gomock.Any()).Return([]database.AIProvider{{Type: database.AIProviderTypeOpenai, Enabled: true}}, nil)
|
||||
db.EXPECT().GetAIProviderKeysByProviderIDs(gomock.Any(), gomock.Any()).Return(nil, nil).AnyTimes()
|
||||
|
||||
server := titleOverrideTestServer(db, logger)
|
||||
@@ -619,7 +619,7 @@ func TestGenerateManualTitleCandidate_ActiveAPIKeyIDFallback(t *testing.T) {
|
||||
provider := database.AIProvider{
|
||||
ID: providerID,
|
||||
Name: "primary-openai",
|
||||
Type: database.AiProviderTypeOpenai,
|
||||
Type: database.AIProviderTypeOpenai,
|
||||
Enabled: true,
|
||||
}
|
||||
wantTitle := "Context title"
|
||||
|
||||
Reference in New Issue
Block a user