aiBridgeListSessions returns AI Bridge sessions (aggregated interceptions). @Summary List AI Bridge sessions @ID list-ai-bridge-sessions @Security CoderSessionToken @Produce json @Tags AI Bridge @Param q query string false "Search query in the format `key:value`. Available keys are: initiator, prov
(rw http.ResponseWriter, r *http.Request)
| 225 | // @Success 200 {object} codersdk.AIBridgeListSessionsResponse |
| 226 | // @Router /api/v2/aibridge/sessions [get] |
| 227 | func (api *API) aiBridgeListSessions(rw http.ResponseWriter, r *http.Request) { |
| 228 | ctx := r.Context() |
| 229 | apiKey := httpmw.APIKey(r) |
| 230 | |
| 231 | page, ok := coderd.ParsePagination(rw, r) |
| 232 | if !ok { |
| 233 | return |
| 234 | } |
| 235 | |
| 236 | afterSessionID := r.URL.Query().Get("after_session_id") |
| 237 | if afterSessionID != "" && page.Offset != 0 { |
| 238 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 239 | Message: "Query parameters have invalid values.", |
| 240 | Detail: "Cannot use both after_session_id and offset pagination in the same request.", |
| 241 | }) |
| 242 | return |
| 243 | } |
| 244 | if page.Limit == 0 { |
| 245 | page.Limit = defaultListSessionsLimit |
| 246 | } |
| 247 | if page.Limit > maxListSessionsLimit || page.Limit < 1 { |
| 248 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 249 | Message: "Invalid pagination limit value.", |
| 250 | Detail: fmt.Sprintf("Pagination limit must be in range (0, %d]", maxListSessionsLimit), |
| 251 | }) |
| 252 | return |
| 253 | } |
| 254 | |
| 255 | queryStr := r.URL.Query().Get("q") |
| 256 | filter, errs := searchquery.AIBridgeSessions(ctx, api.Database, queryStr, page, apiKey.UserID, afterSessionID) |
| 257 | if len(errs) > 0 { |
| 258 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 259 | Message: "Invalid session search query.", |
| 260 | Validations: errs, |
| 261 | }) |
| 262 | return |
| 263 | } |
| 264 | |
| 265 | // Validate the cursor session exists before running the main query. |
| 266 | if afterSessionID != "" { |
| 267 | //nolint:exhaustruct // Only need session_id filter and limit. |
| 268 | cursor, err := api.Database.ListAIBridgeSessions(ctx, database.ListAIBridgeSessionsParams{ |
| 269 | SessionID: afterSessionID, |
| 270 | Limit: 1, |
| 271 | }) |
| 272 | if err != nil { |
| 273 | api.Logger.Error(ctx, "error validating after_session_id cursor", slog.Error(err)) |
| 274 | httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ |
| 275 | Message: "Internal error validating after_session_id cursor.", |
| 276 | Detail: "", // Don't leak database issue to client. |
| 277 | }) |
| 278 | return |
| 279 | } |
| 280 | if len(cursor) == 0 { |
| 281 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 282 | Message: "Query parameter has invalid value.", |
| 283 | Detail: fmt.Sprintf("after_session_id: session %q not found", afterSessionID), |
| 284 | }) |
nothing calls this directly
no test coverage detected