Skip to main content

core_api/node/
mod.rs

1use serde::{Deserialize, Serialize};
2
3pub mod contracts;
4pub mod settings;
5pub mod status;
6
7pub const V1: &str = "v1";
8pub const STATUS_CONTRACT: &str = "mhome.node.status.v1";
9pub const PROTOCOL_V1_MANIFEST: &str = include_str!("../../contract/node-runtime-protocol-v1.json");
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
12#[serde(rename_all = "camelCase", deny_unknown_fields)]
13pub struct RuntimeRequest<T> {
14    pub version: String,
15    pub payload: T,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
19#[serde(rename_all = "camelCase")]
20pub struct RuntimeResponse<T> {
21    pub version: String,
22    pub data: T,
23}
24
25pub fn require_version(actual: &str, expected: &str) -> Result<(), UnsupportedVersion> {
26    if actual == expected {
27        Ok(())
28    } else {
29        Err(UnsupportedVersion {
30            actual: actual.to_string(),
31            expected: expected.to_string(),
32        })
33    }
34}
35
36#[derive(Debug, Clone, PartialEq, Eq)]
37pub struct UnsupportedVersion {
38    actual: String,
39    expected: String,
40}
41
42impl std::fmt::Display for UnsupportedVersion {
43    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44        write!(
45            formatter,
46            "UNSUPPORTED_NODE_PROTOCOL_VERSION: requested version {}, supported version {}",
47            self.actual, self.expected
48        )
49    }
50}
51
52impl std::error::Error for UnsupportedVersion {}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn manifest_matches_internal_targets() {
60        let manifest: serde_json::Value = serde_json::from_str(PROTOCOL_V1_MANIFEST).unwrap();
61        assert_eq!(manifest["version"], V1);
62        assert_eq!(manifest["status"]["contract"], STATUS_CONTRACT);
63        assert_eq!(manifest["status"]["queryTarget"], status::STATUS_TARGET);
64        assert_eq!(
65            manifest["status"]["changedTarget"],
66            status::STATUS_CHANGED_TARGET
67        );
68        assert_eq!(
69            manifest["settings"]["changedTarget"],
70            settings::CHANGED_TARGET
71        );
72        assert_eq!(
73            manifest["llm"]["completeTarget"],
74            crate::llm::COMPLETE_TARGET
75        );
76        assert_eq!(
77            manifest["llm"]["ttsSynthesizeTarget"],
78            contracts::llm::TTS_SYNTHESIZE_TARGET
79        );
80    }
81}