Expand description
The ai: configuration block (DW-075): AI provider adapters.
This is the source shape only — the runtime translation lives in the
AI domain one level up (see the ai module’s AiRuntime), which
consumes these types at compile time. The block is ADDITIVE to the
gateway schema: absent (the default), the gateway has no AI surface
at all; present, it declares the provider pool (providers:) and
the model alias table (models:) that map an OpenAI-shaped client
request onto a concrete provider call.
Design notes (DW-075):
- A provider names an UPSTREAM (
upstreams:entry), not a raw base URL: the provider’s transport — endpoint set, TLS trust, connection pooling, timeouts, breaker, passive health — is the SAME machinery every other upstream gets, and the adapter layer stays pure request/response translation with no HTTP client of its own. A multi-region provider pool is then just an upstream with several endpoints. - Authentication is a verbatim header (
auth.header+auth.value) rather than a per-provider auth enum: providers disagree on the convention (OpenAI wantsAuthorization: Bearer ..., Anthropicx-api-key: ..., Geminix-goog-api-key: ...), and a verbatim pair expresses all of them without the schema growing a variant per provider.valueis secret-bearing: inline values are redacted in every config echo (DW-045) and${...}references resolve at config-compile time, failing the generation closed when unresolvable. models:is a map from the MODEL ALIAS the client names in the request body to the provider that serves it plus the provider’s own model identifier. The alias is what the gateway echoes back in the response; the provider model never leaks to the client.
Structs§
- A2aAgent
- One A2A agent (DW-114
ai.a2a.agents[]). The gateway routes a chat request to the agent by translating it into an A2A task-submit body and placing the call through the named upstream. The Agent Card (discovery doc) declares the agent’s capabilities and authentication; it is parsed at compile time. - A2aAgent
Card - The Agent Card source (DW-114): a file path or an inline JSON
object. One of the two is required when
cardis present. - A2aConfig
- A2A (agent-to-agent) protocol config (DW-114
ai.a2a). Declares the remote A2A agents the gateway can route chat requests to and the session policy for agent-to-agent task sessions. The block is ADDITIVE: absent (the default), the gateway has no A2A surface. Compiled into every build (no cargo feature). - A2aSessions
- A2A session policy (DW-114
ai.a2a.sessions), mirroring MCP. - AiAb
Test - One A/B test (DW-086
ai.experiments.ab_tests.<name>): two or more variants, each naming a model alias, an optional prompt version, and a weight. A model alias declaresab_test: <name>to be served by one; the test is evaluated per request (a deterministic weighted pick by request id selects a variant). - AiAb
Variant - One variant of an A/B test (DW-086
ai.experiments.ab_tests.<name>.variants[]). - AiCanary
Version - One weighted version of a canary split (DW-076
ai.models.<alias>.canary[]). - AiConfig
- The
ai:top-level block (DW-075). Absent: no AI surface. Present: validation requires at least one provider and at least one model — anai:block that can never serve a model is an authoring error, not a silently inert config. - AiCredential
Pool - DW-080 (Ent): a credential pool for a provider — multiple API keys
rotated across to aggregate rate-limit headroom. Each entry is an
AiProviderAuth(same header+value shape as the singularauthfield). The pool is used INSTEAD ofauth; validation rejects a provider that sets both. - AiEval
- One regression eval (DW-086
ai.experiments.evals.<name>): a golden set of input/expected cases plus an optional prompt version. The admin API runs it against a model alias (or an A/B test’s variants) and stores the results in analytics. - AiEval
Case - One eval case (DW-086
ai.experiments.evals.<name>.golden_set[]). - AiExperiments
- Prompt experimentation (DW-086
ai.experiments): prompt versioning, A/B model comparison, regression evals, and feedback ingestion. Absent (the default): no experiments surface. - AiFallback
Chain Policy - A fallback-chain routing policy (DW-085
kind: fallback_chain): cheap-model-first with complexity-signal escalation. Thecheapandescalate_tofields name OTHER model aliases (plain chain/canary aliases — a policy composes over DW-076 routing, so it has no provider/model pair of its own). - AiFeedback
Config - Feedback ingestion config (DW-086
ai.experiments.feedback). - AiGovernance
- Model governance (DW-084
ai.governance): per-team model allowlists plus a shadow-audit switch. A team is a POLICY name (the same vocabulary the token budgets use forscope: policy): every consumer attaching a policy with an allowlist entry is restricted to that allowlist’s aliases. The check runs BEFORE routing, against the client-facing alias (themodelvalue in the request body), so a typo or a renamed alias is blocked at the edge rather than surfacing as a provider 404. Multiple policies with allowlists that bind one request intersect (deny-wins): the model must be in EVERY binding allowlist, matching the authz deny-anywhere-wins principle. Consumers with no binding allowlist policy are unrestricted (fail-open, the DW-017 default posture).audit: truerecords BOTH allowed and denied attempts into theai_governance_eventsanalytics table for shadow review. - AiGuardrail
Rule - One guardrail rule (DW-082
ai.guardrails.rules[]). A rule declares akind(what to check), anaction(what to do on a match), aphase(prompt, response, or both), the patterns or schema to check against, and the policies it attaches to. - AiGuardrails
- Guardrails (DW-082
ai.guardrails): a list of rules that inspect prompts and responses for prompt-injection, PII, banned content, and output schema conformance. Each rule is one check applied at the prompt phase (before the provider call) and/or the response phase (after). Policy-scoped rules apply only to consumers attaching a listed policy; an emptypolicieslist applies to all. SeeAiGuardrailRulefor the per-rule shape. - AiLatency
Cost Candidate - One candidate in a latency-vs-cost policy (DW-085
ai.routing_policies.<name>.candidates[]). - AiLatency
Cost Policy - A latency-vs-cost routing policy (DW-085
kind: latency_cost): static config-based selection. The operator declares cost/latency scores per candidate and a preference; the policy sorts candidates at compile time and picks the best one deterministically (no runtime metrics needed). - AiLogging
- Prompt/response logging (DW-081
ai.logging): opt-in capture of the canonical prompt and response with PII redaction, sampling, and retention. Capture is OFF by default (privacy-first): theenabledfield defaults to false, so anai.loggingblock withoutenabled: truecaptures nothing. When on, a redaction pass scrubs PII/secrets before storage,sample_ratecontrols volume, andretention_secsages records out. Per-consumerai_loggingoverrides respect tenant preference. - AiLogging
External Sink - SCALE-12 (#190): external sink configuration for prompt/response logs. The sync command is invoked by the analytics maintenance tick with the export directory as its first argument. Failures are logged and silently ignored (best-effort sync).
- AiMcp
Config - MCP gateway config (DW-087
ai.mcp): the tool table, session policy, and reserved path. Tools are configured with upstream references; the gateway proxies tool calls to upstream HTTP endpoints (POST JSON body, get JSON response). The gateway is a router, not a tool executor. - AiMcp
Prompt - AI-11 (#200): One MCP static prompt template
(
ai.mcp.prompts.<name>). Prompts are served inline. The template body is returned inprompts/getresponses, with optional argument substitution. - AiMcp
Prompt Argument - AI-11 (#200): One prompt argument definition.
- AiMcp
Resource - AI-11 (#200): One MCP static resource (
ai.mcp.resources.<name>). Resources are served inline (no upstream proxy). The content is returned verbatim inresources/readresponses. - AiMcp
Sessions - MCP session policy (DW-087
ai.mcp.sessions). - AiMcp
Tool - One MCP tool (DW-087
ai.mcp.tools.<name>). The gateway proxies tool calls to the named upstream’s HTTP endpoint: the tool’s arguments are sent as the JSON request body, and the upstream’s response body becomes the tool’s output. - AiModel
- One model alias mapping (DW-075
ai.models{alias}). - AiModel
Target - One provider/model pair an alias can route to (DW-076): the primary shape reused by failover entries and canary versions.
- AiPricing
- Per-model token pricing (DW-079
ai.pricing.<provider_model>). Costs are integer MICRO-USD per 1 000 tokens (1 000 000 micro-USD = $1.00 — no floating-point money). The key in the parent map is the PROVIDER MODEL identifier (the actual model the provider charges for), not the client-facing alias. Spend is computed asinput_tokens * input_per_1k_micros / 1000 + output_tokens * output_per_1k_micros / 1000(integer micro-USD, saturating). - AiPrompt
Version - One prompt version (DW-086
ai.experiments.prompts.<name>.versions.<version>): a system message prepended to the request’s messages when this version is active. - AiPrompt
Versions - One prompt’s version set (DW-086
ai.experiments.prompts.<name>): a map of version names to system messages plus the active version. The active version can be overridden at runtime via the admin API. - AiProvider
- One AI provider (DW-075
ai.providers[]). - AiProvider
Auth - Verbatim authentication header for a provider (DW-075
ai.providers[].auth).valueis SECRET-BEARING: an inline value is replaced by the redaction placeholder in every config echo, and a${...}reference is resolved at config-compile time (DW-045). - Redaction
Config - PII redaction configuration (DW-081
ai.logging.redaction). Built-in patterns scrub common PII/secrets; custom patterns add deployment-specific scrubbing. All patterns are compiled into a singleregex::RegexSetfor one-pass efficiency. - Semantic
Cache Config - Semantic cache config (DW-083
ai.semantic_cache): an embedding-similarity cache for AI prompts. A paraphrased prompt within the cosine-similarity threshold returns the cached response with no provider call and no token spend. Uses an external embedding service (OpenAI-compatible /v1/embeddings API) to vectorize prompts andhnsw_rs(pure Rust HNSW) for approximate nearest neighbor search. Compiled into every build (hnsw_rsis an unconditional dependency).
Enums§
- AiGuardrail
Action - Guardrail action (DW-082
ai.guardrails.rules[].action). - AiGuardrail
Kind - Guardrail kind (DW-082
ai.guardrails.rules[].kind). - AiGuardrail
Phase - Guardrail phase (DW-082
ai.guardrails.rules[].phase). - AiLatency
Preference - The latency-vs-cost selection preference (DW-085
ai.routing_policies.<name>.preference). - AiPool
Strategy - Credential pool rotation strategy (DW-080).
- AiProvider
Kind - The wire protocol an adapter speaks (DW-075).
- AiRouting
Policy - A routing policy (DW-085
ai.routing_policies.<name>): within-request escalation or latency-vs-cost selection. Keyed by name inai.routing_policies. An alias declaresrouting_policy: <name>to be served by one; the policy is evaluated per request and composes over DW-076 routing (the candidate aliases it names are themselves plain chain/canary aliases). Internally tagged bykindso the YAML shape is: - Unknown
Model Policy - The unknown-model pricing policy (DW-AI-03
ai.unknown_model_policy): what the gateway does when a provider model has no entry in theai.pricingtable. The default (allow) preserves the original fail-open behavior (cost 0, never a crash);fail_closedrejects the response with 403ai_unknown_model_pricingso an unpriced model cannot serve traffic silently;alertproceeds with cost 0 but logs a WARN and incrementsdwara_ai_unknown_pricing_total{model}for observability without blocking the call.