Skip to main content

intr_providers/
types.rs

1//! Shared request/response types for all providers.
2
3use std::collections::HashMap;
4
5use secrecy::SecretString;
6use serde::{Deserialize, Serialize};
7
8// ---------------------------------------------------------------------------
9// Messages
10// ---------------------------------------------------------------------------
11
12#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
13#[serde(rename_all = "lowercase")]
14pub enum Role {
15    System,
16    User,
17    Assistant,
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct Message {
22    pub role: Role,
23    pub content: String,
24}
25
26// ---------------------------------------------------------------------------
27// API key
28// ---------------------------------------------------------------------------
29
30/// Represents the API key used for a model call.
31///
32/// Uses [`SecretString`] from the `secrecy` crate which:
33/// - Never exposes the secret in `Debug` output
34/// - Zeroes the memory on drop
35#[derive(Clone)]
36pub enum ApiKey {
37    /// Caller-supplied key - passed per request, never persisted by Intentry.
38    UserSupplied(SecretString),
39    /// Intentry-owned key - resolved from environment at startup.
40    /// (Used when Intentry runs model calls on behalf of the user.)
41    IntentryOwned,
42}
43
44impl std::fmt::Debug for ApiKey {
45    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46        match self {
47            ApiKey::UserSupplied(_) => write!(f, "ApiKey::UserSupplied([REDACTED])"),
48            ApiKey::IntentryOwned => write!(f, "ApiKey::IntentryOwned"),
49        }
50    }
51}
52
53// ---------------------------------------------------------------------------
54// Request
55// ---------------------------------------------------------------------------
56
57/// A model generation request, normalised across providers.
58#[derive(Debug, Clone)]
59pub struct GenerateRequest {
60    /// Model identifier, e.g. `"claude-sonnet-4-6"` or `"gpt-4o"`.
61    pub model: String,
62    /// Conversation turn history.
63    pub messages: Vec<Message>,
64    /// Sampling temperature (0.0–1.0). `None` → provider default.
65    pub temperature: Option<f32>,
66    /// Maximum output tokens. `None` → provider default.
67    pub max_tokens: Option<u32>,
68    /// Request JSON-mode output from the provider when supported.
69    pub json_mode: bool,
70    /// Provider-specific extra parameters (passed through verbatim).
71    pub extra: HashMap<String, serde_json::Value>,
72    /// API key to use for this call.
73    pub api_key: ApiKey,
74    /// Per-request timeout in milliseconds. Default: 30 000 ms.
75    pub timeout_ms: u32,
76}
77
78impl Default for GenerateRequest {
79    fn default() -> Self {
80        Self {
81            model: String::new(),
82            messages: Vec::new(),
83            temperature: None,
84            max_tokens: None,
85            json_mode: false,
86            extra: HashMap::new(),
87            api_key: ApiKey::IntentryOwned,
88            timeout_ms: 30_000,
89        }
90    }
91}
92
93// ---------------------------------------------------------------------------
94// Response
95// ---------------------------------------------------------------------------
96
97#[derive(Debug, Clone, PartialEq, Eq)]
98pub enum FinishReason {
99    Stop,
100    MaxTokens,
101    ContentFilter,
102    Other(String),
103}
104
105/// A normalised generation response.
106#[derive(Debug, Clone)]
107pub struct GenerateResponse {
108    /// Model output text (the assistant turn).
109    pub text: String,
110    /// Why the generation stopped.
111    pub finish_reason: FinishReason,
112    /// Input tokens consumed.
113    pub tokens_in: u32,
114    /// Output tokens generated.
115    pub tokens_out: u32,
116    /// Exact model ID that handled the request (provider may route).
117    pub model_used: String,
118    /// End-to-end wall-clock latency in milliseconds.
119    pub latency_ms: u32,
120    /// Raw provider JSON response (opaque; useful for debugging).
121    pub raw_response: serde_json::Value,
122}