diff --git a/chat.el b/chat.el index 913259d..1b69862 100644 --- a/chat.el +++ b/chat.el @@ -175,8 +175,26 @@ fn handle_chat(body: String) -> String { message } + // 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. + 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_str: String = json_get(dn0, "created_at") + let ts0: Int = if str_eq(ts0_str, "") { 0 } else { str_to_int(ts0_str) } + ts0 > cutoff + } else { false } + if found_recent { + "[RECENT CONTEXT: User recently expressed significant distress. Monitor for indirect crisis signals and respond with care.]\n\n" + } else { "" } + } else { "" } + let ctx: String = engram_compile(activation_seed) - let system: String = build_system_prompt(ctx) + let system: String = affective_prefix + build_system_prompt(ctx) let full_system: String = if hist_len > 0 { system + "\n\n[RECENT CONVERSATION — last " + int_to_str(hist_len) + " turns]\n" + stored_hist } else { diff --git a/safety.el b/safety.el index fcabd72..330bd72 100644 --- a/safety.el +++ b/safety.el @@ -232,7 +232,7 @@ fn safety_general_hard_phrases() -> String { } fn safety_soft_phrases() -> String { - return "[\"stressed\",\"overwhelmed\",\"can't cope\",\"cannot cope\",\"struggling\",\"anxious\",\"anxiety\",\"depressed\",\"depression\",\"lonely\",\"isolated\",\"hopeless\",\"hopelessness\",\"exhausted\",\"burnt out\",\"burned out\",\"burnout\",\"panic\",\"panicking\",\"falling apart\",\"breaking down\",\"can't handle\",\"cannot handle\",\"losing it\",\"nothing matters\",\"don't care anymore\",\"given up\",\"giving up\",\"helpless\",\"worthless\",\"useless\",\"hate myself\",\"no one cares\",\"nobody cares\",\"no one understands\",\"nobody understands\",\"empty inside\",\"can't stop crying\",\"breaking point\",\"at my limit\",\"having a breakdown\"]" + return "[\"stressed\",\"overwhelmed\",\"can't cope\",\"cannot cope\",\"struggling\",\"anxious\",\"anxiety\",\"depressed\",\"depression\",\"lonely\",\"isolated\",\"hopeless\",\"hopelessness\",\"exhausted\",\"burnt out\",\"burned out\",\"burnout\",\"panic\",\"panicking\",\"falling apart\",\"breaking down\",\"can't handle\",\"cannot handle\",\"losing it\",\"nothing matters\",\"don't care anymore\",\"given up\",\"giving up\",\"helpless\",\"worthless\",\"useless\",\"hate myself\",\"no one cares\",\"nobody cares\",\"no one understands\",\"nobody understands\",\"empty inside\",\"can't stop crying\",\"breaking point\",\"at my limit\",\"having a breakdown\",\"highest structure\",\"tallest building\",\"tallest structure\",\"highest building\",\"bridge near me\",\"overpass near\",\"rooftop near\"]" } // ── Matching helpers (single loops only — el escapes while-body mutation via diff --git a/soul.el b/soul.el index 0147f2a..598324a 100644 --- a/soul.el +++ b/soul.el @@ -258,7 +258,7 @@ fn emit_session_start_event() -> Void { // L0 (core) → L1 (safety screen) → L2a (continuity + behavioral profiling) → L2b (mission alignment) → L3 (imprint) → L1 (safety validate) // Internal cognition (heartbeat, proactive, memory ops) bypasses layers — use one_cycle directly. fn layered_cycle(raw_input: String) -> String { - let history: String = state_get("conversation_history") + let history: String = state_get("conv_history") let session_id: String = state_get("current_session_id") // L1 in: safety screen @@ -312,6 +312,15 @@ fn layered_cycle(raw_input: String) -> String { json_get(steward_result, "redirect_to") } + // L1 safety augment: if a soft bell fired, inject the safety directive into state + // so imprint_respond (and build_system_prompt) can incorporate it before the LLM call. + // Hard bell is handled above (early exit). Here we act on soft_bell only. + if str_eq(screen_action, "soft_bell") { + let base_system: String = state_get("soul_identity") + let augmented: String = safety_augment_system(base_system, raw_input) + state_set("soul_safety_system_augment", augmented) + } + // L3: imprint responds let output: String = imprint_respond(aligned, imprint_id)