plano/demos
Musa 844f08bda7
feat(routing): automatic prompt caching + a per-session routing budget (#982)
* feat(routing): cache-aware routing and zero-config prompt caching

Reconcile prompt caching with intelligent routing: zero-config implicit
session affinity, cache_control preservation/injection across transforms,
cache-adjusted routing economics, and a response-driven cache-hit feedback loop.

* refactor(caching): model-aware cache markers, drop cache-aware routing

* feat(routing): session stickiness cache-regret cost gate

* refactor(routing): expose per-model input and cached rates

* fix(docker): patch libssh2 CVEs by upgrading after package install

* feat: record counterfactual route on vetoed session switches

Add opt-in session_stickiness.record_counterfactual that emits the
plano.switch.counterfactual_route OTEL attribute when the cache-regret
gate retains the previous model, capturing the route it would have taken
had the switch been allowed. Telemetry only; the candidate is never
dispatched. Includes schema, demo config, and a getting-started guide.

* refactor: group prompt-caching and session-stickiness logic into cohesive modules

Extract the two concerns interleaved in the LLM handler into dedicated
sibling modules for readability: prompt_caching.rs (cache-marker injection)
and session_stickiness.rs (session key/prefix-hash resolution, pin lookup,
cache-regret gate, and pin planning). handlers/llm/mod.rs is now a thin
orchestrator that calls them at clear phase boundaries. Behavior-preserving.

* refactor(routing): unify session routing into a cumulative switch budget

Replace observed_cache_hit + per-request threshold with time/provider-TTL
warmth and a per-session switch budget in a single session_router::route()
used by both the full-proxy and /routing decision paths.

* refactor(routing): move switch budget to routing.routing_budget and rename telemetry

* refactor(routing): drop negative-cost budget refund from routing_budget

* refactor(routing): express routing_budget as a percentage overhead cap

Replace the absolute seed_usd pool with max_overhead_pct (whole-number
percent) measured against the session's running never-switch baseline:
allow a paid switch only while cumulative switch spend stays within
max_overhead_pct% of what staying on the anchor would have cost. Track
baseline_usd and switch_spend_usd on the binding (monotonic, no refunds).

* refactor(observability): align routing-budget telemetry with the overhead cap

Rename the switch-decision reasons (within_budget/over_budget -> within_cap/
over_cap) and the session span attributes to match the percentage overhead-cap
model: budget_remaining_in_usd -> overhead_pct + switch_spend_in_usd +
baseline_in_usd, and switch threshold_in_usd -> overhead_ceiling_in_usd.

* feat(observability): emit per-request and cumulative session cost

Price each turn from the catalog rates and surface it as llm.usage.{input,
output,total}_cost_usd on the (llm) span, then accumulate into a conversation-
level session_cost_usd on the binding and emit plano.session.total_cost_in_usd
on the routing span. Cache-creation tokens are priced at the plain input rate,
and the OpenAI vs Anthropic prompt-token convention (cached folded in vs
reported separately) is captured at parse time so the cost math is correct for
both. Rates are resolved request-side since the response path is synchronous.

* refactor(routing): price the never-switch baseline against the session default model

Distinguish the session's default_model (the model it started on, i.e. what it
would have cost by never switching) from anchor_model (the model that handled
the latest request, which the session is warm on). The never-switch baseline now
grows at the default model's cached rate rather than the drifting anchor's, so
the overhead-cap denominator stays true to "% above never-switching"; switch cost
is still measured against the current anchor. Also rename estimate_context_tokens
-> actual_context_tokens (and est_context_tokens -> context_tokens) since the
router prefers the provider's real prompt-token count when the session is warm.

* feat(routing): track bounded route history and price returns to still-warm models

Record a bounded (LRU, capped) per-model visit history on the session binding
and use it to sharpen the switch-cost estimate: a return to a model still within
its cache window re-reads only the tokens appended since its last visit (at its
cached rate) instead of the whole context at the uncached rate, so an A->B->A
switch is no longer over-charged as a full re-ingest. History is carried through
the response-side refresh (refining the anchor's entry from real usage) and
cleared on prefix drift. Adds the plano.switch.candidate_warm_tokens span
attribute.

* refactor(routing): tidy test names and rename pin events to binding events

Shorten run-on test names and replace stale "pin" vocabulary in the session
binding metric (brightstaff_session_pin_events_total -> _binding_events_total),
dropping lifecycle event labels that are no longer emitted.

* feat(routing): price switch cost against uncached rates when caching is off

The overhead-cap gate previously always priced the anchor at its cached rate,
assuming a warm provider cache. When prompt caching is disabled there is no
warm cache to lose, so both the switch cost and the never-switch baseline are
now priced at the plain uncached input rate:
switch_cost = context_tokens x (candidate_uncached - anchor_uncached) / 1M.

* fix(brightstaff): bound pricing-feed fetch with timeouts and warn when session state runs without a tenant header

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(routing): validate the session overhead cap end-to-end across a multi-turn session

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs(demos): fix stale pinning semantics and add routing_budget demo script

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Adil Hafeez <adil.hafeez@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 17:53:34 -07:00
..
advanced fix: resolve all open Dependabot security alerts (#866) 2026-04-02 18:00:28 -07:00
agent_orchestration fix: resolve all open Dependabot security alerts (#866) 2026-04-02 18:00:28 -07:00
filter_chains test: add keyless model listener filter demo (#957) 2026-06-25 10:48:31 -07:00
getting_started fix(ci): switch retired claude-sonnet-4-20250514 to claude-sonnet-4-6 (#975) 2026-06-24 10:13:37 -07:00
integrations Run demos without Docker (#809) 2026-03-11 12:49:36 -07:00
llm_routing feat(routing): automatic prompt caching + a per-session routing budget (#982) 2026-07-20 17:53:34 -07:00
shared ci(e2e): stabilize preference demo test execution (#865) 2026-04-02 21:32:20 -04:00
README.md Support for Codex via Plano (#808) 2026-03-10 20:54:14 -07:00

Plano Demos

This directory contains demos showcasing Plano's capabilities as an AI-native proxy for agentic applications.

Getting Started

Demo Description
Weather Forecast Core function calling with a weather query agent, interactive chat UI, and Jaeger tracing
LLM Gateway Key management and dynamic routing to multiple LLM providers with header-based model override

LLM Routing

Demo Description
Preference-Based Routing Routes prompts to LLMs based on user-defined preferences and task type (e.g. code generation vs. understanding)
Model Alias Routing Maps semantic aliases (arch.summarize.v1) to provider-specific models for centralized governance
Claude Code Router Extends Claude Code with multi-provider access and preference-aligned routing for coding tasks
Codex Router Extends Codex CLI with multi-provider access and preference-aligned routing for coding tasks

Agent Orchestration

Demo Description
Travel Agents Multi-agent travel booking with weather and flight agents, intelligent routing, and OpenTelemetry tracing
Multi-Agent CrewAI & LangChain Framework-agnostic orchestration combining CrewAI and LangChain agents in unified conversations

Filter Chains

Demo Description
HTTP Filter RAG agent with filter chains for input validation, query rewriting, and context building
MCP Filter RAG agent using MCP-based filters for domain validation, query optimization, and knowledge base retrieval

Integrations

Demo Description
Ollama Use Ollama as a local LLM provider through Plano
Spotify Bearer Auth Bearer token authentication for third-party APIs (Spotify new releases and top tracks)

Advanced

Demo Description
Currency Exchange Function calling with public REST APIs (Frankfurter currency exchange)
Stock Quote Protected REST API integration with access key management
Multi-Turn RAG Multi-turn conversational RAG agent for answering questions about energy sources
Model Choice Test Harness Evaluation framework for safely testing and switching between models with benchmark fixtures