Skip to main content

kcode_codex_runtime/
model.rs

1use std::{path::PathBuf, time::Duration};
2
3use crate::DEFAULT_CODEX_EXECUTABLE;
4
5/// Maximum model reasoning effort.
6#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
7pub enum ReasoningEffort {
8    /// Disable reasoning when supported.
9    None,
10    /// Minimal reasoning.
11    Minimal,
12    /// Low reasoning.
13    Low,
14    /// Medium reasoning.
15    Medium,
16    /// High reasoning.
17    High,
18    /// Extra-high reasoning.
19    #[default]
20    XHigh,
21    /// Maximum reasoning when supported.
22    Max,
23}
24
25impl ReasoningEffort {
26    /// Returns the Codex configuration value.
27    pub const fn as_str(self) -> &'static str {
28        match self {
29            Self::None => "none",
30            Self::Minimal => "minimal",
31            Self::Low => "low",
32            Self::Medium => "medium",
33            Self::High => "high",
34            Self::XHigh => "xhigh",
35            Self::Max => "max",
36        }
37    }
38}
39
40/// Codex web-search context allocation.
41#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
42pub enum WebSearchContext {
43    /// Low-latency, narrow search context.
44    Low,
45    /// Default search context.
46    Medium,
47    /// Broad search context.
48    High,
49}
50
51impl WebSearchContext {
52    pub(crate) const fn as_str(self) -> &'static str {
53        match self {
54            Self::Low => "low",
55            Self::Medium => "medium",
56            Self::High => "high",
57        }
58    }
59}
60
61/// Research breadth requested from Codex.
62#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
63pub enum SearchDepth {
64    /// Focused research that stops once adequate evidence is available.
65    Focused,
66    /// Thorough bounded research that resolves material conflicts.
67    Thorough,
68}
69
70/// Runtime configuration shared by generation and web search.
71#[derive(Clone, Debug, Eq, PartialEq)]
72pub struct CodexConfig {
73    /// Codex or sandbox-launcher executable.
74    pub executable: String,
75    /// Directory supplied to Codex as its working directory.
76    pub working_directory: PathBuf,
77    /// Fixed application instruction supplied for ordinary generation.
78    pub base_instruction: String,
79    /// Model used for startup prompt-boundary validation.
80    pub validation_model: String,
81    /// Reasoning setting used for startup prompt-boundary validation.
82    pub validation_reasoning_effort: ReasoningEffort,
83}
84
85impl CodexConfig {
86    /// Constructs a configuration for one validation model.
87    pub fn new(validation_model: impl Into<String>) -> Self {
88        Self {
89            executable: DEFAULT_CODEX_EXECUTABLE.into(),
90            working_directory: std::env::temp_dir(),
91            base_instruction: String::new(),
92            validation_model: validation_model.into(),
93            validation_reasoning_effort: ReasoningEffort::XHigh,
94        }
95    }
96}
97
98/// One ordinary Codex generation request.
99#[derive(Clone, Debug, Eq, PartialEq)]
100pub struct GenerationRequest {
101    /// Exact model-visible prompt text.
102    pub prompt: String,
103    /// Codex model identifier.
104    pub model: String,
105    /// Requested reasoning effort.
106    pub reasoning_effort: ReasoningEffort,
107    /// Existing Codex thread identifier to resume, when any.
108    pub previous_thread_id: Option<String>,
109    /// Whether a fresh thread should avoid persistent Codex session storage.
110    pub ephemeral: bool,
111    /// Maximum wall-clock duration.
112    pub timeout: Duration,
113}
114
115impl GenerationRequest {
116    /// Constructs a fresh generation request.
117    pub fn new(prompt: impl Into<String>, model: impl Into<String>) -> Self {
118        Self {
119            prompt: prompt.into(),
120            model: model.into(),
121            reasoning_effort: ReasoningEffort::XHigh,
122            previous_thread_id: None,
123            ephemeral: false,
124            timeout: Duration::from_secs(10 * 60),
125        }
126    }
127}
128
129/// Normalized token accounting from one Codex turn.
130#[derive(Clone, Debug, Default, Eq, PartialEq)]
131pub struct TokenUsage {
132    /// Total input tokens reported for the thread.
133    pub input_tokens: u64,
134    /// Total output tokens reported for the thread.
135    pub output_tokens: u64,
136    /// Cached input tokens.
137    pub cached_input_tokens: u64,
138    /// Reasoning output tokens.
139    pub reasoning_output_tokens: u64,
140    /// Input tokens for only the most recent turn, when reported.
141    pub last_input_tokens: Option<u64>,
142    /// Output tokens for only the most recent turn, when reported.
143    pub last_output_tokens: Option<u64>,
144}
145
146/// Successful ordinary Codex generation.
147#[derive(Clone, Debug, Eq, PartialEq)]
148pub struct GenerationResponse {
149    /// Codex thread identifier used for continuation.
150    pub thread_id: String,
151    /// Final non-empty assistant message.
152    pub answer: String,
153    /// Provider usage, when reported.
154    pub usage: Option<TokenUsage>,
155}
156
157/// One Codex web-search request.
158#[derive(Clone, Debug, Eq, PartialEq)]
159pub struct WebSearchRequest {
160    /// Research question.
161    pub question: String,
162    /// Codex model identifier.
163    pub model: String,
164    /// Requested reasoning effort.
165    pub reasoning_effort: ReasoningEffort,
166    /// Provider web-search context allocation.
167    pub context: WebSearchContext,
168    /// Desired research breadth.
169    pub depth: SearchDepth,
170    /// Fixed application-selected wall-clock limit.
171    pub timeout: Duration,
172}
173
174/// One normalized public HTTP(S) source found in a Codex answer.
175#[derive(Clone, Debug, Eq, PartialEq)]
176pub struct WebSource {
177    /// Source title derived from the Markdown link when available.
178    pub title: String,
179    /// Canonical public HTTP(S) URL.
180    pub url: String,
181}
182
183/// Successful Codex web research.
184#[derive(Clone, Debug, Eq, PartialEq)]
185pub struct WebSearchResponse {
186    /// Evidence-focused answer text.
187    pub answer: String,
188    /// All deduplicated HTTP(S) sources present in the answer.
189    pub sources: Vec<WebSource>,
190    /// Provider usage, when reported.
191    pub usage: Option<TokenUsage>,
192}