Skip to main content

aimux_core/
options.rs

1//! `CallOptions` — the provider-facing options passed to `do_generate` / `do_stream`.
2//!
3//! Aligned with V4 `LanguageModelV4CallOptions`.
4
5use std::collections::HashMap;
6
7use serde::{Deserialize, Serialize};
8use serde_json::Value;
9use ts_rs::TS;
10
11use crate::language_model_message::LanguageModelPrompt;
12use crate::shared::AbortSignal;
13pub use crate::tool::{FunctionTool, ProviderTool, Tool, ToolChoice};
14use crate::types::ReasoningEffort;
15
16/// How the model should format its response.
17#[derive(Debug, Clone, Serialize, Deserialize, TS)]
18#[ts(export)]
19pub enum ResponseFormat {
20    /// Plain text (default).
21    Text,
22    /// JSON output, optionally constrained to a schema.
23    Json {
24        schema: Option<Value>,
25        name: Option<String>,
26        description: Option<String>,
27    },
28}
29
30/// Per-call timeout configuration.
31///
32/// Aligned with V4 `LanguageModelV4CallOptions.timeout`
33/// (`TimeoutConfiguration`). All values are milliseconds; `None` disables the
34/// corresponding limit. A `total` timeout also covers retry backoff and the
35/// whole streamed response.
36#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, TS)]
37#[ts(export)]
38pub struct TimeoutConfiguration {
39    /// Overall timeout for the entire call (including retries and, for
40    /// streaming, the whole stream), in milliseconds.
41    pub total_ms: Option<u64>,
42    /// Timeout waiting for the first stream chunk (streaming only).
43    pub first_chunk_ms: Option<u64>,
44    /// Maximum idle time between consecutive stream chunks (streaming only).
45    pub chunk_ms: Option<u64>,
46}
47
48/// Options passed to `LanguageModel::do_generate` / `do_stream`.
49///
50/// This is the **provider-facing** options struct. Users interact with
51/// `GenerateTextOptions` (user-facing) which is converted to `CallOptions`
52/// by the `generate_text` / `stream_text` functions.
53#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
54#[ts(export)]
55pub struct CallOptions {
56    /// The standardized prompt (message array). Required.
57    pub prompt: LanguageModelPrompt,
58
59    /// Maximum tokens to generate.
60    pub max_output_tokens: Option<u32>,
61
62    /// Sampling temperature.
63    pub temperature: Option<f64>,
64
65    /// Stop sequences.
66    pub stop_sequences: Option<Vec<String>>,
67
68    /// Nucleus sampling `top_p`.
69    pub top_p: Option<f64>,
70
71    /// Top-k sampling.
72    pub top_k: Option<f64>,
73
74    /// Presence penalty.
75    pub presence_penalty: Option<f64>,
76
77    /// Frequency penalty.
78    pub frequency_penalty: Option<f64>,
79
80    /// Response format (text or JSON).
81    pub response_format: Option<ResponseFormat>,
82
83    /// Seed for reproducibility.
84    pub seed: Option<u64>,
85
86    /// Tools available to the model (function tools and/or provider-defined tools).
87    pub tools: Option<Vec<Tool>>,
88
89    /// How the model should choose tools.
90    pub tool_choice: ToolChoice,
91
92    /// Extra HTTP headers.
93    pub headers: Option<HashMap<String, String>>,
94
95    /// Provider-specific options (keyed by provider name).
96    pub provider_options: Option<HashMap<String, Value>>,
97
98    /// Top-level reasoning effort. Maps to OpenAI `reasoning_effort` and
99    /// Anthropic `thinking` config.
100    pub reasoning: Option<ReasoningEffort>,
101
102    /// Per-call request body overrides. Deep-merged into the provider-built
103    /// request body (after any built-in vendor override) before sending.
104    /// `null` values delete the corresponding key. See RFC-0017.
105    pub body_overrides: Option<Value>,
106
107    /// Per-call retry count override. `None` uses the provider's configured
108    /// `RetryConfig.max_retries`. `Some(0)` disables retries.
109    pub max_retries: Option<u32>,
110
111    /// Per-call timeout configuration (total / first-chunk / chunk idle).
112    /// `None` = no timeouts (provider defaults still apply at the HTTP layer).
113    pub timeout: Option<TimeoutConfiguration>,
114
115    /// Abort signal for cancelling the call.
116    ///
117    /// Runtime handle — never crosses the JSON boundary (bindings that only
118    /// pass JSON cannot set it; Node bridges a JS `AbortSignal` natively).
119    #[serde(skip)]
120    #[ts(skip)]
121    pub abort_signal: Option<AbortSignal>,
122}
123
124impl CallOptions {
125    /// Create a `CallOptions` with the given prompt and all other fields set
126    /// to their defaults (`None` / `ToolChoice::Auto`).
127    ///
128    /// This is the recommended construction baseline in tests — combined with
129    /// struct-update syntax (`CallOptions { tools: Some(..), ..CallOptions::new(prompt) }`)
130    /// it avoids spelling out every `None` field, so adding a new optional
131    /// field to `CallOptions` no longer requires batch-editing every test.
132    pub fn new(prompt: LanguageModelPrompt) -> Self {
133        CallOptions {
134            prompt,
135            max_output_tokens: None,
136            temperature: None,
137            stop_sequences: None,
138            top_p: None,
139            top_k: None,
140            presence_penalty: None,
141            frequency_penalty: None,
142            response_format: None,
143            seed: None,
144            tools: None,
145            tool_choice: ToolChoice::default(),
146            headers: None,
147            provider_options: None,
148            reasoning: None,
149            body_overrides: None,
150            max_retries: None,
151            timeout: None,
152            abort_signal: None,
153        }
154    }
155}