We continue the separation between `codex app-server` and `codex mcp-server`. In particular, we introduce a new crate, `codex-app-server-protocol`, and migrate `codex-rs/protocol/src/mcp_protocol.rs` into it, renaming it `codex-rs/app-server-protocol/src/protocol.rs`. Because `ConversationId` was defined in `mcp_protocol.rs`, we move it into its own file, `codex-rs/protocol/src/conversation_id.rs`, and because it is referenced in a ton of places, we have to touch a lot of files as part of this PR. We also decide to get away from proper JSON-RPC 2.0 semantics, so we also introduce `codex-rs/app-server-protocol/src/jsonrpc_lite.rs`, which is basically the same `JSONRPCMessage` type defined in `mcp-types` except with all of the `"jsonrpc": "2.0"` removed. Getting rid of `"jsonrpc": "2.0"` makes our serialization logic considerably simpler, as we can lean heavier on serde to serialize directly into the wire format that we use now.
69 lines
1.4 KiB
Rust
69 lines
1.4 KiB
Rust
use std::fmt::Display;
|
|
|
|
use serde::Deserialize;
|
|
use serde::Serialize;
|
|
use ts_rs::TS;
|
|
use uuid::Uuid;
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, TS, Hash)]
|
|
#[ts(type = "string")]
|
|
pub struct ConversationId {
|
|
uuid: Uuid,
|
|
}
|
|
|
|
impl ConversationId {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
uuid: Uuid::now_v7(),
|
|
}
|
|
}
|
|
|
|
pub fn from_string(s: &str) -> Result<Self, uuid::Error> {
|
|
Ok(Self {
|
|
uuid: Uuid::parse_str(s)?,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl Default for ConversationId {
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
}
|
|
|
|
impl Display for ConversationId {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
write!(f, "{}", self.uuid)
|
|
}
|
|
}
|
|
|
|
impl Serialize for ConversationId {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: serde::Serializer,
|
|
{
|
|
serializer.collect_str(&self.uuid)
|
|
}
|
|
}
|
|
|
|
impl<'de> Deserialize<'de> for ConversationId {
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
where
|
|
D: serde::Deserializer<'de>,
|
|
{
|
|
let value = String::deserialize(deserializer)?;
|
|
let uuid = Uuid::parse_str(&value).map_err(serde::de::Error::custom)?;
|
|
Ok(Self { uuid })
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
#[test]
|
|
fn test_conversation_id_default_is_not_zeroes() {
|
|
let id = ConversationId::default();
|
|
assert_ne!(id.uuid, Uuid::nil());
|
|
}
|
|
}
|