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

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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions coderd/database/dbauthz/dbauthz.go
Original file line number Diff line number Diff line change
Expand Up @@ -5793,12 +5793,12 @@ func (q *querier) HasTemplateVersionsUsingCachedModuleFileInOrg(ctx context.Cont
return q.db.HasTemplateVersionsUsingCachedModuleFileInOrg(ctx, arg)
}

func (q *querier) HydrateAgentChatsContext(ctx context.Context, arg database.HydrateAgentChatsContextParams) error {
func (q *querier) HydrateAgentChatsContext(ctx context.Context, arg database.HydrateAgentChatsContextParams) ([]uuid.UUID, error) {
// System-level operation: an agent context push fans hydration out
// across every not-yet-pinned chat for the agent, so it authorizes at
// the resource level rather than per-chat.
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceChat); err != nil {
return err
return nil, err
}
return q.db.HydrateAgentChatsContext(ctx, arg)
}
Expand Down
5 changes: 3 additions & 2 deletions coderd/database/dbauthz/dbauthz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -548,8 +548,9 @@ func (s *MethodTestSuite) TestConnectionLogs() {
func (s *MethodTestSuite) TestChats() {
s.Run("HydrateAgentChatsContext", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
arg := database.HydrateAgentChatsContextParams{AgentID: uuid.New()}
dbm.EXPECT().HydrateAgentChatsContext(gomock.Any(), arg).Return(nil).AnyTimes()
check.Args(arg).Asserts(rbac.ResourceChat, policy.ActionUpdate)
hydrated := []uuid.UUID{uuid.New()}
dbm.EXPECT().HydrateAgentChatsContext(gomock.Any(), arg).Return(hydrated, nil).AnyTimes()
check.Args(arg).Asserts(rbac.ResourceChat, policy.ActionUpdate).Returns(hydrated)
}))
s.Run("MarkChatsContextDirtyByAgent", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
arg := database.MarkChatsContextDirtyByAgentParams{AgentID: uuid.New()}
Expand Down
6 changes: 3 additions & 3 deletions coderd/database/dbmetrics/querymetrics.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions coderd/database/dbmock/dbmock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions coderd/database/querier.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

95 changes: 92 additions & 3 deletions coderd/database/querier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1296,11 +1296,14 @@ func TestChatContextHydration(t *testing.T) {
_, err := db.ArchiveChatByID(ctx, chatArchived.ID)
require.NoError(t, err)

// Hydrate stamps only the NULL-hash chat for this agent.
require.NoError(t, db.HydrateAgentChatsContext(ctx, database.HydrateAgentChatsContextParams{
// Hydrate stamps only the NULL-hash chat for this agent and returns
// exactly the chats it pinned.
hydrated, err := db.HydrateAgentChatsContext(ctx, database.HydrateAgentChatsContextParams{
AgentID: agent.ID,
AggregateHash: hashH,
}))
})
require.NoError(t, err)
require.Equal(t, []uuid.UUID{chatNull.ID}, hydrated)
gotNull, err := db.GetChatByID(ctx, chatNull.ID)
require.NoError(t, err)
require.Equal(t, hashH, gotNull.ContextAggregateHash, "NULL-hash chat is hydrated")
Expand Down Expand Up @@ -13505,6 +13508,92 @@ func TestUpdateChatLastTurnSummary(t *testing.T) {
require.NotEqual(t, chat.HistoryVersion, fetched.HistoryVersion)
}

func TestUpdateChatWorkspaceBindingNoOp(t *testing.T) {
t.Parallel()
if testing.Short() {
t.SkipNow()
}

sqlDB := testSQLDB(t)
err := migrations.Up(sqlDB)
require.NoError(t, err)
db := database.New(sqlDB)

ctx := testutil.Context(t, testutil.WaitMedium)
owner := dbgen.User(t, db, database.User{})
org := dbgen.Organization(t, db, database.Organization{})
dbgen.OrganizationMember(t, db, database.OrganizationMember{UserID: owner.ID, OrganizationID: org.ID})

dbgen.ChatProvider(t, db, database.ChatProvider{
Provider: "openai",
DisplayName: "OpenAI",
APIKey: "test-key",
Enabled: true,
CentralApiKeyEnabled: true,
})

modelCfg, err := insertChatModelConfigForTest(ctx, t, db, "openai", database.InsertChatModelConfigParams{
Model: "test-model",
DisplayName: "Test Model",
CreatedBy: uuid.NullUUID{UUID: owner.ID, Valid: true},
UpdatedBy: uuid.NullUUID{UUID: owner.ID, Valid: true},
Enabled: true,
IsDefault: true,
ContextLimit: 128000,
CompressionThreshold: 80,
Options: json.RawMessage(`{}`),
})
require.NoError(t, err)

chat, err := db.InsertChat(ctx, database.InsertChatParams{
OrganizationID: org.ID,
Status: database.ChatStatusWaiting,
ClientType: database.ChatClientTypeUi,
OwnerID: owner.ID,
LastModelConfigID: modelCfg.ID,
Title: "binding-chat",
})
require.NoError(t, err)

template := dbgen.Template(t, db, database.Template{
OrganizationID: org.ID,
CreatedBy: owner.ID,
})
workspace := dbgen.Workspace(t, db, database.WorkspaceTable{
OwnerID: owner.ID,
OrganizationID: org.ID,
TemplateID: template.ID,
})
workspaceID := workspace.ID

bound, err := db.UpdateChatWorkspaceBinding(ctx, database.UpdateChatWorkspaceBindingParams{
ID: chat.ID,
WorkspaceID: uuid.NullUUID{UUID: workspaceID, Valid: true},
})
require.NoError(t, err)
require.Equal(t, workspaceID, bound.WorkspaceID.UUID)
require.False(t, bound.UpdatedAt.Before(chat.UpdatedAt))

// Rebinding to the same workspace/build/agent is a no-op and must
// preserve updated_at so chat list ordering and watch events stay
// stable.
rebound, err := db.UpdateChatWorkspaceBinding(ctx, database.UpdateChatWorkspaceBindingParams{
ID: chat.ID,
WorkspaceID: uuid.NullUUID{UUID: workspaceID, Valid: true},
})
require.NoError(t, err)
require.Equal(t, workspaceID, rebound.WorkspaceID.UUID)
require.Equal(t, bound.UpdatedAt, rebound.UpdatedAt)

// Clearing the binding is a real change and must advance updated_at.
cleared, err := db.UpdateChatWorkspaceBinding(ctx, database.UpdateChatWorkspaceBindingParams{
ID: chat.ID,
})
require.NoError(t, err)
require.False(t, cleared.WorkspaceID.Valid)
require.True(t, cleared.UpdatedAt.After(bound.UpdatedAt))
}

func TestDeleteChatDebugDataAfterMessageIDIncludesTriggeredRuns(t *testing.T) {
t.Parallel()

Expand Down
Loading
Loading