feat: Budget skill metadata and surface trimming as a warning (#18298)

Cap the model-visible skills section to a small share of the context
window, with a fallback character budget, and keep only as many implicit
skills as fit within that budget.

Emit a non-fatal warning when enabled skills are omitted, and add a new
app-server warning notification

Record thread-start skill metrics for total enabled skills, kept skills,
and whether truncation happened

---------

Co-authored-by: Matthew Zeng <mzeng@openai.com>
Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
xl-openai
2026-04-17 18:11:47 -07:00
committed by GitHub
co-authored by Matthew Zeng Codex
parent a58a0f083d
commit 3f7222ec76
26 changed files with 883 additions and 17 deletions
@@ -101,6 +101,7 @@ use codex_app_server_protocol::TurnPlanStep;
use codex_app_server_protocol::TurnPlanUpdatedNotification;
use codex_app_server_protocol::TurnStartedNotification;
use codex_app_server_protocol::TurnStatus;
use codex_app_server_protocol::WarningNotification;
use codex_app_server_protocol::build_command_execution_end_item;
use codex_app_server_protocol::build_file_change_approval_request_item;
use codex_app_server_protocol::build_file_change_begin_item;
@@ -268,7 +269,21 @@ pub(crate) async fn apply_bespoke_event_handling(
.await;
}
}
EventMsg::Warning(_warning_event) => {}
EventMsg::Warning(warning_event) => {
if let ApiVersion::V2 = api_version {
let notification = WarningNotification {
thread_id: Some(conversation_id.to_string()),
message: warning_event.message,
};
if let Some(analytics_events_client) = analytics_events_client.as_ref() {
analytics_events_client
.track_notification(ServerNotification::Warning(notification.clone()));
}
outgoing
.send_server_notification(ServerNotification::Warning(notification))
.await;
}
}
EventMsg::GuardianAssessment(assessment) => {
if let ApiVersion::V2 = api_version {
let pending_command_execution = match build_item_from_guardian_event(
@@ -4314,6 +4314,7 @@ impl CodexMessageProcessor {
thread_id,
thread: codex_thread,
session_configured,
..
}) => {
let SessionConfiguredEvent { rollout_path, .. } = session_configured;
let Some(rollout_path) = rollout_path else {