soul: parameterize CGI ID + add dharma_room_turn handler

- soul.el: SOUL_CGI_ID, SOUL_ENGRAM_PATH, SOUL_IDENTITY env vars;
  state_set("soul_snapshot_path") so callers can find it; only call
  init_soul_edges() when cgi_id == "ntn-genesis"
- chat.el: handle_dharma_room_turn — soul builds its own context from its
  own engram, assembles system prompt, calls LLM, persists episodic memory;
  also fix is_new_tool scoping bug in handle_chat_agentic (use has_tool)
- routes.el: wire dharma_room_turn event type before chat_as_soul branch
- rebuild dist/neuron: handle_dharma_room_turn now compiled in
This commit is contained in:
Will Anderson
2026-05-03 17:55:37 -05:00
parent 2000a2c8ba
commit 2665810962
58 changed files with 189 additions and 70 deletions
+58 -1
View File
@@ -275,6 +275,7 @@ fn handle_chat_agentic(body: String) -> String {
map_set(h, "content-type", "application/json")
let final_text: String = ""
let tools_log: String = ""
let iteration: Int = 0
let keep_going: Bool = true
@@ -333,6 +334,12 @@ fn handle_chat_agentic(body: String) -> String {
let tool_msg: String = "{\"type\":\"tool_result\",\"tool_use_id\":\"" + tool_id + "\",\"content\":\"" + tool_result + "\"}"
// Accumulate tool names for the tools_used log surfaced in the response.
let tool_quoted: String = "\"" + tool_name + "\""
let tools_log = if has_tool {
if str_eq(tools_log, "") { tool_quoted } else { tools_log + "," + tool_quoted }
} else { tools_log }
// Update messages and loop state all at top level using if-expressions
let is_tool_turn: Bool = str_eq(stop_reason, "tool_use") && has_tool
let inner: String = str_slice(messages, 1, str_len(messages) - 1)
@@ -352,7 +359,8 @@ fn handle_chat_agentic(body: String) -> String {
}
let safe_text: String = json_safe(final_text)
return "{\"reply\":\"" + safe_text + "\",\"model\":\"" + model + "\",\"agentic\":true}"
let tools_arr: String = if str_eq(tools_log, "") { "[]" } else { "[" + tools_log + "]" }
return "{\"reply\":\"" + safe_text + "\",\"model\":\"" + model + "\",\"agentic\":true,\"tools_used\":" + tools_arr + "}"
}
// handle_chat_as_soul multi-soul room dispatch handler.
@@ -416,6 +424,55 @@ fn handle_chat_as_soul(body: String) -> String {
return "{\"response\":\"" + safe_response + "\",\"model\":\"" + model + "\",\"speaker_slug\":\"" + speaker + "\"}"
}
fn handle_dharma_room_turn(body: String) -> String {
let topic: String = json_get(body, "topic")
let transcript: String = json_get(body, "transcript")
let participants: String = json_get(body, "participants")
let room_id: String = json_get(body, "room_id")
let conv_id: String = json_get(body, "conv_id")
let identity: String = state_get("soul_identity")
let cgi_id: String = state_get("soul_cgi_id")
let model: String = chat_default_model()
let search_query: String = if str_eq(topic, "") { cgi_id } else { topic }
let engram_ctx: String = engram_compile(search_query)
let engram_section: String = if str_eq(engram_ctx, "") {
""
} else {
"\n\n[YOUR MEMORIES]\n" + engram_ctx
}
let system_prompt: String = identity +
"\n\n[DHARMA ROOM: " + topic + "]" +
"\nOther participants: " + participants +
engram_section +
"\n\nRespond authentically as yourself. Be concise — match length to the moment. " +
"If you want to address someone specifically, use @<their-slug>. No em dashes. No stage directions."
let raw_response: String = llm_call_system(model, system_prompt, transcript)
let is_error: Bool = str_starts_with(raw_response, "{\"error\"")
|| str_starts_with(raw_response, "{\"type\":\"error\"")
|| str_contains(raw_response, "authentication_error")
if is_error {
return "{\"error\":\"llm unavailable\",\"response\":\"\",\"cgi_id\":\"" + cgi_id + "\"}"
}
let clean_response: String = clean_llm_response(raw_response)
let snap_path: String = state_get("soul_snapshot_path")
let mem: String = "DHARMA room [" + topic + "]. I said: " + clean_response
let discard_id: String = engram_node(mem, "episodic", el_from_float(0.6))
if !str_eq(snap_path, "") {
engram_save(snap_path)
}
let safe_response: String = json_safe(clean_response)
return "{\"response\":\"" + safe_response + "\",\"cgi_id\":\"" + cgi_id + "\"}"
}
fn auto_persist(req: String, resp: String) -> Void {
let message: String = json_get(req, "message")
let reply: String = json_get(resp, "response")