mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
74dcce594d
## Why Exec-server JSON-RPC calls can cross local and remote transports, but trace context stopped at the RPC boundary. That made client and server work difficult to correlate when diagnosing latency or failures. ## What changed - Propagate the current W3C trace context on outbound JSON-RPC requests. - Parent inbound request spans from received trace context. - Record the received JSON-RPC method on server spans and keep each span open through response enqueue. - Add only the OTEL dependencies required by the exec-server crate. ## Stack Review and land this stack in order: 1. #27466 — trace exec-server JSON-RPC requests **(this PR)** 2. #27467 — record bounded connection, request, and process lifecycle metrics 3. #27470 — observe remote registration and Noise rendezvous lifecycle ## Validation - `just test -p codex-exec-server --lib` (153 passed) - `just bazel-lock-check` - `just fix -p codex-exec-server`
82 lines
2.3 KiB
Rust
82 lines
2.3 KiB
Rust
//! JSON-RPC wire envelopes used by exec-server.
|
|
//!
|
|
//! Exec-server uses the Codex JSON-RPC dialect, which omits the
|
|
//! `"jsonrpc": "2.0"` field on the wire.
|
|
|
|
use std::fmt;
|
|
|
|
use codex_protocol::protocol::W3cTraceContext;
|
|
use serde::Deserialize;
|
|
use serde::Serialize;
|
|
|
|
pub const JSONRPC_VERSION: &str = "2.0";
|
|
|
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Ord, Deserialize, Serialize, Hash, Eq)]
|
|
#[serde(untagged)]
|
|
pub enum RequestId {
|
|
String(String),
|
|
Integer(i64),
|
|
}
|
|
|
|
impl fmt::Display for RequestId {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match self {
|
|
Self::String(value) => f.write_str(value),
|
|
Self::Integer(value) => write!(f, "{value}"),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub type Result = serde_json::Value;
|
|
|
|
/// Any valid exec-server JSON-RPC object that can be decoded from or encoded onto the wire.
|
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
|
#[serde(untagged)]
|
|
pub enum JSONRPCMessage {
|
|
Request(JSONRPCRequest),
|
|
Notification(JSONRPCNotification),
|
|
Response(JSONRPCResponse),
|
|
Error(JSONRPCError),
|
|
}
|
|
|
|
/// A request that expects a response.
|
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
|
pub struct JSONRPCRequest {
|
|
pub id: RequestId,
|
|
pub method: String,
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub params: Option<serde_json::Value>,
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub trace: Option<W3cTraceContext>,
|
|
}
|
|
|
|
/// A notification that does not expect a response.
|
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
|
pub struct JSONRPCNotification {
|
|
pub method: String,
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub params: Option<serde_json::Value>,
|
|
}
|
|
|
|
/// A successful response to a request.
|
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
|
pub struct JSONRPCResponse {
|
|
pub id: RequestId,
|
|
pub result: Result,
|
|
}
|
|
|
|
/// A response indicating that a request failed.
|
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
|
pub struct JSONRPCError {
|
|
pub error: JSONRPCErrorError,
|
|
pub id: RequestId,
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
|
pub struct JSONRPCErrorError {
|
|
pub code: i64,
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub data: Option<serde_json::Value>,
|
|
pub message: String,
|
|
}
|