kcode_codex_runtime_v2/model.rs
1use std::time::Duration;
2
3use serde_json::Value;
4
5/// Model reasoning effort accepted by Codex.
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 protocol 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/// A dynamic function exposed to Codex for a fresh thread.
41#[derive(Clone, Debug, PartialEq)]
42pub struct DynamicTool {
43 /// Function name visible to the model.
44 pub name: String,
45 /// Short function description visible to the model.
46 pub description: String,
47 /// JSON Schema for the function arguments.
48 pub input_schema: Value,
49}
50
51impl DynamicTool {
52 /// Constructs one function tool.
53 pub fn new(
54 name: impl Into<String>,
55 description: impl Into<String>,
56 input_schema: Value,
57 ) -> Self {
58 Self {
59 name: name.into(),
60 description: description.into(),
61 input_schema,
62 }
63 }
64}
65
66/// One standard Codex turn request.
67#[derive(Clone, Debug, PartialEq)]
68pub struct AgentRequest {
69 /// Exact text supplied as the user input item for this turn.
70 pub input: String,
71 /// Codex model identifier.
72 pub model: String,
73 /// Requested reasoning effort.
74 pub reasoning_effort: ReasoningEffort,
75 /// Existing Codex thread identifier to resume.
76 pub previous_thread_id: Option<String>,
77 /// Dynamic functions supplied when a fresh thread is created.
78 pub tools: Vec<DynamicTool>,
79 /// Whether a fresh thread avoids persistent Codex session storage.
80 pub ephemeral: bool,
81 /// Maximum duration of the complete turn, including tool handling.
82 pub timeout: Duration,
83}
84
85impl AgentRequest {
86 /// Constructs a fresh turn with no tools.
87 pub fn new(input: impl Into<String>, model: impl Into<String>) -> Self {
88 Self {
89 input: input.into(),
90 model: model.into(),
91 reasoning_effort: ReasoningEffort::XHigh,
92 previous_thread_id: None,
93 tools: Vec::new(),
94 ephemeral: false,
95 timeout: Duration::from_secs(10 * 60),
96 }
97 }
98}
99
100/// A dynamic function call requested by Codex.
101#[derive(Clone, Debug, PartialEq)]
102pub struct DynamicToolCall {
103 /// Protocol call identifier used when returning the result.
104 pub call_id: String,
105 /// Dynamic function name.
106 pub tool: String,
107 /// Parsed JSON arguments supplied by the model.
108 pub arguments: Value,
109}
110
111/// Caller-provided result for one dynamic function call.
112#[derive(Clone, Debug, Eq, PartialEq)]
113pub struct ToolResult {
114 /// Whether the function completed successfully.
115 pub success: bool,
116 /// Text returned to the model.
117 pub text: String,
118}
119
120impl ToolResult {
121 /// Constructs a successful text result.
122 pub fn success(text: impl Into<String>) -> Self {
123 Self {
124 success: true,
125 text: text.into(),
126 }
127 }
128
129 /// Constructs a failed text result.
130 pub fn failure(text: impl Into<String>) -> Self {
131 Self {
132 success: false,
133 text: text.into(),
134 }
135 }
136}
137
138/// Normalized cumulative and latest-turn token accounting.
139#[derive(Clone, Debug, Default, Eq, PartialEq)]
140pub struct TokenUsage {
141 /// Cumulative input tokens for the thread.
142 pub input_tokens: u64,
143 /// Cumulative output tokens for the thread.
144 pub output_tokens: u64,
145 /// Cumulative cached input tokens for the thread.
146 pub cached_input_tokens: u64,
147 /// Cumulative reasoning output tokens for the thread.
148 pub reasoning_output_tokens: u64,
149 /// Input tokens for the latest model round.
150 pub last_input_tokens: Option<u64>,
151 /// Output tokens for the latest model round.
152 pub last_output_tokens: Option<u64>,
153}
154
155/// Successful terminal state of one Codex turn.
156#[derive(Clone, Debug, Eq, PartialEq)]
157pub struct CompletedTurn {
158 /// Codex thread identifier used for continuation.
159 pub thread_id: String,
160 /// Codex turn identifier.
161 pub turn_id: String,
162 /// Terminal assistant text. It may be empty after a control tool call.
163 pub answer: String,
164 /// Latest provider token accounting, when reported.
165 pub usage: Option<TokenUsage>,
166}
167
168/// Event yielded while a Codex turn is running.
169#[derive(Clone, Debug, PartialEq)]
170pub enum AgentEvent {
171 /// Exact UTF-8 JSONL record written by the client to Codex, including its newline.
172 ProviderInput(String),
173 /// A dynamic function call requiring a response from the caller.
174 ToolCall(DynamicToolCall),
175 /// The turn completed successfully.
176 Completed(CompletedTurn),
177}