mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Async config loading (#18022)
Parts of config will come from executor. Prepare for that by making config loading methods async.
This commit is contained in:
@@ -107,8 +107,8 @@ fn discoverable_connector(id: &str, name: &str, description: &str) -> Discoverab
|
||||
}))
|
||||
}
|
||||
|
||||
fn search_capable_model_info() -> ModelInfo {
|
||||
let config = test_config();
|
||||
async fn search_capable_model_info() -> ModelInfo {
|
||||
let config = test_config().await;
|
||||
let mut model_info = construct_model_info_offline("gpt-5-codex", &config);
|
||||
model_info.supports_search_tool = true;
|
||||
model_info
|
||||
@@ -216,8 +216,8 @@ fn find_namespace_function_tool<'a>(
|
||||
.unwrap_or_else(|| panic!("expected tool {expected_namespace}{expected_name} in namespace"))
|
||||
}
|
||||
|
||||
fn multi_agent_v2_tools_config() -> ToolsConfig {
|
||||
let config = test_config();
|
||||
async fn multi_agent_v2_tools_config() -> ToolsConfig {
|
||||
let config = test_config().await;
|
||||
let model_info = construct_model_info_offline("gpt-5-codex", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::Collab);
|
||||
@@ -250,8 +250,8 @@ fn multi_agent_v2_spawn_agent_description(tools_config: &ToolsConfig) -> String
|
||||
description.clone()
|
||||
}
|
||||
|
||||
fn model_info_from_models_json(slug: &str) -> ModelInfo {
|
||||
let config = test_config();
|
||||
async fn model_info_from_models_json(slug: &str) -> ModelInfo {
|
||||
let config = test_config().await;
|
||||
let response = bundled_models_response()
|
||||
.unwrap_or_else(|err| panic!("bundled models.json should parse: {err}"));
|
||||
let model = response
|
||||
@@ -295,9 +295,9 @@ fn build_specs_with_unavailable_tools(
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn model_provided_unified_exec_is_blocked_for_windows_sandboxed_policies() {
|
||||
let mut model_info = model_info_from_models_json("gpt-5-codex");
|
||||
#[tokio::test]
|
||||
async fn model_provided_unified_exec_is_blocked_for_windows_sandboxed_policies() {
|
||||
let mut model_info = model_info_from_models_json("gpt-5-codex").await;
|
||||
model_info.shell_type = ConfigShellToolType::UnifiedExec;
|
||||
let features = Features::with_defaults();
|
||||
let available_models = Vec::new();
|
||||
@@ -320,9 +320,9 @@ fn model_provided_unified_exec_is_blocked_for_windows_sandboxed_policies() {
|
||||
assert_eq!(config.shell_type, expected_shell_type);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_memory_requires_feature_flag() {
|
||||
let config = test_config();
|
||||
#[tokio::test]
|
||||
async fn get_memory_requires_feature_flag() {
|
||||
let config = test_config().await;
|
||||
let model_info = construct_model_info_offline("gpt-5-codex", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.disable(Feature::MemoryTool);
|
||||
@@ -350,14 +350,14 @@ fn get_memory_requires_feature_flag() {
|
||||
);
|
||||
}
|
||||
|
||||
fn assert_model_tools(
|
||||
async fn assert_model_tools(
|
||||
model_slug: &str,
|
||||
features: &Features,
|
||||
web_search_mode: Option<WebSearchMode>,
|
||||
expected_tools: &[&str],
|
||||
) {
|
||||
let _config = test_config();
|
||||
let model_info = model_info_from_models_json(model_slug);
|
||||
let _config = test_config().await;
|
||||
let model_info = model_info_from_models_json(model_slug).await;
|
||||
let available_models = Vec::new();
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
model_info: &model_info,
|
||||
@@ -388,7 +388,7 @@ fn assert_model_tools(
|
||||
assert_eq!(&tool_names, &expected_tools,);
|
||||
}
|
||||
|
||||
fn assert_default_model_tools(
|
||||
async fn assert_default_model_tools(
|
||||
model_slug: &str,
|
||||
features: &Features,
|
||||
web_search_mode: Option<WebSearchMode>,
|
||||
@@ -401,11 +401,11 @@ fn assert_default_model_tools(
|
||||
vec![shell_tool]
|
||||
};
|
||||
expected.extend(expected_tail);
|
||||
assert_model_tools(model_slug, features, web_search_mode, &expected);
|
||||
assert_model_tools(model_slug, features, web_search_mode, &expected).await;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_specs_gpt5_codex_default() {
|
||||
#[tokio::test]
|
||||
async fn test_build_specs_gpt5_codex_default() {
|
||||
let features = Features::with_defaults();
|
||||
assert_default_model_tools(
|
||||
"gpt-5-codex",
|
||||
@@ -424,11 +424,12 @@ fn test_build_specs_gpt5_codex_default() {
|
||||
"wait_agent",
|
||||
"close_agent",
|
||||
],
|
||||
);
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_specs_gpt51_codex_default() {
|
||||
#[tokio::test]
|
||||
async fn test_build_specs_gpt51_codex_default() {
|
||||
let features = Features::with_defaults();
|
||||
assert_default_model_tools(
|
||||
"gpt-5.1-codex",
|
||||
@@ -447,11 +448,12 @@ fn test_build_specs_gpt51_codex_default() {
|
||||
"wait_agent",
|
||||
"close_agent",
|
||||
],
|
||||
);
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_specs_gpt5_codex_unified_exec_web_search() {
|
||||
#[tokio::test]
|
||||
async fn test_build_specs_gpt5_codex_unified_exec_web_search() {
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
assert_model_tools(
|
||||
@@ -472,11 +474,12 @@ fn test_build_specs_gpt5_codex_unified_exec_web_search() {
|
||||
"wait_agent",
|
||||
"close_agent",
|
||||
],
|
||||
);
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_specs_gpt51_codex_unified_exec_web_search() {
|
||||
#[tokio::test]
|
||||
async fn test_build_specs_gpt51_codex_unified_exec_web_search() {
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
assert_model_tools(
|
||||
@@ -497,11 +500,12 @@ fn test_build_specs_gpt51_codex_unified_exec_web_search() {
|
||||
"wait_agent",
|
||||
"close_agent",
|
||||
],
|
||||
);
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gpt_5_1_codex_max_defaults() {
|
||||
#[tokio::test]
|
||||
async fn test_gpt_5_1_codex_max_defaults() {
|
||||
let features = Features::with_defaults();
|
||||
assert_default_model_tools(
|
||||
"gpt-5.1-codex-max",
|
||||
@@ -520,11 +524,12 @@ fn test_gpt_5_1_codex_max_defaults() {
|
||||
"wait_agent",
|
||||
"close_agent",
|
||||
],
|
||||
);
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_codex_5_1_mini_defaults() {
|
||||
#[tokio::test]
|
||||
async fn test_codex_5_1_mini_defaults() {
|
||||
let features = Features::with_defaults();
|
||||
assert_default_model_tools(
|
||||
"gpt-5.1-codex-mini",
|
||||
@@ -543,11 +548,12 @@ fn test_codex_5_1_mini_defaults() {
|
||||
"wait_agent",
|
||||
"close_agent",
|
||||
],
|
||||
);
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gpt_5_defaults() {
|
||||
#[tokio::test]
|
||||
async fn test_gpt_5_defaults() {
|
||||
let features = Features::with_defaults();
|
||||
assert_default_model_tools(
|
||||
"gpt-5",
|
||||
@@ -565,11 +571,12 @@ fn test_gpt_5_defaults() {
|
||||
"wait_agent",
|
||||
"close_agent",
|
||||
],
|
||||
);
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gpt_5_1_defaults() {
|
||||
#[tokio::test]
|
||||
async fn test_gpt_5_1_defaults() {
|
||||
let features = Features::with_defaults();
|
||||
assert_default_model_tools(
|
||||
"gpt-5.1",
|
||||
@@ -588,11 +595,12 @@ fn test_gpt_5_1_defaults() {
|
||||
"wait_agent",
|
||||
"close_agent",
|
||||
],
|
||||
);
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gpt_5_1_codex_max_unified_exec_web_search() {
|
||||
#[tokio::test]
|
||||
async fn test_gpt_5_1_codex_max_unified_exec_web_search() {
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
assert_model_tools(
|
||||
@@ -613,12 +621,13 @@ fn test_gpt_5_1_codex_max_unified_exec_web_search() {
|
||||
"wait_agent",
|
||||
"close_agent",
|
||||
],
|
||||
);
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_specs_default_shell_present() {
|
||||
let config = test_config();
|
||||
#[tokio::test]
|
||||
async fn test_build_specs_default_shell_present() {
|
||||
let config = test_config().await;
|
||||
let model_info = construct_model_info_offline("o3", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
@@ -649,9 +658,9 @@ fn test_build_specs_default_shell_present() {
|
||||
assert_contains_tool_names(&tools, &subset);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shell_zsh_fork_prefers_shell_command_over_unified_exec() {
|
||||
let config = test_config();
|
||||
#[tokio::test]
|
||||
async fn shell_zsh_fork_prefers_shell_command_over_unified_exec() {
|
||||
let config = test_config().await;
|
||||
let model_info = construct_model_info_offline("o3", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
@@ -713,9 +722,10 @@ fn shell_zsh_fork_prefers_shell_command_over_unified_exec() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spawn_agent_description_omits_usage_hint_when_disabled() {
|
||||
#[tokio::test]
|
||||
async fn spawn_agent_description_omits_usage_hint_when_disabled() {
|
||||
let tools_config = multi_agent_v2_tools_config()
|
||||
.await
|
||||
.with_spawn_agent_usage_hint(/*spawn_agent_usage_hint*/ false);
|
||||
let description = multi_agent_v2_spawn_agent_description(&tools_config);
|
||||
|
||||
@@ -734,11 +744,13 @@ fn spawn_agent_description_omits_usage_hint_when_disabled() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spawn_agent_description_uses_configured_usage_hint_text() {
|
||||
let tools_config = multi_agent_v2_tools_config().with_spawn_agent_usage_hint_text(Some(
|
||||
/*spawn_agent_usage_hint_text*/ "Custom delegation guidance only.".to_string(),
|
||||
));
|
||||
#[tokio::test]
|
||||
async fn spawn_agent_description_uses_configured_usage_hint_text() {
|
||||
let tools_config = multi_agent_v2_tools_config()
|
||||
.await
|
||||
.with_spawn_agent_usage_hint_text(Some(
|
||||
/*spawn_agent_usage_hint_text*/ "Custom delegation guidance only.".to_string(),
|
||||
));
|
||||
let description = multi_agent_v2_spawn_agent_description(&tools_config);
|
||||
|
||||
assert_regex_match(
|
||||
@@ -757,9 +769,9 @@ fn spawn_agent_description_uses_configured_usage_hint_text() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tool_suggest_requires_apps_and_plugins_features() {
|
||||
let model_info = search_capable_model_info();
|
||||
#[tokio::test]
|
||||
async fn tool_suggest_requires_apps_and_plugins_features() {
|
||||
let model_info = search_capable_model_info().await;
|
||||
let discoverable_tools = Some(vec![discoverable_connector(
|
||||
"connector_2128aebfecb84f64a069897515042a44",
|
||||
"Google Calendar",
|
||||
@@ -804,9 +816,9 @@ fn tool_suggest_requires_apps_and_plugins_features() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn search_tool_description_handles_no_enabled_mcp_tools() {
|
||||
let model_info = search_capable_model_info();
|
||||
#[tokio::test]
|
||||
async fn search_tool_description_handles_no_enabled_mcp_tools() {
|
||||
let model_info = search_capable_model_info().await;
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::Apps);
|
||||
features.enable(Feature::ToolSearch);
|
||||
@@ -838,9 +850,9 @@ fn search_tool_description_handles_no_enabled_mcp_tools() {
|
||||
assert!(!description.contains("{{source_descriptions}}"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn search_tool_description_falls_back_to_connector_name_without_description() {
|
||||
let model_info = search_capable_model_info();
|
||||
#[tokio::test]
|
||||
async fn search_tool_description_falls_back_to_connector_name_without_description() {
|
||||
let model_info = search_capable_model_info().await;
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::Apps);
|
||||
features.enable(Feature::ToolSearch);
|
||||
@@ -889,9 +901,9 @@ fn search_tool_description_falls_back_to_connector_name_without_description() {
|
||||
assert!(!description.contains("- Calendar:"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn search_tool_registers_namespaced_mcp_tool_aliases() {
|
||||
let model_info = search_capable_model_info();
|
||||
#[tokio::test]
|
||||
async fn search_tool_registers_namespaced_mcp_tool_aliases() {
|
||||
let model_info = search_capable_model_info().await;
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::Apps);
|
||||
features.enable(Feature::ToolSearch);
|
||||
@@ -974,9 +986,9 @@ fn search_tool_registers_namespaced_mcp_tool_aliases() {
|
||||
assert!(registry.has_handler(&mcp_alias));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn direct_mcp_tools_register_namespaced_handlers() {
|
||||
let config = test_config();
|
||||
#[tokio::test]
|
||||
async fn direct_mcp_tools_register_namespaced_handlers() {
|
||||
let config = test_config().await;
|
||||
let model_info = construct_model_info_offline("gpt-5-codex", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
@@ -1011,9 +1023,9 @@ fn direct_mcp_tools_register_namespaced_handlers() {
|
||||
assert!(!registry.has_handler(&ToolName::plain("mcp__test_server__echo")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unavailable_mcp_tools_are_exposed_as_dummy_function_tools() {
|
||||
let config = test_config();
|
||||
#[tokio::test]
|
||||
async fn unavailable_mcp_tools_are_exposed_as_dummy_function_tools() {
|
||||
let config = test_config().await;
|
||||
let model_info = construct_model_info_offline("gpt-5-codex", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
@@ -1060,9 +1072,9 @@ fn unavailable_mcp_tools_are_exposed_as_dummy_function_tools() {
|
||||
assert!(!registry.has_handler(&ToolName::plain("mcp__codex_apps__calendar_create_event")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mcp_tool_property_missing_type_defaults_to_string() {
|
||||
let config = test_config();
|
||||
#[tokio::test]
|
||||
async fn test_mcp_tool_property_missing_type_defaults_to_string() {
|
||||
let config = test_config().await;
|
||||
let model_info = construct_model_info_offline("gpt-5-codex", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
@@ -1123,9 +1135,9 @@ fn test_mcp_tool_property_missing_type_defaults_to_string() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mcp_tool_preserves_integer_schema() {
|
||||
let config = test_config();
|
||||
#[tokio::test]
|
||||
async fn test_mcp_tool_preserves_integer_schema() {
|
||||
let config = test_config().await;
|
||||
let model_info = construct_model_info_offline("gpt-5-codex", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
@@ -1184,9 +1196,9 @@ fn test_mcp_tool_preserves_integer_schema() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mcp_tool_array_without_items_gets_default_string_items() {
|
||||
let config = test_config();
|
||||
#[tokio::test]
|
||||
async fn test_mcp_tool_array_without_items_gets_default_string_items() {
|
||||
let config = test_config().await;
|
||||
let model_info = construct_model_info_offline("gpt-5-codex", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
@@ -1249,9 +1261,9 @@ fn test_mcp_tool_array_without_items_gets_default_string_items() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mcp_tool_anyof_defaults_to_string() {
|
||||
let config = test_config();
|
||||
#[tokio::test]
|
||||
async fn test_mcp_tool_anyof_defaults_to_string() {
|
||||
let config = test_config().await;
|
||||
let model_info = construct_model_info_offline("gpt-5-codex", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
@@ -1318,9 +1330,9 @@ fn test_mcp_tool_anyof_defaults_to_string() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_openai_tools_mcp_tools_with_additional_properties_schema() {
|
||||
let config = test_config();
|
||||
#[tokio::test]
|
||||
async fn test_get_openai_tools_mcp_tools_with_additional_properties_schema() {
|
||||
let config = test_config().await;
|
||||
let model_info = construct_model_info_offline("gpt-5-codex", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
@@ -1433,8 +1445,8 @@ fn test_get_openai_tools_mcp_tools_with_additional_properties_schema() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn code_mode_only_restricts_model_tools_to_exec_tools() {
|
||||
#[tokio::test]
|
||||
async fn code_mode_only_restricts_model_tools_to_exec_tools() {
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::CodeMode);
|
||||
features.enable(Feature::CodeModeOnly);
|
||||
@@ -1444,5 +1456,6 @@ fn code_mode_only_restricts_model_tools_to_exec_tools() {
|
||||
&features,
|
||||
Some(WebSearchMode::Live),
|
||||
&["exec", "wait"],
|
||||
);
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user