Skip to main content

llmsdk_provider/language_model/
call_options.rs

1//! Call options passed to `do_generate` / `do_stream`.
2//!
3//! Mirrors `language-model-v4-call-options.ts`. We deliberately omit
4//! `abortSignal`: callers cancel by dropping the returned future / stream.
5// Rust guideline compliant 2026-02-21
6
7use serde::{Deserialize, Serialize};
8
9use crate::json::JsonSchema;
10use crate::shared::{Headers, ProviderOptions};
11
12use super::prompt::Prompt;
13use super::tool::{Tool, ToolChoice};
14
15/// Options for one model invocation.
16///
17/// Built directly; only `prompt` is required.
18#[derive(Debug, Clone, Default, Serialize, Deserialize)]
19pub struct CallOptions {
20    /// Standardized prompt; not the user-facing prompt.
21    pub prompt: Prompt,
22    /// Hard cap on generated tokens.
23    #[serde(
24        default,
25        rename = "maxOutputTokens",
26        skip_serializing_if = "Option::is_none"
27    )]
28    pub max_output_tokens: Option<u32>,
29    /// Sampling temperature.
30    #[serde(default, skip_serializing_if = "Option::is_none")]
31    pub temperature: Option<f32>,
32    /// Stop sequences (provider may cap the count).
33    #[serde(
34        default,
35        rename = "stopSequences",
36        skip_serializing_if = "Option::is_none"
37    )]
38    pub stop_sequences: Option<Vec<String>>,
39    /// Nucleus sampling.
40    #[serde(default, rename = "topP", skip_serializing_if = "Option::is_none")]
41    pub top_p: Option<f32>,
42    /// Top-K sampling.
43    #[serde(default, rename = "topK", skip_serializing_if = "Option::is_none")]
44    pub top_k: Option<u32>,
45    /// Presence penalty.
46    #[serde(
47        default,
48        rename = "presencePenalty",
49        skip_serializing_if = "Option::is_none"
50    )]
51    pub presence_penalty: Option<f32>,
52    /// Frequency penalty.
53    #[serde(
54        default,
55        rename = "frequencyPenalty",
56        skip_serializing_if = "Option::is_none"
57    )]
58    pub frequency_penalty: Option<f32>,
59    /// Desired response format. `None` = provider default (text).
60    #[serde(
61        default,
62        rename = "responseFormat",
63        skip_serializing_if = "Option::is_none"
64    )]
65    pub response_format: Option<ResponseFormat>,
66    /// Sampling seed.
67    #[serde(default, skip_serializing_if = "Option::is_none")]
68    pub seed: Option<u64>,
69    /// Available tools.
70    #[serde(default, skip_serializing_if = "Option::is_none")]
71    pub tools: Option<Vec<Tool>>,
72    /// Tool-selection policy.
73    #[serde(
74        default,
75        rename = "toolChoice",
76        skip_serializing_if = "Option::is_none"
77    )]
78    pub tool_choice: Option<ToolChoice>,
79    /// Include raw chunks in the stream (`do_stream` only).
80    #[serde(
81        default,
82        rename = "includeRawChunks",
83        skip_serializing_if = "Option::is_none"
84    )]
85    pub include_raw_chunks: Option<bool>,
86    /// Extra HTTP headers (HTTP providers only).
87    #[serde(default, skip_serializing_if = "Option::is_none")]
88    pub headers: Option<Headers>,
89    /// Reasoning effort.
90    #[serde(default, skip_serializing_if = "Option::is_none")]
91    pub reasoning: Option<ReasoningEffort>,
92    /// Provider-specific options.
93    #[serde(
94        default,
95        rename = "providerOptions",
96        skip_serializing_if = "Option::is_none"
97    )]
98    pub provider_options: Option<ProviderOptions>,
99}
100
101/// Response format directive.
102#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
103#[serde(tag = "type", rename_all = "kebab-case")]
104pub enum ResponseFormat {
105    /// Free-form text.
106    Text,
107    /// JSON with an optional schema and naming hint.
108    Json {
109        /// Optional JSON schema constraining the output.
110        #[serde(default, skip_serializing_if = "Option::is_none")]
111        schema: Option<JsonSchema>,
112        /// Logical name of the output structure.
113        #[serde(default, skip_serializing_if = "Option::is_none")]
114        name: Option<String>,
115        /// Human-readable description of the output structure.
116        #[serde(default, skip_serializing_if = "Option::is_none")]
117        description: Option<String>,
118    },
119}
120
121/// Reasoning effort level.
122///
123/// Mirrors ai-sdk's `reasoning` enum: `provider-default` means "do not
124/// override the provider's default".
125#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
126#[serde(rename_all = "kebab-case")]
127pub enum ReasoningEffort {
128    /// Defer to the provider.
129    ProviderDefault,
130    /// Disable reasoning.
131    None,
132    /// Minimal reasoning.
133    Minimal,
134    /// Low reasoning effort.
135    Low,
136    /// Medium reasoning effort.
137    Medium,
138    /// High reasoning effort.
139    High,
140    /// Extra-high reasoning effort.
141    Xhigh,
142}