| 304 | } |
| 305 | |
| 306 | async fn session_status( |
| 307 | State(state): State<Arc<ServerState>>, |
| 308 | ) -> Result<Json<HashMap<String, SessionStatusInfo>>> { |
| 309 | let run_status = SESSION_RUN_STATUS.read().await.clone(); |
| 310 | let manager = state.sessions.lock().await; |
| 311 | let sessions = manager.list(); |
| 312 | let status: HashMap<String, SessionStatusInfo> = sessions |
| 313 | .into_iter() |
| 314 | .map(|s| { |
| 315 | let lifecycle_status = match s.status { |
| 316 | opencode_session::SessionStatus::Active => "active", |
| 317 | opencode_session::SessionStatus::Completed => "completed", |
| 318 | opencode_session::SessionStatus::Archived => "archived", |
| 319 | opencode_session::SessionStatus::Compacting => "compacting", |
| 320 | }; |
| 321 | let run = run_status.get(&s.id).cloned().unwrap_or_default(); |
| 322 | let (status, idle, busy, attempt, message, next) = match run { |
| 323 | SessionRunStatus::Idle => { |
| 324 | (lifecycle_status.to_string(), true, false, None, None, None) |
| 325 | } |
| 326 | SessionRunStatus::Busy => ("busy".to_string(), false, true, None, None, None), |
| 327 | SessionRunStatus::Retry { |
| 328 | attempt, |
| 329 | message, |
| 330 | next, |
| 331 | } => ( |
| 332 | "retry".to_string(), |
| 333 | false, |
| 334 | true, |
| 335 | Some(attempt), |
| 336 | Some(message), |
| 337 | Some(next), |
| 338 | ), |
| 339 | }; |
| 340 | ( |
| 341 | s.id.clone(), |
| 342 | SessionStatusInfo { |
| 343 | status, |
| 344 | idle, |
| 345 | busy, |
| 346 | attempt, |
| 347 | message, |
| 348 | next, |
| 349 | }, |
| 350 | ) |
| 351 | }) |
| 352 | .collect(); |
| 353 | Ok(Json(status)) |
| 354 | } |
| 355 | |
| 356 | #[derive(Debug, Serialize)] |
| 357 | pub struct SessionStatusInfo { |