feat: use AI provider chat APIs (#25415)

This commit is contained in:
Michael Suchacz
2026-05-22 07:53:23 +02:00
committed by GitHub
parent 10efde3e6c
commit 06526a5822
41 changed files with 2195 additions and 1126 deletions
+38
View File
@@ -722,6 +722,24 @@ var (
}),
Scope: rbac.ScopeAll,
}.WithCachedASTValue()
subjectAIProviderMetadataReader = rbac.Subject{
Type: rbac.SubjectTypeAIProviderMetadataReader,
FriendlyName: "AI Provider Metadata Reader",
ID: uuid.Nil.String(),
Roles: rbac.Roles([]rbac.Role{
{
Identifier: rbac.RoleIdentifier{Name: "ai-provider-metadata-reader"},
DisplayName: "AI Provider Metadata Reader",
Site: rbac.Permissions(map[string][]policy.Action{
rbac.ResourceAIProvider.Type: {policy.ActionRead},
}),
User: []rbac.Permission{},
ByOrgID: map[string]rbac.OrgPermissions{},
},
}),
Scope: rbac.ScopeAll,
}.WithCachedASTValue()
)
// AsProvisionerd returns a context with an actor that has permissions required
@@ -846,6 +864,12 @@ func AsChatd(ctx context.Context) context.Context {
return As(ctx, subjectChatd)
}
// AsAIProviderMetadataReader returns a context with an actor that can read
// AI provider metadata and provider-key presence.
func AsAIProviderMetadataReader(ctx context.Context) context.Context {
return As(ctx, subjectAIProviderMetadataReader)
}
var AsRemoveActor = rbac.Subject{
ID: "remove-actor",
}
@@ -2546,6 +2570,13 @@ func (q *querier) GetAIProviderByID(ctx context.Context, id uuid.UUID) (database
return q.db.GetAIProviderByID(ctx, id)
}
func (q *querier) GetAIProviderByIDForReferenceLock(ctx context.Context, id uuid.UUID) (database.AIProvider, error) {
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceAIProvider); err != nil {
return database.AIProvider{}, err
}
return q.db.GetAIProviderByIDForReferenceLock(ctx, id)
}
func (q *querier) GetAIProviderByName(ctx context.Context, name string) (database.AIProvider, error) {
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceAIProvider); err != nil {
return database.AIProvider{}, err
@@ -2560,6 +2591,13 @@ func (q *querier) GetAIProviderKeyByID(ctx context.Context, id uuid.UUID) (datab
return q.db.GetAIProviderKeyByID(ctx, id)
}
func (q *querier) GetAIProviderKeyPresence(ctx context.Context, arg []uuid.UUID) ([]uuid.UUID, error) {
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceAIProvider); err != nil {
return nil, err
}
return q.db.GetAIProviderKeyPresence(ctx, arg)
}
func (q *querier) GetAIProviderKeys(ctx context.Context, includeDeleted bool) ([]database.AIProviderKey, error) {
// Callers pass include_deleted=TRUE only from the dbcrypt key
// rotation utility, which needs to re-encrypt every row that holds
+13
View File
@@ -6509,6 +6509,11 @@ func (s *MethodTestSuite) TestAIBridge() {
dbm.EXPECT().GetAIProviderByID(gomock.Any(), provider.ID).Return(provider, nil).AnyTimes()
check.Args(provider.ID).Asserts(rbac.ResourceAIProvider, policy.ActionRead).Returns(provider)
}))
s.Run("GetAIProviderByIDForReferenceLock", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
provider := testutil.Fake(s.T(), faker, database.AIProvider{})
dbm.EXPECT().GetAIProviderByIDForReferenceLock(gomock.Any(), provider.ID).Return(provider, nil).AnyTimes()
check.Args(provider.ID).Asserts(rbac.ResourceAIProvider, policy.ActionRead).Returns(provider)
}))
s.Run("GetAIProviderByName", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
provider := testutil.Fake(s.T(), faker, database.AIProvider{})
dbm.EXPECT().GetAIProviderByName(gomock.Any(), provider.Name).Return(provider, nil).AnyTimes()
@@ -6562,6 +6567,14 @@ func (s *MethodTestSuite) TestAIBridge() {
dbm.EXPECT().GetAIProviderKeyByID(gomock.Any(), key.ID).Return(key, nil).AnyTimes()
check.Args(key.ID).Asserts(rbac.ResourceAIProvider, policy.ActionRead).Returns(key)
}))
s.Run("GetAIProviderKeyPresence", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
providerA := testutil.Fake(s.T(), faker, database.AIProvider{})
providerB := testutil.Fake(s.T(), faker, database.AIProvider{})
arg := []uuid.UUID{providerA.ID, providerB.ID}
providerIDs := []uuid.UUID{providerA.ID}
dbm.EXPECT().GetAIProviderKeyPresence(gomock.Any(), arg).Return(providerIDs, nil).AnyTimes()
check.Args(arg).Asserts(rbac.ResourceAIProvider, policy.ActionRead).Returns(providerIDs)
}))
s.Run("GetAIProviderKeysByProviderID", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
provider := testutil.Fake(s.T(), faker, database.AIProvider{})
keyA := testutil.Fake(s.T(), faker, database.AIProviderKey{ProviderID: provider.ID})