Relay — MCP calls run in-cluster without a client header. For off-cluster consumers.
Stream PCAI events — in-stream telemetry chunks, parsed by this console and DSH. Strict API clients should leave it off; new keys default off server-side.
Keys
show revoked
Name
User
Enrollment
Key
Subject
Profile
Scopes
Limits
Budgets
Status
Self-mint
Profile editor
Presets are applied to every key created with this profile.
Preset
Profile name Off-peak fraction
Preset = starters and your saved profiles. Off-peak = bills ×this during low-demand windows (0.5 makes budgets last 2×); blank = gateway default.
RPM preset
TPM preset
Max concurrent preset
Relay tool budget
The three presets are stamped onto keys created with this profile. Relay tool budget = units per relay turn for every key of this profile (blank = inherit the site default; one neutral call ≈ 1 unit).
Cascade model order (first with budget headroom serves)
Model routing
Per-profile rollout. Requires the routing__<model> pseudo-models to be registered.
Policy
Min model
One of the profile's models. Empty = no downgrade.
Saves go live within ~60s — each key's routing config is cached; no restart.
MCP grants mode
Live grants — re-evaluate at call time
On — editing this profile re-scopes running keys on their next call. Per-key rows still win as exceptions.
Off — grants stamp onto keys at creation only.
Enrollment memory
Provision a private memory dataset on redeem
Presets the redeem prompt for codes bound to this profile; the redeemer's explicit answer still wins. Off = the profile declares nothing.
Agents offered
A key of this profile may select these as its model. None checked = no agents.
Default budgets
Per model; * = any model.
Model
Period
Limit type
Token limit
Default MCP grants
Default-deny: nothing is granted until you check it, so a wrong profile cannot silently grant a mutating tool.
checking a server's box grants ALL its tools (snapshot at save — tools added to the server later need re-granting); ▾ expands per-tool control
Profiles
Name
Model order
Budgets
MCP grants
Off-peak
Relay budget
Agents
Routing
Register an MCP server
Name URL API key or Secret name Tool policy
What it is for
One line shown to the model. Prompt text — keep it factual.
Priority
Lower is preferred.
Tool weight
Tool-budget units per call — 0.1 = a cheap call, 3 = an expensive one.
enabled
API key — required even in-cluster. Stored encrypted; blank on re-save keeps the stored one. Rotation = paste + Save, no restart.
Secret name — by-reference path for ops-managed tokens (mcpKeySecrets in chart values).
Priority — lower is preferred: catalog order and failover order.
Tool weight — tool-budget units per call: 0.1 = a cheap call, 3 = an expensive one. A row's edit button loads the whole server into this form; a blank API key on that save keeps the stored one.
Registered servers
Name
URL
Auth secret
Policy
Priority
Enabled
Test
Register a model endpoint pool
Virtual model name Type
Auto-detect probes the endpoint; picking a type skips the probe. A wrong type fails silently in both directions.
Base URL API key or Secret name Priority Weight
Saving replaces the whole pool — endpoints not listed are removed.
Editing — a row's edit button loads the whole pool into this form; the model name is fixed (it is the pool key — remove and re-register to rename), and a blank API key keeps the stored one.
API key — required even in-cluster. Stored encrypted; blank on re-save keeps the stored one. Rotation = paste + Save, no restart.
Secret name — by-reference path for ops-managed tokens (upstreamKeySecrets in chart values).
Priority — lower is preferred. The next tier serves only when every endpoint in it is failing.
Weight — random split within a tier. 0 = standby: failover only.
Live pools
Model
Type
Endpoints
Test
Presented endpoints
What /v1/models advertises, with the reason any entry is absent.
not loaded yet — open this tab or press refresh
Agents
A named tool surface, selectable as a model: a bundle of MCP servers — optionally narrowed to specific tools on each — plus an optional system prompt. A key sees the intersection of its grants and the agent's servers/tools — an agent can only ever HIDE tools, never add one.
Name
The model id clients request, case-sensitive.
Model
Empty = the profile's cascade.
enabled
Description
Rides /v1/models, so a client can pick an agent without reading this page.
MCP servers and tools
The agent's whole visible surface. Tick a server for all its tools, or open it and pick specific ones. Leave every server unchecked for a chat-only agent.
System prompt
Prepended to every model call of an agent turn, after the client's own system message. Never merged into it, never written into the stored conversation.
Defined agents
Name
Description
Servers
Model
Prompt
Offered by
Enabled
Create a guardrail
A content policy evaluated around model calls: pre_call before the upstream call, post_call on the response.
Name Mode
Engine
enabled
Config (JSON)
Guardrails
Name
Mode
Engine
Enabled
Attached models
Totals — ledger rollup; cache_hit rows are visible but cost no budget
Requests
Input tokens
Output tokens
Cached tokens
Cache hit rate
Cost (USD)
Billed tokens
Billed cost
By model
Model
Requests
Input
Output
Cached
Cache rate
Cost (USD)
Billable
Billed cost
By key — chargeback view; who consumed what
Window
From to
Key
User
Requests
Input
Output
Cached
Cache rate
Cost (USD)
Billable
Billed cost
Pricing (USD per 1M units) — unpriced models ledger no cost; costs are stored per request at request time. Unit (P10): what a “1M” of the rates is — voice models bill per second, others per token; a unit that cannot match the model's route is refused (ledger NULL) and reported, never billed at the wrong rate
Model
Unit
Input $/1M Output $/1M Cached $/1M
Model
Unit
Input $/1M
Output $/1M
Cached $/1M
Updated
Recent usage (ledger)
User
pick a user to scope the ledger — rows are tinted per user so callers stay trackable
Time
User
Key
Subject
Model
Endpoint
Input
Output
Cached
Total
Cost
Status
ms
Agent traces
One card per relay request: model iterations, tool calls and wall-clock totals.
User
Key
Since
Limit
no traces yet
Admin audit trail
One immutable row per admin mutation — keys, budgets, models, MCP, profiles, credentials, enrollment. Append-only, never pruned, secret values redacted. Data-plane calls live in the usage ledger.
Every key a user mints via Sign in with SSO gets this tenant's profile. On mint and on every rotate, two things happen: the profile's budgets, MCP grants and rate-limit presets are stamped onto the key row, and the user row is bound to the profile when it has none. Scopes stay the fixed least-privilege grant; profiles never widen them.
Tenant
Profile for SSO-minted keys
Admin-tier profile
Admin groups
The mint's tenant is the deployment's tokenShadowTenantId. Clearing the profile returns mints to the bare grant (60 rpm · 100k tpm, no budgets or grants).
Edit the profile itself under Profiles.
Users who signed in before this setting existed have no profile. Bind existing users backfills them — idempotent, and a user placed by hand is never re-scoped. Until then their keys carry the stamped presets, but cascade ordering, routing, off-peak and agents ignore the profile.
Admin tier — a mint whose SSO groups intersect Admin groups (comma-separated, case-sensitive) gets the Admin-tier profile instead; the token's JWKS-validated groups win over the proxy headers when both are present. Leave Admin groups empty to turn the tier split off — every mint uses the default profile above.
Mint an enrollment code
Self-service key issuance — the code is the credential.
Label Tenant
Profile (presets budgets + grants)
Max uses Expires in days Budget tokens Budget USD Period
overflow
Shared unallocated pool — a key may exceed its own allocation while the team has headroom.
also mint a team leader key
Control-plane key for the /team_leader console — shown once, alongside the code.
The plaintext code is returned once at mint time (only its SHA-256 hash is
stored). Redeem at the chat console via Have an invite code?. Budget (tokens and/or USD per period) is the
enrollment's team envelope — a HARD cap on the whole team; per-key allocations must fit inside it.
With overflow ON (default) the unallocated remainder is a shared pool keys may draw on.
Leave BOTH budget fields blank for an UNCAPPED team — the envelope then says "no cap" on the
team console while the per-key allocations (profile presets, or what the leader hands out) still
apply; there is no way to add a cap afterwards except by approving a top-up, so set it here if the
team should be bounded.
Budget top-up requests
A team leader who has spent the enrollment's available pool can ask
for a bigger envelope from /team_leader. Approving raises the cap — the total stays admin-only, and a leader
can never approve their own ask. The amount is added to the current cap in one transaction, so a double-click is a
409 and never doubles a budget.
Enrollment
Tenant
Requested
Note
Waiting
Label
Tenant
Profile
Uses
Expires
Budget
Allocated
Spend
Leader key
Keys
Status
Created
Off-peak billing
Requests bill at a reduced multiplier while GPU demand is low.
—
GPU avg (last)
—
Last check
never
PromQL
—
MCP server / tool
—
Thresholds
—
Cadence
—
Last error
—
Cache utilization — all models
POD MEMORY is the pod's working set against its memory limit; RAM (cached) is the HiCache host prefix-cache pool (tokens); DISK is the L3 volume occupancy (or activity when only counters exist). Aggregated over the cache-bearing endpoints. GPU stays on the per-model cards.
—
Per-model utilization
One row per model with its own PromQL. This is the evaluator state the discount reads — a model with no query configured has no row.
Model groups
A group is a named set of equivalent registered models. A request naming the group picks a member by LIVE load, the conversation is pinned to that member, and the selected member bills and carries its ACL — the group never bypasses budgets or allowed_models. Members are one level: a member may not itself be a group. While enabled, a group is advertised in /v1/models and usable as a direct model id or a fallback-chain entry.
Group
Type
Members
Policy
Description
Created
Create a model group
Save upserts by name: an existing group is replaced WHOLE — members not listed are dropped. A row's edit button loads the group here.
Group name Members (registered pools)
Policy
Description
Name — a slug: no whitespace, no /, no markup or control characters, 200 chars max. The server also refuses the reserved names auto / auto-demand-aware and any name equal to a registered model (the reason rides the banner).
Members — hold Ctrl/⌘ to select several. Every member must be a registered chat pool; the server rejects unknown names, group members, duplicates and >32 members with the reason in the banner.
Policy — only load exists in v1 (power-of-two choices over live queue depth); anything else is treated as load.
Would pick now (live preview)
The same power-of-two choice a real request would get: scores are the member's minimum request queue across its endpoints (no data = unknown, neither herded nor starved). A preview never pins or mutates anything.
Group
pick a group, then press Preview
Session memory distiller
Quiet conversations are distilled into each key's RAG memory dataset.
—
One canonical pipeline replaces the per-harness distillers (DSH plugin, opencode agent, OWUI filter).
A key with no memory feature attached — no enabled mm-rag registry row, or no stamped dataset pair — is inert: the surface answers 200 with ok=false/inert=true and nothing runs.
Off-peak-only gates the scheduled sweep. An explicit distill call always runs.
Summarizer model
Registered models (the Models tab's pools). Empty = the caller's routing.
Scheduling
off-peak only
Scheduled distills run only while the summarizer model's off-peak evaluator reports low demand (global evaluator when the model has none).
Runtime enabled
enabled
The env flag PCAI_LLM_DISTILLER_ENABLED must also be true — it owns the route mount.
Quiet window
Minutes since the last conversation write before the sweep distills it.
Output cap
Tokens. 0 = the env default.
A conversation that continues after distillation is re-distilled automatically: new writes drop the marker and the sweep re-runs it when quiet again.
Endpoint throughput and load
From the inference servers' own Prometheus metrics. Rates are averaged over the window shown below; a pod with no traffic in that window reads idle, not broken.
— auto-refresh
Pool
Endpoint
Prompt t/s
Decode t/s
Running
Queue
KV%
Cache hit
Prefill share
Model routing — how a routed request picks its model
—
Runtime enabled
enabled
Also requires the env flag PCAI_LLM_ROUTING_ENABLED, which owns the route mount.
Decision mode
off — the heuristics pick the model.
shadow — the model is asked and its pick recorded, the heuristics still serve.
active — the model's pick serves when it clears the confidence floor and lands inside the candidate window.
Decision model
The pool asked to choose. Empty = heuristics only.
Confidence floor
Below this the model is treated as abstaining and the heuristics serve.
Switch margin
A challenger must beat the current model by this much before the router pays a switch.
A switch re-prefills the whole context on the new model.
0 = the first pick wins, 1 = never switch.
Decision timeout (ms)
On timeout the heuristics serve, so a hung endpoint cannot park a request.
Route the default model
also route requests that name auto
Off: auto keeps the profile-order cascade. routing and routing__<model> always route.
Sticky routing
never downgrade a conversation
A thread may escalate, but never falls below the model that already served it.
Sticky idle reset
Seconds of inactivity before a conversation forgets its floor. 0 = never.
Model cards — what each model is for
Tick a model to offer it to the router. Its description becomes that option's text in the routing question, so this is the only place the router learns what a model is good at. Live load, cost and image support are appended to each option automatically; a {{token}} in a description replaces the matching one.
Tick every model to mean no restriction (any chat model is routable). Ticking none is refused: on the wire an empty set means no restriction, so an empty form would save the opposite of "route to nothing".
Decision prompt — the policy every routed request is judged by
inject current GPU load into the prompt
—
Max prompt chars
Cap on the rendered prompt; a longer render truncates.
Routing engages only when a request names routing or routing__<model> (or auto, when enabled above), and the calling key's profile routing policy is shadow or active.
Live statistics — routing counters from this gateway process