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

Appearance settings
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
63 changes: 63 additions & 0 deletions 63 coderd/apidoc/docs.go

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

59 changes: 59 additions & 0 deletions 59 coderd/apidoc/swagger.json

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

26 changes: 26 additions & 0 deletions 26 codersdk/aibridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ type OrganizationGroupAISpend struct {
CurrentSpendMicros int64 `json:"current_spend_micros"`
}

// GroupAISpend is the current AI spend snapshot for a single group within
// the active budget period.
type GroupAISpend struct {
AISpendPeriodWindow
OrganizationGroupAISpend
}

// GroupMembersAISpend reports per-member AI spend attributed to a specific
// group in the active budget period.
type GroupMembersAISpend struct {
Expand Down Expand Up @@ -577,6 +584,25 @@ func (c *Client) OrganizationGroupsAISpend(ctx context.Context, organization uui
return resp, json.NewDecoder(res.Body).Decode(&resp)
}

// GroupAISpend returns AI spend for the given group within the active budget
// period.
func (c *Client) GroupAISpend(ctx context.Context, group uuid.UUID) (GroupAISpend, error) {
res, err := c.Request(ctx, http.MethodGet,
fmt.Sprintf("/api/v2/groups/%s/ai/spend", group.String()),
nil,
)
if err != nil {
return GroupAISpend{}, xerrors.Errorf("make request: %w", err)
}
defer res.Body.Close()

if res.StatusCode != http.StatusOK {
return GroupAISpend{}, ReadBodyAsError(res)
}
var resp GroupAISpend
return resp, json.NewDecoder(res.Body).Decode(&resp)
}

// GroupMembersAISpend returns AI spend attributed to the given group for the
// specified users within the active budget period. At most 100 user IDs may be
// requested per call, and callers with more members are expected to batch
Expand Down
43 changes: 43 additions & 0 deletions 43 docs/reference/api/enterprise.md

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

22 changes: 22 additions & 0 deletions 22 docs/reference/api/schemas.md

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

52 changes: 52 additions & 0 deletions 52 enterprise/coderd/aibridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -1232,6 +1232,58 @@ func (api *API) exportOrganizationAISpend(rw http.ResponseWriter, r *http.Reques
}
}

// @Summary Get group AI spend
// @Description Returns the AI spend limit and aggregate spend for the group.
// @ID get-group-ai-spend
// @Security CoderSessionToken
// @Produce json
// @Tags Enterprise
// @Param group path string true "Group ID" format(uuid)
// @Success 200 {object} codersdk.GroupAISpend
// @Router /api/v2/groups/{group}/ai/spend [get]
func (api *API) groupAISpend(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
group := httpmw.GroupParam(r)
logger := api.Logger.With(slog.F("group_id", group.ID))

periodWindow, err := api.currentAIBudgetWindow()
if err != nil {
logger.Error(ctx, "failed to compute AI budget period", slog.Error(err))
httpapi.InternalServerError(rw, err)
return
}
logger = logger.With(
slog.F("period_start", periodWindow.Start),
slog.F("period_end", periodWindow.End),
)

rows, err := api.Database.GetOrganizationGroupsAISpend(ctx, database.GetOrganizationGroupsAISpendParams{
OrganizationID: group.OrganizationID,
GroupIds: []uuid.UUID{group.ID},
PeriodStart: periodWindow.Start,
})
if err != nil {
logger.Error(ctx, "failed to get group AI spend", slog.Error(err))
httpapi.InternalServerError(rw, err)
return
}
// Read access was already established when the group was extracted from
// the route, so the query only returns no rows when the group was deleted
// in between.
if len(rows) == 0 {
httpapi.ResourceNotFound(rw)
return
}

httpapi.Write(ctx, rw, http.StatusOK, codersdk.GroupAISpend{
AISpendPeriodWindow: codersdk.AISpendPeriodWindow{
PeriodStart: periodWindow.Start,
PeriodEnd: periodWindow.End,
},
OrganizationGroupAISpend: db2sdk.OrganizationGroupAISpend(rows[0]),
})
}

// @Summary Get group members AI spend by organization
// @Description Returns aggregate AI spend attributed to the group per requested user.
// @Description A maximum of 100 user IDs may be requested per call, and requests with more are rejected, so callers are expected to batch across multiple requests.
Expand Down
Loading
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.