clawdentity_core/runtime/
openclaw.rs1use 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 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
37pub 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}