ListLatestSessionsForViewer lists all agent sessions for the authenticated user up to limit.
(ctx context.Context, limit int)
| 213 | // ListLatestSessionsForViewer lists all agent sessions for the |
| 214 | // authenticated user up to limit. |
| 215 | func (c *CAPIClient) ListLatestSessionsForViewer(ctx context.Context, limit int) ([]*Session, error) { |
| 216 | if limit == 0 { |
| 217 | return nil, nil |
| 218 | } |
| 219 | |
| 220 | sessionsURL, err := url.JoinPath(c.capiBaseURL, "agents", "sessions") |
| 221 | if err != nil { |
| 222 | return nil, fmt.Errorf("failed to build sessions URL: %w", err) |
| 223 | } |
| 224 | pageSize := defaultSessionsPerPage |
| 225 | |
| 226 | seenResources := make(map[int64]struct{}) |
| 227 | latestSessions := make([]session, 0, limit) |
| 228 | for page := 1; ; page++ { |
| 229 | req, err := http.NewRequestWithContext(ctx, http.MethodGet, sessionsURL, http.NoBody) |
| 230 | if err != nil { |
| 231 | return nil, err |
| 232 | } |
| 233 | |
| 234 | q := req.URL.Query() |
| 235 | q.Set("page_size", strconv.Itoa(pageSize)) |
| 236 | q.Set("page_number", strconv.Itoa(page)) |
| 237 | q.Set("sort", "last_updated_at,desc") |
| 238 | req.URL.RawQuery = q.Encode() |
| 239 | |
| 240 | res, err := c.httpClient.Do(req) |
| 241 | if err != nil { |
| 242 | return nil, err |
| 243 | } |
| 244 | defer res.Body.Close() |
| 245 | if res.StatusCode != http.StatusOK { |
| 246 | return nil, fmt.Errorf("failed to list sessions: %s", res.Status) |
| 247 | } |
| 248 | var response struct { |
| 249 | Sessions []session `json:"sessions"` |
| 250 | } |
| 251 | if err := json.NewDecoder(res.Body).Decode(&response); err != nil { |
| 252 | return nil, fmt.Errorf("failed to decode sessions response: %w", err) |
| 253 | } |
| 254 | |
| 255 | // Process only the newly fetched page worth of sessions. |
| 256 | pageSessions := response.Sessions |
| 257 | |
| 258 | // De-duplicate sessions by resource ID. |
| 259 | // Because the API returns newest first, once we've seen |
| 260 | // a resource ID we can ignore any older sessions for it. |
| 261 | for _, s := range pageSessions { |
| 262 | if _, exists := seenResources[s.ResourceID]; exists { |
| 263 | continue |
| 264 | } |
| 265 | |
| 266 | // A zero resource ID is a temporary situation before a PR/resource |
| 267 | // is associated with the session. We should not mark such case as seen. |
| 268 | if s.ResourceID != 0 { |
| 269 | seenResources[s.ResourceID] = struct{}{} |
| 270 | } |
| 271 | |
| 272 | latestSessions = append(latestSessions, s) |