The Problem

Building agentic applications quickly reveals a “hidden middleware” problem: routing logic, guardrails, observability, and model‑provider quirks are scattered across frameworks and application code, forcing every team to reinvent the same plumbing before reaching production.

What This Does

Plano is a collection of five semi‑independent projects (crates, apps, demos, cli, packages) that move core delivery concerns into an out‑of‑process data plane.

  • Crates (crates/brightstaff) – Rust‑based core: agent selection, function calling, LLM handling, and signal pipeline processing. Files such as crates/brightstaff/src/handlers/agent_selector.rs, crates/brightstaff/src/handlers/function_calling.rs, and crates/brightstaff/src/signals/analyzer.rs are oversized (≈1 650 loc) and have deep nesting (max indent 8), making control flow hard to follow.
  • Apps (apps/www, apps/katanemo-www) – Next.js front‑ends that consume the data plane; they contain duplicated next‑config and layout boilerplate (1292 repeated 6‑line blocks across 98 files).
  • Demos (demos/) – Small proof‑of‑concepts (e.g., demos/filter_chains/http_filter/src/rag_agent/api) that showcase filter chains, MCP integration, and rag‑agent APIs.
  • CLI (cli/planoai) – Python entry point (cli/planoai/main.py) that exposes commands for tracing and model interaction.
  • Packages (packages/) – Shared UI and utility code (packages/ui/src/lib/utils, packages/ui/src/components/Navbar).

Recurring techniques across the portfolio include filter chains for guardrails, model‑agile routing (by name, alias, or preference), and zero‑code agentic signal capture via OTEL.

How It Is Wired

The internal call graph contains 125 modules and 42 import edges with no circular dependencies (analyzed 253 of 253 code files).

  • Entry points that start a run:
  • cli/planoai/main.py – CLI dispatcher, parses commands and delegates to the data plane.
  • crates/brightstaff/src/main.rs – Rust runtime that boots the proxy/agent orchestrator.
  • apps/www/src/components/research/index.ts and apps/www/schemaTypes/index.ts – Front‑end types and UI that talk to the proxy over HTTP.
  • Control flow: CLI → Python wrapper → Rust crate (brightstaff) → internal handlers (agent_selector, function_calling, pipeline_processor). The handlers import from packages/ui for UI helpers and from each other via a small set of edges (e.g., agent_selector imports function_calling). The widest blast radius is in crates/brightstaff/src/handlers/pipeline_processor.rs (1 659 loc), where a change ripples through agent routing and signal aggregation.
  • Out‑of‑process data plane: The Rust crate listens on a Unix socket/HTTP port; front‑ends and demos communicate via REST/GRPC‑like calls, keeping agent logic isolated from framework specifics.

How To Use It

Setup

# Clone the repo (verbatim URL)
git clone https://github.com/moses-y/plano

# Install Node deps for the web app
cd apps/www && npm install

# Install Python deps for the CLI
cd cli && pip install -r pyproject.toml   # or `uv pip install -r pyproject.toml`

# Build the Rust data plane
cd crates/brightstaff && cargo build --release

Configuration

  • Environment variables are read from .env files referenced in cli/planoai/trace_cmd.py and apps/www/.env.example (not committed). Key vars: PLANO_BACKEND_URL, OPENAI_API_KEY, ANTHROPIC_API_KEY.
  • Docker base images are defined in Dockerfile (rust:1.93.0, python:3.14-slim, docker.io/envoyproxy/envoy:v1.37.0).

Running it

# Start the Rust data plane (background)
cd crates/brightstaff && ./target/release/brightstaff &

# Start the Next.js UI
cd apps/www && npm run dev   # http://localhost:3000

# CLI example – trace a request
cd cli && python planoai/main.py trace --url http://localhost:8080 --model gpt-4o

Real‑World Use

A travel‑agent demo (demos/filter_chains/mcp_filter/src/rag_agent/api) registers three agents (flight, hotel, car). Incoming user requests are routed by Plano’s model‑router (alias “budget‑travel”) through the filter chain that injects moderation policies and logs OTEL traces. The UI (apps/www/src/components/research/index.ts) displays the agent decisions and signal metrics, while the Rust core handles routing without any framework‑specific code.

Code Health & Issues

  • HIGH – Pin third‑party GitHub Actions to commit SHAs: .github/workflows uses @v3.0.1, @v3, @v6, @master for pre-commit/action, docker/setup-buildx-action, docker/build-push-action, aquasecurity/trivy-action. Mutable tags can introduce supply‑chain risk.
  • MEDIUM – Enable Dependabot/Renovate: 24 manifests, no update bot configured.
  • MEDIUM – Pin container base images by digest: Dockerfile uses rust:1.93.0, docker.io/envoyproxy/envoy:v1.37.0, python:3.14-slim without digests.
  • MEDIUM – Move large binaries out of repo: docs/source/_static/img/tracing.png is 8.6 MB; other blobs >5 MB exist.
  • MEDIUM – Add non‑root USER to Docker images: no USER directive present.
  • LOW – Set timeout-minutes on CI jobs: 4 workflows have no job timeout, risking overlap on a two‑hourly schedule.

The Bottom Line

Plano delivers a pragmatic data‑plane for agentic apps: orchestration, model‑agile routing, and observability are provided as reusable Rust services, while the five project buckets let teams pick the pieces they need. The code base is functional but suffers from oversized Rust files, duplicated Next.js config, and SDLC hygiene gaps (mutable Action pins, missing Dependabot, untagged Docker images). It is well‑suited for teams that want to offload routing, guardrails, and tracing without embedding those concerns in their application framework, provided they address the pinning and image‑security findings.