mirror of
https://github.com/openai/codex.git
synced 2026-04-26 23:55:25 +00:00
Add realtime transcript notification in v2 (#15344)
- emit a typed `thread/realtime/transcriptUpdated` notification from live realtime transcript deltas - expose that notification as flat `threadId`, `role`, and `text` fields instead of a nested transcript array - continue forwarding raw `handoff_request` items on `thread/realtime/itemAdded`, including the accumulated `active_transcript` - update app-server docs, tests, and generated protocol schema artifacts to match the delta-based payloads --------- Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
@@ -21,6 +21,7 @@ use codex_app_server_protocol::ThreadRealtimeStartResponse;
|
||||
use codex_app_server_protocol::ThreadRealtimeStartedNotification;
|
||||
use codex_app_server_protocol::ThreadRealtimeStopParams;
|
||||
use codex_app_server_protocol::ThreadRealtimeStopResponse;
|
||||
use codex_app_server_protocol::ThreadRealtimeTranscriptUpdatedNotification;
|
||||
use codex_app_server_protocol::ThreadStartParams;
|
||||
use codex_app_server_protocol::ThreadStartResponse;
|
||||
use codex_features::FEATURES;
|
||||
@@ -66,6 +67,24 @@ async fn realtime_conversation_streams_v2_notifications() -> Result<()> {
|
||||
"content": [{ "type": "text", "text": "hi" }]
|
||||
}
|
||||
}),
|
||||
json!({
|
||||
"type": "conversation.item.input_audio_transcription.delta",
|
||||
"delta": "delegate now"
|
||||
}),
|
||||
json!({
|
||||
"type": "response.output_text.delta",
|
||||
"delta": "working"
|
||||
}),
|
||||
json!({
|
||||
"type": "conversation.item.done",
|
||||
"item": {
|
||||
"id": "item_2",
|
||||
"type": "function_call",
|
||||
"name": "codex",
|
||||
"call_id": "handoff_1",
|
||||
"arguments": "{\"input_transcript\":\"delegate now\"}"
|
||||
}
|
||||
}),
|
||||
json!({
|
||||
"type": "error",
|
||||
"message": "upstream boom"
|
||||
@@ -180,6 +199,40 @@ async fn realtime_conversation_streams_v2_notifications() -> Result<()> {
|
||||
assert_eq!(item_added.thread_id, output_audio.thread_id);
|
||||
assert_eq!(item_added.item["type"], json!("message"));
|
||||
|
||||
let first_transcript_update = read_notification::<ThreadRealtimeTranscriptUpdatedNotification>(
|
||||
&mut mcp,
|
||||
"thread/realtime/transcriptUpdated",
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(first_transcript_update.thread_id, output_audio.thread_id);
|
||||
assert_eq!(first_transcript_update.role, "user");
|
||||
assert_eq!(first_transcript_update.text, "delegate now");
|
||||
|
||||
let second_transcript_update =
|
||||
read_notification::<ThreadRealtimeTranscriptUpdatedNotification>(
|
||||
&mut mcp,
|
||||
"thread/realtime/transcriptUpdated",
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(second_transcript_update.thread_id, output_audio.thread_id);
|
||||
assert_eq!(second_transcript_update.role, "assistant");
|
||||
assert_eq!(second_transcript_update.text, "working");
|
||||
|
||||
let handoff_item_added = read_notification::<ThreadRealtimeItemAddedNotification>(
|
||||
&mut mcp,
|
||||
"thread/realtime/itemAdded",
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(handoff_item_added.thread_id, output_audio.thread_id);
|
||||
assert_eq!(handoff_item_added.item["type"], json!("handoff_request"));
|
||||
assert_eq!(handoff_item_added.item["handoff_id"], json!("handoff_1"));
|
||||
assert_eq!(handoff_item_added.item["item_id"], json!("item_2"));
|
||||
assert_eq!(
|
||||
handoff_item_added.item["input_transcript"],
|
||||
json!("delegate now")
|
||||
);
|
||||
assert_eq!(handoff_item_added.item["active_transcript"], json!([]));
|
||||
|
||||
let realtime_error =
|
||||
read_notification::<ThreadRealtimeErrorNotification>(&mut mcp, "thread/realtime/error")
|
||||
.await?;
|
||||
|
||||
Reference in New Issue
Block a user