mod types;
mod session;
mod persistence;
pub mod tool;
mod trait_impl;
pub use tool::SequentialThinkingTool;
pub use types::{SessionStateSnapshot, ThoughtData};
use anyhow::Result;
use std::sync::Arc;
use std::pin::Pin;
use std::future::Future;
struct SequentialThinkingWrapper(Arc<crate::SequentialThinkingTool>);
impl kodegen_server_http::ShutdownHook for SequentialThinkingWrapper {
fn shutdown(&self) -> Pin<Box<dyn Future<Output = Result<()>> + Send + '_>> {
let tool = self.0.clone();
Box::pin(async move {
tool.shutdown().await
.map_err(|e| anyhow::anyhow!("Failed to shutdown sequential thinking tool: {e}"))
})
}
}
pub async fn start_server(
addr: std::net::SocketAddr,
tls_cert: Option<std::path::PathBuf>,
tls_key: Option<std::path::PathBuf>,
) -> anyhow::Result<kodegen_server_http::ServerHandle> {
use kodegen_server_http::{create_http_server, Managers, RouterSet, register_tool};
use rmcp::handler::server::router::{prompt::PromptRouter, tool::ToolRouter};
use std::time::Duration;
let tls_config = match (tls_cert, tls_key) {
(Some(cert), Some(key)) => Some((cert, key)),
_ => None,
};
let shutdown_timeout = Duration::from_secs(30);
let session_keep_alive = Duration::ZERO;
create_http_server("sequential-thinking", addr, tls_config, shutdown_timeout, session_keep_alive, |_config, _tracker| {
Box::pin(async move {
let mut tool_router = ToolRouter::new();
let mut prompt_router = PromptRouter::new();
let managers = Managers::new();
let tool = crate::SequentialThinkingTool::new();
let tool_arc = Arc::new(tool.clone());
tool_arc.clone().start_cleanup_task();
managers.register(SequentialThinkingWrapper(tool_arc)).await;
(tool_router, prompt_router) = register_tool(
tool_router,
prompt_router,
tool,
);
Ok(RouterSet::new(tool_router, prompt_router, managers))
})
}).await
}
pub async fn start_server_with_listener(
listener: tokio::net::TcpListener,
tls_config: Option<(std::path::PathBuf, std::path::PathBuf)>,
) -> anyhow::Result<kodegen_server_http::ServerHandle> {
use kodegen_server_http::{create_http_server_with_listener, Managers, RouterSet, register_tool};
use rmcp::handler::server::router::{prompt::PromptRouter, tool::ToolRouter};
use std::time::Duration;
let shutdown_timeout = Duration::from_secs(30);
let session_keep_alive = Duration::ZERO;
create_http_server_with_listener("sequential-thinking", listener, tls_config, shutdown_timeout, session_keep_alive, |_config, _tracker| {
Box::pin(async move {
let mut tool_router = ToolRouter::new();
let mut prompt_router = PromptRouter::new();
let managers = Managers::new();
let tool = crate::SequentialThinkingTool::new();
let tool_arc = Arc::new(tool.clone());
tool_arc.clone().start_cleanup_task();
managers.register(SequentialThinkingWrapper(tool_arc)).await;
(tool_router, prompt_router) = register_tool(
tool_router,
prompt_router,
tool,
);
Ok(RouterSet::new(tool_router, prompt_router, managers))
})
}).await
}