xagent-pi 0.2.0

Self-contained local brain (chat UI + API + SSE) for the Pi agent, tunneled into xagent-service.
use axum::body::Body;
use axum::http::{header, Response, StatusCode, Uri};
use axum::response::IntoResponse;

pub struct EmbeddedAsset {
    bytes: &'static [u8],
    content_type: &'static str,
}

include!(concat!(env!("OUT_DIR"), "/embedded_web.rs"));

pub async fn serve(uri: Uri) -> Response<Body> {
    let path = uri.path().trim_start_matches('/');
    let asset = embedded_asset(path).or_else(|| {
        (!path.contains('.'))
            .then(|| embedded_asset("index.html"))
            .flatten()
    });
    let Some(asset) = asset else {
        return StatusCode::NOT_FOUND.into_response();
    };

    let cache_control = if path.is_empty() || path == "index.html" || !path.contains('.') {
        "no-cache"
    } else {
        "public, max-age=31536000, immutable"
    };
    Response::builder()
        .status(StatusCode::OK)
        .header(header::CONTENT_TYPE, asset.content_type)
        .header(header::CACHE_CONTROL, cache_control)
        .body(Body::from(asset.bytes))
        .expect("valid embedded asset response")
}