Files
neuron/dist/awareness.c
T
will.anderson 48ecd83421 fix: restore elb build — import paths, morphology deps, C master declarations header
- Fix wrong ELP import paths in soul.el, elp-input.el, studio.el
  (../foundation/elp/src → ../foundation/el/elp/src)
- Add missing import "morphology.el" to all 29 language morphology modules
- Recompile all affected dist/*.c with correct cross-module declarations
- Add dist/elp-c-decls.h: C-level master forward declarations for ELP package
  (enables elb --force-include to resolve undeclared cross-module calls)
2026-05-08 19:43:57 -05:00

213 lines
8.0 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 mem_boot_count_get(void);
el_val_t mem_boot_count_inc(void);
el_val_t mem_emit_state_event(el_val_t trigger, el_val_t kind, el_val_t content);
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) {
el_val_t from_pending = engram_activate_json(EL_STR("soul-inbox-pending"), 2);
el_val_t pending_ok = (!str_eq(from_pending, EL_STR("")) && !str_eq(from_pending, EL_STR("[]")));
if (pending_ok) {
return from_pending;
}
el_val_t from_inbox = engram_activate_json(EL_STR("soul-inbox"), 2);
el_val_t inbox_ok = (!str_eq(from_inbox, EL_STR("")) && !str_eq(from_inbox, EL_STR("[]")));
if (inbox_ok) {
return from_inbox;
}
return EL_STR("[]");
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);
}
if (str_starts_with(content, EL_STR("search "))) {
el_val_t payload = str_slice(content, 7, str_len(content));
return make_action(EL_STR("search"), payload);
}
if (str_starts_with(content, EL_STR("activate "))) {
el_val_t payload = str_slice(content, 9, str_len(content));
return make_action(EL_STR("activate"), payload);
}
if (str_starts_with(content, EL_STR("strengthen "))) {
el_val_t payload = str_slice(content, 11, str_len(content));
return make_action(EL_STR("strengthen"), payload);
}
if (str_starts_with(content, EL_STR("forget "))) {
el_val_t payload = str_slice(content, 7, str_len(content));
return make_action(EL_STR("forget"), 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("\"}"));
}
if (str_eq(kind, EL_STR("search"))) {
el_val_t results = mem_search(payload, 10);
el_val_t safe_results = str_replace(results, EL_STR("\""), EL_STR("'"));
el_val_t tags = EL_STR("[\"soul-outbox\",\"search-result\"]");
el_val_t id = mem_store(safe_results, EL_STR("search-result"), tags);
return el_str_concat(el_str_concat(EL_STR("{\"outcome\":\"searched\",\"id\":\""), id), EL_STR("\"}"));
}
if (str_eq(kind, EL_STR("activate"))) {
el_val_t results = mem_recall(payload, 3);
el_val_t safe_results = str_replace(results, EL_STR("\""), EL_STR("'"));
el_val_t tags = EL_STR("[\"soul-outbox\",\"activation-result\"]");
el_val_t id = mem_store(safe_results, EL_STR("activation-result"), tags);
return el_str_concat(el_str_concat(EL_STR("{\"outcome\":\"activated\",\"id\":\""), id), EL_STR("\"}"));
}
if (str_eq(kind, EL_STR("strengthen"))) {
engram_strengthen(payload);
return el_str_concat(el_str_concat(EL_STR("{\"outcome\":\"strengthened\",\"id\":\""), payload), EL_STR("\"}"));
}
if (str_eq(kind, EL_STR("forget"))) {
engram_forget(payload);
return el_str_concat(el_str_concat(EL_STR("{\"outcome\":\"forgotten\",\"id\":\""), payload), 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"));
el_val_t is_interesting = (!str_eq(kind, EL_STR("noop")) && !str_eq(kind, EL_STR("respond")));
if (is_interesting) {
el_val_t trigger_content = json_get(node, EL_STR("content"));
el_val_t safe_trigger = str_replace(trigger_content, EL_STR("\""), EL_STR("'"));
el_val_t tags = EL_STR("[\"internal-state\",\"awareness-decision\"]");
el_val_t ts = time_now();
el_val_t event_content = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"trigger\":\""), safe_trigger), EL_STR("\",\"kind\":\"")), kind), EL_STR("\",\"ts\":")), int_to_str(ts)), EL_STR("}"));
el_val_t discard_ev = engram_node_full(event_content, EL_STR("InternalStateEvent"), el_str_concat(EL_STR("state-event:"), kind), el_from_float(0.85), el_from_float(0.8), el_from_float(0.9), EL_STR("Episodic"), tags);
}
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;
}