Skip to main content

clawdentity_core/runtime/
openclaw.rs

1use crate::error::{CoreError, Result};
2use crate::http::client;
3
4#[derive(Debug, Clone)]
5pub struct OpenclawRuntimeConfig {
6    pub base_url: String,
7    pub hook_path: String,
8    pub hook_token: Option<String>,
9}
10
11impl OpenclawRuntimeConfig {
12    /// TODO(clawdentity): document `hook_url`.
13    pub fn hook_url(&self) -> Result<String> {
14        let base = self.base_url.trim();
15        if base.is_empty() {
16            return Err(CoreError::InvalidInput(
17                "openclaw base_url is required".to_string(),
18            ));
19        }
20        let path = if self.hook_path.trim().is_empty() {
21            "/v1/hooks/relay"
22        } else {
23            self.hook_path.trim()
24        };
25        let base_url = url::Url::parse(base).map_err(|_| CoreError::InvalidUrl {
26            context: "openclawBaseUrl",
27            value: base.to_string(),
28        })?;
29        let joined = base_url.join(path).map_err(|_| CoreError::InvalidUrl {
30            context: "openclawHookPath",
31            value: path.to_string(),
32        })?;
33        Ok(joined.to_string())
34    }
35}
36
37/// TODO(clawdentity): document `check_openclaw_gateway_health`.
38pub async fn check_openclaw_gateway_health(base_url: &str) -> Result<bool> {
39    let base = base_url.trim();
40    if base.is_empty() {
41        return Err(CoreError::InvalidInput(
42            "openclaw base url is required".to_string(),
43        ));
44    }
45    let health_url = url::Url::parse(base)
46        .map_err(|_| CoreError::InvalidUrl {
47            context: "openclawBaseUrl",
48            value: base.to_string(),
49        })?
50        .join("/health")
51        .map_err(|_| CoreError::InvalidUrl {
52            context: "openclawBaseUrl",
53            value: base.to_string(),
54        })?;
55    let response = client()?
56        .get(health_url)
57        .send()
58        .await
59        .map_err(|error| CoreError::Http(error.to_string()))?;
60    Ok(response.status().is_success())
61}
62
63#[cfg(test)]
64mod tests {
65    use super::OpenclawRuntimeConfig;
66
67    #[test]
68    fn builds_hook_url_from_base_and_path() {
69        let config = OpenclawRuntimeConfig {
70            base_url: "http://127.0.0.1:11434".to_string(),
71            hook_path: "/v1/hooks/relay".to_string(),
72            hook_token: None,
73        };
74        let url = config.hook_url().expect("hook url");
75        assert_eq!(url, "http://127.0.0.1:11434/v1/hooks/relay");
76    }
77}