diff --git a/src/main.el b/src/main.el index e094698..2ff0b7f 100644 --- a/src/main.el +++ b/src/main.el @@ -804,6 +804,37 @@ fn handle_request(method: String, path: String, body: String) -> String { return "{\"url\":\"" + proj_url + "\",\"anon_key\":\"" + anon_key + "\"}" } + // ── Soul health diagnostic — surfaces raw signal from in-container soul ── + if str_eq(path, "/api/soul-health") { + if str_eq(method, "GET") { + let soul_base: String = state_get("__soul_url__") + // Probe 1: bare GET / — does ANYTHING listen? + let probe_root: String = http_get(soul_base + "/") + let probe_root_len: Int = str_len(probe_root) + // Probe 2: /healthz if soul has one + let probe_health: String = http_get(soul_base + "/healthz") + let probe_health_len: Int = str_len(probe_health) + // Probe 3: empty POST to /dharma/recv — does that route exist? + let probe_dharma_empty: String = http_post(soul_base + "/dharma/recv", "") + let probe_dharma_empty_len: Int = str_len(probe_dharma_empty) + // Probe 4: minimal valid envelope to /dharma/recv + let probe_envelope: String = "{\"channel\":\"health-probe\",\"from\":\"web-tier\",\"content\":\"{}\"}" + let probe_dharma: String = http_post(soul_base + "/dharma/recv", probe_envelope) + let probe_dharma_len: Int = str_len(probe_dharma) + // Escape body content for embedding in JSON response + let root_safe: String = str_replace(str_replace(probe_root, "\\", "\\\\"), "\"", "\\\"") + let health_safe: String = str_replace(str_replace(probe_health, "\\", "\\\\"), "\"", "\\\"") + let de_safe: String = str_replace(str_replace(probe_dharma_empty, "\\", "\\\\"), "\"", "\\\"") + let dharma_safe: String = str_replace(str_replace(probe_dharma, "\\", "\\\\"), "\"", "\\\"") + // Truncate via str_slice(s, 0, N); str_slice clamps end to len + let root_trunc: String = str_slice(root_safe, 0, 200) + let health_trunc: String = str_slice(health_safe, 0, 200) + let de_trunc: String = str_slice(de_safe, 0, 200) + let dharma_trunc: String = str_slice(dharma_safe, 0, 400) + return "{\"soul_url\":\"" + soul_base + "\",\"probe_root\":{\"len\":" + int_to_str(probe_root_len) + ",\"body_first_200\":\"" + root_trunc + "\"},\"probe_healthz\":{\"len\":" + int_to_str(probe_health_len) + ",\"body_first_200\":\"" + health_trunc + "\"},\"probe_dharma_empty\":{\"len\":" + int_to_str(probe_dharma_empty_len) + ",\"body_first_200\":\"" + de_trunc + "\"},\"probe_dharma_envelope\":{\"len\":" + int_to_str(probe_dharma_len) + ",\"body_first_400\":\"" + dharma_trunc + "\"}}" + } + } + // ── Demo chat — proxies to the demo soul at 7772 ───────────────────────── if str_eq(path, "/api/demo") { if str_eq(method, "POST") {