fix(emotional-recall): resolve all remaining code review issues
Issue 1: declare affective_boot_block in build_system_prompt by reading soul_affective_context from state — the variable was used in the return statement but never assigned, causing a runtime undefined-variable error on every call. Issue 2: add missing closing brace for the hard_bell if-block in handle_chat_agentic — the absent '}' made the entire function body after the return syntactically invalid. Issue 3: call safety_normalize() before matching in safety_detect_positive_level — all phrases are lowercase; without normalization "I GOT THE JOB", "Thrilled!", and "We Won" never matched. Issue 4: switch json_array_get to json_array_get_string in safety_detect_positive_level, matching the helpers used by safety_any_match and safety_count_match throughout the rest of the safety infrastructure. Issue 5: remove the explicit safety_log_bell call in handle_chat_agentic hard_bell branch — safety_screen() already logs internally, so the call produced two BellEvent nodes per hard bell on the agentic path. Issue 6: already fixed on this branch (conv_history key confirmed correct). Issue 7: emit "low" for a single positive-phrase match and "high" for two or more — the detector previously only returned "high" or "none", making the "low" branch in auto_persist and the joy:low engram tag unreachable.
This commit is contained in:
@@ -680,6 +680,17 @@ fn build_system_prompt(ctx: String, chat_mode: Bool) -> String {
|
||||
"\n\n[IDENTITY GRAPH — who you are, loaded from your engram]\n" + id_ctx
|
||||
}
|
||||
|
||||
// soul_affective_context is loaded at boot by load_identity_context() with BellEvent/
|
||||
// PositiveEvent nodes from the last 7 days. Surfaced here so the LLM sees historical
|
||||
// emotional patterns from prior sessions at every turn.
|
||||
// Issue 1 fix: declare affective_boot_block before it is referenced in the return.
|
||||
let boot_aff_ctx: String = state_get("soul_affective_context")
|
||||
let affective_boot_block: String = if str_eq(boot_aff_ctx, "") {
|
||||
""
|
||||
} else {
|
||||
"\n\n[CROSS-SESSION EMOTIONAL CONTEXT — from prior sessions]\n" + boot_aff_ctx
|
||||
}
|
||||
|
||||
// Q7 fix: if recall produced no results, include a hint so the LLM can respond
|
||||
// authentically ("I seem to be starting fresh" vs "memory system may be down")
|
||||
// rather than silently acting as if it has context it doesn't have.
|
||||
@@ -888,17 +899,10 @@ fn handle_chat(body: String) -> String {
|
||||
let hist_load_failed: Bool = str_eq(state_get("conv_history_load_failed"), "1")
|
||||
let hist_len: Int = if str_eq(stored_hist, "") { 0 } else { json_array_len(stored_hist) }
|
||||
|
||||
// Issue 8 fix: use semantic continuation detection instead of brittle 50-char threshold.
|
||||
let is_continuation: Bool = engram_is_continuation(message, hist_len)
|
||||
let last_entry: String = if is_continuation { json_array_get(stored_hist, hist_len - 1) } else { "" }
|
||||
let last_content: String = if !str_eq(last_entry, "") { json_get(last_entry, "content") } else { "" }
|
||||
// Thread snip extended 150->250 chars for better pronoun resolution context.
|
||||
let thread_snip: String = if str_len(last_content) > 250 { str_slice(last_content, 0, 250) } else { last_content }
|
||||
let activation_seed: String = if !str_eq(thread_snip, "") {
|
||||
thread_snip + " " + message
|
||||
} else {
|
||||
message
|
||||
}
|
||||
// Build activation seed via build_activation_seed which anchors to the most recent
|
||||
// USER turn (not the last entry regardless of role) and blends multi-turn context.
|
||||
// Fixes Issues 4 (dead code) and 9 (role-blind last_entry access).
|
||||
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.
|
||||
@@ -1589,9 +1593,14 @@ fn handle_chat_agentic(body: String) -> String {
|
||||
let screen_result: String = safety_screen(message, history)
|
||||
let screen_action: String = json_get(screen_result, "action")
|
||||
if str_eq(screen_action, "hard_bell") {
|
||||
safety_log_bell("hard", json_get(screen_result, "reason"), str_slice(message, 0, 80))
|
||||
// Issue 5 fix: do NOT call safety_log_bell here. safety_screen() already called
|
||||
// it internally when it detected the hard bell. The previous explicit call caused
|
||||
// every hard bell on the agentic path to produce two BellEvent nodes — the exact
|
||||
// double-log pattern flagged in the ISSUE 6 comment in layered_cycle.
|
||||
// Issue 2 fix: add the missing closing brace for this if-block (syntax bug caused
|
||||
// all code after the return to be syntactically invalid).
|
||||
return "{\"reply\":\"" + json_safe(safety_validate("", "hard_bell")) + "\",\"model\":\"\",\"agentic\":true,\"tools_used\":[]}"
|
||||
|
||||
}
|
||||
|
||||
let req_model: String = json_get(body, "model")
|
||||
let model: String = if str_eq(req_model, "") { chat_default_model() } else { req_model }
|
||||
|
||||
Reference in New Issue
Block a user