soul: native cognitive API — port all MCP logic to soul daemon
neuron-api.el is a new first-class El module that implements all Neuron cognitive API handlers natively — no HTTP round-trips, no MCP wrapper, direct engram builtin calls. All capabilities that previously lived in the MCP wrapper adapter now live here in the soul. Handlers: begin_session, compile_ctx, remember, recall, search_knowledge, browse_knowledge, capture_knowledge, evolve_knowledge, promote_knowledge, browse_processes, define_process, log_state_event, list_state_events, inspect_config, tune_config, inspect_graph, link_entities, list_typed, consolidate. Routes wired in routes.el under /api/neuron/* (GET + POST). Also compiles all loop-1/loop-2 .el source changes into dist/*.c and rebuilds the binary. memory.elh and neuron-api.elh updated with new exports.
This commit is contained in:
Vendored
+140
-10
@@ -30,6 +30,8 @@ el_val_t build_system_prompt(el_val_t ctx);
|
||||
el_val_t hist_append(el_val_t hist, el_val_t role, el_val_t content);
|
||||
el_val_t hist_trim(el_val_t hist);
|
||||
el_val_t clean_llm_response(el_val_t s);
|
||||
el_val_t conv_history_persist(el_val_t hist);
|
||||
el_val_t conv_history_load(void);
|
||||
el_val_t handle_chat(el_val_t body);
|
||||
el_val_t handle_see(el_val_t body);
|
||||
el_val_t studio_tools_json(void);
|
||||
@@ -41,6 +43,7 @@ el_val_t handle_chat_as_soul(el_val_t body);
|
||||
el_val_t handle_dharma_room_turn(el_val_t body);
|
||||
el_val_t handle_dharma_room_turn_agentic(el_val_t body);
|
||||
el_val_t auto_persist(el_val_t req, el_val_t resp);
|
||||
el_val_t strengthen_chat_nodes(el_val_t activation_nodes);
|
||||
el_val_t auth_headers(el_val_t tok);
|
||||
el_val_t axon_get(el_val_t path);
|
||||
el_val_t axon_post(el_val_t path, el_val_t body);
|
||||
@@ -56,6 +59,32 @@ el_val_t elp_extract_topic(el_val_t msg);
|
||||
el_val_t elp_detect_predicate(el_val_t msg);
|
||||
el_val_t elp_parse(el_val_t msg);
|
||||
el_val_t handle_elp_chat(el_val_t body);
|
||||
el_val_t api_json_escape(el_val_t s);
|
||||
el_val_t api_query_param(el_val_t path, el_val_t key);
|
||||
el_val_t api_query_int(el_val_t path, el_val_t key, el_val_t default_val);
|
||||
el_val_t api_ok(el_val_t extra);
|
||||
el_val_t api_err(el_val_t msg);
|
||||
el_val_t api_nonempty(el_val_t s);
|
||||
el_val_t api_or_empty(el_val_t s);
|
||||
el_val_t handle_api_begin_session(el_val_t body);
|
||||
el_val_t handle_api_compile_ctx(el_val_t body);
|
||||
el_val_t handle_api_remember(el_val_t body);
|
||||
el_val_t handle_api_recall(el_val_t method, el_val_t path, el_val_t body);
|
||||
el_val_t handle_api_search_knowledge(el_val_t method, el_val_t path, el_val_t body);
|
||||
el_val_t handle_api_browse_knowledge(el_val_t path, el_val_t body);
|
||||
el_val_t handle_api_capture_knowledge(el_val_t body);
|
||||
el_val_t handle_api_evolve_knowledge(el_val_t body);
|
||||
el_val_t handle_api_promote_knowledge(el_val_t body);
|
||||
el_val_t handle_api_browse_processes(el_val_t method, el_val_t path, el_val_t body);
|
||||
el_val_t handle_api_define_process(el_val_t body);
|
||||
el_val_t handle_api_log_state_event(el_val_t body);
|
||||
el_val_t handle_api_list_state_events(el_val_t method, el_val_t path, el_val_t body);
|
||||
el_val_t handle_api_inspect_config(el_val_t path, el_val_t body);
|
||||
el_val_t handle_api_tune_config(el_val_t body);
|
||||
el_val_t handle_api_inspect_graph(el_val_t method, el_val_t path, el_val_t body);
|
||||
el_val_t handle_api_link_entities(el_val_t body);
|
||||
el_val_t handle_api_list_typed(el_val_t node_type, el_val_t path, el_val_t body);
|
||||
el_val_t handle_api_consolidate(el_val_t body);
|
||||
el_val_t strip_query(el_val_t path);
|
||||
el_val_t err_404(el_val_t path);
|
||||
el_val_t err_405(el_val_t method, el_val_t path);
|
||||
@@ -65,6 +94,7 @@ el_val_t route_imprint_contextual(el_val_t body);
|
||||
el_val_t route_imprint_user(el_val_t body);
|
||||
el_val_t route_synthesize(el_val_t body);
|
||||
el_val_t handle_dharma_recv(el_val_t body);
|
||||
el_val_t route_sessions(void);
|
||||
el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body);
|
||||
|
||||
el_val_t strip_query(el_val_t path) {
|
||||
@@ -88,7 +118,13 @@ el_val_t err_405(el_val_t method, el_val_t path) {
|
||||
|
||||
el_val_t route_health(void) {
|
||||
el_val_t cgi_id = state_get(EL_STR("soul_cgi_id"));
|
||||
return el_str_concat(el_str_concat(EL_STR("{\"status\":\"alive\",\"cgi_id\":\""), cgi_id), EL_STR("\"}"));
|
||||
el_val_t boot = state_get(EL_STR("soul_boot_count"));
|
||||
el_val_t boot_num = ({ el_val_t _if_result_1 = 0; if (str_eq(boot, EL_STR(""))) { _if_result_1 = (EL_STR("0")); } else { _if_result_1 = (boot); } _if_result_1; });
|
||||
el_val_t node_ct = engram_node_count();
|
||||
el_val_t edge_ct = engram_edge_count();
|
||||
el_val_t pulse = state_get(EL_STR("soul.pulse"));
|
||||
el_val_t pulse_num = ({ el_val_t _if_result_2 = 0; if (str_eq(pulse, EL_STR(""))) { _if_result_2 = (EL_STR("0")); } else { _if_result_2 = (pulse); } _if_result_2; });
|
||||
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"status\":\"alive\""), EL_STR(",\"cgi_id\":\"")), cgi_id), EL_STR("\"")), EL_STR(",\"boot\":")), boot_num), EL_STR(",\"node_count\":")), int_to_str(node_ct)), EL_STR(",\"edge_count\":")), int_to_str(edge_ct)), EL_STR(",\"pulse\":")), pulse_num), EL_STR("}"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -157,28 +193,28 @@ el_val_t handle_dharma_recv(el_val_t body) {
|
||||
el_val_t from_id = json_get(body, EL_STR("from"));
|
||||
el_val_t event_type = json_get(content_raw, EL_STR("event_type"));
|
||||
el_val_t payload = json_get(content_raw, EL_STR("payload"));
|
||||
el_val_t eff_event = ({ el_val_t _if_result_1 = 0; if (str_eq(event_type, EL_STR(""))) { _if_result_1 = (EL_STR("chat")); } else { _if_result_1 = (event_type); } _if_result_1; });
|
||||
el_val_t eff_payload = ({ el_val_t _if_result_2 = 0; if (str_eq(payload, EL_STR(""))) { _if_result_2 = (content_raw); } else { _if_result_2 = (payload); } _if_result_2; });
|
||||
el_val_t eff_event = ({ el_val_t _if_result_3 = 0; if (str_eq(event_type, EL_STR(""))) { _if_result_3 = (EL_STR("chat")); } else { _if_result_3 = (event_type); } _if_result_3; });
|
||||
el_val_t eff_payload = ({ el_val_t _if_result_4 = 0; if (str_eq(payload, EL_STR(""))) { _if_result_4 = (content_raw); } else { _if_result_4 = (payload); } _if_result_4; });
|
||||
if (str_eq(eff_event, EL_STR("chat"))) {
|
||||
el_val_t msg = json_get(eff_payload, EL_STR("message"));
|
||||
el_val_t chat_body = ({ el_val_t _if_result_3 = 0; if (str_eq(msg, EL_STR(""))) { _if_result_3 = (el_str_concat(el_str_concat(EL_STR("{\"message\":\""), str_replace(str_replace(eff_payload, EL_STR("\\"), EL_STR("\\\\")), EL_STR("\""), EL_STR("\\\""))), EL_STR("\"}"))); } else { _if_result_3 = (eff_payload); } _if_result_3; });
|
||||
el_val_t chat_body = ({ el_val_t _if_result_5 = 0; if (str_eq(msg, EL_STR(""))) { _if_result_5 = (el_str_concat(el_str_concat(EL_STR("{\"message\":\""), str_replace(str_replace(eff_payload, EL_STR("\\"), EL_STR("\\\\")), EL_STR("\""), EL_STR("\\\""))), EL_STR("\"}"))); } else { _if_result_5 = (eff_payload); } _if_result_5; });
|
||||
el_val_t agentic_flag = json_get_bool(eff_payload, EL_STR("agentic"));
|
||||
el_val_t reply = ({ el_val_t _if_result_4 = 0; if (agentic_flag) { _if_result_4 = (handle_chat_agentic(chat_body)); } else { _if_result_4 = (handle_chat(chat_body)); } _if_result_4; });
|
||||
el_val_t reply = ({ el_val_t _if_result_6 = 0; if (agentic_flag) { _if_result_6 = (handle_chat_agentic(chat_body)); } else { _if_result_6 = (handle_chat(chat_body)); } _if_result_6; });
|
||||
auto_persist(chat_body, reply);
|
||||
return reply;
|
||||
}
|
||||
if (str_eq(eff_event, EL_STR("memory"))) {
|
||||
el_val_t query = json_get(eff_payload, EL_STR("query"));
|
||||
el_val_t limit_str = json_get(eff_payload, EL_STR("limit"));
|
||||
el_val_t limit = ({ el_val_t _if_result_5 = 0; if (str_eq(limit_str, EL_STR(""))) { _if_result_5 = (20); } else { _if_result_5 = (str_to_int(limit_str)); } _if_result_5; });
|
||||
el_val_t q = ({ el_val_t _if_result_6 = 0; if (str_eq(query, EL_STR(""))) { _if_result_6 = (eff_payload); } else { _if_result_6 = (query); } _if_result_6; });
|
||||
el_val_t limit = ({ el_val_t _if_result_7 = 0; if (str_eq(limit_str, EL_STR(""))) { _if_result_7 = (20); } else { _if_result_7 = (str_to_int(limit_str)); } _if_result_7; });
|
||||
el_val_t q = ({ el_val_t _if_result_8 = 0; if (str_eq(query, EL_STR(""))) { _if_result_8 = (eff_payload); } else { _if_result_8 = (query); } _if_result_8; });
|
||||
return engram_search_json(q, limit);
|
||||
}
|
||||
if (str_eq(eff_event, EL_STR("tool"))) {
|
||||
el_val_t path_field = json_get(eff_payload, EL_STR("path"));
|
||||
el_val_t method_field = json_get(eff_payload, EL_STR("method"));
|
||||
el_val_t tool_body = json_get(eff_payload, EL_STR("body"));
|
||||
el_val_t eff_method = ({ el_val_t _if_result_7 = 0; if (str_eq(method_field, EL_STR(""))) { _if_result_7 = (EL_STR("POST")); } else { _if_result_7 = (method_field); } _if_result_7; });
|
||||
el_val_t eff_method = ({ el_val_t _if_result_9 = 0; if (str_eq(method_field, EL_STR(""))) { _if_result_9 = (EL_STR("POST")); } else { _if_result_9 = (method_field); } _if_result_9; });
|
||||
return handle_tool(path_field, eff_method, tool_body);
|
||||
}
|
||||
if (str_eq(eff_event, EL_STR("see"))) {
|
||||
@@ -203,6 +239,18 @@ el_val_t handle_dharma_recv(el_val_t body) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
el_val_t route_sessions(void) {
|
||||
el_val_t results = engram_search_json(EL_STR("session-start"), 20);
|
||||
if (str_eq(results, EL_STR(""))) {
|
||||
return EL_STR("[]");
|
||||
}
|
||||
if (str_eq(results, EL_STR("[]"))) {
|
||||
return EL_STR("[]");
|
||||
}
|
||||
return results;
|
||||
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("POST")) && str_eq(clean, EL_STR("/dharma/recv"))) {
|
||||
@@ -212,6 +260,9 @@ el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body) {
|
||||
if (str_eq(clean, EL_STR("/health"))) {
|
||||
return route_health();
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/sessions"))) {
|
||||
return route_sessions();
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/lineage"))) {
|
||||
return route_lineage();
|
||||
}
|
||||
@@ -223,7 +274,7 @@ el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body) {
|
||||
engram_save(snap_path);
|
||||
el_val_t snap = fs_read(snap_path);
|
||||
el_val_t edges_raw = json_get_raw(snap, EL_STR("edges"));
|
||||
return ({ el_val_t _if_result_8 = 0; if (str_eq(edges_raw, EL_STR(""))) { _if_result_8 = (EL_STR("[]")); } else { _if_result_8 = (edges_raw); } _if_result_8; });
|
||||
return ({ el_val_t _if_result_10 = 0; if (str_eq(edges_raw, EL_STR(""))) { _if_result_10 = (EL_STR("[]")); } else { _if_result_10 = (edges_raw); } _if_result_10; });
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/chat"))) {
|
||||
return handle_chat(body);
|
||||
@@ -264,6 +315,37 @@ el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body) {
|
||||
if (str_eq(clean, EL_STR("/"))) {
|
||||
return render_studio();
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/neuron/session/begin"))) {
|
||||
return handle_api_begin_session(EL_STR(""));
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/neuron/ctx"))) {
|
||||
return handle_api_compile_ctx(EL_STR(""));
|
||||
}
|
||||
if (str_starts_with(clean, EL_STR("/api/neuron/knowledge/search"))) {
|
||||
return handle_api_search_knowledge(method, path, body);
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/neuron/knowledge"))) {
|
||||
return handle_api_browse_knowledge(path, body);
|
||||
}
|
||||
if (str_starts_with(clean, EL_STR("/api/neuron/processes"))) {
|
||||
return handle_api_browse_processes(method, path, body);
|
||||
}
|
||||
if (str_starts_with(clean, EL_STR("/api/neuron/state-events"))) {
|
||||
return handle_api_list_state_events(method, path, body);
|
||||
}
|
||||
if (str_starts_with(clean, EL_STR("/api/neuron/config"))) {
|
||||
return handle_api_inspect_config(path, body);
|
||||
}
|
||||
if (str_starts_with(clean, EL_STR("/api/neuron/graph"))) {
|
||||
return handle_api_inspect_graph(method, path, body);
|
||||
}
|
||||
if (str_starts_with(clean, EL_STR("/api/neuron/list/"))) {
|
||||
el_val_t node_type = str_slice(clean, 16, str_len(clean));
|
||||
return handle_api_list_typed(node_type, path, body);
|
||||
}
|
||||
if (str_starts_with(clean, EL_STR("/api/neuron/recall"))) {
|
||||
return handle_api_recall(method, path, body);
|
||||
}
|
||||
return err_404(clean);
|
||||
}
|
||||
if (str_eq(method, EL_STR("POST"))) {
|
||||
@@ -281,7 +363,7 @@ el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body) {
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/chat"))) {
|
||||
el_val_t agentic_flag = json_get_bool(body, EL_STR("agentic"));
|
||||
el_val_t reply = ({ el_val_t _if_result_9 = 0; if (agentic_flag) { _if_result_9 = (handle_chat_agentic(body)); } else { _if_result_9 = (handle_chat(body)); } _if_result_9; });
|
||||
el_val_t reply = ({ el_val_t _if_result_11 = 0; if (agentic_flag) { _if_result_11 = (handle_chat_agentic(body)); } else { _if_result_11 = (handle_chat(body)); } _if_result_11; });
|
||||
auto_persist(body, reply);
|
||||
return reply;
|
||||
}
|
||||
@@ -321,6 +403,54 @@ el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body) {
|
||||
if (str_starts_with(clean, EL_STR("/api/imprints"))) {
|
||||
return axon_post(clean, body);
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/neuron/session/begin"))) {
|
||||
return handle_api_begin_session(body);
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/neuron/ctx"))) {
|
||||
return handle_api_compile_ctx(body);
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/neuron/knowledge/search"))) {
|
||||
return handle_api_search_knowledge(method, path, body);
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/neuron/knowledge/capture"))) {
|
||||
return handle_api_capture_knowledge(body);
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/neuron/knowledge/evolve"))) {
|
||||
return handle_api_evolve_knowledge(body);
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/neuron/knowledge/promote"))) {
|
||||
return handle_api_promote_knowledge(body);
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/neuron/processes"))) {
|
||||
return handle_api_browse_processes(method, path, body);
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/neuron/processes/define"))) {
|
||||
return handle_api_define_process(body);
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/neuron/state-events"))) {
|
||||
return handle_api_log_state_event(body);
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/neuron/config"))) {
|
||||
return handle_api_inspect_config(path, body);
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/neuron/config/tune"))) {
|
||||
return handle_api_tune_config(body);
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/neuron/graph"))) {
|
||||
return handle_api_inspect_graph(method, path, body);
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/neuron/graph/link"))) {
|
||||
return handle_api_link_entities(body);
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/neuron/memory"))) {
|
||||
return handle_api_remember(body);
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/neuron/recall"))) {
|
||||
return handle_api_recall(method, path, body);
|
||||
}
|
||||
if (str_eq(clean, EL_STR("/api/neuron/consolidate"))) {
|
||||
return handle_api_consolidate(body);
|
||||
}
|
||||
return err_404(clean);
|
||||
}
|
||||
return err_405(method, clean);
|
||||
|
||||
Reference in New Issue
Block a user