Add realtime output modality and transcript events (#17701)

- Add outputModality to thread/realtime/start and wire text/audio output
selection through app-server, core, API, and TUI.\n- Rename the realtime
transcript delta notification and add a separate transcript done
notification that forwards final text from item done without correlating
it with deltas.
This commit is contained in:
Ahmed Ibrahim
2026-04-14 00:13:13 -07:00
committed by GitHub
Unverified
parent a6b03a22cc
commit 2f6fc7c137
38 changed files with 711 additions and 77 deletions
@@ -83,7 +83,8 @@ use codex_app_server_protocol::ThreadRealtimeItemAddedNotification;
use codex_app_server_protocol::ThreadRealtimeOutputAudioDeltaNotification;
use codex_app_server_protocol::ThreadRealtimeSdpNotification;
use codex_app_server_protocol::ThreadRealtimeStartedNotification;
use codex_app_server_protocol::ThreadRealtimeTranscriptUpdatedNotification;
use codex_app_server_protocol::ThreadRealtimeTranscriptDeltaNotification;
use codex_app_server_protocol::ThreadRealtimeTranscriptDoneNotification;
use codex_app_server_protocol::ThreadRollbackResponse;
use codex_app_server_protocol::ThreadTokenUsage;
use codex_app_server_protocol::ThreadTokenUsageUpdatedNotification;
@@ -408,26 +409,50 @@ pub(crate) async fn apply_bespoke_event_handling(
.await;
}
RealtimeEvent::InputTranscriptDelta(event) => {
let notification = ThreadRealtimeTranscriptUpdatedNotification {
let notification = ThreadRealtimeTranscriptDeltaNotification {
thread_id: conversation_id.to_string(),
role: "user".to_string(),
text: event.delta,
delta: event.delta,
};
outgoing
.send_server_notification(
ServerNotification::ThreadRealtimeTranscriptUpdated(notification),
ServerNotification::ThreadRealtimeTranscriptDelta(notification),
)
.await;
}
RealtimeEvent::InputTranscriptDone(event) => {
let notification = ThreadRealtimeTranscriptDoneNotification {
thread_id: conversation_id.to_string(),
role: "user".to_string(),
text: event.text,
};
outgoing
.send_server_notification(
ServerNotification::ThreadRealtimeTranscriptDone(notification),
)
.await;
}
RealtimeEvent::OutputTranscriptDelta(event) => {
let notification = ThreadRealtimeTranscriptUpdatedNotification {
let notification = ThreadRealtimeTranscriptDeltaNotification {
thread_id: conversation_id.to_string(),
role: "assistant".to_string(),
text: event.delta,
delta: event.delta,
};
outgoing
.send_server_notification(
ServerNotification::ThreadRealtimeTranscriptUpdated(notification),
ServerNotification::ThreadRealtimeTranscriptDelta(notification),
)
.await;
}
RealtimeEvent::OutputTranscriptDone(event) => {
let notification = ThreadRealtimeTranscriptDoneNotification {
thread_id: conversation_id.to_string(),
role: "assistant".to_string(),
text: event.text,
};
outgoing
.send_server_notification(
ServerNotification::ThreadRealtimeTranscriptDone(notification),
)
.await;
}
@@ -7323,6 +7323,7 @@ impl CodexMessageProcessor {
&request_id,
thread.as_ref(),
Op::RealtimeConversationStart(ConversationStartParams {
output_modality: params.output_modality,
prompt: params.prompt,
session_id: params.session_id,
transport: params.transport.map(|transport| match transport {