Files
storkit/server/src/http/chat.rs

59 lines
1.4 KiB
Rust
Raw Normal View History

2026-02-16 16:24:21 +00:00
use crate::http::context::{AppContext, OpenApiResult, bad_request};
use crate::llm::chat;
2026-02-16 16:50:50 +00:00
use poem_openapi::{OpenApi, Tags, payload::Json};
2026-02-16 16:35:25 +00:00
use std::sync::Arc;
2026-02-16 16:24:21 +00:00
2026-02-16 16:50:50 +00:00
#[derive(Tags)]
enum ChatTags {
Chat,
}
2026-02-16 16:35:25 +00:00
pub struct ChatApi {
pub ctx: Arc<AppContext>,
}
2026-02-16 16:50:50 +00:00
#[OpenApi(tag = "ChatTags::Chat")]
2026-02-16 16:35:25 +00:00
impl ChatApi {
2026-02-16 16:50:50 +00:00
/// Cancel the currently running chat stream, if any.
///
/// Returns `true` once the cancellation signal is issued.
2026-02-16 16:35:25 +00:00
#[oai(path = "/chat/cancel", method = "post")]
async fn cancel_chat(&self) -> OpenApiResult<Json<bool>> {
chat::cancel_chat(&self.ctx.state).map_err(bad_request)?;
Ok(Json(true))
}
2026-02-16 16:24:21 +00:00
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::TempDir;
fn test_api(dir: &TempDir) -> ChatApi {
ChatApi {
ctx: Arc::new(AppContext::new_test(dir.path().to_path_buf())),
}
}
#[tokio::test]
async fn cancel_chat_returns_true() {
let dir = TempDir::new().unwrap();
let api = test_api(&dir);
let result = api.cancel_chat().await;
assert!(result.is_ok());
assert!(result.unwrap().0);
}
#[tokio::test]
async fn cancel_chat_sends_cancel_signal() {
let dir = TempDir::new().unwrap();
let api = test_api(&dir);
let mut cancel_rx = api.ctx.state.cancel_rx.clone();
cancel_rx.borrow_and_update();
api.cancel_chat().await.unwrap();
assert!(*cancel_rx.borrow());
}
}