Centralize app enabled-state evaluation (#36916)

## What changed

- Add `AppToolPolicyEvaluator::apply_app_enabled_state` and use it when
  presenting app lists, building plugin context, and deciding whether app
  instructions are available.
- Preserve each app's source state unless local or managed configuration
  explicitly overrides it.
- Keep connector discovery and post-install refresh checks based on raw
  accessibility rather than configured enablement.

## Testing

- Cover default enablement, per-app overrides, managed disablement, and
  preservation of unconfigured source state.

GitOrigin-RevId: f1a62d55e7cc48b37113848e3baa0d69d8d9c8a8
This commit is contained in:
jif authored and copyberry committed 2026-08-04 15:49:49 +00:00
1 parent 2999b8e831
commit c8e255e7f8
9 files changed
+123 -136

No files matched your search

+4 -17
View File
@@ -71,6 +71,7 @@ use codex_analytics::InvocationType;
use codex_analytics::TurnResolvedConfigFact;
use codex_analytics::build_track_events_context;
use codex_async_utils::OrCancelExt;
use codex_connectors::AppToolPolicyEvaluator;
use codex_core_plugins::RecommendedPluginCandidatesInput;
use codex_core_skills::injection::InjectedHostSkillPrompts;
use codex_extension_api::ExtensionData;
@@ -754,7 +755,8 @@ async fn build_skills_and_plugins(
.map(|connector_id| connector_id.0.clone()),
connectors::accessible_connectors_from_mcp_tools(mcp_tools),
);
connectors::with_app_enabled_state(connectors, &turn_context.config)
AppToolPolicyEvaluator::new(&turn_context.config.config_layer_stack)
.apply_app_enabled_state(connectors)
} else {
Vec::new()
};
@@ -1476,21 +1478,6 @@ pub(crate) async fn built_tools(
let apps_enabled = turn_context.apps_enabled();
let accessible_connectors =
apps_enabled.then(|| connectors::accessible_connectors_from_mcp_tools(all_mcp_tools));
let connectors = if apps_enabled {
let connectors = codex_connectors::merge::merge_plugin_connectors_with_accessible(
connector_snapshot
.connector_ids()
.iter()
.map(|connector_id| connector_id.0.clone()),
accessible_connectors.clone().unwrap_or_default(),
);
Some(connectors::with_app_enabled_state(
connectors,
&turn_context.config,
))
} else {
None
};
let tool_suggest_is_enabled = tool_suggest_enabled(turn_context);
let PreparedToolRecommendations {
auth,
@@ -1510,7 +1497,7 @@ pub(crate) async fn built_tools(
.collect::<Vec<_>>();
async {
if apps_enabled && tool_suggest_is_enabled {
if let Some(accessible_connectors) = connectors.as_ref() {
if let Some(accessible_connectors) = accessible_connectors.as_ref() {
match connectors::list_tool_suggest_discoverable_tools_with_auth(
&turn_context.config,
sess.services.plugins_manager.as_ref(),