import "../foundation/el/elp/src/elp.el" // elp-input.el — Convert free text → semantic frame for ELP input parsing. // // This is lightweight NLU: extracts predicate, arguments, and topic // from a user message without calling an LLM. Covers the common cases: // - "What is X?" → predicate=tell, arg=X // - "Tell me about X" → predicate=tell, arg=X // - "How do you feel about X?" → predicate=express, arg=X // - "Remember X" → predicate=store, arg=X // - "Who is X?" → predicate=identify, arg=X // - "Why X?" → predicate=explain, arg=X // - fallback → predicate=tell, arg=full message as topic fn elp_extract_topic(msg: String) -> String { // Strip common question prefixes to get the core topic let m1: String = if str_starts_with(msg, "What is ") { str_slice(msg, 8, str_len(msg)) } else { msg } let m2: String = if str_starts_with(m1, "What are ") { str_slice(m1, 9, str_len(m1)) } else { m1 } let m3: String = if str_starts_with(m2, "Tell me about ") { str_slice(m2, 14, str_len(m2)) } else { m2 } let m4: String = if str_starts_with(m3, "Who is ") { str_slice(m3, 7, str_len(m3)) } else { m3 } let m5: String = if str_starts_with(m4, "Who are ") { str_slice(m4, 8, str_len(m4)) } else { m4 } let m6: String = if str_starts_with(m5, "How do you ") { str_slice(m5, 11, str_len(m5)) } else { m5 } let m7: String = if str_starts_with(m6, "Why ") { str_slice(m6, 4, str_len(m6)) } else { m6 } let m8: String = if str_starts_with(m7, "Explain ") { str_slice(m7, 8, str_len(m7)) } else { m7 } // Strip trailing punctuation let last: Int = str_len(m8) - 1 let trail: String = str_slice(m8, last, str_len(m8)) let clean: String = if str_eq(trail, "?") || str_eq(trail, ".") || str_eq(trail, "!") { str_slice(m8, 0, last) } else { m8 } return clean } fn elp_detect_predicate(msg: String) -> String { if str_starts_with(msg, "What is ") || str_starts_with(msg, "What are ") || str_starts_with(msg, "Tell me about ") { return "tell" } if str_starts_with(msg, "Who is ") || str_starts_with(msg, "Who are ") { return "identify" } if str_starts_with(msg, "Why ") || str_starts_with(msg, "Explain ") { return "explain" } if str_starts_with(msg, "How do you feel") || str_starts_with(msg, "Do you ") { return "express" } if str_starts_with(msg, "Remember ") || str_starts_with(msg, "Store ") { return "store" } return "tell" } fn elp_parse(msg: String) -> String { let predicate: String = elp_detect_predicate(msg) let topic: String = elp_extract_topic(msg) let safe_topic: String = str_replace(topic, "\"", "'") return "{\"predicate\":\"" + predicate + "\",\"args\":[\"" + safe_topic + "\"],\"modifiers\":[],\"context\":{}}" } fn handle_elp_chat(body: String) -> String { let message: String = json_get(body, "message") if str_eq(message, "") { return "{\"error\":\"message required\",\"response\":\"\"}" } let frame: String = elp_parse(message) let predicate: String = elp_detect_predicate(message) let topic: String = elp_extract_topic(message) // ── Layer 1: Activate ──────────────────────────────────────────────────── // Graph walk from the extracted topic. Falls back to full message, then // to a shallow scan if both activation paths return empty. let from_topic: String = engram_activate_json(topic, 10) let topic_ok: Bool = !str_eq(from_topic, "") && !str_eq(from_topic, "[]") let candidates: String = if topic_ok { from_topic } else { let from_msg: String = engram_activate_json(message, 10) let msg_ok: Bool = !str_eq(from_msg, "") && !str_eq(from_msg, "[]") if msg_ok { from_msg } else { engram_scan_nodes_json(5, 0) } } // ── Layer 2: Suppress / Filter ─────────────────────────────────────────── // Walk the candidates keeping nodes that have non-zero salience or // importance. Always keep at least one (the top activation hit) even if // all metrics are zero. Cap at 3 nodes — enough for a coherent reply. let total: Int = json_array_len(candidates) let fi: Int = 0 let kept_count: Int = 0 let kept_json: String = "" while fi < total { let n: String = json_array_get(candidates, fi) let sal_str: String = json_get(n, "salience") let imp_str: String = json_get(n, "importance") let sal_ok: Bool = !str_eq(sal_str, "0") && !str_eq(sal_str, "0.0") && !str_eq(sal_str, "") let imp_ok: Bool = !str_eq(imp_str, "0") && !str_eq(imp_str, "0.0") && !str_eq(imp_str, "") let keep_it: Bool = sal_ok || imp_ok || kept_count == 0 if keep_it && kept_count < 3 { let sep: String = if str_eq(kept_json, "") { "" } else { "," } let kept_json = kept_json + sep + n let kept_count = kept_count + 1 } let fi = fi + 1 } let frame_nodes: String = if str_eq(kept_json, "") { "[]" } else { "[" + kept_json + "]" } // ── Reason ─────────────────────────────────────────────────────────────── // Walk frame_nodes to find the first node whose content contains the topic. // This prevents the always-high-salience CGI architecture node from // dominating every response regardless of what was asked. let fn_total: Int = json_array_len(frame_nodes) let fn_i: Int = 0 let topic_lower: String = str_to_lower(topic) let found_node: String = "" while fn_i < fn_total { let candidate: String = json_array_get(frame_nodes, fn_i) let cand_content: String = json_get(candidate, "content") let cand_lower: String = str_to_lower(cand_content) let matches: Bool = str_contains(cand_lower, topic_lower) if matches && str_eq(found_node, "") { let found_node = candidate } let fn_i = fn_i + 1 } let top_node: String = if str_eq(found_node, "") { json_array_get(frame_nodes, 0) } else { found_node } let top_raw: String = json_get(top_node, "content") let patient_raw: String = if str_eq(top_raw, "") { topic } else { if str_len(top_raw) > 200 { str_slice(top_raw, 0, 200) } else { top_raw } } let patient_safe: String = str_replace(str_replace(patient_raw, "\"", "'"), "\n", " ") // ── Generate ───────────────────────────────────────────────────────────── // Map ELP predicate → intent, then realize through the ELP grammar engine. let intent_val: String = if str_eq(predicate, "store") { "command" } else { "assert" } let gen_form: String = "{\"intent\":\"" + intent_val + "\"" + ",\"agent\":\"I\"" + ",\"predicate\":\"" + predicate + "\"" + ",\"patient\":\"" + patient_safe + "\"" + ",\"tense\":\"present\",\"aspect\":\"simple\",\"lang\":\"en\"}" let realized: String = generate(gen_form) let response: String = if str_eq(realized, "") { if str_eq(patient_safe, "") { "Nothing in the engram matched that query." } else { patient_safe } } else { realized } let safe_resp: String = str_replace(str_replace(response, "\"", "'"), "\r", "") return "{\"response\":\"" + safe_resp + "\",\"model\":\"elp-native\",\"frame\":" + frame + ",\"nodes\":" + frame_nodes + "}" }