mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
[1/4] Add executor HTTP request protocol (#18581)
### Why Remote streamable HTTP MCP needs a transport-shaped executor primitive before the MCP client can move network I/O to the executor. This layer keeps the executor unaware of MCP and gives later PRs an ordered streaming surface for response bodies. ### What - Add typed `http/request` and `http/request/bodyDelta` protocol payloads. - Add executor client helpers for buffered and streamed HTTP responses. - Route body-delta notifications to request-scoped streams with sequence validation and cleanup when a stream finishes or is dropped. - Document the new protocol constants, transport structs, public client methods, body-stream lifecycle, and request-scoped routing helpers. - Add in-memory JSON-RPC client coverage for streamed HTTP response-body notifications, with comments spelling out what the test proves and each setup/exercise/assert phase. ### Stack 1. #18581 protocol 2. #18582 runner 3. #18583 RMCP client 4. #18584 manager wiring and local/remote coverage ### Verification - `just fmt` - `cargo check -p codex-exec-server -p codex-rmcp-client --tests` - `cargo check -p codex-core --test all` compile-only - `git diff --check` - Online full CI is running from the `full-ci` branch, including the remote Rust test job. Co-authored-by: Codex <noreply@openai.com> --------- Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
cefcfe43b9
commit
d6af7a6c03
@@ -26,6 +26,10 @@ pub const FS_GET_METADATA_METHOD: &str = "fs/getMetadata";
|
||||
pub const FS_READ_DIRECTORY_METHOD: &str = "fs/readDirectory";
|
||||
pub const FS_REMOVE_METHOD: &str = "fs/remove";
|
||||
pub const FS_COPY_METHOD: &str = "fs/copy";
|
||||
/// JSON-RPC request method for executor-side HTTP requests.
|
||||
pub const HTTP_REQUEST_METHOD: &str = "http/request";
|
||||
/// JSON-RPC notification method for streamed executor HTTP response bodies.
|
||||
pub const HTTP_REQUEST_BODY_DELTA_METHOD: &str = "http/request/bodyDelta";
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
@@ -254,6 +258,83 @@ pub struct FsCopyParams {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct FsCopyResponse {}
|
||||
|
||||
/// HTTP header represented in the executor protocol.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct HttpHeader {
|
||||
/// Header name as it appears on the HTTP wire.
|
||||
pub name: String,
|
||||
/// Header value after UTF-8 conversion.
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
/// Executor-side HTTP request envelope.
|
||||
///
|
||||
/// This intentionally stays transport-shaped rather than MCP-shaped so callers
|
||||
/// can use it for Streamable HTTP, OAuth discovery, and future executor-owned
|
||||
/// HTTP probes without introducing one protocol method per higher-level use.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct HttpRequestParams {
|
||||
/// HTTP method, for example `GET`, `POST`, or `DELETE`.
|
||||
pub method: String,
|
||||
/// Absolute `http://` or `https://` URL.
|
||||
pub url: String,
|
||||
/// Ordered request headers. Repeated header names are preserved.
|
||||
#[serde(default)]
|
||||
pub headers: Vec<HttpHeader>,
|
||||
/// Optional request body bytes.
|
||||
#[serde(default, rename = "bodyBase64")]
|
||||
pub body: Option<ByteChunk>,
|
||||
/// Optional request timeout in milliseconds.
|
||||
#[serde(default)]
|
||||
pub timeout_ms: Option<u64>,
|
||||
/// Caller-chosen stream id for `http/request/bodyDelta` notifications.
|
||||
///
|
||||
/// The id must remain unique on a connection until the terminal body delta
|
||||
/// arrives, even if the caller stops reading the stream earlier.
|
||||
#[serde(default)]
|
||||
pub request_id: Option<String>,
|
||||
/// Return after response headers and stream the response body as deltas.
|
||||
#[serde(default)]
|
||||
pub stream_response: bool,
|
||||
}
|
||||
|
||||
/// HTTP response envelope returned from an executor `http/request` call.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct HttpRequestResponse {
|
||||
/// Numeric HTTP response status code.
|
||||
pub status: u16,
|
||||
/// Ordered response headers. Repeated header names are preserved.
|
||||
pub headers: Vec<HttpHeader>,
|
||||
/// Buffered response body bytes. Empty when `streamResponse` is true.
|
||||
#[serde(rename = "bodyBase64")]
|
||||
pub body: ByteChunk,
|
||||
}
|
||||
|
||||
/// Ordered response-body frame for `streamResponse` HTTP requests.
|
||||
///
|
||||
/// Headers are returned in the `http/request` response so the caller can choose
|
||||
/// a parser immediately; body bytes then arrive on this notification stream.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct HttpRequestBodyDeltaNotification {
|
||||
/// Request id from the streamed `http/request` call.
|
||||
pub request_id: String,
|
||||
/// Monotonic one-based body frame sequence number.
|
||||
pub seq: u64,
|
||||
/// Response-body bytes carried by this frame.
|
||||
#[serde(rename = "deltaBase64")]
|
||||
pub delta: ByteChunk,
|
||||
/// Marks response-body EOF. No later deltas are expected for this request.
|
||||
#[serde(default)]
|
||||
pub done: bool,
|
||||
/// Terminal stream error. Set only on the final notification.
|
||||
#[serde(default)]
|
||||
pub error: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum ExecOutputStream {
|
||||
|
||||
Reference in New Issue
Block a user