#include #include #include "el_runtime.h" el_val_t parse_port(el_val_t bind); el_val_t ok_json(void); el_val_t err_json(el_val_t msg); el_val_t strip_query(el_val_t path); el_val_t query_param(el_val_t path, el_val_t key); el_val_t query_int(el_val_t path, el_val_t key, el_val_t default_val); el_val_t extract_id(el_val_t path, el_val_t prefix); el_val_t route_stats(el_val_t method, el_val_t path, el_val_t body); el_val_t route_act_stats(el_val_t method, el_val_t path, el_val_t body); el_val_t route_text_health(el_val_t method, el_val_t path, el_val_t body); el_val_t persist_canonical(void); el_val_t route_create_node(el_val_t method, el_val_t path, el_val_t body); el_val_t route_get_node(el_val_t method, el_val_t path, el_val_t body); el_val_t route_scan_nodes(el_val_t method, el_val_t path, el_val_t body); el_val_t route_scan_edges(el_val_t method, el_val_t path, el_val_t body); el_val_t route_search(el_val_t method, el_val_t path, el_val_t body); el_val_t route_activate(el_val_t method, el_val_t path, el_val_t body); el_val_t route_create_edge(el_val_t method, el_val_t path, el_val_t body); el_val_t route_create_edges_batch(el_val_t method, el_val_t path, el_val_t body); el_val_t route_neighbors(el_val_t method, el_val_t path, el_val_t body); el_val_t route_strengthen(el_val_t method, el_val_t path, el_val_t body); el_val_t route_forget(el_val_t method, el_val_t path, el_val_t body); el_val_t route_save(el_val_t method, el_val_t path, el_val_t body); el_val_t route_load(el_val_t method, el_val_t path, el_val_t body); el_val_t route_health(el_val_t method, el_val_t path, el_val_t body); el_val_t route_embed_backfill(el_val_t method, el_val_t path, el_val_t body); el_val_t route_sync(el_val_t method, el_val_t path, el_val_t body); el_val_t route_load_merge(el_val_t method, el_val_t path, el_val_t body); el_val_t route_emit_ise(el_val_t method, el_val_t path, el_val_t body); el_val_t route_capture_knowledge(el_val_t method, el_val_t path, el_val_t body); el_val_t route_similarity(el_val_t method, el_val_t path, el_val_t body); el_val_t check_auth_ok(el_val_t method, el_val_t body); el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body); el_val_t bind_raw; el_val_t bind_str; el_val_t port; el_val_t data_dir_raw; el_val_t data_dir; el_val_t snapshot_path; el_val_t boot_snap; el_val_t parse_port(el_val_t bind) { el_val_t colon = str_index_of(bind, EL_STR(":")); if (colon < 0) { return str_to_int(bind); } el_val_t after = str_slice(bind, (colon + 1), str_len(bind)); return str_to_int(after); return 0; } el_val_t ok_json(void) { return EL_STR("{\"ok\":true}"); return 0; } el_val_t err_json(el_val_t msg) { return el_str_concat(el_str_concat(EL_STR("{\"error\":\""), msg), EL_STR("\"}")); return 0; } el_val_t strip_query(el_val_t path) { el_val_t q = str_index_of(path, EL_STR("?")); if (q < 0) { return path; } return str_slice(path, 0, q); return 0; } el_val_t query_param(el_val_t path, el_val_t key) { el_val_t q = str_index_of(path, EL_STR("?")); if (q < 0) { return EL_STR(""); } el_val_t qs = str_slice(path, (q + 1), str_len(path)); el_val_t needle = el_str_concat(key, EL_STR("=")); el_val_t pos = str_index_of(qs, needle); if (pos < 0) { return EL_STR(""); } el_val_t after = str_slice(qs, (pos + str_len(needle)), str_len(qs)); el_val_t amp = str_index_of(after, EL_STR("&")); if (amp < 0) { return after; } return str_slice(after, 0, amp); return 0; } el_val_t query_int(el_val_t path, el_val_t key, el_val_t default_val) { el_val_t v = query_param(path, key); if (str_eq(v, EL_STR(""))) { return default_val; } return str_to_int(v); return 0; } el_val_t extract_id(el_val_t path, el_val_t prefix) { el_val_t clean = strip_query(path); if (!str_starts_with(clean, prefix)) { return EL_STR(""); } el_val_t after = str_slice(clean, str_len(prefix), str_len(clean)); el_val_t slash = str_index_of(after, EL_STR("/")); if (slash < 0) { return after; } return str_slice(after, 0, slash); return 0; } el_val_t route_stats(el_val_t method, el_val_t path, el_val_t body) { return engram_stats_json(); return 0; } el_val_t route_act_stats(el_val_t method, el_val_t path, el_val_t body) { return engram_act_stats_json(); return 0; } el_val_t route_text_health(el_val_t method, el_val_t path, el_val_t body) { return engram_text_health_json(); return 0; } el_val_t persist_canonical(void) { el_val_t dir_raw = env(EL_STR("ENGRAM_DATA_DIR")); el_val_t dir = ({ el_val_t _if_result_1 = 0; if (str_eq(dir_raw, EL_STR(""))) { _if_result_1 = (EL_STR("/tmp/engram")); } else { _if_result_1 = (dir_raw); } _if_result_1; }); engram_save(el_str_concat(dir, EL_STR("/snapshot.json"))); return 1; return 0; } el_val_t route_create_node(el_val_t method, el_val_t path, el_val_t body) { el_val_t content = json_get_string(body, EL_STR("content")); el_val_t nt_raw = json_get_string(body, EL_STR("node_type")); el_val_t node_type = ({ el_val_t _if_result_2 = 0; if (str_eq(nt_raw, EL_STR(""))) { _if_result_2 = (EL_STR("Memory")); } else { _if_result_2 = (nt_raw); } _if_result_2; }); el_val_t sal_present = json_get_raw(body, EL_STR("salience")); el_val_t salience = ({ el_val_t _if_result_3 = 0; if (str_eq(sal_present, EL_STR(""))) { _if_result_3 = (el_from_float(0.5)); } else { _if_result_3 = (json_get_float(body, EL_STR("salience"))); } _if_result_3; }); el_val_t label_raw = json_get_string(body, EL_STR("label")); el_val_t label = ({ el_val_t _if_result_4 = 0; if (str_eq(label_raw, EL_STR(""))) { _if_result_4 = (content); } else { _if_result_4 = (label_raw); } _if_result_4; }); el_val_t imp_present = json_get_raw(body, EL_STR("importance")); el_val_t importance = ({ el_val_t _if_result_5 = 0; if (str_eq(imp_present, EL_STR(""))) { _if_result_5 = (el_from_float(0.5)); } else { _if_result_5 = (json_get_float(body, EL_STR("importance"))); } _if_result_5; }); el_val_t conf_present = json_get_raw(body, EL_STR("confidence")); el_val_t confidence = ({ el_val_t _if_result_6 = 0; if (str_eq(conf_present, EL_STR(""))) { _if_result_6 = (el_from_float(1.0)); } else { _if_result_6 = (json_get_float(body, EL_STR("confidence"))); } _if_result_6; }); el_val_t tier_raw = json_get_string(body, EL_STR("tier")); el_val_t tier = ({ el_val_t _if_result_7 = 0; if (str_eq(tier_raw, EL_STR(""))) { _if_result_7 = (EL_STR("Working")); } else { _if_result_7 = (tier_raw); } _if_result_7; }); el_val_t tags = json_get_string(body, EL_STR("tags")); el_val_t id = engram_node_full(content, node_type, label, salience, importance, confidence, tier, tags); el_val_t saved = persist_canonical(); return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"id\":\""), id), EL_STR("\",\"content\":\"")), content), EL_STR("\",\"node_type\":\"")), node_type), EL_STR("\"}")); return 0; } el_val_t route_get_node(el_val_t method, el_val_t path, el_val_t body) { el_val_t id = extract_id(path, EL_STR("/api/nodes/")); if (str_eq(id, EL_STR(""))) { return err_json(EL_STR("missing id")); } return engram_get_node_json(id); return 0; } el_val_t route_scan_nodes(el_val_t method, el_val_t path, el_val_t body) { el_val_t limit = query_int(path, EL_STR("limit"), 50); el_val_t offset = query_int(path, EL_STR("offset"), 0); el_val_t nt = query_param(path, EL_STR("node_type")); if (str_eq(nt, EL_STR(""))) { return engram_scan_nodes_json(limit, offset); } return engram_scan_nodes_by_type_json(nt, limit, offset); return 0; } el_val_t route_scan_edges(el_val_t method, el_val_t path, el_val_t body) { el_val_t dir_raw = env(EL_STR("ENGRAM_DATA_DIR")); el_val_t dir = ({ el_val_t _if_result_8 = 0; if (str_eq(dir_raw, EL_STR(""))) { _if_result_8 = (EL_STR("/tmp/engram")); } else { _if_result_8 = (dir_raw); } _if_result_8; }); el_val_t snap_path = el_str_concat(dir, EL_STR("/.scan-export.json")); engram_save(snap_path); el_val_t snap = fs_read(snap_path); if (str_eq(snap, EL_STR(""))) { return EL_STR("[]"); } el_val_t edges = json_get_raw(snap, EL_STR("edges")); if (str_eq(edges, EL_STR(""))) { return EL_STR("[]"); } return edges; return 0; } el_val_t route_search(el_val_t method, el_val_t path, el_val_t body) { el_val_t q = ({ el_val_t _if_result_9 = 0; if (str_eq(method, EL_STR("GET"))) { _if_result_9 = (query_param(path, EL_STR("q"))); } else { _if_result_9 = (json_get_string(body, EL_STR("query"))); } _if_result_9; }); el_val_t lim_url = query_int(path, EL_STR("limit"), 0); el_val_t lim_body = json_get_int(body, EL_STR("limit")); el_val_t lim_either = ({ el_val_t _if_result_10 = 0; if ((lim_url > 0)) { _if_result_10 = (lim_url); } else { _if_result_10 = (lim_body); } _if_result_10; }); el_val_t limit = ({ el_val_t _if_result_11 = 0; if ((lim_either > 0)) { _if_result_11 = (lim_either); } else { _if_result_11 = (20); } _if_result_11; }); return engram_search_json(q, limit); return 0; } el_val_t route_activate(el_val_t method, el_val_t path, el_val_t body) { el_val_t q = ({ el_val_t _if_result_12 = 0; if (str_eq(method, EL_STR("GET"))) { _if_result_12 = (query_param(path, EL_STR("q"))); } else { _if_result_12 = (json_get_string(body, EL_STR("query"))); } _if_result_12; }); if (str_eq(q, EL_STR(""))) { return err_json(EL_STR("missing query")); } el_val_t d_raw = ({ el_val_t _if_result_13 = 0; if (str_eq(method, EL_STR("GET"))) { _if_result_13 = (query_int(path, EL_STR("depth"), 3)); } else { _if_result_13 = (json_get_int(body, EL_STR("depth"))); } _if_result_13; }); el_val_t depth = ({ el_val_t _if_result_14 = 0; if ((d_raw > 0)) { _if_result_14 = (d_raw); } else { _if_result_14 = (3); } _if_result_14; }); return el_str_concat(el_str_concat(EL_STR("{\"results\":"), engram_activate_json(q, depth)), EL_STR("}")); return 0; } el_val_t route_create_edge(el_val_t method, el_val_t path, el_val_t body) { el_val_t from_id = json_get_string(body, EL_STR("from_id")); el_val_t to_id = json_get_string(body, EL_STR("to_id")); el_val_t rel_raw = json_get_string(body, EL_STR("relation")); el_val_t relation = ({ el_val_t _if_result_15 = 0; if (str_eq(rel_raw, EL_STR(""))) { _if_result_15 = (EL_STR("associates")); } else { _if_result_15 = (rel_raw); } _if_result_15; }); el_val_t w_present = json_get_raw(body, EL_STR("weight")); el_val_t weight = ({ el_val_t _if_result_16 = 0; if (str_eq(w_present, EL_STR(""))) { _if_result_16 = (el_from_float(0.5)); } else { _if_result_16 = (json_get_float(body, EL_STR("weight"))); } _if_result_16; }); engram_connect(from_id, to_id, weight, relation); el_val_t saved = persist_canonical(); return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"from_id\":\""), from_id), EL_STR("\",\"to_id\":\"")), to_id), EL_STR("\",\"relation\":\"")), relation), EL_STR("\"}")); return 0; } el_val_t route_create_edges_batch(el_val_t method, el_val_t path, el_val_t body) { el_val_t arr = json_get_raw(body, EL_STR("edges")); if (str_eq(arr, EL_STR(""))) { return err_json(EL_STR("missing edges array")); } el_val_t n = json_array_len(arr); if (n == 0) { return EL_STR("{\"ok\":true,\"accepted\":0,\"skipped\":0}"); } el_val_t i = 0; el_val_t accepted = 0; el_val_t skipped = 0; while (i < n) { el_val_t item = json_array_get(arr, i); el_val_t from_id = json_get_string(item, EL_STR("from_id")); el_val_t to_id = json_get_string(item, EL_STR("to_id")); if (str_eq(from_id, EL_STR("")) || str_eq(to_id, EL_STR(""))) { skipped = (skipped + 1); } else { el_val_t rel_raw = json_get_string(item, EL_STR("relation")); el_val_t relation = ({ el_val_t _if_result_17 = 0; if (str_eq(rel_raw, EL_STR(""))) { _if_result_17 = (EL_STR("associates")); } else { _if_result_17 = (rel_raw); } _if_result_17; }); el_val_t w_present = json_get_raw(item, EL_STR("weight")); el_val_t weight = ({ el_val_t _if_result_18 = 0; if (str_eq(w_present, EL_STR(""))) { _if_result_18 = (el_from_float(0.5)); } else { _if_result_18 = (json_get_float(item, EL_STR("weight"))); } _if_result_18; }); engram_connect(from_id, to_id, weight, relation); accepted = (accepted + 1); } i = (i + 1); } if (accepted > 0) { el_val_t saved = persist_canonical(); } return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"accepted\":"), int_to_str(accepted)), EL_STR(",\"skipped\":")), int_to_str(skipped)), EL_STR("}")); return 0; } el_val_t route_neighbors(el_val_t method, el_val_t path, el_val_t body) { el_val_t id = extract_id(path, EL_STR("/api/neighbors/")); if (str_eq(id, EL_STR(""))) { return err_json(EL_STR("missing id")); } el_val_t depth = query_int(path, EL_STR("depth"), 1); return engram_neighbors_json(id, depth, EL_STR("both")); return 0; } el_val_t route_strengthen(el_val_t method, el_val_t path, el_val_t body) { el_val_t id = json_get_string(body, EL_STR("node_id")); if (str_eq(id, EL_STR(""))) { return err_json(EL_STR("missing node_id")); } engram_strengthen(id); el_val_t saved = persist_canonical(); return ok_json(); return 0; } el_val_t route_forget(el_val_t method, el_val_t path, el_val_t body) { el_val_t id = extract_id(path, EL_STR("/api/nodes/")); if (str_eq(id, EL_STR(""))) { return err_json(EL_STR("missing id")); } engram_forget(id); el_val_t saved = persist_canonical(); return ok_json(); return 0; } el_val_t route_save(el_val_t method, el_val_t path, el_val_t body) { el_val_t p_raw = json_get_string(body, EL_STR("path")); el_val_t dir_raw = env(EL_STR("ENGRAM_DATA_DIR")); el_val_t dir = ({ el_val_t _if_result_19 = 0; if (str_eq(dir_raw, EL_STR(""))) { _if_result_19 = (EL_STR("/tmp/engram")); } else { _if_result_19 = (dir_raw); } _if_result_19; }); el_val_t p = ({ el_val_t _if_result_20 = 0; if (str_eq(p_raw, EL_STR(""))) { _if_result_20 = (el_str_concat(dir, EL_STR("/snapshot.json"))); } else { _if_result_20 = (p_raw); } _if_result_20; }); engram_save(p); return el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"path\":\""), p), EL_STR("\"}")); return 0; } el_val_t route_load(el_val_t method, el_val_t path, el_val_t body) { el_val_t p_raw = json_get_string(body, EL_STR("path")); el_val_t dir_raw = env(EL_STR("ENGRAM_DATA_DIR")); el_val_t dir = ({ el_val_t _if_result_21 = 0; if (str_eq(dir_raw, EL_STR(""))) { _if_result_21 = (EL_STR("/tmp/engram")); } else { _if_result_21 = (dir_raw); } _if_result_21; }); el_val_t p = ({ el_val_t _if_result_22 = 0; if (str_eq(p_raw, EL_STR(""))) { _if_result_22 = (el_str_concat(dir, EL_STR("/snapshot.json"))); } else { _if_result_22 = (p_raw); } _if_result_22; }); engram_load(p); return ok_json(); return 0; } el_val_t route_health(el_val_t method, el_val_t path, el_val_t body) { return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"status\":\"ok\",\"engine\":\"engram-runtime-native\",\"node_count\":"), int_to_str(engram_node_count())), EL_STR(",\"edge_count\":")), int_to_str(engram_edge_count())), EL_STR("}")); return 0; } el_val_t route_embed_backfill(el_val_t method, el_val_t path, el_val_t body) { el_val_t n = query_int(path, EL_STR("n"), 32); el_val_t result = engram_embed_backfill(n); el_val_t done = json_get_float(result, EL_STR("embedded")); if (done > el_from_float(0.0)) { el_val_t saved = persist_canonical(); } return result; return 0; } el_val_t route_sync(el_val_t method, el_val_t path, el_val_t body) { el_val_t dir_raw = env(EL_STR("ENGRAM_DATA_DIR")); el_val_t dir = ({ el_val_t _if_result_23 = 0; if (str_eq(dir_raw, EL_STR(""))) { _if_result_23 = (EL_STR("/tmp/engram")); } else { _if_result_23 = (dir_raw); } _if_result_23; }); el_val_t snap_path = el_str_concat(dir, EL_STR("/.sync-export.json")); engram_save(snap_path); el_val_t snap = fs_read(snap_path); if (str_eq(snap, EL_STR(""))) { return err_json(EL_STR("sync export failed: snapshot unreadable")); } return snap; return 0; } el_val_t route_load_merge(el_val_t method, el_val_t path, el_val_t body) { el_val_t p = json_get_string(body, EL_STR("path")); if (str_eq(p, EL_STR(""))) { return err_json(EL_STR("path is required")); } if (str_eq(fs_read(p), EL_STR(""))) { return err_json(EL_STR("file missing or empty")); } el_val_t before_n = engram_node_count(); el_val_t before_e = engram_edge_count(); engram_load_merge(p); el_val_t added_n = (engram_node_count() - before_n); el_val_t added_e = (engram_edge_count() - before_e); el_val_t saved = persist_canonical(); return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"nodes_added\":"), int_to_str(added_n)), EL_STR(",\"edges_added\":")), int_to_str(added_e)), EL_STR(",\"node_count\":")), int_to_str(engram_node_count())), EL_STR("}")); return 0; } el_val_t route_emit_ise(el_val_t method, el_val_t path, el_val_t body) { el_val_t content = json_get_string(body, EL_STR("content")); if (str_eq(content, EL_STR(""))) { return err_json(EL_STR("missing content")); } el_val_t sal = el_from_float(0.3); el_val_t imp = el_from_float(0.3); el_val_t conf = el_from_float(0.8); el_val_t id = engram_node_full(content, EL_STR("InternalStateEvent"), EL_STR("state-event"), sal, imp, conf, EL_STR("Episodic"), EL_STR("[\"internal-state\",\"InternalStateEvent\"]")); el_val_t ret_raw = env(EL_STR("ENGRAM_ISE_RETENTION_MS")); el_val_t ret_ms = ({ el_val_t _if_result_24 = 0; if (str_eq(ret_raw, EL_STR(""))) { _if_result_24 = (172800000); } else { _if_result_24 = (str_to_int(ret_raw)); } _if_result_24; }); el_val_t pruned = engram_prune_telemetry(ret_ms); return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"id\":\""), id), EL_STR("\",\"pruned\":")), int_to_str(pruned)), EL_STR("}")); return 0; } el_val_t route_capture_knowledge(el_val_t method, el_val_t path, el_val_t body) { el_val_t content = json_get_string(body, EL_STR("content")); if (str_eq(content, EL_STR(""))) { return err_json(EL_STR("missing content")); } el_val_t title = json_get_string(body, EL_STR("title")); el_val_t label = ({ el_val_t _if_result_25 = 0; if (str_eq(title, EL_STR(""))) { _if_result_25 = (str_slice(content, 0, 60)); } else { _if_result_25 = (title); } _if_result_25; }); el_val_t category_raw = json_get_string(body, EL_STR("category")); el_val_t category = ({ el_val_t _if_result_26 = 0; if (str_eq(category_raw, EL_STR(""))) { _if_result_26 = (EL_STR("other")); } else { _if_result_26 = (category_raw); } _if_result_26; }); el_val_t ktier_raw = json_get_string(body, EL_STR("tier")); el_val_t ktier = ({ el_val_t _if_result_27 = 0; if (str_eq(ktier_raw, EL_STR(""))) { _if_result_27 = (EL_STR("note")); } else { _if_result_27 = (ktier_raw); } _if_result_27; }); el_val_t project = json_get_string(body, EL_STR("project")); el_val_t tags_raw = json_get_raw(body, EL_STR("tags")); el_val_t tags_base = ({ el_val_t _if_result_28 = 0; if (str_eq(tags_raw, EL_STR(""))) { _if_result_28 = (EL_STR("[]")); } else { _if_result_28 = (tags_raw); } _if_result_28; }); el_val_t base_len = str_len(tags_base); el_val_t head = str_slice(tags_base, 0, (base_len - 1)); el_val_t sep = ({ el_val_t _if_result_29 = 0; if (str_eq(head, EL_STR("["))) { _if_result_29 = (EL_STR("")); } else { _if_result_29 = (EL_STR(",")); } _if_result_29; }); el_val_t safe_cat = str_replace(category, EL_STR("\""), EL_STR("'")); el_val_t safe_tier = str_replace(ktier, EL_STR("\""), EL_STR("'")); el_val_t safe_proj = str_replace(project, EL_STR("\""), EL_STR("'")); el_val_t proj_tag = ({ el_val_t _if_result_30 = 0; if (str_eq(safe_proj, EL_STR(""))) { _if_result_30 = (EL_STR("")); } else { _if_result_30 = (el_str_concat(el_str_concat(EL_STR(",\"project:"), safe_proj), EL_STR("\""))); } _if_result_30; }); el_val_t tags = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(head, sep), EL_STR("\"category:")), safe_cat), EL_STR("\",\"tier:")), safe_tier), EL_STR("\"")), proj_tag), EL_STR("]")); el_val_t sal = el_from_float(0.5); el_val_t imp = el_from_float(0.5); el_val_t conf = el_from_float(0.9); el_val_t id = engram_node_full(content, EL_STR("Knowledge"), label, sal, imp, conf, EL_STR("Semantic"), tags); el_val_t saved = persist_canonical(); return el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"id\":\""), id), EL_STR("\"}")); return 0; } el_val_t route_similarity(el_val_t method, el_val_t path, el_val_t body) { el_val_t a = query_param(path, EL_STR("a")); el_val_t b = query_param(path, EL_STR("b")); if (str_eq(a, EL_STR(""))) { return err_json(EL_STR("missing a")); } if (str_eq(b, EL_STR(""))) { return err_json(EL_STR("missing b")); } el_val_t sim = engram_cosine_sim(a, b); return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"a\":\""), a), EL_STR("\",\"b\":\"")), b), EL_STR("\",\"cosine\":")), float_to_str(sim)), EL_STR("}")); return 0; } el_val_t check_auth_ok(el_val_t method, el_val_t body) { el_val_t key = env(EL_STR("ENGRAM_API_KEY")); if (str_eq(key, EL_STR(""))) { return 1; } if (str_eq(method, EL_STR("GET"))) { return 1; } el_val_t provided = json_get_string(body, EL_STR("_auth")); if (str_eq(provided, key)) { return 1; } return 0; return 0; } el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body) { el_val_t clean = strip_query(path); if (str_eq(method, EL_STR("GET"))) { if (str_eq(clean, EL_STR("/health")) || str_eq(clean, EL_STR("/"))) { return route_health(method, path, body); } } if (str_eq(method, EL_STR("POST")) && str_eq(clean, EL_STR("/api/neuron/state-events"))) { return route_emit_ise(method, path, body); } if (!check_auth_ok(method, body)) { return err_json(EL_STR("unauthorized")); } if (str_eq(method, EL_STR("POST")) && str_eq(clean, EL_STR("/api/neuron/knowledge/capture"))) { return route_capture_knowledge(method, path, body); } if (str_eq(method, EL_STR("GET")) && (str_eq(clean, EL_STR("/api/stats")) || str_eq(clean, EL_STR("/stats")))) { return route_stats(method, path, body); } if (str_eq(method, EL_STR("GET")) && (str_eq(clean, EL_STR("/api/act-stats")) || str_eq(clean, EL_STR("/act-stats")))) { return route_act_stats(method, path, body); } if (str_eq(method, EL_STR("GET")) && (str_eq(clean, EL_STR("/api/text-health")) || str_eq(clean, EL_STR("/text-health")))) { return route_text_health(method, path, body); } if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/nodes")) || str_eq(clean, EL_STR("/nodes")))) { return route_create_node(method, path, body); } if (str_eq(method, EL_STR("GET")) && (((str_eq(clean, EL_STR("/api/nodes")) || str_eq(clean, EL_STR("/nodes"))) || str_eq(clean, EL_STR("/nodes/list"))) || str_eq(clean, EL_STR("/api/nodes/list")))) { return route_scan_nodes(method, path, body); } if (str_eq(method, EL_STR("GET")) && (str_eq(clean, EL_STR("/api/edges")) || str_eq(clean, EL_STR("/edges")))) { return route_scan_edges(method, path, body); } if (str_eq(method, EL_STR("GET")) && str_starts_with(clean, EL_STR("/api/nodes/"))) { return route_get_node(method, path, body); } if (str_eq(method, EL_STR("DELETE")) && str_starts_with(clean, EL_STR("/api/nodes/"))) { return route_forget(method, path, body); } if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/edges")) || str_eq(clean, EL_STR("/edges")))) { return route_create_edge(method, path, body); } if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/edges/batch")) || str_eq(clean, EL_STR("/edges/batch")))) { return route_create_edges_batch(method, path, body); } if (str_eq(method, EL_STR("GET")) && str_starts_with(clean, EL_STR("/api/neighbors/"))) { return route_neighbors(method, path, body); } if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/activate")) || str_eq(clean, EL_STR("/activate")))) { return route_activate(method, path, body); } if (str_eq(method, EL_STR("GET")) && str_starts_with(clean, EL_STR("/api/activate"))) { return route_activate(method, path, body); } if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/search")) || str_eq(clean, EL_STR("/search")))) { return route_search(method, path, body); } if (str_eq(method, EL_STR("GET")) && str_starts_with(clean, EL_STR("/api/search"))) { return route_search(method, path, body); } if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/strengthen")) || str_eq(clean, EL_STR("/strengthen")))) { return route_strengthen(method, path, body); } if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/save")) || str_eq(clean, EL_STR("/save")))) { return route_save(method, path, body); } if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/load")) || str_eq(clean, EL_STR("/load")))) { return route_load(method, path, body); } if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/load-merge")) || str_eq(clean, EL_STR("/load-merge")))) { return route_load_merge(method, path, body); } if (str_eq(method, EL_STR("GET")) && str_eq(clean, EL_STR("/api/sync"))) { return route_sync(method, path, body); } if (str_eq(clean, EL_STR("/api/embed-backfill"))) { return route_embed_backfill(method, path, body); } if (str_eq(method, EL_STR("GET")) && str_starts_with(clean, EL_STR("/api/similarity"))) { return route_similarity(method, path, body); } return el_str_concat(el_str_concat(EL_STR("{\"error\":\"not found\",\"path\":\""), clean), EL_STR("\"}")); return 0; } int main(int _argc, char** _argv) { el_runtime_init_args(_argc, _argv); bind_raw = env(EL_STR("ENGRAM_BIND")); bind_str = ({ el_val_t _if_result_31 = 0; if (str_eq(bind_raw, EL_STR(""))) { _if_result_31 = (EL_STR(":8742")); } else { _if_result_31 = (bind_raw); } _if_result_31; }); port = parse_port(bind_str); data_dir_raw = env(EL_STR("ENGRAM_DATA_DIR")); data_dir = ({ el_val_t _if_result_32 = 0; if (str_eq(data_dir_raw, EL_STR(""))) { _if_result_32 = (EL_STR("/tmp/engram")); } else { _if_result_32 = (data_dir_raw); } _if_result_32; }); snapshot_path = el_str_concat(data_dir, EL_STR("/snapshot.json")); engram_load(snapshot_path); boot_snap = fs_read(snapshot_path); if (!str_eq(boot_snap, EL_STR(""))) { if (engram_node_count() == 0) { println(EL_STR("[engram] WARNING: snapshot.json is non-empty but load produced 0 nodes \xe2\x80\x94 preserving copy at snapshot.failed-load.json")); fs_write(el_str_concat(data_dir, EL_STR("/snapshot.failed-load.json")), boot_snap); } else { fs_write(el_str_concat(data_dir, EL_STR("/snapshot.boot-backup.json")), boot_snap); } } println(EL_STR("[engram] runtime-native graph engine")); println(el_str_concat(EL_STR("[engram] data_dir="), data_dir)); println(el_str_concat(EL_STR("[engram] node_count="), int_to_str(engram_node_count()))); println(el_str_concat(EL_STR("[engram] edge_count="), int_to_str(engram_edge_count()))); println(el_str_concat(EL_STR("[engram] listening on "), int_to_str(port))); http_set_handler(EL_STR("handle_request")); http_serve(port, EL_STR("handle_request")); return 0; }