This commit is contained in:
Roy Han
2026-03-31 15:07:23 -07:00
1807 changed files with 41233 additions and 163241 deletions
+1 -1
View File
@@ -2690,7 +2690,7 @@ export type Config = { stableField: Keep, unstableField: string | null } & ({ [k
fn generate_json_filters_experimental_fields_and_methods() -> Result<()> {
let output_dir = std::env::temp_dir().join(format!("codex_schema_{}", Uuid::now_v7()));
fs::create_dir(&output_dir)?;
generate_json_with_experimental(&output_dir, false)?;
generate_json_with_experimental(&output_dir, /*experimental_api*/ false)?;
let thread_start_json =
fs::read_to_string(output_dir.join("v2").join("ThreadStartParams.json"))?;
@@ -1435,16 +1435,35 @@ mod tests {
Ok(())
}
#[test]
fn serialize_account_login_chatgpt_device_code() -> Result<()> {
let request = ClientRequest::LoginAccount {
request_id: RequestId::Integer(4),
params: v2::LoginAccountParams::ChatgptDeviceCode,
};
assert_eq!(
json!({
"method": "account/login/start",
"id": 4,
"params": {
"type": "chatgptDeviceCode"
}
}),
serde_json::to_value(&request)?,
);
Ok(())
}
#[test]
fn serialize_account_logout() -> Result<()> {
let request = ClientRequest::LogoutAccount {
request_id: RequestId::Integer(4),
request_id: RequestId::Integer(5),
params: None,
};
assert_eq!(
json!({
"method": "account/logout",
"id": 4,
"id": 5,
}),
serde_json::to_value(&request)?,
);
@@ -1454,7 +1473,7 @@ mod tests {
#[test]
fn serialize_account_login_chatgpt_auth_tokens() -> Result<()> {
let request = ClientRequest::LoginAccount {
request_id: RequestId::Integer(5),
request_id: RequestId::Integer(6),
params: v2::LoginAccountParams::ChatgptAuthTokens {
access_token: "access-token".to_string(),
chatgpt_account_id: "org-123".to_string(),
@@ -1464,7 +1483,7 @@ mod tests {
assert_eq!(
json!({
"method": "account/login/start",
"id": 5,
"id": 6,
"params": {
"type": "chatgptAuthTokens",
"accessToken": "access-token",
@@ -866,12 +866,38 @@ pub struct NetworkRequirements {
pub allow_upstream_proxy: Option<bool>,
pub dangerously_allow_non_loopback_proxy: Option<bool>,
pub dangerously_allow_all_unix_sockets: Option<bool>,
/// Canonical network permission map for `experimental_network`.
pub domains: Option<BTreeMap<String, NetworkDomainPermission>>,
/// When true, only managed allowlist entries are respected while managed
/// network enforcement is active.
pub managed_allowed_domains_only: Option<bool>,
/// Legacy compatibility view derived from `domains`.
pub allowed_domains: Option<Vec<String>>,
/// Legacy compatibility view derived from `domains`.
pub denied_domains: Option<Vec<String>>,
/// Canonical unix socket permission map for `experimental_network`.
pub unix_sockets: Option<BTreeMap<String, NetworkUnixSocketPermission>>,
/// Legacy compatibility view derived from `unix_sockets`.
pub allow_unix_sockets: Option<Vec<String>>,
pub allow_local_binding: Option<bool>,
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "lowercase")]
#[ts(export_to = "v2/")]
pub enum NetworkDomainPermission {
Allow,
Deny,
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "lowercase")]
#[ts(export_to = "v2/")]
pub enum NetworkUnixSocketPermission {
Allow,
None,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
@@ -1563,6 +1589,9 @@ pub enum LoginAccountParams {
#[serde(rename = "chatgpt")]
#[ts(rename = "chatgpt")]
Chatgpt,
#[serde(rename = "chatgptDeviceCode")]
#[ts(rename = "chatgptDeviceCode")]
ChatgptDeviceCode,
/// [UNSTABLE] FOR OPENAI INTERNAL USE ONLY - DO NOT USE.
/// The access token must contain the same scopes that Codex-managed ChatGPT auth tokens have.
#[experimental("account/login/start.chatgptAuthTokens")]
@@ -1600,6 +1629,17 @@ pub enum LoginAccountResponse {
/// URL the client should open in a browser to initiate the OAuth flow.
auth_url: String,
},
#[serde(rename = "chatgptDeviceCode", rename_all = "camelCase")]
#[ts(rename = "chatgptDeviceCode", rename_all = "camelCase")]
ChatgptDeviceCode {
// Use plain String for identifiers to avoid TS/JSON Schema quirks around uuid-specific types.
// Convert to/from UUIDs at the application layer as needed.
login_id: String,
/// URL the client should open in a browser to complete device code authorization.
verification_url: String,
/// One-time code the user must enter after signing in.
user_code: String,
},
#[serde(rename = "chatgptAuthTokens", rename_all = "camelCase")]
#[ts(rename = "chatgptAuthTokens", rename_all = "camelCase")]
ChatgptAuthTokens {},
@@ -7496,6 +7536,94 @@ mod tests {
);
}
#[test]
fn network_requirements_deserializes_legacy_fields() {
let requirements: NetworkRequirements = serde_json::from_value(json!({
"allowedDomains": ["api.openai.com"],
"deniedDomains": ["blocked.example.com"],
"allowUnixSockets": ["/tmp/proxy.sock"]
}))
.expect("legacy network requirements should deserialize");
assert_eq!(
requirements,
NetworkRequirements {
enabled: None,
http_port: None,
socks_port: None,
allow_upstream_proxy: None,
dangerously_allow_non_loopback_proxy: None,
dangerously_allow_all_unix_sockets: None,
domains: None,
managed_allowed_domains_only: None,
allowed_domains: Some(vec!["api.openai.com".to_string()]),
denied_domains: Some(vec!["blocked.example.com".to_string()]),
unix_sockets: None,
allow_unix_sockets: Some(vec!["/tmp/proxy.sock".to_string()]),
allow_local_binding: None,
}
);
}
#[test]
fn network_requirements_serializes_canonical_and_legacy_fields() {
let requirements = NetworkRequirements {
enabled: Some(true),
http_port: Some(8080),
socks_port: Some(1080),
allow_upstream_proxy: Some(false),
dangerously_allow_non_loopback_proxy: Some(false),
dangerously_allow_all_unix_sockets: Some(true),
domains: Some(BTreeMap::from([
("api.openai.com".to_string(), NetworkDomainPermission::Allow),
(
"blocked.example.com".to_string(),
NetworkDomainPermission::Deny,
),
])),
managed_allowed_domains_only: Some(true),
allowed_domains: Some(vec!["api.openai.com".to_string()]),
denied_domains: Some(vec!["blocked.example.com".to_string()]),
unix_sockets: Some(BTreeMap::from([
(
"/tmp/proxy.sock".to_string(),
NetworkUnixSocketPermission::Allow,
),
(
"/tmp/ignored.sock".to_string(),
NetworkUnixSocketPermission::None,
),
])),
allow_unix_sockets: Some(vec!["/tmp/proxy.sock".to_string()]),
allow_local_binding: Some(true),
};
assert_eq!(
serde_json::to_value(requirements).expect("network requirements should serialize"),
json!({
"enabled": true,
"httpPort": 8080,
"socksPort": 1080,
"allowUpstreamProxy": false,
"dangerouslyAllowNonLoopbackProxy": false,
"dangerouslyAllowAllUnixSockets": true,
"domains": {
"api.openai.com": "allow",
"blocked.example.com": "deny"
},
"managedAllowedDomainsOnly": true,
"allowedDomains": ["api.openai.com"],
"deniedDomains": ["blocked.example.com"],
"unixSockets": {
"/tmp/ignored.sock": "none",
"/tmp/proxy.sock": "allow"
},
"allowUnixSockets": ["/tmp/proxy.sock"],
"allowLocalBinding": true
})
);
}
#[test]
fn core_turn_item_into_thread_item_converts_supported_variants() {
let user_item = TurnItem::UserMessage(UserMessageItem {