AIBridgeSessionThreads converts session metadata and thread interceptions into the threads response. It groups interceptions into threads, builds agentic actions from tool usages and model thoughts, and aggregates token usage with metadata.
( session database.ListAIBridgeSessionsRow, interceptions []database.ListAIBridgeSessionThreadsRow, tokenUsages []database.AIBridgeTokenUsage, toolUsages []database.AIBridgeToolUsage, userPrompts []database.AIBridgeUserPrompt, modelThoughts []database.AIBridgeModelThought, )
| 1218 | // agentic actions from tool usages and model thoughts, and aggregates |
| 1219 | // token usage with metadata. |
| 1220 | func AIBridgeSessionThreads( |
| 1221 | session database.ListAIBridgeSessionsRow, |
| 1222 | interceptions []database.ListAIBridgeSessionThreadsRow, |
| 1223 | tokenUsages []database.AIBridgeTokenUsage, |
| 1224 | toolUsages []database.AIBridgeToolUsage, |
| 1225 | userPrompts []database.AIBridgeUserPrompt, |
| 1226 | modelThoughts []database.AIBridgeModelThought, |
| 1227 | ) codersdk.AIBridgeSessionThreadsResponse { |
| 1228 | // Index subresources by interception ID. |
| 1229 | tokensByInterception := make(map[uuid.UUID][]database.AIBridgeTokenUsage, len(interceptions)) |
| 1230 | for _, tu := range tokenUsages { |
| 1231 | tokensByInterception[tu.InterceptionID] = append(tokensByInterception[tu.InterceptionID], tu) |
| 1232 | } |
| 1233 | toolsByInterception := make(map[uuid.UUID][]database.AIBridgeToolUsage, len(interceptions)) |
| 1234 | for _, tu := range toolUsages { |
| 1235 | toolsByInterception[tu.InterceptionID] = append(toolsByInterception[tu.InterceptionID], tu) |
| 1236 | } |
| 1237 | promptsByInterception := make(map[uuid.UUID][]database.AIBridgeUserPrompt, len(interceptions)) |
| 1238 | for _, up := range userPrompts { |
| 1239 | promptsByInterception[up.InterceptionID] = append(promptsByInterception[up.InterceptionID], up) |
| 1240 | } |
| 1241 | thoughtsByInterception := make(map[uuid.UUID][]database.AIBridgeModelThought, len(interceptions)) |
| 1242 | for _, mt := range modelThoughts { |
| 1243 | thoughtsByInterception[mt.InterceptionID] = append(thoughtsByInterception[mt.InterceptionID], mt) |
| 1244 | } |
| 1245 | |
| 1246 | // Group interceptions by thread_id, preserving the order returned by the |
| 1247 | // SQL query. |
| 1248 | interceptionsByThread := make(map[uuid.UUID][]database.AIBridgeInterception, len(interceptions)) |
| 1249 | var threadIDs []uuid.UUID |
| 1250 | for _, row := range interceptions { |
| 1251 | if _, ok := interceptionsByThread[row.ThreadID]; !ok { |
| 1252 | threadIDs = append(threadIDs, row.ThreadID) |
| 1253 | } |
| 1254 | interceptionsByThread[row.ThreadID] = append(interceptionsByThread[row.ThreadID], row.AIBridgeInterception) |
| 1255 | } |
| 1256 | |
| 1257 | // Build threads and track page time bounds. |
| 1258 | threads := make([]codersdk.AIBridgeThread, 0, len(threadIDs)) |
| 1259 | var pageStartedAt, pageEndedAt *time.Time |
| 1260 | for _, threadID := range threadIDs { |
| 1261 | intcs := interceptionsByThread[threadID] |
| 1262 | thread := buildAIBridgeThread(threadID, intcs, tokensByInterception, toolsByInterception, promptsByInterception, thoughtsByInterception) |
| 1263 | for _, intc := range intcs { |
| 1264 | if pageStartedAt == nil || intc.StartedAt.Before(*pageStartedAt) { |
| 1265 | t := intc.StartedAt |
| 1266 | pageStartedAt = &t |
| 1267 | } |
| 1268 | if intc.EndedAt.Valid { |
| 1269 | if pageEndedAt == nil || intc.EndedAt.Time.After(*pageEndedAt) { |
| 1270 | t := intc.EndedAt.Time |
| 1271 | pageEndedAt = &t |
| 1272 | } |
| 1273 | } |
| 1274 | } |
| 1275 | threads = append(threads, thread) |
| 1276 | } |
| 1277 |
no test coverage detected