Add app-server v2 thread realtime API (#12715)

Add experimental `thread/realtime/*` v2 requests and notifications, then
route app-server realtime events through that thread-scoped surface with
integration coverage.

---------

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Ahmed Ibrahim
2026-02-25 09:59:10 -08:00
committed by GitHub
parent 0543d0a022
commit 947092283a
25 changed files with 1706 additions and 2 deletions

View File

@@ -10,6 +10,7 @@ use codex_app_server_protocol::JSONRPCMessage;
use codex_app_server_protocol::JSONRPCResponse;
use codex_app_server_protocol::MockExperimentalMethodParams;
use codex_app_server_protocol::RequestId;
use codex_app_server_protocol::ThreadRealtimeStartParams;
use codex_app_server_protocol::ThreadStartParams;
use codex_app_server_protocol::ThreadStartResponse;
use pretty_assertions::assert_eq;
@@ -50,6 +51,40 @@ async fn mock_experimental_method_requires_experimental_api_capability() -> Resu
Ok(())
}
#[tokio::test]
async fn realtime_conversation_start_requires_experimental_api_capability() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let init = mcp
.initialize_with_capabilities(
default_client_info(),
Some(InitializeCapabilities {
experimental_api: false,
opt_out_notification_methods: None,
}),
)
.await?;
let JSONRPCMessage::Response(_) = init else {
anyhow::bail!("expected initialize response, got {init:?}");
};
let request_id = mcp
.send_thread_realtime_start_request(ThreadRealtimeStartParams {
thread_id: "thr_123".to_string(),
prompt: "hello".to_string(),
session_id: None,
})
.await?;
let error = timeout(
DEFAULT_TIMEOUT,
mcp.read_stream_until_error_message(RequestId::Integer(request_id)),
)
.await??;
assert_experimental_capability_error(error, "thread/realtime/start");
Ok(())
}
#[tokio::test]
async fn thread_start_mock_field_requires_experimental_api_capability() -> Result<()> {
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;