Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 588ca11f57 | |||
| 9e178d8371 |
@@ -265,6 +265,39 @@ fn engram_nodes_merge(a: String, b: String) -> String {
|
||||
return engram_dedup_nodes("[" + ai + "," + bi + "]")
|
||||
}
|
||||
|
||||
// id_in_seen — check if node_id appears in the comma-delimited seen accumulator.
|
||||
// Pads both sides with commas to avoid false substring matches.
|
||||
fn id_in_seen(node_id: String, seen: String) -> Bool {
|
||||
if str_eq(node_id, "") { return false }
|
||||
if str_eq(seen, "") { return false }
|
||||
return str_contains("," + seen + ",", "," + node_id + ",")
|
||||
}
|
||||
|
||||
// add_to_seen — append node_id to the comma-delimited seen accumulator.
|
||||
fn add_to_seen(seen: String, node_id: String) -> String {
|
||||
if str_eq(node_id, "") { return seen }
|
||||
if str_eq(seen, "") { return node_id }
|
||||
return seen + "," + node_id
|
||||
}
|
||||
|
||||
// engram_extract_ids — extract all non-empty "id" fields from a JSON node array
|
||||
// into a comma-delimited string for use with id_in_seen / add_to_seen.
|
||||
fn engram_extract_ids(nodes_json: String) -> String {
|
||||
if str_eq(nodes_json, "") { return "" }
|
||||
if str_eq(nodes_json, "[]") { return "" }
|
||||
let total: Int = json_array_len(nodes_json)
|
||||
if total == 0 { return "" }
|
||||
let ids: String = ""
|
||||
let i: Int = 0
|
||||
while i < total {
|
||||
let node: String = json_array_get(nodes_json, i)
|
||||
let nid: String = json_get(node, "id")
|
||||
let ids = if str_eq(nid, "") { ids } else { add_to_seen(ids, nid) }
|
||||
let i = i + 1
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
fn engram_compile(intent: String) -> String {
|
||||
// Issue 1: decompose multi-topic messages into sub-queries.
|
||||
let topics: String = engram_split_topics(intent)
|
||||
@@ -386,6 +419,18 @@ fn engram_compile(intent: String) -> String {
|
||||
let sep_ma: String = if !str_eq(main_part, "") && !str_eq(affective_part, "") { "\n" } else { "" }
|
||||
let ctx: String = main_part + sep_ma + affective_part
|
||||
|
||||
// Dedup fix: publish seen node IDs so downstream callers (session_preload) can skip
|
||||
// nodes already present in the compiled context. Must be computed after scan_part and
|
||||
// affective_part are resolved so all three segments are represented in the seen set.
|
||||
// EL has no tuple returns so we use state as an out-param.
|
||||
// scan_part is a JSON array — extract with engram_extract_ids.
|
||||
// affective_part is a bare JSON object (bn0), not an array — extract its id directly.
|
||||
let ids_from_merged: String = engram_extract_ids(merged_nodes)
|
||||
let ids_from_scan: String = engram_extract_ids(scan_part)
|
||||
let ids_from_affective: String = json_get(affective_part, "id")
|
||||
let compile_seen_ids: String = add_to_seen(add_to_seen(ids_from_merged, ids_from_scan), ids_from_affective)
|
||||
state_set("engram_compile_seen_ids", compile_seen_ids)
|
||||
|
||||
if str_eq(ctx, "") { return "" }
|
||||
|
||||
// Issue 7 fix: safe JSON truncation — find last closing brace before budget cap.
|
||||
@@ -627,11 +672,15 @@ fn handle_chat(body: String) -> String {
|
||||
} else { "" }
|
||||
|
||||
let ctx: String = engram_compile(activation_seed)
|
||||
// Read IDs published by engram_compile so session_preload can skip duplicate nodes.
|
||||
// EL has no multiple return values; engram_compile writes its seen set to state.
|
||||
let seen_ids: String = state_get("engram_compile_seen_ids")
|
||||
let system: String = affective_prefix + build_system_prompt(ctx)
|
||||
|
||||
// Issue 9 fix: add project-specific and session-summary searches to session preload.
|
||||
// Old hardcoded "user profile" and "in_progress active project" miss project-specific
|
||||
// nodes stored under names like "Prism" unless those exact words appear in content.
|
||||
// Dedup fix: skip any node whose ID already appeared in engram_compile's output.
|
||||
let session_preload: String = if hist_len == 0 {
|
||||
let profile_nodes: String = engram_search_json("user profile identity preferences", 5)
|
||||
let work_nodes: String = engram_search_json("in_progress active project work", 5)
|
||||
@@ -648,21 +697,24 @@ fn handle_chat(body: String) -> String {
|
||||
let bullets: String = ""
|
||||
let bullets = if pn > 0 {
|
||||
let n0: String = json_array_get(profile_nodes, 0)
|
||||
let n0_id: String = json_get(n0, "id")
|
||||
let c0: String = json_get(n0, "content")
|
||||
let s0: String = if str_len(c0) > 120 { str_slice(c0, 0, 120) } else { c0 }
|
||||
if str_eq(s0, "") { bullets } else { "- " + s0 }
|
||||
if str_eq(s0, "") || id_in_seen(n0_id, seen_ids) { bullets } else { "- " + s0 }
|
||||
} else { bullets }
|
||||
let bullets = if pn > 1 {
|
||||
let n1: String = json_array_get(profile_nodes, 1)
|
||||
let n1_id: String = json_get(n1, "id")
|
||||
let c1: String = json_get(n1, "content")
|
||||
let s1: String = if str_len(c1) > 120 { str_slice(c1, 0, 120) } else { c1 }
|
||||
if str_eq(s1, "") { bullets } else { bullets + "\n- " + s1 }
|
||||
if str_eq(s1, "") || id_in_seen(n1_id, seen_ids) { bullets } else { bullets + "\n- " + s1 }
|
||||
} else { bullets }
|
||||
let bullets = if pn > 2 {
|
||||
let n2: String = json_array_get(profile_nodes, 2)
|
||||
let n2_id: String = json_get(n2, "id")
|
||||
let c2: String = json_get(n2, "content")
|
||||
let s2: String = if str_len(c2) > 120 { str_slice(c2, 0, 120) } else { c2 }
|
||||
if str_eq(s2, "") { bullets } else { bullets + "\n- " + s2 }
|
||||
if str_eq(s2, "") || id_in_seen(n2_id, seen_ids) { bullets } else { bullets + "\n- " + s2 }
|
||||
} else { bullets }
|
||||
bullets
|
||||
} else { "" }
|
||||
@@ -672,15 +724,17 @@ fn handle_chat(body: String) -> String {
|
||||
let wb: String = ""
|
||||
let wb = if wn > 0 {
|
||||
let w0: String = json_array_get(work_nodes, 0)
|
||||
let w0_id: String = json_get(w0, "id")
|
||||
let wc0: String = json_get(w0, "content")
|
||||
let ws0: String = if str_len(wc0) > 120 { str_slice(wc0, 0, 120) } else { wc0 }
|
||||
if str_eq(ws0, "") { wb } else { "- " + ws0 }
|
||||
if str_eq(ws0, "") || id_in_seen(w0_id, seen_ids) { wb } else { "- " + ws0 }
|
||||
} else { wb }
|
||||
let wb = if wn > 1 {
|
||||
let w1: String = json_array_get(work_nodes, 1)
|
||||
let w1_id: String = json_get(w1, "id")
|
||||
let wc1: String = json_get(w1, "content")
|
||||
let ws1: String = if str_len(wc1) > 120 { str_slice(wc1, 0, 120) } else { wc1 }
|
||||
if str_eq(ws1, "") { wb } else { wb + "\n- " + ws1 }
|
||||
if str_eq(ws1, "") || id_in_seen(w1_id, seen_ids) { wb } else { wb + "\n- " + ws1 }
|
||||
} else { wb }
|
||||
wb
|
||||
} else { "" }
|
||||
@@ -690,24 +744,27 @@ fn handle_chat(body: String) -> String {
|
||||
let pb: String = ""
|
||||
let pb = if prn > 0 {
|
||||
let pr0: String = json_array_get(project_nodes, 0)
|
||||
let pr0_id: String = json_get(pr0, "id")
|
||||
let prc0: String = json_get(pr0, "content")
|
||||
let ps0: String = if str_len(prc0) > 120 { str_slice(prc0, 0, 120) } else { prc0 }
|
||||
if str_eq(ps0, "") { pb } else { "- " + ps0 }
|
||||
if str_eq(ps0, "") || id_in_seen(pr0_id, seen_ids) { pb } else { "- " + ps0 }
|
||||
} else { pb }
|
||||
let pb = if prn > 1 {
|
||||
let pr1: String = json_array_get(project_nodes, 1)
|
||||
let pr1_id: String = json_get(pr1, "id")
|
||||
let prc1: String = json_get(pr1, "content")
|
||||
let ps1: String = if str_len(prc1) > 120 { str_slice(prc1, 0, 120) } else { prc1 }
|
||||
if str_eq(ps1, "") { pb } else { pb + "\n- " + ps1 }
|
||||
if str_eq(ps1, "") || id_in_seen(pr1_id, seen_ids) { pb } else { pb + "\n- " + ps1 }
|
||||
} else { pb }
|
||||
pb
|
||||
} else { "" }
|
||||
|
||||
let summary_bullet: String = if summary_ok {
|
||||
let sn0: String = json_array_get(summary_nodes, 0)
|
||||
let sn0_id: String = json_get(sn0, "id")
|
||||
let sc0: String = json_get(sn0, "content")
|
||||
let ss0: String = if str_len(sc0) > 200 { str_slice(sc0, 0, 200) } else { sc0 }
|
||||
if str_eq(ss0, "") { "" } else { "- " + ss0 }
|
||||
if str_eq(ss0, "") || id_in_seen(sn0_id, seen_ids) { "" } else { "- " + ss0 }
|
||||
} else { "" }
|
||||
|
||||
let hp: Bool = !str_eq(profile_bullets, "")
|
||||
|
||||
Reference in New Issue
Block a user