From cbe8c09068cee586b35a98e41e4df2d247805b7b Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Mon, 22 Jun 2026 13:15:33 -0500 Subject: [PATCH] feat(recall): context-dedup improvements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Cache bell node in engram_compile state (engram_compile_bell_node) so handle_chat reads cached value instead of duplicate bell query (Issue 2) - Cache activation result (engram_compile_activation_json) for strengthen_chat_nodes reuse — eliminates third activation query per turn (Issue 7) - Fix context cap to truncate at clean JSON object boundary (Issue 6) --- chat.el | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/chat.el b/chat.el index 1ae7598..7196af8 100644 --- a/chat.el +++ b/chat.el @@ -422,13 +422,26 @@ fn engram_compile(intent: String) -> String { let sep3: String = if (!str_eq(act_part, "") || !str_eq(srch_part, "") || !str_eq(scan_part, "")) && !str_eq(affective_part, "") { "\n" } else { "" } let ctx: String = act_part + sep1 + srch_part + sep2 + scan_part + sep3 + affective_part + // Cache bell and activation results for handle_chat reuse (Issues 2, 7). + state_set("engram_compile_bell_node", recent_bell) + state_set("engram_compile_activation_json", if act_ok { activate_json } else { "[]" }) + if str_eq(ctx, "") { return "" } - // Raise the cap slightly to match the ranked (higher-signal) output. - if str_len(ctx) > 6000 { - return str_slice(ctx, 0, 6000) + // Fix Issue 6: cap at a clean JSON object boundary. + let cap_len: Int = 6000 + if str_len(ctx) <= cap_len { return ctx } + let cap_search: Int = cap_len - 1 + let cap_min: Int = if cap_len > 500 { cap_len - 500 } else { 0 } + let cap_pos: Int = -1 + let cap_si: Int = cap_search + while cap_si >= cap_min && cap_pos < 0 { + let cap_ch: String = str_slice(ctx, cap_si, cap_si + 1) + let cap_pos = if str_eq(cap_ch, "}") { cap_si } else { cap_pos } + let cap_si = if cap_pos < 0 { cap_si - 1 } else { cap_si } } - return ctx + if cap_pos > 0 { return str_slice(ctx, 0, cap_pos + 1) } + return str_slice(ctx, 0, cap_len) } fn json_safe(s: String) -> String { @@ -623,21 +636,10 @@ fn handle_chat(body: String) -> String { // and tail-biased snipping from long assistant replies. let activation_seed: String = build_activation_seed(message, stored_hist, hist_len) - // Cross-session affective context: on session start (no history yet), check engram - // for recent distress signals within 72h and prepend a care directive if found. + // Fix Issue 2: reuse cached bell result from engram_compile — no second engram query. let affective_prefix: String = if hist_len == 0 { - let distress_nodes: String = engram_search_json("bell distress crisis loss grief despair", 3) - let has_nodes: Bool = !str_eq(distress_nodes, "") && !str_eq(distress_nodes, "[]") - let now_ts: Int = time_now() - let cutoff: Int = now_ts - 259200 - let found_recent: Bool = if has_nodes { - let dn0: String = json_array_get(distress_nodes, 0) - let ts0_raw: String = json_get(dn0, "created_at") - let ts0_str: String = if str_eq(ts0_raw, "") { json_get(dn0, "updated_at") } else { ts0_raw } - let ts0: Int = if str_eq(ts0_str, "") { 0 } else { str_to_int(ts0_str) } - ts0 > cutoff - } else { false } - if found_recent { + let cached_bell: String = state_get("engram_compile_bell_node") + if !str_eq(cached_bell, "") { "[RECENT CONTEXT: User recently expressed significant distress. Monitor for indirect crisis signals and respond with care.]\n\n" } else { "" } } else { "" } @@ -752,9 +754,11 @@ fn handle_chat(body: String) -> String { state_set("conv_history", final_hist) conv_history_persist(final_hist) - let activation_nodes: String = engram_activate_json(message, 2) - let act_ok: Bool = !str_eq(activation_nodes, "") && !str_eq(activation_nodes, "[]") - let act_out: String = if act_ok { activation_nodes } else { "[]" } + // Fix Issue 7: reuse activation JSON from engram_compile — no third activate query. + let cached_act: String = state_get("engram_compile_activation_json") + let act_out: String = if !str_eq(cached_act, "") && !str_eq(cached_act, "[]") { + cached_act + } else { "[]" } strengthen_chat_nodes(act_out) return "{\"response\":\"" + safe_response + "\",\"model\":\"" + model + "\",\"activation_nodes\":" + act_out + "}"