From 13035561cd5fa33078354afc95a3184eed68c7fe Mon Sep 17 00:00:00 2001 From: Javi <666807+JaviSoto@users.noreply.github.com> Date: Tue, 14 Oct 2025 11:55:10 -0700 Subject: [PATCH] feat: pass codex thread ID in notifier metadata (#4582) --- codex-rs/core/src/codex.rs | 1 + codex-rs/core/src/user_notification.rs | 4 +++- docs/config.md | 7 ++++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/codex-rs/core/src/codex.rs b/codex-rs/core/src/codex.rs index 495af42c..88f42c0f 100644 --- a/codex-rs/core/src/codex.rs +++ b/codex-rs/core/src/codex.rs @@ -1858,6 +1858,7 @@ pub(crate) async fn run_task( ); sess.notifier() .notify(&UserNotification::AgentTurnComplete { + thread_id: sess.conversation_id.to_string(), turn_id: sub_id.clone(), input_messages: turn_input_messages, last_assistant_message: last_agent_message.clone(), diff --git a/codex-rs/core/src/user_notification.rs b/codex-rs/core/src/user_notification.rs index 5eb9e980..be96d562 100644 --- a/codex-rs/core/src/user_notification.rs +++ b/codex-rs/core/src/user_notification.rs @@ -49,6 +49,7 @@ impl UserNotifier { pub(crate) enum UserNotification { #[serde(rename_all = "kebab-case")] AgentTurnComplete { + thread_id: String, turn_id: String, /// Messages that the user sent to the agent to initiate the turn. @@ -67,6 +68,7 @@ mod tests { #[test] fn test_user_notification() -> Result<()> { let notification = UserNotification::AgentTurnComplete { + thread_id: "b5f6c1c2-1111-2222-3333-444455556666".to_string(), turn_id: "12345".to_string(), input_messages: vec!["Rename `foo` to `bar` and update the callsites.".to_string()], last_assistant_message: Some( @@ -76,7 +78,7 @@ mod tests { let serialized = serde_json::to_string(¬ification)?; assert_eq!( serialized, - r#"{"type":"agent-turn-complete","turn-id":"12345","input-messages":["Rename `foo` to `bar` and update the callsites."],"last-assistant-message":"Rename complete and verified `cargo build` succeeds."}"# + r#"{"type":"agent-turn-complete","thread-id":"b5f6c1c2-1111-2222-3333-444455556666","turn-id":"12345","input-messages":["Rename `foo` to `bar` and update the callsites."],"last-assistant-message":"Rename complete and verified `cargo build` succeeds."}"# ); Ok(()) } diff --git a/docs/config.md b/docs/config.md index 2ac7aba6..c1d305f3 100644 --- a/docs/config.md +++ b/docs/config.md @@ -602,6 +602,7 @@ Specify a program that will be executed to get notified about events generated b ```json { "type": "agent-turn-complete", + "thread-id": "b5f6c1c2-1111-2222-3333-444455556666", "turn-id": "12345", "input-messages": ["Rename `foo` to `bar` and update the callsites."], "last-assistant-message": "Rename complete and verified `cargo build` succeeds." @@ -610,6 +611,8 @@ Specify a program that will be executed to get notified about events generated b The `"type"` property will always be set. Currently, `"agent-turn-complete"` is the only notification type that is supported. +`"thread-id"` contains a string that identifies the Codex session that produced the notification; you can use it to correlate multiple turns that belong to the same task. + As an example, here is a Python script that parses the JSON and decides whether to show a desktop push notification using [terminal-notifier](https://github.com/julienXX/terminal-notifier) on macOS: ```python @@ -644,6 +647,8 @@ def main() -> int: print(f"not sending a push notification for: {notification_type}") return 0 + thread_id = notification.get("thread-id", "") + subprocess.check_output( [ "terminal-notifier", @@ -652,7 +657,7 @@ def main() -> int: "-message", message, "-group", - "codex", + "codex-" + thread_id, "-ignoreDnD", "-activate", "com.googlecode.iterm2",