mod auth;
mod error;
pub mod handlers;
mod state;
pub mod types;
use axum::{middleware, Router};
use crate::state::OpsState;
use klieo_a2a::task_store::A2aTaskStore;
use klieo_auth_common::Authenticator;
use klieo_core::resume::KvResumeBuffer;
use klieo_runlog::RunLogStore;
use std::sync::Arc;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum OpsBuilderError {
#[error("authenticator not configured — call with_authenticator() before build()")]
MissingAuthenticator,
}
pub struct OpsRouterBuilder {
authenticator: Option<Arc<dyn Authenticator>>,
run_log_store: Option<Arc<dyn RunLogStore>>,
task_store: Option<Arc<A2aTaskStore>>,
resume_buffer: Option<Arc<KvResumeBuffer>>,
}
impl OpsRouterBuilder {
pub fn new() -> Self {
Self {
authenticator: None,
run_log_store: None,
task_store: None,
resume_buffer: None,
}
}
pub fn with_authenticator(mut self, auth: Arc<dyn Authenticator>) -> Self {
self.authenticator = Some(auth);
self
}
pub fn with_run_log_store(mut self, store: Arc<dyn RunLogStore>) -> Self {
self.run_log_store = Some(store);
self
}
pub fn with_task_store(mut self, store: Arc<A2aTaskStore>) -> Self {
self.task_store = Some(store);
self
}
pub fn with_resume_buffer(mut self, buf: Arc<KvResumeBuffer>) -> Self {
self.resume_buffer = Some(buf);
self
}
pub fn build(self) -> Result<Router, OpsBuilderError> {
let authenticator = self
.authenticator
.ok_or(OpsBuilderError::MissingAuthenticator)?;
let state = Arc::new(OpsState {
authenticator,
run_log_store: self.run_log_store,
task_store: self.task_store,
resume_buffer: self.resume_buffer,
});
use axum::routing::get;
use crate::handlers::{runs, tasks, streams};
Ok(Router::new()
.route("/runs", get(runs::list_runs))
.route("/runs/:run_id", get(runs::get_run))
.route("/agents", get(runs::list_agents))
.route("/tasks", get(tasks::list_tasks))
.route("/streams", get(streams::list_streams))
.layer(middleware::from_fn_with_state(
Arc::clone(&state),
crate::auth::require_auth,
))
.with_state(state))
}
}
impl Default for OpsRouterBuilder {
fn default() -> Self {
Self::new()
}
}