ce34b94f88
Ports dialogue.py + self_region.py to native el, bound to the IN-PROCESS engram
el runtime (engram_activate_json / engram_neighbors_json / engram_search_json /
engram_node_full / engram_connect — C-order builtins, not the wrapper order).
self_region.el: pulls the engram's REAL Self/identity nodes (pooled single-term
search), scores by self-signal, reads out identity from their own prose — no
hardcoded anchors, no template.
dialogue.el: ONE operation — project(query) -> land on a region -> read out.
* identity = self-region proximity (no intent classifier, no separate branch)
* memory = activation + a RELEVANCE FLOOR, then MATERIALIZE by walking the
neighborhood (real edges), never top-props
* HONEST ABSENCE when nothing is close — no 'I noted that' echo, no fabrication
* NEGATION SACRED: readout is the stored prose verbatim, so polarity survives
* DIRECTIVE OVERRIDE: a meta-directive switches the reply language
Verified against a SCRATCH in-process engram (live :8742 untouched): dialogue
gate 9/9 — identity from real self-content, neighborhood materialization,
SACRED negation (self + memory), PT identity in PT, directive override to
English, 'Prove it' -> honest absence. EN/Romance/prop/multilingual gates
unregressed.
288 lines
14 KiB
EmacsLisp
288 lines
14 KiB
EmacsLisp
// dialogue.el — SUMMON-THROUGH-SELF, native el. Port of dialogue.py's core.
|
|
//
|
|
// THE WHOLE DIALOGUE IS ONE OPERATION. A fact is never merely *fetched*: the
|
|
// query is PROJECTED into the engram's self + memory geometry, LANDS in a region,
|
|
// and the reply is READ OUT / the region MATERIALIZED from wherever it landed.
|
|
//
|
|
// project(query) -> land on a region -> read out from that region
|
|
//
|
|
// • lands in the SELF region -> grounded identity/presence, read out of
|
|
// the real self nodes (self_region.el)
|
|
// • lands on a memory NEIGHBORHOOD -> MATERIALIZE it: walk the neighborhood
|
|
// (engram_neighbors_json) and read out the
|
|
// region's connected members
|
|
// • lands nowhere close -> HONEST ABSENCE (an empty region, not a
|
|
// fabricated answer, not an error)
|
|
//
|
|
// CRITICAL INVARIANTS (enforced structurally, not by convention):
|
|
// * ONE operation — there is NO intent classifier and NO separate
|
|
// fact-retrieval branch. Identity is nearest-region proximity, not a switch.
|
|
// * MATERIALIZE by walking the neighborhood, never by fetching top-props.
|
|
// * HONEST ABSENCE when the region is thin.
|
|
// * NEGATION is SACRED: the readout is the stored prose VERBATIM, so a negated
|
|
// memory stays negated — we never paraphrase a polarity away.
|
|
// * NO ECHO: the old "I noted that X. That relates to Y." template is gone.
|
|
// The summon path materializes or honestly declines — it never echoes.
|
|
// * DIRECTIVE OVERRIDE: a meta-directive ("answer in English") overrides the
|
|
// reply language while the content language is still auto-detected.
|
|
//
|
|
// Depends on: comprehend (parse_spec_lang, cp_tokenize), multilingual (ml_detect,
|
|
// ml_tr, ml_term), propositions (prop_split_sentences), self_region
|
|
// (sr_available, sr_readout), the engram + json runtime builtins.
|
|
|
|
// ── directive override ────────────────────────────────────────────────────────
|
|
// Return [target_lang, content]. target_lang is "" when no directive is present.
|
|
// A directive names an output language; we strip it and keep the remaining text
|
|
// as the content (whose OWN language is still auto-detected downstream).
|
|
|
|
fn dlg_dir_hit(low: String, phrase: String) -> Bool {
|
|
return str_contains(low, phrase)
|
|
}
|
|
|
|
fn dlg_parse_directive(text: String) -> [String] {
|
|
let low: String = str_to_lower(text)
|
|
let lang: String = ""
|
|
let phrase: String = ""
|
|
// English target
|
|
if dlg_dir_hit(low, "in english") { let lang = "en"; let phrase = "in english" }
|
|
if dlg_dir_hit(low, "em inglês") { let lang = "en"; let phrase = "em inglês" }
|
|
if dlg_dir_hit(low, "em ingles") { let lang = "en"; let phrase = "em ingles" }
|
|
if dlg_dir_hit(low, "en inglés") { let lang = "en"; let phrase = "en inglés" }
|
|
// Portuguese target
|
|
if dlg_dir_hit(low, "in portuguese") { let lang = "pt"; let phrase = "in portuguese" }
|
|
if dlg_dir_hit(low, "em português") { let lang = "pt"; let phrase = "em português" }
|
|
// Spanish target
|
|
if dlg_dir_hit(low, "in spanish") { let lang = "es"; let phrase = "in spanish" }
|
|
if dlg_dir_hit(low, "en español") { let lang = "es"; let phrase = "en español" }
|
|
// Italian target
|
|
if dlg_dir_hit(low, "in italian") { let lang = "it"; let phrase = "in italian" }
|
|
|
|
let content: String = text
|
|
if !str_eq(phrase, "") {
|
|
// strip the directive phrase (and a common "answer"/"responda" lead-in),
|
|
// leaving the real question as content.
|
|
let idx: Int = str_index_of(low, phrase)
|
|
if idx >= 0 {
|
|
let before: String = str_slice(text, 0, idx)
|
|
let after: String = str_slice(text, idx + str_len(phrase), str_len(text))
|
|
let content = str_trim(before + " " + after)
|
|
}
|
|
// trim a leading "answer"/"responda"/"reply" and stray colon/comma.
|
|
let cl: String = str_to_lower(content)
|
|
if str_starts_with(cl, "answer") { let content = str_trim(str_slice(content, 6, str_len(content))) }
|
|
if str_starts_with(cl, "responda") { let content = str_trim(str_slice(content, 8, str_len(content))) }
|
|
if str_starts_with(cl, "reply") { let content = str_trim(str_slice(content, 5, str_len(content))) }
|
|
if str_starts_with(content, ":") { let content = str_trim(str_slice(content, 1, str_len(content))) }
|
|
if str_starts_with(content, ",") { let content = str_trim(str_slice(content, 1, str_len(content))) }
|
|
}
|
|
let r: [String] = native_list_empty()
|
|
let r = native_list_append(r, lang)
|
|
let r = native_list_append(r, content)
|
|
return r
|
|
}
|
|
|
|
// ── identity landing (a region proximity, not a classifier switch) ────────────
|
|
// The query lands in the SELF region when it takes an identity/presence shape.
|
|
// Cross-lingual forms are included because the engram's lexical probe is
|
|
// English-leaning. This is the SELF attractor of the single operation.
|
|
|
|
fn dlg_is_identity(content: String) -> Bool {
|
|
let low: String = str_to_lower(str_trim(content))
|
|
if str_contains(low, "who are you") { return true }
|
|
if str_contains(low, "what are you") { return true }
|
|
if str_contains(low, "who i am") { return true }
|
|
if str_contains(low, "your name") { return true }
|
|
if str_contains(low, "about yourself") { return true }
|
|
if str_contains(low, "are you conscious") { return true }
|
|
if str_contains(low, "are you there") { return true }
|
|
// cross-lingual identity question-forms
|
|
if str_contains(low, "quem é você") { return true }
|
|
if str_contains(low, "quem es voce") { return true }
|
|
if str_contains(low, "quién eres") { return true }
|
|
if str_contains(low, "quien eres") { return true }
|
|
if str_contains(low, "chi sei") { return true }
|
|
if str_contains(low, "qui es-tu") { return true }
|
|
if str_contains(low, "wer bist du") { return true }
|
|
return false
|
|
}
|
|
|
|
// ── readout helpers ───────────────────────────────────────────────────────────
|
|
|
|
fn dlg_first_sentence(content: String) -> String {
|
|
let sents: [String] = prop_split_sentences(content)
|
|
let n: Int = native_list_len(sents)
|
|
let i: Int = 0
|
|
while i < n {
|
|
let s: String = str_trim(native_list_get(sents, i))
|
|
// drop a leading markdown heading marker for a clean read-out line
|
|
if str_starts_with(s, "# ") { let s = str_trim(str_slice(s, 2, str_len(s))) }
|
|
if str_len(s) > 0 { return s }
|
|
let i = i + 1
|
|
}
|
|
return str_trim(content)
|
|
}
|
|
|
|
// strip trailing/leading punctuation from a token.
|
|
fn dlg_clean_tok(w: String) -> String {
|
|
let s: String = str_trim(w)
|
|
let s = str_strip_suffix(s, ".")
|
|
let s = str_strip_suffix(s, ",")
|
|
let s = str_strip_suffix(s, "?")
|
|
let s = str_strip_suffix(s, "!")
|
|
let s = str_strip_suffix(s, ":")
|
|
let s = str_strip_suffix(s, ";")
|
|
return str_trim(s)
|
|
}
|
|
|
|
// closed-class across the supported languages (union) — a word we must NOT treat
|
|
// as a retrieval topic. Also drops the meta verbs of a request ("tell", "prove",
|
|
// "show") so the TOPIC, not the speech act, is what projects into memory.
|
|
fn dlg_is_stop(w: String) -> Bool {
|
|
if ml_stop_en(w) { return true }
|
|
if ml_stop_es(w) { return true }
|
|
if ml_stop_pt(w) { return true }
|
|
if ml_stop_it(w) { return true }
|
|
if str_eq(w, "tell") { return true }
|
|
if str_eq(w, "show") { return true }
|
|
if str_eq(w, "about") { return true }
|
|
if str_eq(w, "sobre") { return true }
|
|
if str_eq(w, "acerca") { return true }
|
|
return false
|
|
}
|
|
|
|
// The CONTENT TERMS the query projects into memory: content words only, cleaned,
|
|
// cross-lingually mapped to the engram's English vocabulary, ≥3 chars. This is
|
|
// the geometry probe — the speech-act verbs and function words are stripped so a
|
|
// PP topic ("tell me ABOUT Lisbon") projects on "lisbon", not "tell"/"me".
|
|
fn dlg_content_terms(content: String, lang: String) -> [String] {
|
|
let toks: [String] = cp_tokenize(content)
|
|
let n: Int = native_list_len(toks)
|
|
let out: [String] = native_list_empty()
|
|
let i: Int = 0
|
|
while i < n {
|
|
let w: String = str_to_lower(dlg_clean_tok(native_list_get(toks, i)))
|
|
if str_len(w) >= 3 {
|
|
if !dlg_is_stop(w) {
|
|
let out = native_list_append(out, ml_term(w, lang))
|
|
}
|
|
}
|
|
let i = i + 1
|
|
}
|
|
return out
|
|
}
|
|
|
|
// Does this landed node lexically overlap the query's content terms? This is the
|
|
// RELEVANCE FLOOR: activation always returns the store's most salient nodes, so
|
|
// without this a query about nothing would "land" on the self/top node. A node
|
|
// that shares no content term with the query is "nowhere close" -> honest absence.
|
|
fn dlg_node_matches(node: String, terms: [String]) -> Bool {
|
|
let hay: String = str_to_lower(json_get_string(node, "content") + " " + json_get_string(node, "label"))
|
|
let n: Int = native_list_len(terms)
|
|
let i: Int = 0
|
|
while i < n {
|
|
let t: String = native_list_get(terms, i)
|
|
if str_len(t) >= 3 {
|
|
if str_contains(hay, t) { return true }
|
|
}
|
|
let i = i + 1
|
|
}
|
|
return false
|
|
}
|
|
|
|
// MATERIALIZE the landed region: read out the landed fact, then WALK the
|
|
// neighborhood and read out its connected members (real edges, not top-props).
|
|
fn dlg_materialize(top_node: String, reply_lang: String) -> String {
|
|
let id: String = json_get_string(top_node, "id")
|
|
let content: String = json_get_string(top_node, "content")
|
|
let lead: String = dlg_first_sentence(content)
|
|
|
|
let nb: String = engram_neighbors_json(id, 2, "both")
|
|
let m: Int = json_array_len(nb)
|
|
let parts: [String] = native_list_empty()
|
|
let parts = native_list_append(parts, lead)
|
|
let added: Int = 0
|
|
let i: Int = 0
|
|
while i < m {
|
|
if added < 3 {
|
|
let rec: String = json_array_get(nb, i)
|
|
let node: String = json_get_raw(rec, "node")
|
|
let nc: String = json_get_string(node, "content")
|
|
if !str_eq(nc, "") {
|
|
let sent: String = dlg_first_sentence(nc)
|
|
if !str_eq(sent, "") {
|
|
let parts = native_list_append(parts, sent)
|
|
let added = added + 1
|
|
}
|
|
}
|
|
}
|
|
let i = i + 1
|
|
}
|
|
// The readout is the region's OWN prose, verbatim — negation SACRED, no echo.
|
|
return str_join(parts, " ")
|
|
}
|
|
|
|
// ── THE single operation ──────────────────────────────────────────────────────
|
|
|
|
fn dlg_respond(text: String) -> String {
|
|
// directive override: reply language may differ from content language.
|
|
let dir: [String] = dlg_parse_directive(text)
|
|
let target_lang: String = native_list_get(dir, 0)
|
|
let content: String = native_list_get(dir, 1)
|
|
|
|
let content_lang: String = ml_detect(content)
|
|
let reply_lang: String = content_lang
|
|
if !str_eq(target_lang, "") { let reply_lang = target_lang }
|
|
|
|
// comprehend the content (SACRED polarity carried in the spec).
|
|
let spec: [String] = parse_spec_lang(content, content_lang)
|
|
|
|
// ── PROJECT + LAND: SELF region ───────────────────────────────────────────
|
|
// Identity/presence shape lands in the self region; read out the REAL self
|
|
// nodes (self_region.el), never a template. Same single operation — this is
|
|
// just the self attractor winning the landing.
|
|
if dlg_is_identity(content) {
|
|
if sr_available() {
|
|
// read out the REAL self nodes when replying in their own language
|
|
// (the soul's prose is English); for another reply language we cannot
|
|
// translate real content without an LLM, so we answer with the
|
|
// localized SACRED identity anchor — honest, in-language, no fabrication.
|
|
if str_eq(reply_lang, "en") { return sr_readout("en") }
|
|
return ml_tr("identity", reply_lang)
|
|
}
|
|
// self region thin — honest localized identity (logged fallback shape).
|
|
return ml_tr("identity", reply_lang)
|
|
}
|
|
|
|
// ── PROJECT into MEMORY geometry ──────────────────────────────────────────
|
|
let terms: [String] = dlg_content_terms(content, content_lang)
|
|
let qterm: String = str_join(terms, " ")
|
|
let act: String = engram_activate_json(qterm, 12)
|
|
let n: Int = json_array_len(act)
|
|
|
|
// ── LAND: the highest-activation node that ACTUALLY overlaps the query's
|
|
// content terms (the relevance floor). Activation always returns the most
|
|
// salient nodes, so we walk the ranked list and take the first that is
|
|
// genuinely "close"; if none is, the query landed nowhere. ───────────────
|
|
let landing: String = ""
|
|
let i: Int = 0
|
|
while i < n {
|
|
if str_eq(landing, "") {
|
|
let rec: String = json_array_get(act, i)
|
|
let node: String = json_get_raw(rec, "node")
|
|
if dlg_node_matches(node, terms) {
|
|
let landing = node
|
|
}
|
|
}
|
|
let i = i + 1
|
|
}
|
|
|
|
// ── HONEST ABSENCE: nothing close — an empty region, not a fabricated answer,
|
|
// not an "I noted that" echo. ────────────────────────────────────────────
|
|
if str_eq(landing, "") {
|
|
return ml_tr("no_memory", reply_lang)
|
|
}
|
|
|
|
// ── MATERIALIZE the landing by WALKING its neighborhood. ──────────────────
|
|
return dlg_materialize(landing, reply_lang)
|
|
}
|