Files
neuron/dist/awareness.c
T
Will Anderson 2622bb04bd ELP: two-layer activation pipeline (activate → suppress → reason → generate)
elp-input.el: replace broken engram_search_json with engram_activate_json
as Layer 1. Layer 2 suppress/filter keeps nodes with non-zero salience/
importance. Reason step extracts patient from top activated node content.
ELP grammar realizes the response via generate().

routes.el: add 'elp' event_type to handle_dharma_recv so the studio can
route ELP requests through dharma.
2026-05-03 11:31:04 -05:00

153 lines
4.8 KiB
C

#include <stdint.h>
#include <stdlib.h>
#include "el_runtime.h"
el_val_t tier_working(void);
el_val_t tier_episodic(void);
el_val_t tier_canonical(void);
el_val_t mem_store(el_val_t content, el_val_t label, el_val_t tags);
el_val_t mem_remember(el_val_t content, el_val_t tags);
el_val_t mem_recall(el_val_t query, el_val_t depth);
el_val_t mem_search(el_val_t query, el_val_t limit);
el_val_t mem_strengthen(el_val_t node_id);
el_val_t mem_forget(el_val_t node_id);
el_val_t mem_consolidate(void);
el_val_t mem_save(el_val_t path);
el_val_t mem_load(el_val_t path);
el_val_t pulse_count(void);
el_val_t pulse_inc(void);
el_val_t make_action(el_val_t kind, el_val_t payload);
el_val_t perceive(void);
el_val_t attend(el_val_t node_json);
el_val_t respond(el_val_t action_json);
el_val_t record(el_val_t outcome_json);
el_val_t one_cycle(void);
el_val_t awareness_run(void);
el_val_t pulse_count(void) {
el_val_t s = state_get(EL_STR("soul.pulse"));
if (str_eq(s, EL_STR(""))) {
return 0;
}
return str_to_int(s);
return 0;
}
el_val_t pulse_inc(void) {
el_val_t n = (pulse_count() + 1);
state_set(EL_STR("soul.pulse"), int_to_str(n));
return n;
return 0;
}
el_val_t make_action(el_val_t kind, el_val_t payload) {
el_val_t safe = str_replace(payload, EL_STR("\\"), EL_STR("\\\\"));
el_val_t safe2 = str_replace(safe, EL_STR("\""), EL_STR("\\\""));
el_val_t safe3 = str_replace(safe2, EL_STR("\n"), EL_STR("\\n"));
el_val_t safe4 = str_replace(safe3, EL_STR("\r"), EL_STR("\\r"));
return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"kind\":\""), kind), EL_STR("\",\"payload\":\"")), safe4), EL_STR("\"}"));
return 0;
}
el_val_t perceive(void) {
return engram_activate_json(EL_STR("soul-inbox-pending"), 2);
return 0;
}
el_val_t attend(el_val_t node_json) {
if (str_eq(node_json, EL_STR(""))) {
return make_action(EL_STR("noop"), EL_STR(""));
}
if (str_eq(node_json, EL_STR("[]"))) {
return make_action(EL_STR("noop"), EL_STR(""));
}
el_val_t node_id = json_get(node_json, EL_STR("id"));
if (!str_eq(node_id, EL_STR(""))) {
engram_strengthen(node_id);
}
el_val_t content = json_get(node_json, EL_STR("content"));
if (str_eq(content, EL_STR(""))) {
return make_action(EL_STR("noop"), EL_STR(""));
}
if (str_eq(content, EL_STR("consolidate"))) {
return make_action(EL_STR("consolidate"), EL_STR(""));
}
if (str_starts_with(content, EL_STR("remember "))) {
el_val_t payload = str_slice(content, 9, str_len(content));
return make_action(EL_STR("remember"), payload);
}
return make_action(EL_STR("respond"), content);
return 0;
}
el_val_t respond(el_val_t action_json) {
el_val_t kind = json_get(action_json, EL_STR("kind"));
el_val_t payload = json_get(action_json, EL_STR("payload"));
if (str_eq(kind, EL_STR("noop"))) {
return EL_STR("{\"outcome\":\"noop\"}");
}
if (str_eq(kind, EL_STR("remember"))) {
el_val_t tags = EL_STR("[\"soul-memory\",\"awareness\"]");
el_val_t id = mem_remember(payload, tags);
return el_str_concat(el_str_concat(EL_STR("{\"outcome\":\"remembered\",\"id\":\""), id), EL_STR("\"}"));
}
if (str_eq(kind, EL_STR("consolidate"))) {
el_val_t stats = mem_consolidate();
return el_str_concat(el_str_concat(EL_STR("{\"outcome\":\"consolidated\",\"stats\":"), stats), EL_STR("}"));
}
if (str_eq(kind, EL_STR("respond"))) {
el_val_t tags = EL_STR("[\"soul-outbox\",\"awareness\"]");
el_val_t id = mem_store(payload, EL_STR("soul-response"), tags);
return el_str_concat(el_str_concat(EL_STR("{\"outcome\":\"response\",\"id\":\""), id), EL_STR("\"}"));
}
return EL_STR("{\"outcome\":\"noop\"}");
return 0;
}
el_val_t record(el_val_t outcome_json) {
el_val_t tags = EL_STR("[\"loop-outcome\"]");
mem_store(outcome_json, EL_STR("loop-outcome"), tags);
return 0;
}
el_val_t one_cycle(void) {
el_val_t raw = perceive();
if (str_eq(raw, EL_STR(""))) {
return 0;
}
if (str_eq(raw, EL_STR("[]"))) {
return 0;
}
el_val_t node = json_array_get(raw, 0);
if (str_eq(node, EL_STR(""))) {
return 0;
}
el_val_t action = attend(node);
el_val_t kind = json_get(action, EL_STR("kind"));
if (str_eq(kind, EL_STR("noop"))) {
return 0;
}
el_val_t outcome = respond(action);
record(outcome);
pulse_inc();
return 1;
return 0;
}
el_val_t awareness_run(void) {
println(EL_STR("[awareness] entering"));
el_val_t tick_raw = env(EL_STR("SOUL_TICK_MS"));
el_val_t tick_ms = ({ el_val_t _if_result_1 = 0; if (str_eq(tick_raw, EL_STR(""))) { _if_result_1 = (200); } else { _if_result_1 = (str_to_int(tick_raw)); } _if_result_1; });
while (1) {
el_val_t running = state_get(EL_STR("soul.running"));
if (str_eq(running, EL_STR("false"))) {
println(EL_STR("[awareness] exiting"));
return EL_STR("");
}
one_cycle();
sleep_ms(tick_ms);
}
return 0;
}