Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

chore: add user details to aibridge interception list endpoint#20397

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
deansheather merged 3 commits intomainfromdean/aibridge-list-with-user
Oct 22, 2025
Merged
Show file tree
Hide file tree
Changes fromall 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: 4 additions & 0 deletionscli/sharing_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,6 +54,7 @@ func TestSharingShare(t *testing.T) {
MinimalUser: codersdk.MinimalUser{
ID: toShareWithUser.ID,
Username: toShareWithUser.Username,
Name: toShareWithUser.Name,
AvatarURL: toShareWithUser.AvatarURL,
},
Role: codersdk.WorkspaceRole("use"),
Expand DownExpand Up@@ -103,6 +104,7 @@ func TestSharingShare(t *testing.T) {
MinimalUser: codersdk.MinimalUser{
ID: toShareWithUser1.ID,
Username: toShareWithUser1.Username,
Name: toShareWithUser1.Name,
AvatarURL: toShareWithUser1.AvatarURL,
},
Role: codersdk.WorkspaceRoleUse,
Expand All@@ -111,6 +113,7 @@ func TestSharingShare(t *testing.T) {
MinimalUser: codersdk.MinimalUser{
ID: toShareWithUser2.ID,
Username: toShareWithUser2.Username,
Name: toShareWithUser2.Name,
AvatarURL: toShareWithUser2.AvatarURL,
},
Role: codersdk.WorkspaceRoleUse,
Expand DownExpand Up@@ -155,6 +158,7 @@ func TestSharingShare(t *testing.T) {
MinimalUser: codersdk.MinimalUser{
ID: toShareWithUser.ID,
Username: toShareWithUser.Username,
Name: toShareWithUser.Name,
AvatarURL: toShareWithUser.AvatarURL,
},
Role: codersdk.WorkspaceRoleAdmin,
Expand Down
2 changes: 1 addition & 1 deletioncli/testdata/coder_users_list_--help.golden
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@ USAGE:
Aliases: ls

OPTIONS:
-c, --column [id|username|email|created at|updated at|status] (default: username,email,created at,status)
-c, --column [id|username|name|email|created at|updated at|status] (default: username,email,created at,status)
Columns to display in table output.

--github-user-id int
Expand Down
11 changes: 8 additions & 3 deletionscoderd/apidoc/docs.go
View file
Open in desktop

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

11 changes: 8 additions & 3 deletionscoderd/apidoc/swagger.json
View file
Open in desktop

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

15 changes: 12 additions & 3 deletionscoderd/database/db2sdk/db2sdk.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -189,6 +189,16 @@ func MinimalUser(user database.User) codersdk.MinimalUser {
return codersdk.MinimalUser{
ID: user.ID,
Username: user.Username,
Name: user.Name,
AvatarURL: user.AvatarURL,
}
}

func MinimalUserFromVisibleUser(user database.VisibleUser) codersdk.MinimalUser {
return codersdk.MinimalUser{
ID: user.ID,
Username: user.Username,
Name: user.Name,
AvatarURL: user.AvatarURL,
}
}
Expand All@@ -197,7 +207,6 @@ func ReducedUser(user database.User) codersdk.ReducedUser {
return codersdk.ReducedUser{
MinimalUser: MinimalUser(user),
Email: user.Email,
Name: user.Name,
CreatedAt: user.CreatedAt,
UpdatedAt: user.UpdatedAt,
LastSeenAt: user.LastSeenAt,
Expand DownExpand Up@@ -927,7 +936,7 @@ func PreviewParameterValidation(v *previewtypes.ParameterValidation) codersdk.Pr
}
}

func AIBridgeInterception(interception database.AIBridgeInterception, tokenUsages []database.AIBridgeTokenUsage, userPrompts []database.AIBridgeUserPrompt, toolUsages []database.AIBridgeToolUsage) codersdk.AIBridgeInterception {
func AIBridgeInterception(interception database.AIBridgeInterception,initiator database.VisibleUser,tokenUsages []database.AIBridgeTokenUsage, userPrompts []database.AIBridgeUserPrompt, toolUsages []database.AIBridgeToolUsage) codersdk.AIBridgeInterception {
sdkTokenUsages := List(tokenUsages, AIBridgeTokenUsage)
sort.Slice(sdkTokenUsages, func(i, j int) bool {
// created_at ASC
Expand All@@ -945,7 +954,7 @@ func AIBridgeInterception(interception database.AIBridgeInterception, tokenUsage
})
return codersdk.AIBridgeInterception{
ID: interception.ID,
InitiatorID: interception.InitiatorID,
Initiator: MinimalUserFromVisibleUser(initiator),
Provider: interception.Provider,
Model: interception.Model,
Metadata: jsonOrEmptyMap(interception.Metadata),
Expand Down
4 changes: 2 additions & 2 deletionscoderd/database/dbauthz/dbauthz.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4461,7 +4461,7 @@ func (q *querier) InsertWorkspaceResourceMetadata(ctx context.Context, arg datab
return q.db.InsertWorkspaceResourceMetadata(ctx, arg)
}

func (q *querier) ListAIBridgeInterceptions(ctx context.Context, arg database.ListAIBridgeInterceptionsParams) ([]database.AIBridgeInterception, error) {
func (q *querier) ListAIBridgeInterceptions(ctx context.Context, arg database.ListAIBridgeInterceptionsParams) ([]database.ListAIBridgeInterceptionsRow, error) {
prep, err := prepareSQLFilter(ctx, q.auth, policy.ActionRead, rbac.ResourceAibridgeInterception.Type)
if err != nil {
return nil, xerrors.Errorf("(dev error) prepare sql filter: %w", err)
Expand DownExpand Up@@ -5870,7 +5870,7 @@ func (q *querier) CountAuthorizedConnectionLogs(ctx context.Context, arg databas
return q.CountConnectionLogs(ctx, arg)
}

func (q *querier) ListAuthorizedAIBridgeInterceptions(ctx context.Context, arg database.ListAIBridgeInterceptionsParams, _ rbac.PreparedAuthorized) ([]database.AIBridgeInterception, error) {
func (q *querier) ListAuthorizedAIBridgeInterceptions(ctx context.Context, arg database.ListAIBridgeInterceptionsParams, _ rbac.PreparedAuthorized) ([]database.ListAIBridgeInterceptionsRow, error) {
// TODO: Delete this function, all ListAIBridgeInterceptions should be authorized. For now just call ListAIBridgeInterceptions on the authz querier.
// This cannot be deleted for now because it's included in the
// database.Store interface, so dbauthz needs to implement it.
Expand Down
4 changes: 2 additions & 2 deletionscoderd/database/dbauthz/dbauthz_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4537,14 +4537,14 @@ func (s *MethodTestSuite) TestAIBridge() {

s.Run("ListAIBridgeInterceptions", s.Mocked(func(db *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
params := database.ListAIBridgeInterceptionsParams{}
db.EXPECT().ListAuthorizedAIBridgeInterceptions(gomock.Any(), params, gomock.Any()).Return([]database.AIBridgeInterception{}, nil).AnyTimes()
db.EXPECT().ListAuthorizedAIBridgeInterceptions(gomock.Any(), params, gomock.Any()).Return([]database.ListAIBridgeInterceptionsRow{}, nil).AnyTimes()
// No asserts here because SQLFilter.
check.Args(params).Asserts()
}))

s.Run("ListAuthorizedAIBridgeInterceptions", s.Mocked(func(db *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
params := database.ListAIBridgeInterceptionsParams{}
db.EXPECT().ListAuthorizedAIBridgeInterceptions(gomock.Any(), params, gomock.Any()).Return([]database.AIBridgeInterception{}, nil).AnyTimes()
db.EXPECT().ListAuthorizedAIBridgeInterceptions(gomock.Any(), params, gomock.Any()).Return([]database.ListAIBridgeInterceptionsRow{}, nil).AnyTimes()
// No asserts here because SQLFilter.
check.Args(params, emptyPreparedAuthorized{}).Asserts()
}))
Expand Down
4 changes: 2 additions & 2 deletionscoderd/database/dbmetrics/querymetrics.go
View file
Open in desktop

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

8 changes: 4 additions & 4 deletionscoderd/database/dbmock/dbmock.go
View file
Open in desktop

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

3 changes: 3 additions & 0 deletionscoderd/database/dump.sql
View file
Open in desktop

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

1 change: 1 addition & 0 deletionscoderd/database/foreign_key_constraint.go
View file
Open in desktop

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

View file
Open in desktop
Empty file.
49 changes: 49 additions & 0 deletionscoderd/database/migrations/000385_aibridge_fks.up.sql
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
-- We didn't add an FK as a premature optimization when the aibridge tables were
-- added, but for the initiator_id it's pretty annoying not having a strong
-- reference.
--
-- Since the aibridge feature is still in early access, we're going to add the
-- FK and drop any rows that violate it (which should be none). This isn't a
-- very efficient migration, but since the feature is behind an experimental
-- flag, it shouldn't have any impact on deployments that aren't using the
-- feature.

-- Step 1: Add FK without validating it
ALTER TABLE aibridge_interceptions
ADD CONSTRAINT aibridge_interceptions_initiator_id_fkey
FOREIGN KEY (initiator_id)
REFERENCES users(id)
-- We can't:
-- - Cascade delete because this is an auditing feature, and it also
-- wouldn't delete related aibridge rows since we don't FK them.
-- - Set null because you can't correlate to the original user ID if the
-- user somehow gets deleted.
--
-- So we just use the default and don't do anything. This will result in a
-- deferred constraint violation error when the user is deleted.
--
-- In Coder, we don't delete user rows ever, so this should never happen
-- unless an admin manually deletes a user with SQL.
ON DELETE NO ACTION
-- Delay validation of existing data until after we've dropped rows that
-- violate the FK.
NOT VALID;

-- Step 2: Drop existing interceptions that violate the FK.
DELETE FROM aibridge_interceptions
WHERE initiator_id NOT IN (SELECT id FROM users);

-- Step 3: Drop existing rows from other tables that no longer have a valid
-- interception in the database.
DELETE FROM aibridge_token_usages
WHERE interception_id NOT IN (SELECT id FROM aibridge_interceptions);

DELETE FROM aibridge_user_prompts
WHERE interception_id NOT IN (SELECT id FROM aibridge_interceptions);

DELETE FROM aibridge_tool_usages
WHERE interception_id NOT IN (SELECT id FROM aibridge_interceptions);

-- Step 4: Validate the FK
ALTER TABLE aibridge_interceptions
VALIDATE CONSTRAINT aibridge_interceptions_initiator_id_fkey;
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,7 +8,7 @@ INSERT INTO
)
VALUES (
'be003e1e-b38f-43bf-847d-928074dd0aa8',
'30095c71-380b-457a-8995-97b8ee6e5307',
'30095c71-380b-457a-8995-97b8ee6e5307', -- admin@coder.com, from 000022_initial_v0.6.6.up.sql
'openai',
'gpt-5',
'2025-09-15 12:45:13.921148+00'
Expand DownExpand Up@@ -77,3 +77,82 @@ VALUES (
'{}',
'2025-09-15 12:45:21.674335+00'
);

-- For a later migration, we'll add an invalid interception without a valid
-- initiator_id.
INSERT INTO
aibridge_interceptions (
id,
initiator_id,
provider,
model,
started_at
)
VALUES (
'c6d29c6e-26a3-4137-bb2e-9dfeef3c1c26',
'cab8d56a-8922-4999-81a9-046b43ac1312', -- user does not exist
'openai',
'gpt-5',
'2025-09-15 12:45:13.921148+00'
);
INSERT INTO
aibridge_token_usages (
id,
interception_id,
provider_response_id,
input_tokens,
output_tokens,
metadata,
created_at
)
VALUES (
'5650db6c-0b7c-49e3-bb26-9b2ba0107e11',
'c6d29c6e-26a3-4137-bb2e-9dfeef3c1c26',
'chatcmpl-CG2s28QlpKIoooUtXuLTmGbdtyS1k',
10950,
118,
'{}',
'2025-09-15 12:45:21.674413+00'
);
INSERT INTO
aibridge_user_prompts (
id,
interception_id,
provider_response_id,
prompt,
metadata,
created_at
)
VALUES (
'1e76cb5b-7c34-4160-b604-a4256f856169',
'c6d29c6e-26a3-4137-bb2e-9dfeef3c1c26',
'chatcmpl-CG2s28QlpKIoooUtXuLTmGbdtyS1k',
'how many workspaces do i have',
'{}',
'2025-09-15 12:45:21.674335+00'
);
INSERT INTO
aibridge_tool_usages (
id,
interception_id,
provider_response_id,
tool,
server_url,
input,
injected,
invocation_error,
metadata,
created_at
)
VALUES (
'351b440f-d605-4f37-8ceb-011f0377b695',
'c6d29c6e-26a3-4137-bb2e-9dfeef3c1c26',
'chatcmpl-CG2s28QlpKIoooUtXuLTmGbdtyS1k',
'coder_list_workspaces',
'http://localhost:3000/api/experimental/mcp/http',
'{}',
true,
NULL,
'{}',
'2025-09-15 12:45:21.674413+00'
);
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp