Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c8d5f57de7 |
@@ -885,7 +885,7 @@ fn handle_chat(body: String) -> String {
|
||||
|
||||
// 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 = {
|
||||
let affective_prefix: String = if true {
|
||||
// Runs every turn. Uses correct BellEvent/PositiveEvent tags.
|
||||
let aff_now_ts: Int = time_now()
|
||||
let aff_cutoff: Int = aff_now_ts - 259200
|
||||
@@ -940,7 +940,7 @@ fn handle_chat(body: String) -> String {
|
||||
"[RECENT CONTEXT: User recently shared exciting or joyful news. Acknowledge and celebrate with them when relevant.]\n\n"
|
||||
} else { "" }
|
||||
}
|
||||
}
|
||||
} else { "" }
|
||||
|
||||
let ctx: String = engram_compile(activation_seed)
|
||||
let system: String = affective_prefix + build_system_prompt(ctx, true)
|
||||
@@ -2086,6 +2086,18 @@ fn handle_chat_as_soul(body: String) -> String {
|
||||
// The soul's engram activates on the transcript content — its own recall,
|
||||
// not external injection. The system prompt is just identity.
|
||||
//
|
||||
// distill_transcript — reduce a full room transcript to the salient tail that
|
||||
// should drive engram activation. Minimal implementation: keep the last 4000
|
||||
// characters (the recent exchange + trailing question). A full transcript still
|
||||
// activates correctly; this just bounds the activation seed for long rooms.
|
||||
fn distill_transcript(transcript: String) -> String {
|
||||
let tlen: Int = str_len(transcript)
|
||||
if tlen <= 4000 {
|
||||
return transcript
|
||||
}
|
||||
return str_slice(transcript, tlen - 4000, tlen)
|
||||
}
|
||||
|
||||
// After responding, the soul records what it said in its own engram.
|
||||
// That is how it learns. Not from being told about the room.
|
||||
fn handle_dharma_room_turn(body: String) -> String {
|
||||
|
||||
@@ -109,8 +109,22 @@ fn mem_consolidate() -> String {
|
||||
}
|
||||
|
||||
fn mem_save(path: String) -> Void {
|
||||
let save_result: String = engram_save(path)
|
||||
if str_eq(save_result, "") {
|
||||
// ENGRAM_STORE on: the durable path is a checkpoint of the resident graph into
|
||||
// the paged store (persists learned hebb + activation-formed edges via the WAL).
|
||||
// The JSON engram_save stays available as an explicit export elsewhere; here the
|
||||
// store is authoritative, so we checkpoint instead of writing the snapshot.
|
||||
let store_flag: String = env("ENGRAM_STORE")
|
||||
if str_eq(store_flag, "1") || str_eq(store_flag, "on") || str_eq(store_flag, "true") {
|
||||
let ck: Int = engram_store_checkpoint()
|
||||
if ck == 0 {
|
||||
println("[memory] mem_save: engram_store_checkpoint returned 0 — checkpoint may have failed")
|
||||
}
|
||||
return
|
||||
}
|
||||
// engram_save returns Int 1/0 (ok/fail), not a String — checking it as a
|
||||
// String (str_eq(save_result, "")) dereferences a tagged int and segfaults.
|
||||
let save_result: Int = engram_save(path)
|
||||
if save_result == 0 {
|
||||
println("[memory] mem_save: engram_save failed for " + path + " — snapshot may be incomplete")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,7 +244,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\"]"
|
||||
}
|
||||
|
||||
// ISSUE 5 TODO: phrase lists are rebuilt from JSON literals on every call.
|
||||
|
||||
+2
-2
@@ -503,10 +503,10 @@ fn session_hist_save(session_id: String, hist: String) -> Void {
|
||||
let last_role: String = json_get(last_entry, "role")
|
||||
let last_content: String = json_get(last_entry, "content")
|
||||
let topic_snip: String = if str_len(last_content) > 200 { str_slice(last_content, 0, 200) } else { last_content }
|
||||
let safe_topic: String = str_replace(topic_snip, """, "'")
|
||||
let safe_topic: String = str_replace(topic_snip, "\"", "'")
|
||||
let ts_now: String = int_to_str(time_now())
|
||||
let topic_content: String = "last-session-topic | ts:" + ts_now + " | session:" + session_id + " | topic:" + safe_topic
|
||||
let topic_tags: String = "["last-session-topic","conv:history","Conversation","session:topic"]"
|
||||
let topic_tags: String = "[\"last-session-topic\",\"conv:history\",\"Conversation\",\"session:topic\"]"
|
||||
let topic_label: String = "last-session-topic:" + session_id
|
||||
// Delete old last-session-topic node for this session before writing fresh
|
||||
let old_topic: String = engram_search_json("last-session-topic:" + session_id, 2)
|
||||
|
||||
@@ -500,11 +500,28 @@ println("[soul] boot - cgi=" + soul_cgi_id + " port=" + int_to_str(port))
|
||||
|
||||
let using_http_engram: Bool = !str_eq(engram_url_raw, "")
|
||||
|
||||
// ENGRAM_STORE (tiered paged store): when the flag is on, the durable neuron.egm
|
||||
// store — not the JSON snapshot — is the source of truth. engram_store_boot does
|
||||
// import-once + WAL-replay + resident load; every structural mutation is mirrored
|
||||
// into the store's WAL, and mem_save() checkpoints the resident graph (incl.
|
||||
// learned hebb) so associations survive a restart. Flag OFF is unchanged.
|
||||
let engram_store_flag: String = env("ENGRAM_STORE")
|
||||
let engram_store_on: Bool = str_eq(engram_store_flag, "1") || str_eq(engram_store_flag, "on") || str_eq(engram_store_flag, "true")
|
||||
let engram_data_dir_raw: String = env("ENGRAM_DATA_DIR")
|
||||
let engram_data_dir: String = if str_eq(engram_data_dir_raw, "") { env("HOME") + "/.neuron/engram" } else { engram_data_dir_raw }
|
||||
|
||||
// Always try local snapshot first. If it has content (>50 nodes) it was
|
||||
// previously seeded from HTTP Engram and is kept up-to-date by the awareness
|
||||
// loop — use it. This preserves sessions and memories across restarts.
|
||||
// HTTP Engram is only used for the very first boot (empty/absent snapshot).
|
||||
engram_load(snapshot)
|
||||
if engram_store_on {
|
||||
let booted: Int = engram_store_boot(engram_data_dir)
|
||||
println("[soul] ENGRAM_STORE on — booted paged store from " + engram_data_dir
|
||||
+ " (rc=" + int_to_str(booted) + ") nodes=" + int_to_str(engram_node_count())
|
||||
+ " edges=" + int_to_str(engram_edge_count()))
|
||||
} else {
|
||||
engram_load(snapshot)
|
||||
}
|
||||
let local_node_count: Int = engram_node_count()
|
||||
let snapshot_usable: Bool = local_node_count > 50
|
||||
|
||||
|
||||
Reference in New Issue
Block a user