AiConfig

Struct AiConfig 

Source
pub struct AiConfig {
    pub providers: Vec<AiProvider>,
    pub models: BTreeMap<String, AiModel>,
    pub pricing: BTreeMap<String, AiPricing>,
    pub governance: Option<AiGovernance>,
    pub logging: Option<AiLogging>,
    pub guardrails: Option<AiGuardrails>,
    pub semantic_cache: Option<SemanticCacheConfig>,
    pub routing_policies: BTreeMap<String, AiRoutingPolicy>,
    pub experiments: Option<AiExperiments>,
    pub mcp: Option<AiMcpConfig>,
    pub a2a: Option<A2aConfig>,
    pub unknown_model_policy: Option<UnknownModelPolicy>,
}
Expand description

The ai: top-level block (DW-075). Absent: no AI surface. Present: validation requires at least one provider and at least one model — an ai: block that can never serve a model is an authoring error, not a silently inert config.

Fields§

§providers: Vec<AiProvider>

The provider pool. Each entry names an upstream that carries the transport and the adapter kind that carries the wire translation.

§models: BTreeMap<String, AiModel>

Model alias table: the model value a client puts in its request body maps to the provider that serves it and the provider’s own model identifier. The alias is echoed back to the client; the provider_model never leaves the gateway.

§pricing: BTreeMap<String, AiPricing>

Per-model pricing table (DW-079): the key is the PROVIDER MODEL identifier (the actual model the provider charges for, e.g. gpt-4o-mini), NOT the client-facing alias. Costs are integer micro-USD per 1 000 tokens (1 000 000 micro-USD = $1.00 — no floating-point money). Spend = usage x price, aggregated per key/team/model (DW-079). Absent (the default): no pricing, so cost attribution records zero cost (the budget cost window and the spend store stay live but inert until prices are declared).

§governance: Option<AiGovernance>

Model governance (DW-084): per-team (policy) model allowlists and the shadow-audit switch. Absent (the default): no governance — every consumer may call every configured alias, and no governance audit events are recorded.

§logging: Option<AiLogging>

Prompt/response logging (DW-081): opt-in capture of the canonical prompt and response with PII redaction, sampling, and retention. Absent (the default): no capture — privacy-first (no prompt or response text is ever stored). When present and enabled: true, a redaction pass scrubs PII/secrets before storage, sample_rate controls volume, and retention_secs ages records out. Per-consumer ai_logging overrides respect tenant preference (see crate::config::Consumer::ai_logging).

§guardrails: Option<AiGuardrails>

Guardrails (DW-082): prompt-injection heuristics, PII detection, banned-content filters, and output schema enforcement as a middleware chain on the AI proxy action. Absent (the default): no guardrails — every prompt and response passes through uninspected. When present, each rule inspects the prompt (before the provider call) and/or the response (after), and blocks, redacts, or logs per its action. Policy-scoped rules apply only to consumers attaching a listed policy; an empty policies list applies to all. Schema enforcement uses the unconditional jsonschema dependency and works in every build.

§semantic_cache: Option<SemanticCacheConfig>

Semantic cache (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) and a pure-Rust HNSW ANN index (hnsw_rs). Feature-gated behind the semantic_cache cargo feature; without it the config is accepted but the cache is a no-op. Absent (the default): no semantic cache.

§routing_policies: BTreeMap<String, AiRoutingPolicy>

Routing policies (DW-085 ai.routing_policies): named within-request escalation or latency-vs-cost selection plans, keyed by name. A model alias declares routing_policy: <name> to be served by one; the policy is evaluated per request (a FallbackChain policy may call an external classifier service; a LatencyCost policy picks deterministically at compile time). Absent (the default): no routing policies.

§experiments: Option<AiExperiments>

Prompt experimentation (DW-086 ai.experiments): prompt versioning, A/B model comparison, regression evals, and feedback ingestion. Absent (the default): no experiments.

§mcp: Option<AiMcpConfig>

MCP gateway (DW-087 ai.mcp): turns dwara into an MCP (Model Context Protocol) server/router. Configured tools are exposed over JSON-RPC 2.0 on a reserved HTTP path (default /mcp); the gateway proxies tool calls to upstream HTTP endpoints with authN/authZ, manages agent sessions in the state store, and correlates tool calls in analytics. Absent (the default): no MCP surface (the /mcp path returns 404).

§a2a: Option<A2aConfig>

A2A (agent-to-agent) protocol support (DW-114 ai.a2a): configures remote A2A agents that the gateway can route chat requests to. Each agent names an upstream (the transport) and an Agent Card (discovery doc, file path or inline JSON). The adapter translates a canonical chat request into an A2A task-submit body; the task lifecycle is STUBBED pending spec freeze. Compiled into every build (no cargo feature). Absent (the default): no A2A surface.

§unknown_model_policy: Option<UnknownModelPolicy>

Unknown-model pricing policy (DW-AI-03 ai.unknown_model_policy): what to do when a provider model has no entry in ai.pricing. Absent (the default): allow (cost 0, fail-open — the original behavior). fail_closed rejects the response with 403 ai_unknown_model_pricing; alert proceeds with cost 0 but logs a WARN and increments the dwara_ai_unknown_pricing_total{model} metric.

Trait Implementations§

Source§

impl Clone for AiConfig

Source§

fn clone(&self) -> AiConfig

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for AiConfig

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for AiConfig

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl JsonSchema for AiConfig

Source§

fn schema_name() -> Cow<'static, str>

The name of the generated JSON Schema. Read more
Source§

fn schema_id() -> Cow<'static, str>

Returns a string that uniquely identifies the schema produced by this type. Read more
Source§

fn json_schema(generator: &mut SchemaGenerator) -> Schema

Generates a JSON Schema for this type. Read more
Source§

fn inline_schema() -> bool

Whether JSON Schemas generated for this type should be included directly in parent schemas, rather than being re-used where possible using the $ref keyword. Read more
Source§

impl PartialEq for AiConfig

Source§

fn eq(&self, other: &AiConfig) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for AiConfig

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for AiConfig

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> AnyExt for T
where T: Any + ?Sized,

§

fn downcast_ref<T>(this: &Self) -> Option<&T>
where T: Any,

Attempts to downcast this to T behind reference
§

fn downcast_mut<T>(this: &mut Self) -> Option<&mut T>
where T: Any,

Attempts to downcast this to T behind mutable reference
§

fn downcast_rc<T>(this: Rc<Self>) -> Result<Rc<T>, Rc<Self>>
where T: Any,

Attempts to downcast this to T behind Rc pointer
§

fn downcast_arc<T>(this: Arc<Self>) -> Result<Arc<T>, Arc<Self>>
where T: Any,

Attempts to downcast this to T behind Arc pointer
§

fn downcast_box<T>(this: Box<Self>) -> Result<Box<T>, Box<Self>>
where T: Any,

Attempts to downcast this to T behind Box pointer
§

fn downcast_move<T>(this: Self) -> Option<T>
where T: Any, Self: Sized,

Attempts to downcast owned Self to T, useful only in generic context as a workaround for specialization
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T, X> CoerceTo<T> for X
where T: CoerceFrom<X> + ?Sized,

§

fn coerce_rc_to(self: Rc<X>) -> Rc<T>

§

fn coerce_box_to(self: Box<X>) -> Box<T>

§

fn coerce_ref_to(&self) -> &T

§

fn coerce_mut_to(&mut self) -> &mut T

Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<T> ServiceExt for T

§

fn map_response_body<F>(self, f: F) -> MapResponseBody<Self, F>
where Self: Sized,

Apply a transformation to the response body. Read more
§

fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>
where Self: Sized,

High level tracing that classifies responses using HTTP status codes. Read more
§

fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>
where Self: Sized,

High level tracing that classifies responses using gRPC headers. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> TryIntoValue for T
where T: Serialize,

§

type Error = SerializationError

§

fn try_into_value(self) -> Result<Value, <T as TryIntoValue>::Error>

§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,