mirror of
https://github.com/openai/codex.git
synced 2026-04-25 15:15:15 +00:00
201 lines
7.2 KiB
Rust
201 lines
7.2 KiB
Rust
use super::*;
|
|
use codex_features::Feature;
|
|
use codex_features::Features;
|
|
use codex_protocol::config_types::WebSearchMode;
|
|
use codex_protocol::config_types::WindowsSandboxLevel;
|
|
use codex_protocol::openai_models::ConfigShellToolType;
|
|
use codex_protocol::openai_models::InputModality;
|
|
use codex_protocol::openai_models::ModelInfo;
|
|
use codex_protocol::protocol::SandboxPolicy;
|
|
use codex_protocol::protocol::SessionSource;
|
|
use codex_protocol::protocol::SubAgentSource;
|
|
use codex_utils_absolute_path::AbsolutePathBuf;
|
|
use pretty_assertions::assert_eq;
|
|
use serde_json::json;
|
|
use std::path::PathBuf;
|
|
|
|
fn model_info() -> ModelInfo {
|
|
serde_json::from_value(json!({
|
|
"slug": "test-model",
|
|
"display_name": "Test Model",
|
|
"description": null,
|
|
"supported_reasoning_levels": [],
|
|
"shell_type": "unified_exec",
|
|
"visibility": "list",
|
|
"supported_in_api": true,
|
|
"priority": 1,
|
|
"availability_nux": null,
|
|
"upgrade": null,
|
|
"base_instructions": "base",
|
|
"model_messages": null,
|
|
"supports_reasoning_summaries": false,
|
|
"default_reasoning_summary": "auto",
|
|
"support_verbosity": false,
|
|
"default_verbosity": null,
|
|
"apply_patch_tool_type": null,
|
|
"truncation_policy": {
|
|
"mode": "bytes",
|
|
"limit": 10000
|
|
},
|
|
"supports_parallel_tool_calls": false,
|
|
"supports_image_detail_original": false,
|
|
"context_window": null,
|
|
"auto_compact_token_limit": null,
|
|
"effective_context_window_percent": 95,
|
|
"experimental_supported_tools": [],
|
|
"input_modalities": ["text", "image"],
|
|
"supports_search_tool": false
|
|
}))
|
|
.expect("deserialize test model")
|
|
}
|
|
|
|
#[test]
|
|
fn unified_exec_is_blocked_for_windows_sandboxed_policies_only() {
|
|
assert!(!unified_exec_allowed_in_environment(
|
|
/*is_windows*/ true,
|
|
&SandboxPolicy::new_read_only_policy(),
|
|
WindowsSandboxLevel::RestrictedToken,
|
|
));
|
|
assert!(!unified_exec_allowed_in_environment(
|
|
/*is_windows*/ true,
|
|
&SandboxPolicy::new_workspace_write_policy(),
|
|
WindowsSandboxLevel::RestrictedToken,
|
|
));
|
|
assert!(unified_exec_allowed_in_environment(
|
|
/*is_windows*/ true,
|
|
&SandboxPolicy::DangerFullAccess,
|
|
WindowsSandboxLevel::RestrictedToken,
|
|
));
|
|
assert!(unified_exec_allowed_in_environment(
|
|
/*is_windows*/ true,
|
|
&SandboxPolicy::DangerFullAccess,
|
|
WindowsSandboxLevel::Disabled,
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn shell_zsh_fork_prefers_shell_command_over_unified_exec() {
|
|
let model_info = model_info();
|
|
let mut features = Features::with_defaults();
|
|
features.enable(Feature::UnifiedExec);
|
|
features.enable(Feature::ShellZshFork);
|
|
|
|
let available_models = Vec::new();
|
|
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
|
model_info: &model_info,
|
|
available_models: &available_models,
|
|
features: &features,
|
|
web_search_mode: Some(WebSearchMode::Live),
|
|
session_source: SessionSource::Cli,
|
|
sandbox_policy: &SandboxPolicy::DangerFullAccess,
|
|
windows_sandbox_level: WindowsSandboxLevel::Disabled,
|
|
});
|
|
|
|
assert_eq!(tools_config.shell_type, ConfigShellToolType::ShellCommand);
|
|
assert_eq!(
|
|
tools_config.shell_command_backend,
|
|
ShellCommandBackendConfig::ZshFork
|
|
);
|
|
assert_eq!(
|
|
tools_config.unified_exec_shell_mode,
|
|
UnifiedExecShellMode::Direct
|
|
);
|
|
assert_eq!(
|
|
tools_config
|
|
.with_unified_exec_shell_mode_for_session(
|
|
ToolUserShellType::Zsh,
|
|
Some(&PathBuf::from(if cfg!(windows) {
|
|
r"C:\opt\codex\zsh"
|
|
} else {
|
|
"/opt/codex/zsh"
|
|
})),
|
|
Some(&PathBuf::from(if cfg!(windows) {
|
|
r"C:\opt\codex\codex-execve-wrapper"
|
|
} else {
|
|
"/opt/codex/codex-execve-wrapper"
|
|
})),
|
|
)
|
|
.unified_exec_shell_mode,
|
|
if cfg!(unix) {
|
|
UnifiedExecShellMode::ZshFork(ZshForkConfig {
|
|
shell_zsh_path: AbsolutePathBuf::from_absolute_path("/opt/codex/zsh").unwrap(),
|
|
main_execve_wrapper_exe: AbsolutePathBuf::from_absolute_path(
|
|
"/opt/codex/codex-execve-wrapper",
|
|
)
|
|
.unwrap(),
|
|
})
|
|
} else {
|
|
UnifiedExecShellMode::Direct
|
|
}
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn subagents_keep_request_user_input_schema_and_agent_jobs_workers_opt_in_by_label() {
|
|
let model_info = model_info();
|
|
let mut features = Features::with_defaults();
|
|
features.enable(Feature::SpawnCsv);
|
|
|
|
let available_models = Vec::new();
|
|
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
|
model_info: &model_info,
|
|
available_models: &available_models,
|
|
features: &features,
|
|
web_search_mode: Some(WebSearchMode::Cached),
|
|
session_source: SessionSource::SubAgent(SubAgentSource::Other(
|
|
"agent_job:test".to_string(),
|
|
)),
|
|
sandbox_policy: &SandboxPolicy::DangerFullAccess,
|
|
windows_sandbox_level: WindowsSandboxLevel::Disabled,
|
|
});
|
|
|
|
assert!(tools_config.request_user_input);
|
|
assert!(!tools_config.default_mode_request_user_input);
|
|
assert!(tools_config.agent_jobs_tools);
|
|
assert!(tools_config.agent_jobs_worker_tools);
|
|
}
|
|
|
|
#[test]
|
|
fn image_generation_requires_feature_and_supported_model() {
|
|
let supported_model_info = model_info();
|
|
let mut unsupported_model_info = supported_model_info.clone();
|
|
unsupported_model_info.input_modalities = vec![InputModality::Text];
|
|
|
|
let default_features = Features::with_defaults();
|
|
let mut image_generation_features = default_features.clone();
|
|
image_generation_features.enable(Feature::ImageGeneration);
|
|
|
|
let available_models = Vec::new();
|
|
let default_tools_config = ToolsConfig::new(&ToolsConfigParams {
|
|
model_info: &supported_model_info,
|
|
available_models: &available_models,
|
|
features: &default_features,
|
|
web_search_mode: Some(WebSearchMode::Cached),
|
|
session_source: SessionSource::Cli,
|
|
sandbox_policy: &SandboxPolicy::DangerFullAccess,
|
|
windows_sandbox_level: WindowsSandboxLevel::Disabled,
|
|
});
|
|
let supported_tools_config = ToolsConfig::new(&ToolsConfigParams {
|
|
model_info: &supported_model_info,
|
|
available_models: &available_models,
|
|
features: &image_generation_features,
|
|
web_search_mode: Some(WebSearchMode::Cached),
|
|
session_source: SessionSource::Cli,
|
|
sandbox_policy: &SandboxPolicy::DangerFullAccess,
|
|
windows_sandbox_level: WindowsSandboxLevel::Disabled,
|
|
});
|
|
let unsupported_tools_config = ToolsConfig::new(&ToolsConfigParams {
|
|
model_info: &unsupported_model_info,
|
|
available_models: &available_models,
|
|
features: &image_generation_features,
|
|
web_search_mode: Some(WebSearchMode::Cached),
|
|
session_source: SessionSource::Cli,
|
|
sandbox_policy: &SandboxPolicy::DangerFullAccess,
|
|
windows_sandbox_level: WindowsSandboxLevel::Disabled,
|
|
});
|
|
|
|
assert!(!default_tools_config.image_gen_tool);
|
|
assert!(supported_tools_config.image_gen_tool);
|
|
assert!(!unsupported_tools_config.image_gen_tool);
|
|
}
|