soul: persist sessions across restarts via local snapshot
On startup, prefer the local engram snapshot if it has >50 nodes. HTTP Engram is only used on first boot (no snapshot yet). This means sessions, conversation history, and in-process state survive daemon restarts. awareness.el: sync source with compiled binary (periodic mem_save on heartbeat was already in the binary but not in source). Rebuilds soul.c with the new startup logic and ships updated binary.
This commit is contained in:
@@ -440,6 +440,12 @@ fn awareness_run() -> Void {
|
|||||||
if should_beat {
|
if should_beat {
|
||||||
emit_heartbeat()
|
emit_heartbeat()
|
||||||
state_set("soul.last_beat_ts", int_to_str(now_ts))
|
state_set("soul.last_beat_ts", int_to_str(now_ts))
|
||||||
|
// Persist in-process Engram (sessions, memories, conversation nodes)
|
||||||
|
// to local snapshot so they survive restarts.
|
||||||
|
let snap_path: String = state_get("soul_snapshot_path")
|
||||||
|
if !str_eq(snap_path, "") {
|
||||||
|
mem_save(snap_path)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Curiosity scan: idle-gated AND wall-clock based. Only fires when the
|
// Curiosity scan: idle-gated AND wall-clock based. Only fires when the
|
||||||
|
|||||||
Vendored
BIN
Binary file not shown.
Vendored
+28101
-82
File diff suppressed because one or more lines are too long
@@ -251,11 +251,17 @@ println("[soul] boot - cgi=" + soul_cgi_id + " port=" + int_to_str(port))
|
|||||||
|
|
||||||
let using_http_engram: Bool = !str_eq(engram_url_raw, "")
|
let using_http_engram: Bool = !str_eq(engram_url_raw, "")
|
||||||
|
|
||||||
if using_http_engram {
|
// Always try local snapshot first. If it has content (>50 nodes) it was
|
||||||
// Bootstrap in-memory Engram store from the running HTTP Engram server.
|
// previously seeded from HTTP Engram and is kept up-to-date by the awareness
|
||||||
// Fetch all nodes and edges, compose a snapshot JSON, write to a temp
|
// loop — use it. This preserves sessions and memories across restarts.
|
||||||
// file, and load it. The HTTP Engram owns persistence — we do not save back.
|
// HTTP Engram is only used for the very first boot (empty/absent snapshot).
|
||||||
println("[soul] engram -> HTTP " + engram_url_raw)
|
engram_load(snapshot)
|
||||||
|
let local_node_count: Int = engram_node_count()
|
||||||
|
let snapshot_usable: Bool = local_node_count > 50
|
||||||
|
|
||||||
|
if using_http_engram && !snapshot_usable {
|
||||||
|
// First boot or empty/corrupt snapshot: seed from HTTP Engram.
|
||||||
|
println("[soul] engram -> HTTP " + engram_url_raw + " (no local snapshot, first boot)")
|
||||||
let nodes_json: String = http_get(engram_url_raw + "/api/nodes?limit=10000")
|
let nodes_json: String = http_get(engram_url_raw + "/api/nodes?limit=10000")
|
||||||
let edges_json: String = http_get(engram_url_raw + "/api/edges")
|
let edges_json: String = http_get(engram_url_raw + "/api/edges")
|
||||||
let nodes_part: String = if str_eq(nodes_json, "") { "[]" } else { nodes_json }
|
let nodes_part: String = if str_eq(nodes_json, "") { "[]" } else { nodes_json }
|
||||||
@@ -266,9 +272,7 @@ if using_http_engram {
|
|||||||
engram_load(tmp_path)
|
engram_load(tmp_path)
|
||||||
println("[soul] loaded from HTTP Engram - nodes=" + int_to_str(engram_node_count()) + " edges=" + int_to_str(engram_edge_count()))
|
println("[soul] loaded from HTTP Engram - nodes=" + int_to_str(engram_node_count()) + " edges=" + int_to_str(engram_edge_count()))
|
||||||
} else {
|
} else {
|
||||||
println("[soul] engram -> " + snapshot)
|
println("[soul] loaded from local snapshot - nodes=" + int_to_str(local_node_count) + " edges=" + int_to_str(engram_edge_count()))
|
||||||
engram_load(snapshot)
|
|
||||||
println("[soul] loaded - nodes=" + int_to_str(engram_node_count()) + " edges=" + int_to_str(engram_edge_count()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
load_identity_context()
|
load_identity_context()
|
||||||
|
|||||||
Reference in New Issue
Block a user