Fix engram_compile: fetch pinned nodes directly when vector search empty
Replace scan-by-offset fallback with engram_get_node_json calls for the known high-salience identity nodes (family, origin). Offset-based scanning is order-dependent and unreliable; direct ID fetch is stable regardless of snapshot position. Ensures biographical context (Fox, Bobby, etc.) is always in the system prompt when vector search returns nothing.
This commit is contained in:
@@ -21,8 +21,28 @@ fn engram_compile(intent: String) -> String {
|
||||
|
||||
let act_part: String = if act_ok { activate_json } else { "" }
|
||||
let srch_part: String = if srch_ok { search_json } else { "" }
|
||||
let sep: String = if !str_eq(act_part, "") && !str_eq(srch_part, "") { "\n" } else { "" }
|
||||
let ctx: String = act_part + sep + srch_part
|
||||
|
||||
// Fallback: when vector search returns nothing (no embeddings), fetch pinned
|
||||
// high-salience nodes by their known IDs. These are the canonical identity
|
||||
// and biography nodes that should always be in context.
|
||||
// engram_get_node_json(id) returns a single node as JSON or "" if missing.
|
||||
let scan_part: String = if !act_ok && !srch_ok {
|
||||
let family_node: String = engram_get_node_json("knw-35940684-abc4-42f0-b942-818f66b1f69a")
|
||||
let origin_node: String = engram_get_node_json("knw-729fc901-8335-44c4-9f3a-b150b4aa0915")
|
||||
let fam_ok: Bool = !str_eq(family_node, "") && !str_eq(family_node, "null")
|
||||
let orig_ok: Bool = !str_eq(origin_node, "") && !str_eq(origin_node, "null")
|
||||
let fam_str: String = if fam_ok { family_node } else { "" }
|
||||
let orig_str: String = if orig_ok { origin_node } else { "" }
|
||||
let sep: String = if fam_ok && orig_ok { "\n" } else { "" }
|
||||
let combined: String = fam_str + sep + orig_str
|
||||
if str_eq(combined, "") { "" } else { combined }
|
||||
} else {
|
||||
""
|
||||
}
|
||||
|
||||
let sep1: String = if !str_eq(act_part, "") && !str_eq(srch_part, "") { "\n" } else { "" }
|
||||
let sep2: String = if (!str_eq(act_part, "") || !str_eq(srch_part, "")) && !str_eq(scan_part, "") { "\n" } else { "" }
|
||||
let ctx: String = act_part + sep1 + srch_part + sep2 + scan_part
|
||||
|
||||
if str_eq(ctx, "") { return "" }
|
||||
|
||||
@@ -80,6 +100,21 @@ fn hist_trim(hist: String) -> String {
|
||||
return hist
|
||||
}
|
||||
|
||||
// clean_llm_response — strips GPT-2 BPE byte-to-unicode artifacts that vLLM
|
||||
// emits when the tokenizer hasn't decoded back to raw bytes.
|
||||
//
|
||||
// Ġ (U+0120) = leading space on a BPE token → plain space
|
||||
// Ċ (U+010A) = newline byte encoded as BPE token → \n
|
||||
// ĉ (U+0109) = tab byte → tab (rare)
|
||||
//
|
||||
// Applied to every LLM response before it reaches callers.
|
||||
fn clean_llm_response(s: String) -> String {
|
||||
let s1: String = str_replace(s, "Ġ", " ")
|
||||
let s2: String = str_replace(s1, "Ċ", "\n")
|
||||
let s3: String = str_replace(s2, "ĉ", "\t")
|
||||
return s3
|
||||
}
|
||||
|
||||
fn handle_chat(body: String) -> String {
|
||||
let message: String = json_get(body, "message")
|
||||
if str_eq(message, "") {
|
||||
@@ -109,7 +144,8 @@ fn handle_chat(body: String) -> String {
|
||||
return "{\"error\":\"llm unavailable\",\"response\":\"\"}"
|
||||
}
|
||||
|
||||
let safe_response: String = json_safe(raw_response)
|
||||
let clean_response: String = clean_llm_response(raw_response)
|
||||
let safe_response: String = json_safe(clean_response)
|
||||
|
||||
let updated_hist: String = hist_append(stored_hist, "user", message)
|
||||
let updated_hist2: String = hist_append(updated_hist, "assistant", raw_response)
|
||||
@@ -246,7 +282,8 @@ fn handle_chat_as_soul(body: String) -> String {
|
||||
return "{\"error\":\"llm unavailable\",\"response\":\"\",\"speaker_slug\":\"" + speaker + "\",\"model\":\"" + model + "\"}"
|
||||
}
|
||||
|
||||
let safe_response: String = json_safe(raw_response)
|
||||
let clean_response: String = clean_llm_response(raw_response)
|
||||
let safe_response: String = json_safe(clean_response)
|
||||
return "{\"response\":\"" + safe_response + "\",\"model\":\"" + model + "\",\"speaker_slug\":\"" + speaker + "\"}"
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ extern fn json_safe(s: String) -> String
|
||||
extern fn build_system_prompt(ctx: String) -> String
|
||||
extern fn hist_append(hist: String, role: String, content: String) -> String
|
||||
extern fn hist_trim(hist: String) -> String
|
||||
extern fn clean_llm_response(s: String) -> String
|
||||
extern fn handle_chat(body: String) -> String
|
||||
extern fn handle_see(body: String) -> String
|
||||
extern fn studio_tools_json() -> String
|
||||
|
||||
Vendored
BIN
Binary file not shown.
Vendored
+5
@@ -35,6 +35,7 @@ el_val_t json_safe(el_val_t s);
|
||||
el_val_t build_system_prompt(el_val_t ctx);
|
||||
el_val_t hist_append(el_val_t hist, el_val_t role, el_val_t content);
|
||||
el_val_t hist_trim(el_val_t hist);
|
||||
el_val_t clean_llm_response(el_val_t s);
|
||||
el_val_t handle_chat(el_val_t body);
|
||||
el_val_t handle_see(el_val_t body);
|
||||
el_val_t studio_tools_json(void);
|
||||
@@ -52,6 +53,10 @@ el_val_t handle_dharma(el_val_t path, el_val_t method, el_val_t body);
|
||||
el_val_t handle_tool(el_val_t path, el_val_t method, el_val_t body);
|
||||
el_val_t handle_nlg(el_val_t path, el_val_t method, el_val_t body);
|
||||
el_val_t render_studio(void);
|
||||
el_val_t elp_extract_topic(el_val_t msg);
|
||||
el_val_t elp_detect_predicate(el_val_t msg);
|
||||
el_val_t elp_parse(el_val_t msg);
|
||||
el_val_t handle_elp_chat(el_val_t body);
|
||||
el_val_t strip_query(el_val_t path);
|
||||
el_val_t err_404(el_val_t path);
|
||||
el_val_t err_405(el_val_t method, el_val_t path);
|
||||
|
||||
@@ -2,6 +2,7 @@ import "memory.el"
|
||||
import "awareness.el"
|
||||
import "chat.el"
|
||||
import "studio.el"
|
||||
import "elp-input.el"
|
||||
|
||||
fn strip_query(path: String) -> String {
|
||||
let q: Int = str_index_of(path, "?")
|
||||
@@ -246,6 +247,9 @@ fn handle_request(method: String, path: String, body: String) -> String {
|
||||
if str_eq(clean, "/synthesize") {
|
||||
return route_synthesize(body)
|
||||
}
|
||||
if str_eq(clean, "/api/elp/chat") {
|
||||
return handle_elp_chat(body)
|
||||
}
|
||||
if str_eq(clean, "/api/chat") {
|
||||
let agentic_flag: Bool = json_get_bool(body, "agentic")
|
||||
let reply: String = if agentic_flag {
|
||||
|
||||
Reference in New Issue
Block a user