#web-server #axum #polaris-ai #axum-server

polaris_app

Shared HTTP server runtime for Polaris products

7 unstable releases (3 breaking)

Uses new Rust 2024

new 0.3.0 Apr 16, 2026
0.2.2 Apr 16, 2026
0.1.1 Apr 11, 2026
0.0.2 Apr 10, 2026

#1419 in HTTP server


Used in 3 crates (2 directly)

Apache-2.0

780KB
11K SLoC

polaris_app

Shared HTTP server runtime for Polaris products. Provides an axum-based server that integrates with the Polaris plugin lifecycle.

Quick Start

use polaris_system::server::Server;
use polaris_app::{AppPlugin, AppConfig};

let mut server = Server::new();
server.add_plugins(
    AppPlugin::new(AppConfig::new().with_port(8080))
);
// Add other plugins that register routes...
server.finish(); // Server starts listening on ready()

Adding Routes

Any plugin that depends on AppPlugin can register routes via the HttpRouter API:

use polaris_system::plugin::{Plugin, PluginId, Version};
use polaris_system::server::Server;
use polaris_app::{AppPlugin, HttpRouter};
use axum::{Router, routing::get};

struct HealthPlugin;

impl Plugin for HealthPlugin {
    const ID: &'static str = "myapp::health";
    const VERSION: Version = Version::new(0, 1, 0);

    fn build(&self, server: &mut Server) {
        let router = Router::new()
            .route("/healthz", get(|| async { "ok" }));
        server.api::<HttpRouter>()
            .expect("AppPlugin must be added first")
            .add_routes(router);
    }

    fn dependencies(&self) -> Vec<PluginId> {
        vec![PluginId::of::<AppPlugin>()]
    }
}

Multiple plugins can register routes independently -- they are all merged before the server starts.

HttpIOProvider

Bridges HTTP requests to agent UserIO via tokio channels. Used by session HTTP endpoints to connect an HTTP handler to an agent's IO abstraction:

use polaris_app::HttpIOProvider;
use polaris_core_plugins::{IOMessage, UserIO};
use std::sync::Arc;

let (provider, input_tx, mut output_rx) = HttpIOProvider::new(32);

// Pre-load user input from HTTP request body
// input_tx.send(IOMessage::user_text("hello")).await;

// Wrap as UserIO for the agent
// let user_io = UserIO::new(Arc::new(provider));

// Collect agent output for HTTP response
// let response = output_rx.recv().await;

Configuration

use polaris_app::AppConfig;

AppConfig::new()
    .with_host("0.0.0.0")        // Default: 127.0.0.1
    .with_port(8080)              // Default: 3000
    .with_cors_origin("http://localhost:3000")
    .with_cors_origin("https://app.example.com");

Empty CORS origins (default) allows any origin.

Middleware

Applied automatically to all routes:

Layer Description
Request ID Injects UUID x-request-id header on every request
Tracing Logs request/response spans via tracing
CORS Configurable allowed origins, methods, headers
Propagate Copies x-request-id to response headers

Dependencies

Crate Purpose
polaris_system Plugin trait, Server, GlobalResource, API
polaris_core_plugins IOProvider trait, IOMessage types
axum HTTP framework
tower-http CORS, tracing, request ID middleware
tokio Async runtime, channels, networking

Dependencies

~16–24MB
~370K SLoC