Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 715dea0f44 |
@@ -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 }
|
||||
|
||||
@@ -299,19 +299,31 @@ fn safety_positive_phrases() -> String {
|
||||
return "[\"thrilled\",\"so excited\",\"so happy\",\"over the moon\",\"ecstatic\",\"amazing news\",\"great news\",\"fantastic news\",\"wonderful news\",\"incredible news\",\"i got the job\",\"got accepted\",\"got in\",\"we won\",\"i won\",\"we got\",\"just got engaged\",\"getting married\",\"baby is here\",\"she said yes\",\"he said yes\",\"passed the exam\",\"aced it\",\"nailed it\",\"best day\",\"dream come true\",\"milestone\",\"promotion\",\"got promoted\",\"raise\",\"got a raise\",\"celebrating\",\"just graduated\",\"we closed\",\"launched\",\"shipped it\",\"we did it\",\"so proud\",\"proud of myself\",\"proud of us\",\"so grateful\",\"feel amazing\",\"feeling amazing\",\"feel great\",\"feeling great\",\"on top of the world\",\"life is good\",\"couldn't be happier\"]"
|
||||
}
|
||||
|
||||
// Returns "none" | "low" | "high".
|
||||
// Issue 3 fix: normalize the message before matching — all phrases in the list are
|
||||
// lowercase, and sibling functions (safety_detect_bell_level, safety_classify_hard_bell)
|
||||
// both call safety_normalize() first. Without normalization, messages like "I GOT THE JOB",
|
||||
// "Thrilled!", or "We Won" never match and silently return "none".
|
||||
// Issue 4 fix: use json_array_get_string (matching safety_any_match / safety_count_match)
|
||||
// instead of json_array_get, so phrase extraction uses the same helper everywhere.
|
||||
// Issue 7 fix: emit "low" for a single-phrase match and "high" for two or more.
|
||||
// Previously only "high" or "none" were possible, making the "low" branch in auto_persist
|
||||
// and the "joy:low" engram tag permanently unreachable.
|
||||
fn safety_detect_positive_level(message: String) -> String {
|
||||
let text: String = safety_normalize(message)
|
||||
let phrases: String = safety_positive_phrases()
|
||||
let phrases_ok: Bool = !str_eq(phrases, "") && !str_eq(phrases, "[]")
|
||||
if !phrases_ok { return "none" }
|
||||
let n: Int = json_array_len(phrases)
|
||||
let i: Int = 0
|
||||
let count: Int = 0
|
||||
while i < n {
|
||||
let phrase: String = json_array_get(phrases, i)
|
||||
if str_contains(message, phrase) {
|
||||
return "high"
|
||||
}
|
||||
let phrase: String = json_array_get_string(phrases, i)
|
||||
let count = if str_contains(text, phrase) { count + 1 } else { count }
|
||||
let i = i + 1
|
||||
}
|
||||
if count >= 2 { return "high" }
|
||||
if count == 1 { return "low" }
|
||||
return "none"
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user