Skip to main content

systemprompt_ai/services/gateway/
spec.rs

1//! Declarative gateway-policy specification.
2//!
3//! Spec payload of `ai_gateway_policies` rows, shared with the YAML schema in
4//! `services/gateway/policies.yaml`. Carries quota windows and safety
5//! configuration.
6//!
7//! Model exposure lives on the profile's gateway catalog, not here — see
8//! `GatewayConfig::is_model_exposed`.
9//!
10//! Copyright (c) systemprompt.io — Business Source License 1.1.
11//! See <https://systemprompt.io> for licensing details.
12
13use serde::{Deserialize, Serialize};
14
15#[derive(Debug, Clone, Copy, Serialize, Deserialize, Default)]
16#[serde(deny_unknown_fields)]
17pub struct QuotaWindow {
18    pub window_seconds: i32,
19    pub max_requests: Option<i64>,
20    pub max_input_tokens: Option<i64>,
21    pub max_output_tokens: Option<i64>,
22}
23
24/// How far back into a conversation the request-phase scanners look.
25///
26/// A request carries the whole conversation, so scanning all of it re-reads
27/// every earlier turn on every turn: one finding would deny the rest of the
28/// conversation, and each turn would persist the same finding again.
29#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
30#[serde(rename_all = "lowercase")]
31pub enum SafetyHistoryMode {
32    /// Judge only the newest user turn.
33    #[default]
34    Off,
35    /// Also scan earlier turns, recording findings at phase `request_history`
36    /// without denying the request.
37    Audit,
38    /// Scan earlier turns and let their findings deny the request.
39    Block,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize, Default)]
43#[serde(deny_unknown_fields)]
44pub struct SafetyConfig {
45    #[serde(default)]
46    pub scanners: Vec<String>,
47    #[serde(default)]
48    pub block_categories: Vec<String>,
49    #[serde(default)]
50    pub history: SafetyHistoryMode,
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize, Default)]
54#[serde(deny_unknown_fields)]
55pub struct GatewayPolicySpec {
56    #[serde(default)]
57    pub quota_windows: Vec<QuotaWindow>,
58    #[serde(default)]
59    pub safety: SafetyConfig,
60}
61
62impl GatewayPolicySpec {
63    #[must_use]
64    pub fn permissive() -> Self {
65        Self::default()
66    }
67}