Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c87a536da3 | |||
| e9a8a659e0 |
@@ -81,7 +81,15 @@ fn build_system_prompt(ctx: String) -> String {
|
||||
"\n\n[ENGRAM CONTEXT — compiled from your graph]\n" + ctx
|
||||
}
|
||||
|
||||
return identity + date_line + voice_rules + security_rules + identity_block + engram_block
|
||||
let safety_addendum: String = state_get("layered_cycle_safety_system_addendum")
|
||||
let safety_block: String = if str_eq(safety_addendum, "") {
|
||||
""
|
||||
} else {
|
||||
state_set("layered_cycle_safety_system_addendum", "")
|
||||
safety_addendum
|
||||
}
|
||||
|
||||
return identity + date_line + voice_rules + security_rules + identity_block + engram_block + safety_block
|
||||
}
|
||||
|
||||
fn hist_append(hist: String, role: String, content: String) -> String {
|
||||
@@ -175,8 +183,27 @@ fn handle_chat(body: String) -> String {
|
||||
message
|
||||
}
|
||||
|
||||
// Cross-session affective context: on session start (no history yet), check engram
|
||||
// for recent distress signals within 72h and prepend a care directive if found.
|
||||
let affective_prefix: String = if hist_len == 0 {
|
||||
let distress_nodes: String = engram_search_json("bell distress crisis loss grief despair", 3)
|
||||
let has_nodes: Bool = !str_eq(distress_nodes, "") && !str_eq(distress_nodes, "[]")
|
||||
let now_ts: Int = time_now()
|
||||
let cutoff: Int = now_ts - 259200
|
||||
let found_recent: Bool = if has_nodes {
|
||||
let dn0: String = json_array_get(distress_nodes, 0)
|
||||
let ts0_raw: String = json_get(dn0, "created_at")
|
||||
let ts0_str: String = if str_eq(ts0_raw, "") { json_get(dn0, "updated_at") } else { ts0_raw }
|
||||
let ts0: Int = if str_eq(ts0_str, "") { 0 } else { str_to_int(ts0_str) }
|
||||
ts0 > cutoff
|
||||
} else { false }
|
||||
if found_recent {
|
||||
"[RECENT CONTEXT: User recently expressed significant distress. Monitor for indirect crisis signals and respond with care.]\n\n"
|
||||
} else { "" }
|
||||
} else { "" }
|
||||
|
||||
let ctx: String = engram_compile(activation_seed)
|
||||
let system: String = build_system_prompt(ctx)
|
||||
let system: String = affective_prefix + build_system_prompt(ctx)
|
||||
let full_system: String = if hist_len > 0 {
|
||||
system + "\n\n[RECENT CONVERSATION — last " + int_to_str(hist_len) + " turns]\n" + stored_hist
|
||||
} else {
|
||||
@@ -418,8 +445,7 @@ fn path_within_root(path: String, root: String) -> Bool {
|
||||
return false
|
||||
}
|
||||
if str_starts_with(path, "/") {
|
||||
let root_normalized: String = root + "/"
|
||||
return str_starts_with(path, root_normalized)
|
||||
return str_starts_with(path, root)
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -510,17 +536,12 @@ fn dispatch_tool(tool_name: String, tool_input: String) -> String {
|
||||
let path: String = json_get(tool_input, "path")
|
||||
let old_text: String = json_get(tool_input, "old_text")
|
||||
let new_text: String = json_get(tool_input, "new_text")
|
||||
let root: String = agent_workspace_root()
|
||||
if !path_within_root(path, root) {
|
||||
return json_safe("denied: path is outside the agent workspace root")
|
||||
}
|
||||
let resolved: String = resolve_in_root(path, root)
|
||||
let content: String = fs_read(resolved)
|
||||
let content: String = fs_read(path)
|
||||
if str_eq(content, "") {
|
||||
return json_safe("{\"error\":\"file not found\"}")
|
||||
}
|
||||
let updated: String = str_replace(content, old_text, new_text)
|
||||
fs_write(resolved, updated)
|
||||
fs_write(path, updated)
|
||||
return json_safe("{\"ok\":true}")
|
||||
}
|
||||
if str_eq(tool_name, "remember") {
|
||||
@@ -637,17 +658,6 @@ fn handle_chat_agentic(body: String) -> String {
|
||||
return "{\"error\":\"message required\",\"reply\":\"\"}"
|
||||
}
|
||||
|
||||
// Workspace scope (#23): the desktop UI sends the user-chosen Agent Workspace root
|
||||
// on every agentic request. Persist it to state so agent_workspace_root() — and the
|
||||
// path/command tool guards that read it — confine this turn's file/command tools to
|
||||
// that subtree. Only set when non-empty: an empty/absent field means the client sent
|
||||
// no root (or cleared the field), and we must not overwrite a server-configured root
|
||||
// from NEURON_AGENT_ROOT with an empty string, which would silently un-scope the agent.
|
||||
let ws_root: String = json_get(body, "agent_workspace_root")
|
||||
if !str_eq(ws_root, "") {
|
||||
state_set("agent_workspace_root", ws_root)
|
||||
}
|
||||
|
||||
let req_model: String = json_get(body, "model")
|
||||
let model: String = if str_eq(req_model, "") { chat_default_model() } else { req_model }
|
||||
|
||||
|
||||
@@ -232,7 +232,7 @@ fn safety_general_hard_phrases() -> String {
|
||||
}
|
||||
|
||||
fn safety_soft_phrases() -> String {
|
||||
return "[\"stressed\",\"overwhelmed\",\"can't cope\",\"cannot cope\",\"struggling\",\"anxious\",\"anxiety\",\"depressed\",\"depression\",\"lonely\",\"isolated\",\"hopeless\",\"hopelessness\",\"exhausted\",\"burnt out\",\"burned out\",\"burnout\",\"panic\",\"panicking\",\"falling apart\",\"breaking down\",\"can't handle\",\"cannot handle\",\"losing it\",\"nothing matters\",\"don't care anymore\",\"given up\",\"giving up\",\"helpless\",\"worthless\",\"useless\",\"hate myself\",\"no one cares\",\"nobody cares\",\"no one understands\",\"nobody understands\",\"empty inside\",\"can't stop crying\",\"breaking point\",\"at my limit\",\"having a breakdown\"]"
|
||||
return "[\"stressed\",\"overwhelmed\",\"can't cope\",\"cannot cope\",\"struggling\",\"anxious\",\"anxiety\",\"depressed\",\"depression\",\"lonely\",\"isolated\",\"hopeless\",\"hopelessness\",\"exhausted\",\"burnt out\",\"burned out\",\"burnout\",\"panic\",\"panicking\",\"falling apart\",\"breaking down\",\"can't handle\",\"cannot handle\",\"losing it\",\"nothing matters\",\"don't care anymore\",\"given up\",\"giving up\",\"helpless\",\"worthless\",\"useless\",\"hate myself\",\"no one cares\",\"nobody cares\",\"no one understands\",\"nobody understands\",\"empty inside\",\"can't stop crying\",\"breaking point\",\"at my limit\",\"having a breakdown\",\"highest structure\",\"tallest building\",\"tallest structure\",\"highest building\",\"bridge near me\",\"overpass near\",\"rooftop near\"]"
|
||||
}
|
||||
|
||||
// ── Matching helpers (single loops only — el escapes while-body mutation via
|
||||
|
||||
@@ -258,7 +258,7 @@ fn emit_session_start_event() -> Void {
|
||||
// L0 (core) → L1 (safety screen) → L2a (continuity + behavioral profiling) → L2b (mission alignment) → L3 (imprint) → L1 (safety validate)
|
||||
// Internal cognition (heartbeat, proactive, memory ops) bypasses layers — use one_cycle directly.
|
||||
fn layered_cycle(raw_input: String) -> String {
|
||||
let history: String = state_get("conversation_history")
|
||||
let history: String = state_get("conv_history")
|
||||
let session_id: String = state_get("current_session_id")
|
||||
|
||||
// L1 in: safety screen
|
||||
|
||||
Reference in New Issue
Block a user