Skip to main content

opendev_web/routes/sessions/
models.rs

1//! Session model overlay management routes.
2
3use axum::Json;
4use axum::extract::{Path as AxumPath, State};
5use serde::Deserialize;
6
7use crate::error::WebError;
8use crate::state::AppState;
9
10/// Session model update request.
11#[derive(Debug, Deserialize)]
12pub struct SessionModelUpdate {
13    pub model_provider: Option<String>,
14    pub model: Option<String>,
15    pub model_vlm_provider: Option<String>,
16    pub model_vlm: Option<String>,
17}
18
19/// Get session model overlay.
20pub(super) async fn get_session_model(
21    State(state): State<AppState>,
22    AxumPath(id): AxumPath<String>,
23) -> Result<Json<serde_json::Value>, WebError> {
24    let mgr = state.session_manager().await;
25    let session = mgr
26        .load_session(&id)
27        .map_err(|e| WebError::NotFound(format!("Session {} not found: {}", id, e)))?;
28
29    let overlay = session
30        .metadata
31        .get("session_model")
32        .cloned()
33        .unwrap_or(serde_json::json!({}));
34
35    Ok(Json(overlay))
36}
37
38/// Update session model overlay.
39pub(super) async fn update_session_model(
40    State(state): State<AppState>,
41    AxumPath(id): AxumPath<String>,
42    Json(body): Json<SessionModelUpdate>,
43) -> Result<Json<serde_json::Value>, WebError> {
44    let mgr = state.session_manager().await;
45
46    let mut session = mgr
47        .load_session(&id)
48        .map_err(|e| WebError::NotFound(format!("Session {} not found: {}", id, e)))?;
49
50    // Build overlay from non-None fields.
51    let mut overlay = serde_json::Map::new();
52    if let Some(v) = body.model_provider {
53        overlay.insert("model_provider".to_string(), serde_json::json!(v));
54    }
55    if let Some(v) = body.model {
56        overlay.insert("model".to_string(), serde_json::json!(v));
57    }
58    if let Some(v) = body.model_vlm_provider {
59        overlay.insert("model_vlm_provider".to_string(), serde_json::json!(v));
60    }
61    if let Some(v) = body.model_vlm {
62        overlay.insert("model_vlm".to_string(), serde_json::json!(v));
63    }
64
65    if overlay.is_empty() {
66        return Err(WebError::BadRequest("No model fields provided".to_string()));
67    }
68
69    // Store overlay in session metadata.
70    session.metadata.insert(
71        "session_model".to_string(),
72        serde_json::Value::Object(overlay),
73    );
74
75    mgr.save_session(&session)
76        .map_err(|e| WebError::Internal(format!("Failed to save session: {}", e)))?;
77
78    Ok(Json(serde_json::json!({
79        "status": "success",
80        "message": "Session model updated",
81    })))
82}
83
84/// Clear session model overlay.
85pub(super) async fn clear_session_model(
86    State(state): State<AppState>,
87    AxumPath(id): AxumPath<String>,
88) -> Result<Json<serde_json::Value>, WebError> {
89    let mgr = state.session_manager().await;
90
91    let mut session = mgr
92        .load_session(&id)
93        .map_err(|e| WebError::NotFound(format!("Session {} not found: {}", id, e)))?;
94
95    session.metadata.remove("session_model");
96
97    mgr.save_session(&session)
98        .map_err(|e| WebError::Internal(format!("Failed to save session: {}", e)))?;
99
100    Ok(Json(serde_json::json!({
101        "status": "success",
102        "message": "Session model cleared",
103    })))
104}