mirror of
https://github.com/openai/codex.git
synced 2026-10-18 17:18:52 +00:00
Add tool namespace metadata configuration (#37389)
## What changed - Add `features.tool_registry.include_tool_namespaces_info` to the TOML model, generated schema, and resolved runtime configuration. The setting defaults to `false` and controls whether per-turn request metadata includes the resolved tool namespace inventory. - Preserve the resolved setting in session configuration locks. - Cover top-level and profile-scoped strict configuration, deserialization, resolution, and lock-file persistence. GitOrigin-RevId: 74124086c0d7de30094b411001f0ec0af490935d
This commit is contained in:
@@ -95,6 +95,8 @@ fn strict_config_accepts_tool_registry_config() {
|
||||
for contents in [
|
||||
"[features.tool_registry]\nerror_on_tool_collisions = true\n",
|
||||
"[profiles.work.features.tool_registry]\nerror_on_tool_collisions = true\n",
|
||||
"[features.tool_registry]\ninclude_tool_namespaces_info = true\n",
|
||||
"[profiles.work.features.tool_registry]\ninclude_tool_namespaces_info = true\n",
|
||||
] {
|
||||
assert_eq!(
|
||||
config_error_from_ignored_toml_fields::<ConfigToml>(path, contents),
|
||||
|
||||
@@ -3218,6 +3218,10 @@
|
||||
"error_on_tool_collisions": {
|
||||
"description": "Fail the turn when multiple tools share the same effective name.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"include_tool_namespaces_info": {
|
||||
"description": "Include the resolved tool namespace inventory in per-turn request metadata.",
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
|
||||
@@ -574,11 +574,17 @@ disable_in_process_fallback = true
|
||||
async fn load_config_resolves_tool_registry_config() -> std::io::Result<()> {
|
||||
let codex_home = tempdir()?;
|
||||
|
||||
for (config_toml, error_on_tool_collisions) in [
|
||||
("", false),
|
||||
for (config_toml, error_on_tool_collisions, include_tool_namespaces_info) in [
|
||||
("", false, false),
|
||||
(
|
||||
"[features.tool_registry]\nerror_on_tool_collisions = true\n",
|
||||
true,
|
||||
false,
|
||||
),
|
||||
(
|
||||
"[features.tool_registry]\ninclude_tool_namespaces_info = true\n",
|
||||
false,
|
||||
true,
|
||||
),
|
||||
] {
|
||||
let config_toml: ConfigToml =
|
||||
@@ -594,6 +600,10 @@ async fn load_config_resolves_tool_registry_config() -> std::io::Result<()> {
|
||||
config.tool_registry.error_on_tool_collisions,
|
||||
error_on_tool_collisions
|
||||
);
|
||||
assert_eq!(
|
||||
config.tool_registry.include_tool_namespaces_info,
|
||||
include_tool_namespaces_info
|
||||
);
|
||||
assert!(!config.features.enabled(Feature::CodeMode));
|
||||
}
|
||||
|
||||
|
||||
@@ -1115,6 +1115,8 @@ pub struct Config {
|
||||
pub struct ToolRegistryConfig {
|
||||
/// Fail the turn when multiple tools share the same effective name.
|
||||
pub error_on_tool_collisions: bool,
|
||||
/// Include the resolved tool namespace inventory in per-turn request metadata.
|
||||
pub include_tool_namespaces_info: bool,
|
||||
}
|
||||
|
||||
const DEFAULT_CODE_MODE_EXEC_YIELD_TIME_MS: u64 = 30_000;
|
||||
@@ -3717,6 +3719,12 @@ impl Config {
|
||||
.and_then(|features| features.tool_registry.as_ref())
|
||||
.and_then(|config| config.error_on_tool_collisions)
|
||||
.unwrap_or_default(),
|
||||
include_tool_namespaces_info: cfg
|
||||
.features
|
||||
.as_ref()
|
||||
.and_then(|features| features.tool_registry.as_ref())
|
||||
.and_then(|config| config.include_tool_namespaces_info)
|
||||
.unwrap_or_default(),
|
||||
};
|
||||
let code_mode = resolve_code_mode_config(&cfg);
|
||||
let multi_agent_v2 = resolve_multi_agent_v2_config(&cfg);
|
||||
|
||||
@@ -154,9 +154,13 @@ fn save_config_resolved_fields(
|
||||
.features
|
||||
.get_or_insert_with(FeaturesToml::default);
|
||||
features.materialize_resolved_enabled(config.features.get());
|
||||
if config.tool_registry.error_on_tool_collisions || features.tool_registry.is_some() {
|
||||
if config.tool_registry.error_on_tool_collisions
|
||||
|| config.tool_registry.include_tool_namespaces_info
|
||||
|| features.tool_registry.is_some()
|
||||
{
|
||||
features.tool_registry = Some(ToolRegistryConfigToml {
|
||||
error_on_tool_collisions: Some(config.tool_registry.error_on_tool_collisions),
|
||||
include_tool_namespaces_info: Some(config.tool_registry.include_tool_namespaces_info),
|
||||
});
|
||||
}
|
||||
let mut multi_agent_v2: MultiAgentV2ConfigToml =
|
||||
@@ -269,6 +273,7 @@ mod tests {
|
||||
let mut sc = crate::session::tests::make_session_configuration_for_tests().await;
|
||||
let mut config = (*sc.original_config_do_not_use).clone();
|
||||
config.tool_registry.error_on_tool_collisions = true;
|
||||
config.tool_registry.include_tool_namespaces_info = true;
|
||||
config.multi_agent_v2.subagent_developer_instructions =
|
||||
Some("Locked subagent developer instructions.".to_string());
|
||||
config.token_budget = Some(crate::config::TokenBudgetConfig {
|
||||
@@ -329,6 +334,7 @@ mod tests {
|
||||
features.tool_registry,
|
||||
Some(ToolRegistryConfigToml {
|
||||
error_on_tool_collisions: Some(true),
|
||||
include_tool_namespaces_info: Some(true),
|
||||
})
|
||||
);
|
||||
let feature_entries = features.entries();
|
||||
|
||||
@@ -10,6 +10,9 @@ pub struct ToolRegistryConfigToml {
|
||||
/// Fail the turn when multiple tools share the same effective name.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub error_on_tool_collisions: Option<bool>,
|
||||
/// Include the resolved tool namespace inventory in per-turn request metadata.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub include_tool_namespaces_info: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq, JsonSchema)]
|
||||
|
||||
@@ -29,14 +29,16 @@ fn under_development_features_are_disabled_by_default() {
|
||||
|
||||
#[test]
|
||||
fn tool_registry_config_is_not_a_feature_toggle() {
|
||||
let features: FeaturesToml =
|
||||
toml::from_str("[tool_registry]\nerror_on_tool_collisions = true\n")
|
||||
.expect("tool registry settings should deserialize");
|
||||
let features: FeaturesToml = toml::from_str(
|
||||
"[tool_registry]\nerror_on_tool_collisions = true\ninclude_tool_namespaces_info = true\n",
|
||||
)
|
||||
.expect("tool registry settings should deserialize");
|
||||
|
||||
assert_eq!(
|
||||
features.tool_registry,
|
||||
Some(crate::ToolRegistryConfigToml {
|
||||
error_on_tool_collisions: Some(true),
|
||||
include_tool_namespaces_info: Some(true),
|
||||
})
|
||||
);
|
||||
assert!(features.entries().is_empty());
|
||||
@@ -552,6 +554,7 @@ fn materialize_resolved_enabled_writes_all_features_and_preserves_custom_config(
|
||||
let mut features_toml = FeaturesToml {
|
||||
tool_registry: Some(crate::ToolRegistryConfigToml {
|
||||
error_on_tool_collisions: Some(true),
|
||||
include_tool_namespaces_info: Some(true),
|
||||
}),
|
||||
code_mode_host: Some(FeatureToml::Config(crate::CodeModeHostConfigToml {
|
||||
enabled: Some(false),
|
||||
@@ -584,6 +587,7 @@ fn materialize_resolved_enabled_writes_all_features_and_preserves_custom_config(
|
||||
features_toml.tool_registry,
|
||||
Some(crate::ToolRegistryConfigToml {
|
||||
error_on_tool_collisions: Some(true),
|
||||
include_tool_namespaces_info: Some(true),
|
||||
})
|
||||
);
|
||||
let entries = features_toml.entries();
|
||||
|
||||
Reference in New Issue
Block a user