diff --git a/engram/dist/engram b/engram/dist/engram index 71e459e..84d2f60 100755 Binary files a/engram/dist/engram and b/engram/dist/engram differ diff --git a/engram/dist/engram.c b/engram/dist/engram.c index e8c3c93..8f1fb67 100644 --- a/engram/dist/engram.c +++ b/engram/dist/engram.c @@ -301,7 +301,7 @@ el_val_t route_create_node(el_val_t method, el_val_t path, el_val_t body) { node_type = EL_STR("Memory"); } el_val_t salience = json_get_float(body, EL_STR("salience")); - if (salience == el_from_float(0.0)) { + if (str_eq(salience, el_from_float(0.0))) { salience = el_from_float(0.5); } el_val_t id = engram_node(content, node_type, salience); @@ -451,7 +451,7 @@ el_val_t route_create_edge(el_val_t method, el_val_t path, el_val_t body) { relation = EL_STR("associates"); } el_val_t weight = json_get_float(body, EL_STR("weight")); - if (weight == el_from_float(0.0)) { + if (str_eq(weight, el_from_float(0.0))) { weight = el_from_float(0.5); } engram_connect(from_id, to_id, weight, relation); @@ -780,7 +780,7 @@ el_val_t route_neuron_graph_link(el_val_t method, el_val_t path, el_val_t body) relation = EL_STR("related"); } el_val_t weight = json_get_float(body, EL_STR("weight")); - if (weight == el_from_float(0.0)) { + if (str_eq(weight, el_from_float(0.0))) { weight = el_from_float(0.5); } engram_connect(from_id, to_id, weight, relation); diff --git a/lang/dist/platform/elc b/lang/dist/platform/elc index 5e582a3..93c4207 100755 Binary files a/lang/dist/platform/elc and b/lang/dist/platform/elc differ diff --git a/lang/dist/platform/elc.c b/lang/dist/platform/elc.c index 2fd558d..bbb49e1 100644 --- a/lang/dist/platform/elc.c +++ b/lang/dist/platform/elc.c @@ -4342,6 +4342,9 @@ el_val_t builtin_arity(el_val_t name) { if (str_eq(name, EL_STR("http_serve"))) { return 2; } + if (str_eq(name, EL_STR("http_serve_async"))) { + return 2; + } if (str_eq(name, EL_STR("http_set_handler"))) { return 1; } diff --git a/lang/el-compiler/src/codegen.el b/lang/el-compiler/src/codegen.el index 917fb31..3cee9ba 100644 --- a/lang/el-compiler/src/codegen.el +++ b/lang/el-compiler/src/codegen.el @@ -2502,6 +2502,7 @@ fn builtin_arity(name: String) -> Int { if str_eq(name, "http_post_with_headers") { return 3 } if str_eq(name, "http_post_form_auth") { return 3 } if str_eq(name, "http_serve") { return 2 } + if str_eq(name, "http_serve_async") { return 2 } if str_eq(name, "http_set_handler") { return 1 } // Seed primitives (__-prefix) — runtime/el_seed.c if str_eq(name, "__str_len") { return 1 } diff --git a/lang/releases/v1.0.0-20260501/el_runtime.c b/lang/releases/v1.0.0-20260501/el_runtime.c index 1253c24..348bc05 100644 --- a/lang/releases/v1.0.0-20260501/el_runtime.c +++ b/lang/releases/v1.0.0-20260501/el_runtime.c @@ -6394,6 +6394,24 @@ static void engram_sort_indices_by_salience(int64_t* arr, int64_t n, } } +/* Sort node indices by created_at descending (most recent first). + * Used for InternalStateEvent scans so that the API returns recent ISEs + * at low offsets rather than burying them behind old high-salience events. + * Insertion sort — adequate for typical ISE counts (< 30K). */ +static void engram_sort_indices_by_created_at_desc(int64_t* arr, int64_t n, + const EngramNode* nodes) { + for (int64_t i = 1; i < n; i++) { + int64_t key = arr[i]; + int64_t kt = nodes[key].created_at; + int64_t j = i - 1; + while (j >= 0 && nodes[arr[j]].created_at < kt) { + arr[j + 1] = arr[j]; + j--; + } + arr[j + 1] = key; + } +} + el_val_t engram_scan_nodes(el_val_t limit, el_val_t offset) { EngramStore* g = engram_get(); int64_t lim = (int64_t)limit; if (lim <= 0) lim = 100; @@ -8566,7 +8584,10 @@ el_val_t engram_scan_nodes_json(el_val_t limit, el_val_t offset) { /* engram_scan_nodes_by_type_json — filter by node_type before paginating. * Empty / NULL type_v falls back to the unfiltered scan (existing behaviour). - * Result is JSON array, salience-sorted, transparent layers skipped. */ + * Result is JSON array. Ordering: + * - InternalStateEvent → created_at DESC (most-recent-first) so recent ISEs + * surface at low offsets instead of being buried behind old high-salience ones. + * - All other types → salience DESC (existing behaviour). */ el_val_t engram_scan_nodes_by_type_json(el_val_t type_v, el_val_t limit, el_val_t offset) { const char* type_filter = EL_CSTR(type_v); if (!type_filter || !*type_filter) { @@ -8587,7 +8608,12 @@ el_val_t engram_scan_nodes_by_type_json(el_val_t type_v, el_val_t limit, el_val_ if (!nt || strcmp(nt, type_filter) != 0) continue; idx[live++] = i; } - engram_sort_indices_by_salience(idx, live, g->nodes); + /* ISEs sort recent-first so monitoring tools see current state, not history. */ + if (strcmp(type_filter, "InternalStateEvent") == 0) { + engram_sort_indices_by_created_at_desc(idx, live, g->nodes); + } else { + engram_sort_indices_by_salience(idx, live, g->nodes); + } int64_t end = off + lim; if (end > live) end = live; int first = 1;