codex-python 0.2.10__tar.gz → 0.2.11__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codex_python-0.2.10 → codex_python-0.2.11}/PKG-INFO +1 -1
- {codex_python-0.2.10 → codex_python-0.2.11}/codex/__init__.py +1 -1
- codex_python-0.2.11/codex/config.py +242 -0
- {codex_python-0.2.10 → codex_python-0.2.11}/crates/codex_native/Cargo.lock +1 -1
- {codex_python-0.2.10 → codex_python-0.2.11}/crates/codex_native/Cargo.toml +1 -1
- {codex_python-0.2.10 → codex_python-0.2.11}/crates/codex_native/src/lib.rs +121 -7
- codex_python-0.2.10/codex/config.py +0 -82
- {codex_python-0.2.10 → codex_python-0.2.11}/LICENSE +0 -0
- {codex_python-0.2.10 → codex_python-0.2.11}/README.md +0 -0
- {codex_python-0.2.10 → codex_python-0.2.11}/codex/api.py +0 -0
- {codex_python-0.2.10 → codex_python-0.2.11}/codex/event.py +0 -0
- {codex_python-0.2.10 → codex_python-0.2.11}/codex/native.py +0 -0
- {codex_python-0.2.10 → codex_python-0.2.11}/codex/protocol/types.py +0 -0
- {codex_python-0.2.10 → codex_python-0.2.11}/codex/py.typed +0 -0
- {codex_python-0.2.10 → codex_python-0.2.11}/pyproject.toml +0 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from typing import Any, cast
|
|
5
|
+
|
|
6
|
+
from pydantic import AliasChoices, BaseModel, ConfigDict, Field
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ApprovalPolicy(str, Enum):
|
|
10
|
+
"""Approval policy for executing shell commands.
|
|
11
|
+
|
|
12
|
+
Matches Rust enum `AskForApproval` (serde kebab-case):
|
|
13
|
+
- "untrusted": auto-approve safe read-only commands, ask otherwise
|
|
14
|
+
- "on-failure": sandbox by default; ask only if the sandboxed run fails
|
|
15
|
+
- "on-request": model decides (default)
|
|
16
|
+
- "never": never ask the user
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
UNTRUSTED = "untrusted"
|
|
20
|
+
ON_FAILURE = "on-failure"
|
|
21
|
+
ON_REQUEST = "on-request"
|
|
22
|
+
NEVER = "never"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class SandboxMode(str, Enum):
|
|
26
|
+
"""High-level sandbox mode override.
|
|
27
|
+
|
|
28
|
+
Matches Rust enum `SandboxMode` (serde kebab-case):
|
|
29
|
+
- "read-only"
|
|
30
|
+
- "workspace-write"
|
|
31
|
+
- "danger-full-access"
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
READ_ONLY = "read-only"
|
|
35
|
+
WORKSPACE_WRITE = "workspace-write"
|
|
36
|
+
DANGER_FULL_ACCESS = "danger-full-access"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class HistoryPersistence(str, Enum):
|
|
40
|
+
SAVE_ALL = "save-all"
|
|
41
|
+
NONE = "none"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class HistoryConfig(BaseModel):
|
|
45
|
+
persistence: HistoryPersistence | None = None
|
|
46
|
+
max_bytes: int | None = None
|
|
47
|
+
|
|
48
|
+
model_config = ConfigDict(extra="allow")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class SandboxWorkspaceWrite(BaseModel):
|
|
52
|
+
writable_roots: list[str] | None = None
|
|
53
|
+
network_access: bool | None = None
|
|
54
|
+
exclude_tmpdir_env_var: bool | None = None
|
|
55
|
+
exclude_slash_tmp: bool | None = None
|
|
56
|
+
|
|
57
|
+
model_config = ConfigDict(extra="allow")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class McpServerConfig(BaseModel):
|
|
61
|
+
command: str
|
|
62
|
+
args: list[str] | None = None
|
|
63
|
+
env: dict[str, str] | None = None
|
|
64
|
+
startup_timeout_ms: int | None = None
|
|
65
|
+
|
|
66
|
+
model_config = ConfigDict(extra="allow")
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class WireApi(str, Enum):
|
|
70
|
+
CHAT = "chat"
|
|
71
|
+
RESPONSES = "responses"
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class ModelProviderConfig(BaseModel):
|
|
75
|
+
name: str | None = None
|
|
76
|
+
base_url: str | None = None
|
|
77
|
+
env_key: str | None = None
|
|
78
|
+
wire_api: WireApi | None = None
|
|
79
|
+
query_params: dict[str, str] | None = None
|
|
80
|
+
http_headers: dict[str, str] | None = None
|
|
81
|
+
env_http_headers: dict[str, str] | None = None
|
|
82
|
+
request_max_retries: int | None = None
|
|
83
|
+
stream_max_retries: int | None = None
|
|
84
|
+
stream_idle_timeout_ms: int | None = None
|
|
85
|
+
|
|
86
|
+
model_config = ConfigDict(extra="allow")
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class FileOpener(str, Enum):
|
|
90
|
+
VSCODE = "vscode"
|
|
91
|
+
VSCODE_INSIDERS = "vscode-insiders"
|
|
92
|
+
WINDSURF = "windsurf"
|
|
93
|
+
CURSOR = "cursor"
|
|
94
|
+
NONE = "none"
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class ReasoningEffort(str, Enum):
|
|
98
|
+
MINIMAL = "minimal"
|
|
99
|
+
LOW = "low"
|
|
100
|
+
MEDIUM = "medium"
|
|
101
|
+
HIGH = "high"
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class ReasoningSummary(str, Enum):
|
|
105
|
+
AUTO = "auto"
|
|
106
|
+
CONCISE = "concise"
|
|
107
|
+
DETAILED = "detailed"
|
|
108
|
+
NONE = "none"
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class ReasoningSummaryFormat(str, Enum):
|
|
112
|
+
NONE = "none"
|
|
113
|
+
EXPERIMENTAL = "experimental"
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class Verbosity(str, Enum):
|
|
117
|
+
LOW = "low"
|
|
118
|
+
MEDIUM = "medium"
|
|
119
|
+
HIGH = "high"
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class ToolsConfig(BaseModel):
|
|
123
|
+
# Accept either "web_search" or legacy alias "web_search_request" on input
|
|
124
|
+
web_search: bool | None = Field(
|
|
125
|
+
default=None, validation_alias=AliasChoices("web_search", "web_search_request")
|
|
126
|
+
)
|
|
127
|
+
# Also expose view_image knob (defaults handled in Rust)
|
|
128
|
+
view_image: bool | None = None
|
|
129
|
+
|
|
130
|
+
model_config = ConfigDict(extra="allow")
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class ProfileConfig(BaseModel):
|
|
134
|
+
model: str | None = None
|
|
135
|
+
model_provider: str | None = None
|
|
136
|
+
approval_policy: ApprovalPolicy | None = None
|
|
137
|
+
model_reasoning_effort: ReasoningEffort | None = None
|
|
138
|
+
model_reasoning_summary: ReasoningSummary | None = None
|
|
139
|
+
model_verbosity: Verbosity | None = None
|
|
140
|
+
chatgpt_base_url: str | None = None
|
|
141
|
+
experimental_instructions_file: str | None = None
|
|
142
|
+
|
|
143
|
+
model_config = ConfigDict(extra="allow")
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
class ProjectConfig(BaseModel):
|
|
147
|
+
trust_level: str | None = Field(
|
|
148
|
+
default=None, description='Only "trusted" is recognized by the core.'
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
model_config = ConfigDict(extra="allow")
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class PreferredAuthMethod(str, Enum):
|
|
155
|
+
CHATGPT = "chatgpt"
|
|
156
|
+
APIKEY = "apikey"
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class CodexConfig(BaseModel):
|
|
160
|
+
"""Configuration overrides for Codex.
|
|
161
|
+
|
|
162
|
+
This mirrors `codex_core::config::ConfigOverrides` and is intentionally
|
|
163
|
+
conservative: only values present (not None) are passed to the native core.
|
|
164
|
+
"""
|
|
165
|
+
|
|
166
|
+
# Model selection
|
|
167
|
+
model: str | None = Field(default=None, description="Model slug, e.g. 'gpt-5' or 'o3'.")
|
|
168
|
+
model_provider: str | None = Field(
|
|
169
|
+
default=None, description="Provider key from config, e.g. 'openai'."
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
# Safety/Execution
|
|
173
|
+
approval_policy: ApprovalPolicy | None = Field(default=None)
|
|
174
|
+
sandbox_mode: SandboxMode | None = Field(default=None)
|
|
175
|
+
sandbox_workspace_write: SandboxWorkspaceWrite | None = None
|
|
176
|
+
|
|
177
|
+
# Environment
|
|
178
|
+
cwd: str | None = Field(default=None, description="Working directory for the session.")
|
|
179
|
+
config_profile: str | None = Field(
|
|
180
|
+
default=None, description="Config profile key to use (from profiles.*)."
|
|
181
|
+
)
|
|
182
|
+
codex_linux_sandbox_exe: str | None = Field(
|
|
183
|
+
default=None, description="Absolute path to codex-linux-sandbox (Linux only)."
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
# UX / features
|
|
187
|
+
base_instructions: str | None = Field(default=None, description="Override base instructions.")
|
|
188
|
+
include_plan_tool: bool | None = Field(default=None)
|
|
189
|
+
include_apply_patch_tool: bool | None = Field(default=None)
|
|
190
|
+
include_view_image_tool: bool | None = Field(default=None)
|
|
191
|
+
show_raw_agent_reasoning: bool | None = Field(default=None)
|
|
192
|
+
|
|
193
|
+
# Model/runtime tuning
|
|
194
|
+
model_context_window: int | None = None
|
|
195
|
+
model_max_output_tokens: int | None = None
|
|
196
|
+
model_reasoning_effort: ReasoningEffort | None = None
|
|
197
|
+
model_reasoning_summary: ReasoningSummary | None = None
|
|
198
|
+
model_verbosity: Verbosity | None = None
|
|
199
|
+
model_supports_reasoning_summaries: bool | None = None
|
|
200
|
+
model_reasoning_summary_format: ReasoningSummaryFormat | None = None
|
|
201
|
+
|
|
202
|
+
# Auth/UI options
|
|
203
|
+
hide_agent_reasoning: bool | None = None
|
|
204
|
+
chatgpt_base_url: str | None = None
|
|
205
|
+
preferred_auth_method: PreferredAuthMethod | None = None
|
|
206
|
+
file_opener: FileOpener | None = None
|
|
207
|
+
|
|
208
|
+
# Config file composed sections
|
|
209
|
+
history: HistoryConfig | None = None
|
|
210
|
+
tui: dict[str, Any] | None = None
|
|
211
|
+
notify: list[str] | None = None
|
|
212
|
+
instructions: str | None = Field(
|
|
213
|
+
default=None,
|
|
214
|
+
description="Ignored by core; prefer AGENTS.md or experimental_instructions_file.",
|
|
215
|
+
)
|
|
216
|
+
mcp_servers: dict[str, McpServerConfig] | None = None
|
|
217
|
+
model_providers: dict[str, ModelProviderConfig] | None = None
|
|
218
|
+
project_doc_max_bytes: int | None = None
|
|
219
|
+
profile: str | None = None
|
|
220
|
+
profiles: dict[str, ProfileConfig] | None = None
|
|
221
|
+
tools: ToolsConfig | None = None
|
|
222
|
+
projects: dict[str, ProjectConfig] | None = None
|
|
223
|
+
|
|
224
|
+
# Experimental / internal
|
|
225
|
+
experimental_resume: str | None = None
|
|
226
|
+
experimental_instructions_file: str | None = None
|
|
227
|
+
experimental_use_exec_command_tool: bool | None = None
|
|
228
|
+
responses_originator_header_internal_override: str | None = None
|
|
229
|
+
disable_response_storage: bool | None = Field(
|
|
230
|
+
default=None, description="Accepted in some clients; ignored by core."
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
def to_dict(self) -> dict[str, Any]:
|
|
234
|
+
"""Return overrides as a plain dict with None values removed.
|
|
235
|
+
|
|
236
|
+
Enum fields are emitted as their string values.
|
|
237
|
+
"""
|
|
238
|
+
return cast(dict[str, Any], self.model_dump(exclude_none=True))
|
|
239
|
+
|
|
240
|
+
# Pydantic v2 config. `use_enum_values=True` ensures enums dump as strings.
|
|
241
|
+
# Place at end of class, extra='allow' per style.
|
|
242
|
+
model_config = ConfigDict(extra="allow", validate_assignment=True, use_enum_values=True)
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
use anyhow::{Context, Result};
|
|
2
|
-
use codex_core::config::{
|
|
2
|
+
use codex_core::config::{
|
|
3
|
+
find_codex_home, load_config_as_toml_with_cli_overrides, Config, ConfigOverrides, ConfigToml,
|
|
4
|
+
};
|
|
3
5
|
use codex_core::protocol::{EventMsg, InputItem};
|
|
4
6
|
use codex_core::{AuthManager, ConversationManager};
|
|
5
7
|
// use of SandboxMode is handled within core::config; not needed here
|
|
6
8
|
use pyo3::prelude::*;
|
|
7
9
|
use pyo3::types::{PyDict, PyFloat, PyList, PyModule, PyString};
|
|
8
10
|
use serde_json::Value as JsonValue;
|
|
11
|
+
use toml::value::Value as TomlValue;
|
|
12
|
+
use toml::value::Table as TomlTable;
|
|
9
13
|
use std::path::PathBuf;
|
|
10
14
|
use std::sync::{mpsc, Arc, Mutex};
|
|
11
15
|
use std::thread;
|
|
@@ -173,7 +177,10 @@ fn build_config(
|
|
|
173
177
|
load_default_config: bool,
|
|
174
178
|
) -> Result<Config> {
|
|
175
179
|
let mut overrides_struct = ConfigOverrides::default();
|
|
180
|
+
let mut cli_overrides: Vec<(String, TomlValue)> = Vec::new();
|
|
181
|
+
|
|
176
182
|
if let Some(dict) = overrides {
|
|
183
|
+
// Extract strongly-typed overrides first (these take precedence over CLI overrides).
|
|
177
184
|
if let Some(model) = dict.get_item("model")? {
|
|
178
185
|
overrides_struct.model = Some(model.extract()?);
|
|
179
186
|
}
|
|
@@ -222,17 +229,124 @@ fn build_config(
|
|
|
222
229
|
if let Some(v) = dict.get_item("tools_web_search_request")? {
|
|
223
230
|
overrides_struct.tools_web_search_request = Some(v.extract()?);
|
|
224
231
|
}
|
|
232
|
+
|
|
233
|
+
// Keys handled as strongly-typed above should not be duplicated in CLI overrides.
|
|
234
|
+
let typed_keys = [
|
|
235
|
+
"model",
|
|
236
|
+
"model_provider",
|
|
237
|
+
"config_profile",
|
|
238
|
+
"approval_policy",
|
|
239
|
+
"sandbox_mode",
|
|
240
|
+
"cwd",
|
|
241
|
+
"codex_linux_sandbox_exe",
|
|
242
|
+
"base_instructions",
|
|
243
|
+
"include_plan_tool",
|
|
244
|
+
"include_apply_patch_tool",
|
|
245
|
+
"include_view_image_tool",
|
|
246
|
+
"show_raw_agent_reasoning",
|
|
247
|
+
"tools_web_search_request",
|
|
248
|
+
];
|
|
249
|
+
|
|
250
|
+
// Collect remaining extras and turn them into CLI-style dotted overrides.
|
|
251
|
+
for (key_obj, value_obj) in dict.iter() {
|
|
252
|
+
let key: String = match key_obj.extract() {
|
|
253
|
+
Ok(s) => s,
|
|
254
|
+
Err(_) => continue,
|
|
255
|
+
};
|
|
256
|
+
if typed_keys.contains(&key.as_str()) {
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Convert Python value -> TomlValue
|
|
261
|
+
let tv = match py_to_toml_value(value_obj)? {
|
|
262
|
+
Some(v) => v,
|
|
263
|
+
None => continue, // skip None/null values
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
if key.contains('.') {
|
|
267
|
+
// Already a dotted path: use as-is.
|
|
268
|
+
cli_overrides.push((key, tv));
|
|
269
|
+
} else {
|
|
270
|
+
// Flatten nested tables; otherwise add directly.
|
|
271
|
+
flatten_overrides(&mut cli_overrides, &key, tv);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
225
274
|
}
|
|
226
275
|
|
|
227
276
|
if load_default_config {
|
|
228
|
-
Ok(Config::load_with_cli_overrides(
|
|
277
|
+
Ok(Config::load_with_cli_overrides(cli_overrides, overrides_struct)?)
|
|
229
278
|
} else {
|
|
230
279
|
let codex_home = find_codex_home()?;
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
280
|
+
let cfg = load_config_as_toml_with_cli_overrides(&codex_home, cli_overrides)?;
|
|
281
|
+
Ok(Config::load_from_base_config_with_overrides(cfg, overrides_struct, codex_home)?)
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/// Convert a Python object into a TOML value. Returns Ok(None) for `None`.
|
|
286
|
+
fn py_to_toml_value(obj: Bound<'_, PyAny>) -> Result<Option<TomlValue>> {
|
|
287
|
+
use pyo3::types::{PyBool, PyDict, PyFloat, PyInt, PyList, PyString};
|
|
288
|
+
|
|
289
|
+
if obj.is_none() {
|
|
290
|
+
return Ok(None);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if let Ok(b) = obj.downcast::<PyBool>() {
|
|
294
|
+
return Ok(Some(TomlValue::Boolean(b.is_true())));
|
|
295
|
+
}
|
|
296
|
+
if let Ok(i) = obj.downcast::<PyInt>() {
|
|
297
|
+
let v: i64 = i.extract()?;
|
|
298
|
+
return Ok(Some(TomlValue::Integer(v.into())));
|
|
299
|
+
}
|
|
300
|
+
if let Ok(f) = obj.downcast::<PyFloat>() {
|
|
301
|
+
let v: f64 = f.extract()?;
|
|
302
|
+
return Ok(Some(TomlValue::Float(v.into())));
|
|
303
|
+
}
|
|
304
|
+
if let Ok(s) = obj.downcast::<PyString>() {
|
|
305
|
+
let v: String = s.extract()?;
|
|
306
|
+
return Ok(Some(TomlValue::String(v.into())));
|
|
307
|
+
}
|
|
308
|
+
if let Ok(list) = obj.downcast::<PyList>() {
|
|
309
|
+
let mut arr = Vec::with_capacity(list.len());
|
|
310
|
+
for item in list.iter() {
|
|
311
|
+
if let Some(tv) = py_to_toml_value(item)? {
|
|
312
|
+
arr.push(tv);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return Ok(Some(TomlValue::Array(arr)));
|
|
316
|
+
}
|
|
317
|
+
if let Ok(map) = obj.downcast::<PyDict>() {
|
|
318
|
+
let mut tbl = TomlTable::new();
|
|
319
|
+
for (k_obj, v_obj) in map.iter() {
|
|
320
|
+
let key: String = match k_obj.extract() {
|
|
321
|
+
Ok(s) => s,
|
|
322
|
+
Err(_) => continue,
|
|
323
|
+
};
|
|
324
|
+
if let Some(tv) = py_to_toml_value(v_obj)? {
|
|
325
|
+
tbl.insert(key, tv);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return Ok(Some(TomlValue::Table(tbl)));
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Fallback: use `str(obj)`
|
|
332
|
+
let s = obj.str()?.to_string_lossy().to_string();
|
|
333
|
+
Ok(Some(TomlValue::String(s.into())))
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/// Recursively flatten a TOML value into dotted overrides.
|
|
337
|
+
fn flatten_overrides(out: &mut Vec<(String, TomlValue)>, prefix: &str, val: TomlValue) {
|
|
338
|
+
match val {
|
|
339
|
+
TomlValue::Table(tbl) => {
|
|
340
|
+
for (k, v) in tbl.into_iter() {
|
|
341
|
+
let key = if prefix.is_empty() {
|
|
342
|
+
k
|
|
343
|
+
} else {
|
|
344
|
+
format!("{prefix}.{k}")
|
|
345
|
+
};
|
|
346
|
+
flatten_overrides(out, &key, v);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
other => out.push((prefix.to_string(), other)),
|
|
236
350
|
}
|
|
237
351
|
}
|
|
238
352
|
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from enum import Enum
|
|
4
|
-
from typing import Any, cast
|
|
5
|
-
|
|
6
|
-
from pydantic import BaseModel, ConfigDict, Field
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class ApprovalPolicy(str, Enum):
|
|
10
|
-
"""Approval policy for executing shell commands.
|
|
11
|
-
|
|
12
|
-
Matches Rust enum `AskForApproval` (serde kebab-case):
|
|
13
|
-
- "untrusted": auto-approve safe read-only commands, ask otherwise
|
|
14
|
-
- "on-failure": sandbox by default; ask only if the sandboxed run fails
|
|
15
|
-
- "on-request": model decides (default)
|
|
16
|
-
- "never": never ask the user
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
UNTRUSTED = "untrusted"
|
|
20
|
-
ON_FAILURE = "on-failure"
|
|
21
|
-
ON_REQUEST = "on-request"
|
|
22
|
-
NEVER = "never"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class SandboxMode(str, Enum):
|
|
26
|
-
"""High-level sandbox mode override.
|
|
27
|
-
|
|
28
|
-
Matches Rust enum `SandboxMode` (serde kebab-case):
|
|
29
|
-
- "read-only"
|
|
30
|
-
- "workspace-write"
|
|
31
|
-
- "danger-full-access"
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
READ_ONLY = "read-only"
|
|
35
|
-
WORKSPACE_WRITE = "workspace-write"
|
|
36
|
-
DANGER_FULL_ACCESS = "danger-full-access"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
class CodexConfig(BaseModel):
|
|
40
|
-
"""Configuration overrides for Codex.
|
|
41
|
-
|
|
42
|
-
This mirrors `codex_core::config::ConfigOverrides` and is intentionally
|
|
43
|
-
conservative: only values present (not None) are passed to the native core.
|
|
44
|
-
"""
|
|
45
|
-
|
|
46
|
-
# Model selection
|
|
47
|
-
model: str | None = Field(default=None, description="Model slug, e.g. 'gpt-5' or 'o3'.")
|
|
48
|
-
model_provider: str | None = Field(
|
|
49
|
-
default=None, description="Provider key from config, e.g. 'openai'."
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
# Safety/Execution
|
|
53
|
-
approval_policy: ApprovalPolicy | None = Field(default=None)
|
|
54
|
-
sandbox_mode: SandboxMode | None = Field(default=None)
|
|
55
|
-
|
|
56
|
-
# Environment
|
|
57
|
-
cwd: str | None = Field(default=None, description="Working directory for the session.")
|
|
58
|
-
config_profile: str | None = Field(
|
|
59
|
-
default=None, description="Config profile key to use (from profiles.*)."
|
|
60
|
-
)
|
|
61
|
-
codex_linux_sandbox_exe: str | None = Field(
|
|
62
|
-
default=None, description="Absolute path to codex-linux-sandbox (Linux only)."
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
# UX / features
|
|
66
|
-
base_instructions: str | None = Field(default=None, description="Override base instructions.")
|
|
67
|
-
include_plan_tool: bool | None = Field(default=None)
|
|
68
|
-
include_apply_patch_tool: bool | None = Field(default=None)
|
|
69
|
-
include_view_image_tool: bool | None = Field(default=None)
|
|
70
|
-
show_raw_agent_reasoning: bool | None = Field(default=None)
|
|
71
|
-
tools_web_search_request: bool | None = Field(default=None)
|
|
72
|
-
|
|
73
|
-
def to_dict(self) -> dict[str, Any]:
|
|
74
|
-
"""Return overrides as a plain dict with None values removed.
|
|
75
|
-
|
|
76
|
-
Enum fields are emitted as their string values.
|
|
77
|
-
"""
|
|
78
|
-
return cast(dict[str, Any], self.model_dump(exclude_none=True))
|
|
79
|
-
|
|
80
|
-
# Pydantic v2 config. `use_enum_values=True` ensures enums dump as strings.
|
|
81
|
-
# Place at end of class, extra='allow' per style.
|
|
82
|
-
model_config = ConfigDict(extra="allow", validate_assignment=True, use_enum_values=True)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|