feat(engram): wire cosine similarity into Layer 2 activation scoring

engram_cosine_sim() was defined and embeddings were computed per-node
via nomic-embed-text on write, but the function was never called during
activation scoring. The goal_bias computation used only lexical substring
matching, ignoring all stored embedding vectors.

This change adds engram_embed_query() to embed the query string at search
time (5s timeout so Ollama latency never blocks activation), then blends
cosine similarity into the working-memory bias with α=0.3:

  bias_final = goal_bias(lexical) * (1 + 0.3 * max(0, cosine_sim))

Nodes with high semantic similarity to the query but low lexical overlap
now receive up to 30% bias boost into working memory promotion. Gracefully
degrades to pure lexical when Ollama is unavailable or node has no embedding.
This commit is contained in:
2026-05-14 11:05:56 -05:00
parent 0c2ff6957e
commit 1a8a16002e
2 changed files with 87 additions and 6 deletions
+6 -1
View File
@@ -493,8 +493,13 @@ fn route_neuron_config(method: String, path: String, body: String) -> String {
"{\"key\":\"" + key + "\",\"value\":\"\"}"
}
// route_neuron_state_events log internal state event node
// route_neuron_state_events GET lists ISEs, POST logs a new one
fn route_neuron_state_events(method: String, path: String, body: String) -> String {
if str_eq(method, "GET") {
let limit_str: String = query_param(path, "limit")
let limit: Int = if str_eq(limit_str, "") { 50 } else { str_to_int(limit_str) }
return engram_scan_nodes_by_type_json("InternalStateEvent", limit, 0)
}
let content: String = json_get_string(body, "content")
if str_eq(content, "") { let content = body }
let id: String = engram_node_full(content, "InternalStateEvent", "state-event", 0.3, 0.3, 1.0, "Working", "internal-state")