mirror of
https://github.com/openai/codex.git
synced 2026-11-03 08:22:30 +00:00
deprecate legacy notify (#20524)
# Why `notify` is the remaining compatibility surface from the legacy hook implementation. The newer lifecycle hook engine now owns the active hook system, so we should start steering users away from adding new `notify` configs before removing the old path entirely. This also adds a lightweight watchpoint for the deprecation so we can see how much legacy usage remains before the clean drop. # What - emit a startup deprecation notice when a non-empty `notify` command is configured - emit `codex.notify.configured` when a session starts with legacy `notify` configured - emit `codex.notify.run` when the legacy notify path fires after a completed turn - mark `notify` as deprecated in the config schema and repo docs - remove the orphaned `codex-rs/hooks/src/user_notification.rs` file that is no longer compiled - add regression coverage for the new deprecation notice # Next steps A follow-up PR can remove the legacy notify path entirely once we are ready for the clean drop. Before then, we can watch `codex.notify.configured` and `codex.notify.run` to understand the deprecation impact and remaining active usage. The cleanup PR should then delete the `notify` config field, the `legacy_notify` implementation, the old compatibility dispatch types and callsites that only exist for the legacy path, and the remaining compatibility docs/tests. # Testing - `cargo test -p codex-hooks` - `cargo test -p codex-config` - `cargo test -p codex-core emits_deprecation_notice_for_notify`
This commit is contained in:
1 parent
9b8d585075
commit
78baa20780
10 files changed
+72
-159
No files matched your search
@@ -479,7 +479,7 @@ pub struct Config {
|
||||
/// - `Some("...")`: use the provided attribution text verbatim
|
||||
pub commit_attribution: Option<String>,
|
||||
|
||||
/// Optional external notifier command. When set, Codex will spawn this
|
||||
/// Deprecated optional external notifier command. When set, Codex will spawn this
|
||||
/// program after each completed *turn* (i.e. when the agent finishes
|
||||
/// processing a user submission). The value must be the full command
|
||||
/// broken into argv tokens **without** the trailing JSON argument - Codex
|
||||
@@ -498,7 +498,7 @@ pub struct Config {
|
||||
/// notify-send Codex '{"type":"agent-turn-complete","turn-id":"12345"}'
|
||||
/// ```
|
||||
///
|
||||
/// If unset the feature is disabled.
|
||||
/// If unset the feature is disabled. Use lifecycle hooks for new automation.
|
||||
pub notify: Option<Vec<String>>,
|
||||
|
||||
/// TUI notification settings, including enabled events, delivery method, and focus condition.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use super::*;
|
||||
use crate::goals::GoalRuntimeState;
|
||||
use codex_otel::LEGACY_NOTIFY_CONFIGURED_METRIC;
|
||||
use codex_protocol::permissions::FileSystemPath;
|
||||
use codex_protocol::permissions::FileSystemSpecialPath;
|
||||
use tokio::sync::Semaphore;
|
||||
@@ -576,6 +577,24 @@ impl Session {
|
||||
}),
|
||||
});
|
||||
}
|
||||
let legacy_notify_configured = config
|
||||
.notify
|
||||
.as_ref()
|
||||
.is_some_and(|argv| !argv.is_empty() && !argv[0].is_empty());
|
||||
if legacy_notify_configured {
|
||||
post_session_configured_events.push(Event {
|
||||
id: INITIAL_SUBMIT_ID.to_owned(),
|
||||
msg: EventMsg::DeprecationNotice(DeprecationNoticeEvent {
|
||||
summary:
|
||||
"`notify` is deprecated and will be removed in a future release."
|
||||
.to_string(),
|
||||
details: Some(
|
||||
"Switch to a `Stop` hook for end-of-turn automation. See https://developers.openai.com/codex/hooks."
|
||||
.to_string(),
|
||||
),
|
||||
}),
|
||||
});
|
||||
}
|
||||
for message in &config.startup_warnings {
|
||||
post_session_configured_events.push(Event {
|
||||
id: "".to_owned(),
|
||||
@@ -633,6 +652,9 @@ impl Session {
|
||||
if let Some(service_name) = session_configuration.metrics_service_name.as_deref() {
|
||||
session_telemetry = session_telemetry.with_metrics_service_name(service_name);
|
||||
}
|
||||
if legacy_notify_configured {
|
||||
session_telemetry.counter(LEGACY_NOTIFY_CONFIGURED_METRIC, /*inc*/ 1, &[]);
|
||||
}
|
||||
let network_proxy_audit_metadata = NetworkProxyAuditMetadata {
|
||||
conversation_id: Some(conversation_id.to_string()),
|
||||
app_version: Some(env!("CARGO_PKG_VERSION").to_string()),
|
||||
|
||||
@@ -71,6 +71,7 @@ use codex_hooks::HookEvent;
|
||||
use codex_hooks::HookEventAfterAgent;
|
||||
use codex_hooks::HookPayload;
|
||||
use codex_hooks::HookResult;
|
||||
use codex_otel::LEGACY_NOTIFY_RUN_METRIC;
|
||||
use codex_protocol::config_types::ModeKind;
|
||||
use codex_protocol::error::CodexErr;
|
||||
use codex_protocol::error::Result as CodexResult;
|
||||
@@ -575,6 +576,13 @@ pub(crate) async fn run_turn(
|
||||
},
|
||||
})
|
||||
.await;
|
||||
if !hook_outcomes.is_empty() {
|
||||
turn_context.session_telemetry.counter(
|
||||
LEGACY_NOTIFY_RUN_METRIC,
|
||||
/*inc*/ 1,
|
||||
&[],
|
||||
);
|
||||
}
|
||||
|
||||
let mut abort_message = None;
|
||||
for hook_outcome in hook_outcomes {
|
||||
|
||||
Reference in new issue
Block a user