steer-auth-plugin 0.19.0

Auth plugin primitives for Steer.
Documentation
use crate::error::Result;
use crate::identifiers::ModelId;
use async_trait::async_trait;
use std::fmt;
use std::sync::Arc;

#[derive(Debug, Clone)]
pub struct HeaderPair {
    pub name: String,
    pub value: String,
}

#[derive(Debug, Clone)]
pub struct QueryParam {
    pub name: String,
    pub value: String,
}

#[derive(Debug, Clone, Copy)]
pub enum RequestKind {
    Complete,
    Stream,
}

#[derive(Debug, Clone)]
pub struct AuthHeaderContext {
    pub model_id: Option<ModelId>,
    pub request_kind: RequestKind,
}

#[derive(Debug, Clone)]
pub struct AuthErrorContext {
    pub status: Option<u16>,
    pub body_snippet: Option<String>,
    pub request_kind: RequestKind,
}

#[derive(Debug, Clone, Copy)]
pub enum AuthErrorAction {
    RetryOnce,
    ReauthRequired,
    NoAction,
}

#[async_trait]
pub trait AuthHeaderProvider: Send + Sync {
    async fn headers(&self, ctx: AuthHeaderContext) -> Result<Vec<HeaderPair>>;

    async fn on_auth_error(&self, ctx: AuthErrorContext) -> Result<AuthErrorAction>;
}

#[derive(Debug, Clone)]
pub enum InstructionPolicy {
    Prefix(String),
    DefaultIfEmpty(String),
    Override(String),
}

#[derive(Debug, Clone)]
pub enum AuthDirective {
    OpenAiResponses(OpenAiResponsesAuth),
    Anthropic(AnthropicAuth),
}

#[derive(Clone)]
pub struct OpenAiResponsesAuth {
    pub headers: Arc<dyn AuthHeaderProvider>,
    pub base_url_override: Option<String>,
    pub require_streaming: Option<bool>,
    pub instruction_policy: Option<InstructionPolicy>,
    pub include: Option<Vec<String>>,
}

impl fmt::Debug for OpenAiResponsesAuth {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("OpenAiResponsesAuth")
            .field("headers", &"<AuthHeaderProvider>")
            .field("base_url_override", &self.base_url_override)
            .field("require_streaming", &self.require_streaming)
            .field("instruction_policy", &self.instruction_policy)
            .field("include", &self.include)
            .finish()
    }
}

#[derive(Clone)]
pub struct AnthropicAuth {
    pub headers: Arc<dyn AuthHeaderProvider>,
    pub instruction_policy: Option<InstructionPolicy>,
    pub query_params: Option<Vec<QueryParam>>,
}

impl fmt::Debug for AnthropicAuth {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("AnthropicAuth")
            .field("headers", &"<AuthHeaderProvider>")
            .field("instruction_policy", &self.instruction_policy)
            .field("query_params", &self.query_params)
            .finish()
    }
}