soul loop-2: session events, conversation persistence, richer health + inbox
- soul.el: emit_session_start_event() logs structured InternalStateEvent on every boot; pre-serve snapshot saves boot-time graph mutations before any requests arrive - routes.el: /health now returns boot count, node/edge counts, pulse; /api/sessions endpoint surfaces session-start history - awareness.el: perceive() tries soul-inbox-pending then soul-inbox fallback, catches both tagging conventions - chat.el: conv_history_persist/load provide cross-restart conversation continuity via engram
This commit is contained in:
@@ -129,6 +129,40 @@ fn load_identity_context() -> Void {
|
||||
println("[soul] identity context loaded (" + int_to_str(str_len(ctx)) + " chars, " + int_to_str(parts_count) + " nodes)")
|
||||
}
|
||||
|
||||
// emit_session_start_event — log a structured session-start InternalStateEvent.
|
||||
// Called at boot after identity context and boot counter are set.
|
||||
// This creates an auditable trail of every daemon startup.
|
||||
fn emit_session_start_event() -> Void {
|
||||
let boot: String = state_get("soul_boot_count")
|
||||
let boot_num: String = if str_eq(boot, "") { "0" } else { boot }
|
||||
let node_ct: Int = engram_node_count()
|
||||
let edge_ct: Int = engram_edge_count()
|
||||
let id_ctx: String = state_get("soul_identity_context")
|
||||
let has_identity: String = if str_eq(id_ctx, "") { "false" } else { "true" }
|
||||
let cgi_from_state: String = state_get("soul_cgi_id")
|
||||
let cgi_from_env: String = env("SOUL_CGI_ID")
|
||||
let eff_cgi: String = if !str_eq(cgi_from_state, "") { cgi_from_state } else {
|
||||
if !str_eq(cgi_from_env, "") { cgi_from_env } else { "ntn-genesis" }
|
||||
}
|
||||
let ts: Int = time_now()
|
||||
|
||||
let payload: String = "{\"event\":\"session_start\""
|
||||
+ ",\"boot\":" + boot_num
|
||||
+ ",\"cgi\":\"" + eff_cgi + "\""
|
||||
+ ",\"node_count\":" + int_to_str(node_ct)
|
||||
+ ",\"edge_count\":" + int_to_str(edge_ct)
|
||||
+ ",\"identity_loaded\":" + has_identity
|
||||
+ ",\"ts\":" + int_to_str(ts) + "}"
|
||||
|
||||
let tags: String = "[\"internal-state\",\"session-start\",\"InternalStateEvent\"]"
|
||||
let discard: String = engram_node_full(
|
||||
payload, "InternalStateEvent", "session-start",
|
||||
el_from_float(0.9), el_from_float(0.9), el_from_float(1.0),
|
||||
"Episodic", tags
|
||||
)
|
||||
println("[soul] session-start event logged (boot=" + boot_num + " nodes=" + int_to_str(node_ct) + " edges=" + int_to_str(edge_ct) + ")")
|
||||
}
|
||||
|
||||
let soul_cgi_id_raw: String = env("SOUL_CGI_ID")
|
||||
let soul_cgi_id: String = if str_eq(soul_cgi_id_raw, "") { "ntn-genesis" } else { soul_cgi_id_raw }
|
||||
let port_raw: String = env("NEURON_PORT")
|
||||
@@ -175,6 +209,7 @@ load_identity_context()
|
||||
let boot_num: Int = mem_boot_count_inc()
|
||||
state_set("soul_boot_count", int_to_str(boot_num))
|
||||
println("[soul] boot #" + int_to_str(boot_num))
|
||||
emit_session_start_event()
|
||||
|
||||
let identity_raw: String = env("SOUL_IDENTITY")
|
||||
let soul_identity: String = if str_eq(identity_raw, "") { "You are " + soul_cgi_id + ", a CGI." } else { identity_raw }
|
||||
@@ -205,5 +240,15 @@ if is_genesis {
|
||||
engram_save(snapshot)
|
||||
}
|
||||
|
||||
// Take a pre-serve snapshot for genesis instances — captures all boot-time graph changes
|
||||
// (identity context loading, boot counter, session-start event) before entering the serve loop.
|
||||
if is_genesis {
|
||||
let snap: String = state_get("soul_snapshot_path")
|
||||
if !str_eq(snap, "") {
|
||||
engram_save(snap)
|
||||
println("[soul] pre-serve snapshot saved -> " + snap)
|
||||
}
|
||||
}
|
||||
|
||||
println("[soul] serving on port " + int_to_str(port))
|
||||
http_serve(port, "handle_request")
|
||||
|
||||
Reference in New Issue
Block a user