codex_codes/io/
options.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
5#[serde(rename_all = "kebab-case")]
6pub enum ApprovalMode {
7 Never,
8 OnRequest,
9 OnFailure,
10 Untrusted,
11}
12
13#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
15#[serde(rename_all = "kebab-case")]
16pub enum SandboxMode {
17 ReadOnly,
18 WorkspaceWrite,
19 DangerFullAccess,
20}
21
22impl SandboxMode {
23 pub fn as_cli_str(&self) -> &'static str {
25 match self {
26 SandboxMode::ReadOnly => "read-only",
27 SandboxMode::WorkspaceWrite => "workspace-write",
28 SandboxMode::DangerFullAccess => "danger-full-access",
29 }
30 }
31}
32
33#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
35#[serde(rename_all = "snake_case")]
36pub enum ModelReasoningEffort {
37 Minimal,
38 Low,
39 Medium,
40 High,
41 Xhigh,
42}
43
44#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
46#[serde(rename_all = "snake_case")]
47pub enum WebSearchMode {
48 Disabled,
49 Cached,
50 Live,
51}
52
53#[derive(Debug, Clone, Default, Serialize, Deserialize)]
55pub struct ThreadOptions {
56 #[serde(skip_serializing_if = "Option::is_none")]
57 pub model: Option<String>,
58 #[serde(skip_serializing_if = "Option::is_none")]
59 pub sandbox_mode: Option<SandboxMode>,
60 #[serde(skip_serializing_if = "Option::is_none")]
61 pub working_directory: Option<String>,
62 #[serde(skip_serializing_if = "Option::is_none")]
63 pub skip_git_repo_check: Option<bool>,
64 #[serde(skip_serializing_if = "Option::is_none")]
65 pub model_reasoning_effort: Option<ModelReasoningEffort>,
66 #[serde(skip_serializing_if = "Option::is_none")]
67 pub network_access_enabled: Option<bool>,
68 #[serde(skip_serializing_if = "Option::is_none")]
69 pub web_search_mode: Option<WebSearchMode>,
70 #[serde(skip_serializing_if = "Option::is_none")]
71 pub web_search_enabled: Option<bool>,
72 #[serde(skip_serializing_if = "Option::is_none")]
73 pub approval_policy: Option<ApprovalMode>,
74 #[serde(default, skip_serializing_if = "Vec::is_empty")]
75 pub additional_directories: Vec<String>,
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 #[test]
83 fn test_thread_options_default() {
84 let opts = ThreadOptions::default();
85 assert!(opts.model.is_none());
86 assert!(opts.sandbox_mode.is_none());
87 assert!(opts.additional_directories.is_empty());
88 }
89
90 #[test]
91 fn test_approval_mode_serde() {
92 let json = r#""on-request""#;
93 let mode: ApprovalMode = serde_json::from_str(json).unwrap();
94 assert_eq!(mode, ApprovalMode::OnRequest);
95 }
96
97 #[test]
98 fn test_sandbox_mode_serde() {
99 let json = r#""workspace-write""#;
100 let mode: SandboxMode = serde_json::from_str(json).unwrap();
101 assert_eq!(mode, SandboxMode::WorkspaceWrite);
102 }
103
104 #[test]
105 fn test_reasoning_effort_serde() {
106 let json = r#""xhigh""#;
107 let effort: ModelReasoningEffort = serde_json::from_str(json).unwrap();
108 assert_eq!(effort, ModelReasoningEffort::Xhigh);
109 }
110
111 #[test]
112 fn test_web_search_mode_serde() {
113 let json = r#""live""#;
114 let mode: WebSearchMode = serde_json::from_str(json).unwrap();
115 assert_eq!(mode, WebSearchMode::Live);
116 }
117}