chore(dist): compile EL recall/dedup/session-continuity fixes to C
Updates soul.c and all per-module .c files with: - parse_float_x100() engram score fix - id_in_seen dedup wiring across session_preload - session-end summary hook + session-start recall - Emergency structural repair (no duplicate fns, all callsites wired)
This commit is contained in:
@@ -109,6 +109,43 @@ fn ensure_self_canonical_bridge() -> Void {
|
||||
}
|
||||
}
|
||||
|
||||
// aff_try_slot — accumulate one affective-context node into state.
|
||||
// Replaces the broken `let bacc = while bi < N { ... let bacc = ... }` pattern
|
||||
// that caused ELC to emit duplicate C declarations for `bacc`.
|
||||
// (2026-06-23 self-review: EL compiler codegen bug — while loop with let-rebinding
|
||||
// inside the loop body generates `el_val_t bacc = ...` twice in the same C scope.)
|
||||
// Callers unroll manually to 3 slots (matching engram_search_json limit=3).
|
||||
// Guards: empty slot_json (out-of-bounds json_array_get) → no-op.
|
||||
fn aff_try_slot(slot_json: String, aff_7d_ts: Int, acc_key: String) -> Void {
|
||||
if str_eq(slot_json, "") { return "" }
|
||||
let bn_c: String = json_get(slot_json, "content")
|
||||
if str_eq(bn_c, "") { return "" }
|
||||
let bm: String = " | ts:"
|
||||
let bmp: Int = str_index_of(bn_c, bm)
|
||||
state_set("_ats_ts_raw", "")
|
||||
if bmp >= 0 {
|
||||
let bs: Int = bmp + str_len(bm)
|
||||
let br: String = str_slice(bn_c, bs, str_len(bn_c))
|
||||
let bn_next: Int = str_index_of(br, " | ")
|
||||
if bn_next < 0 { state_set("_ats_ts_raw", br) }
|
||||
if bn_next >= 0 { state_set("_ats_ts_raw", str_slice(br, 0, bn_next)) }
|
||||
}
|
||||
if bmp < 0 {
|
||||
let bca: String = json_get(slot_json, "created_at")
|
||||
if str_eq(bca, "") { state_set("_ats_ts_raw", json_get(slot_json, "updated_at")) }
|
||||
if !str_eq(bca, "") { state_set("_ats_ts_raw", bca) }
|
||||
}
|
||||
let bn_ts_raw: String = state_get("_ats_ts_raw")
|
||||
let bn_ts: Int = if str_eq(bn_ts_raw, "") { 0 } else { str_to_int(bn_ts_raw) }
|
||||
let snip: String = if str_len(bn_c) > 200 { str_slice(bn_c, 0, 200) } else { bn_c }
|
||||
if bn_ts >= aff_7d_ts && !str_eq(snip, "") {
|
||||
let cur_acc: String = state_get(acc_key)
|
||||
if str_eq(cur_acc, "") { state_set(acc_key, snip) }
|
||||
if !str_eq(cur_acc, "") { state_set(acc_key, cur_acc + "\n" + snip) }
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// load_identity_context — pull key identity nodes from engram into working state.
|
||||
// Called at boot after engram_load. These nodes contain values, intellectual-dna,
|
||||
// memory-philosophy — the graph-stored self that chat.el can include in prompts.
|
||||
@@ -172,68 +209,29 @@ fn load_identity_context() -> Void {
|
||||
}
|
||||
|
||||
// Cross-session affective context: load BellEvent and PositiveEvent nodes from last 7 days.
|
||||
// (2026-06-23: replaced while-loop accumulation with manual 3-slot unroll via aff_try_slot.
|
||||
// The EL codegen bug: `let bacc = while ... { ... let bacc = ... }` emits `el_val_t bacc`
|
||||
// twice in the same C scope. Since search limit=3, manual unrolling is exact.)
|
||||
let aff_now: Int = time_now()
|
||||
let aff_7d: Int = aff_now - 604800
|
||||
let bell_raw: String = engram_search_json("bell:soft bell:hard BellEvent affective", 3)
|
||||
let bell_aff_ok: Bool = !str_eq(bell_raw, "") && !str_eq(bell_raw, "[]")
|
||||
let aff_ctx: String = ""
|
||||
let aff_ctx = if bell_aff_ok {
|
||||
let bn_total: Int = json_array_len(bell_raw)
|
||||
let bacc: String = ""
|
||||
let bi: Int = 0
|
||||
let bacc = while bi < bn_total {
|
||||
let bn: String = json_array_get(bell_raw, bi)
|
||||
let bn_c: String = json_get(bn, "content")
|
||||
let bm: String = " | ts:"
|
||||
let bmp: Int = str_index_of(bn_c, bm)
|
||||
let bn_ts_raw: String = if bmp >= 0 {
|
||||
let bs: Int = bmp + str_len(bm)
|
||||
let br: String = str_slice(bn_c, bs, str_len(bn_c))
|
||||
let bn_next: Int = str_index_of(br, " | ")
|
||||
if bn_next < 0 { br } else { str_slice(br, 0, bn_next) }
|
||||
} else {
|
||||
let bca: String = json_get(bn, "created_at")
|
||||
if str_eq(bca, "") { json_get(bn, "updated_at") } else { bca }
|
||||
}
|
||||
let bn_ts: Int = if str_eq(bn_ts_raw, "") { 0 } else { str_to_int(bn_ts_raw) }
|
||||
let snip: String = if str_len(bn_c) > 200 { str_slice(bn_c, 0, 200) } else { bn_c }
|
||||
let bacc = if bn_ts >= aff_7d && !str_eq(snip, "") {
|
||||
if str_eq(bacc, "") { snip } else { bacc + "\n" + snip }
|
||||
} else { bacc }
|
||||
let bi = bi + 1
|
||||
bacc
|
||||
}
|
||||
bacc
|
||||
state_set("_bell_acc", "")
|
||||
aff_try_slot(json_array_get(bell_raw, 0), aff_7d, "_bell_acc")
|
||||
aff_try_slot(json_array_get(bell_raw, 1), aff_7d, "_bell_acc")
|
||||
aff_try_slot(json_array_get(bell_raw, 2), aff_7d, "_bell_acc")
|
||||
state_get("_bell_acc")
|
||||
} else { "" }
|
||||
let pos_raw: String = engram_search_json("PositiveEvent joy:high joy:low affective", 3)
|
||||
let pos_aff_ok: Bool = !str_eq(pos_raw, "") && !str_eq(pos_raw, "[]")
|
||||
let aff_ctx = if pos_aff_ok {
|
||||
let pn_total: Int = json_array_len(pos_raw)
|
||||
let pacc: String = aff_ctx
|
||||
let pi: Int = 0
|
||||
let pacc = while pi < pn_total {
|
||||
let pn: String = json_array_get(pos_raw, pi)
|
||||
let pn_c: String = json_get(pn, "content")
|
||||
let pm: String = " | ts:"
|
||||
let pmp: Int = str_index_of(pn_c, pm)
|
||||
let pn_ts_raw: String = if pmp >= 0 {
|
||||
let ps: Int = pmp + str_len(pm)
|
||||
let pr: String = str_slice(pn_c, ps, str_len(pn_c))
|
||||
let pn_next: Int = str_index_of(pr, " | ")
|
||||
if pn_next < 0 { pr } else { str_slice(pr, 0, pn_next) }
|
||||
} else {
|
||||
let pca: String = json_get(pn, "created_at")
|
||||
if str_eq(pca, "") { json_get(pn, "updated_at") } else { pca }
|
||||
}
|
||||
let pn_ts: Int = if str_eq(pn_ts_raw, "") { 0 } else { str_to_int(pn_ts_raw) }
|
||||
let psnip: String = if str_len(pn_c) > 200 { str_slice(pn_c, 0, 200) } else { pn_c }
|
||||
let pacc = if pn_ts >= aff_7d && !str_eq(psnip, "") {
|
||||
if str_eq(pacc, "") { psnip } else { pacc + "\n" + psnip }
|
||||
} else { pacc }
|
||||
let pi = pi + 1
|
||||
pacc
|
||||
}
|
||||
pacc
|
||||
state_set("_pos_acc", aff_ctx)
|
||||
aff_try_slot(json_array_get(pos_raw, 0), aff_7d, "_pos_acc")
|
||||
aff_try_slot(json_array_get(pos_raw, 1), aff_7d, "_pos_acc")
|
||||
aff_try_slot(json_array_get(pos_raw, 2), aff_7d, "_pos_acc")
|
||||
state_get("_pos_acc")
|
||||
} else { aff_ctx }
|
||||
if !str_eq(aff_ctx, "") {
|
||||
state_set("soul_affective_context", aff_ctx)
|
||||
|
||||
Reference in New Issue
Block a user