Compare commits

..

3 Commits

Author SHA1 Message Date
Tim Lingo f47c92a71a feat: vision in the agentic chat path (image content block)
Neuron Soul CI / build (pull_request) Failing after 23m26s
handle_chat_agentic now reads body image + image_media_type and, when present, sends the current
user turn as an Anthropic content-block array [{text},{image}] instead of a plain string — so the
model sees raw pixels alongside memory, history, and tools (parity with the CLI). Additive: no image
=> output byte-identical to before. elc-clean. Pairs with neuron-ui fix/chat-vision-attachments.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 12:25:26 -05:00
will.anderson d4609c7baa chore(dist): update neuron.c and routes.c to 2-arg build_system_prompt
Deploy Soul to GKE / deploy (push) Failing after 7m15s
Neuron Soul CI / build (push) Failing after 21m49s
neuron.c and routes.c were compiled against the old 1-arg soul interface.
chat.c already uses the 2-arg signature. The Windows cross-compile build
generates elp-c-decls.h from all dist/*.c files, causing a conflicting-types
error when both signatures appear. Recompile these modules against the
current soul API to eliminate the conflict.
2026-06-25 13:10:20 -05:00
will.anderson 98603f5ae8 self-review 2026-06-24: rebuild with goal_bias fix (Knowledge type boost)
Linked against dev runtime with is_knowledge fix that adds Knowledge
node type. Engram goal_bias now gives Knowledge nodes +0.3 boost on
technical queries, consistent with how Belief/DharmaSelf/Safety nodes
are already treated. Same el_runtime source as concurrent foundation/el
commit 16d62bd.
2026-06-24 08:48:21 -05:00
6 changed files with 523 additions and 81303 deletions
+15 -2
View File
@@ -1688,12 +1688,25 @@ fn handle_chat_agentic(body: String) -> String {
let safe_msg: String = json_safe(message)
let safe_sys: String = json_safe(system)
// Vision in the agentic brain (2026-06-27): when the client attaches an image
// (base64 in body "image", mime in "image_media_type"), send it as a real Anthropic
// image content block on THIS user turn so the model sees raw pixels WITH memory,
// history, and tools (parity with the CLI). img_b64 == "" => byte-identical to before.
let img_b64: String = json_get(body, "image")
let img_mt_raw: String = json_get(body, "image_media_type")
let img_mt: String = if str_eq(img_mt_raw, "") { "image/png" } else { img_mt_raw }
let cur_user_content: String = if str_eq(img_b64, "") {
"\"" + safe_msg + "\""
} else {
"[{\"type\":\"text\",\"text\":\"" + safe_msg + "\"},{\"type\":\"image\",\"source\":{\"type\":\"base64\",\"media_type\":\"" + img_mt + "\",\"data\":\"" + img_b64 + "\"}}]"
}
// Seed the messages array with recent history if available, so the LLM sees the thread.
let prior_messages: String = if agentic_hist_len > 0 {
let inner: String = str_slice(agentic_hist, 1, str_len(agentic_hist) - 1)
"[" + inner + ",{\"role\":\"user\",\"content\":\"" + safe_msg + "\"}]"
"[" + inner + ",{\"role\":\"user\",\"content\":" + cur_user_content + "}]"
} else {
"[{\"role\":\"user\",\"content\":\"" + safe_msg + "\"}]"
"[{\"role\":\"user\",\"content\":" + cur_user_content + "}]"
}
let messages: String = prior_messages
let api_url: String = "https://api.anthropic.com/v1/messages"
Generated Vendored
+30
View File
@@ -2,6 +2,7 @@
#include "el_runtime.h"
el_val_t add_punct(el_val_t s, el_val_t intent);
el_val_t add_to_seen(el_val_t seen, el_val_t node_id);
el_val_t aff_try_slot(el_val_t slot_json, el_val_t aff_7d_ts, el_val_t acc_key);
el_val_t agent_number(el_val_t agent);
el_val_t agent_person(el_val_t agent);
@@ -93,8 +94,10 @@ el_val_t api_err(el_val_t msg);
el_val_t api_err_protected(el_val_t id);
el_val_t api_json_escape(el_val_t s);
el_val_t api_nonempty(el_val_t s);
el_val_t api_not_persisted(el_val_t id);
el_val_t api_ok(el_val_t extra);
el_val_t api_or_empty(el_val_t s);
el_val_t api_persisted(el_val_t id);
el_val_t api_query_int(el_val_t path, el_val_t key, el_val_t default_val);
el_val_t api_query_param(el_val_t path, el_val_t key);
el_val_t append_tool_log(el_val_t log, el_val_t name);
@@ -138,6 +141,7 @@ el_val_t build_np(el_val_t referent, el_val_t slots);
el_val_t build_pp(el_val_t loc);
el_val_t build_rules(void);
el_val_t build_system_prompt(el_val_t ctx);
el_val_t build_system_prompt(el_val_t ctx, el_val_t chat_mode);
el_val_t build_vocab(void);
el_val_t build_vp_body(el_val_t slots);
el_val_t build_vp_from_slots(el_val_t slots);
@@ -254,6 +258,19 @@ el_val_t en_verb_form(el_val_t base, el_val_t tense, el_val_t person, el_val_t n
el_val_t en_verb_gerund(el_val_t base);
el_val_t en_verb_past(el_val_t base);
el_val_t engram_compile(el_val_t intent);
el_val_t engram_compile_multi(el_val_t topic);
el_val_t engram_compile_ranked(el_val_t nodes_json, el_val_t max_nodes);
el_val_t engram_dedup_nodes(el_val_t nodes_json);
el_val_t engram_detect_recall_intent(el_val_t message);
el_val_t engram_extract_entities(el_val_t message);
el_val_t engram_extract_ids(el_val_t nodes_json);
el_val_t engram_is_continuation(el_val_t message, el_val_t hist_len);
el_val_t engram_nodes_merge(el_val_t a, el_val_t b);
el_val_t engram_numeric_valid(el_val_t s);
el_val_t engram_render_node(el_val_t node_json);
el_val_t engram_render_nodes(el_val_t nodes_json);
el_val_t engram_score_node(el_val_t node_json);
el_val_t engram_split_topics(el_val_t message);
el_val_t enm_been_past(el_val_t slot);
el_val_t enm_been_present(el_val_t slot);
el_val_t enm_comen_past(el_val_t slot);
@@ -567,6 +584,9 @@ el_val_t handle_api_list_typed(el_val_t node_type, el_val_t path, el_val_t body)
el_val_t handle_api_log_state_event(el_val_t body);
el_val_t handle_api_memory_delete(el_val_t body);
el_val_t handle_api_memory_update(el_val_t body);
el_val_t handle_api_node_create(el_val_t body);
el_val_t handle_api_node_delete(el_val_t body);
el_val_t handle_api_node_update(el_val_t body);
el_val_t handle_api_promote_knowledge(el_val_t body);
el_val_t handle_api_recall(el_val_t method, el_val_t path, el_val_t body);
el_val_t handle_api_remember(el_val_t body);
@@ -648,6 +668,8 @@ el_val_t hi_verb_stem(el_val_t infinitive);
el_val_t hi_verb_stem_clean(el_val_t infinitive);
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 hist_trim_with_bell_guard(el_val_t hist);
el_val_t id_in_seen(el_val_t node_id, el_val_t seen);
el_val_t idle_count(void);
el_val_t idle_inc(void);
el_val_t idle_reset(void);
@@ -836,6 +858,7 @@ el_val_t non_vera_present(el_val_t slot);
el_val_t non_weak_past(el_val_t stem, el_val_t slot);
el_val_t non_weak_present(el_val_t stem, el_val_t slot);
el_val_t one_cycle(void);
el_val_t parse_float_x100(el_val_t s);
el_val_t parse_session_id_from_path(el_val_t path);
el_val_t parse_session_subpath(el_val_t path);
el_val_t path_within_root(el_val_t path, el_val_t root);
@@ -970,6 +993,7 @@ el_val_t safety_classify_hard_bell(el_val_t message);
el_val_t safety_contact_path(void);
el_val_t safety_count_match(el_val_t text, el_val_t phrases_json);
el_val_t safety_detect_bell_level(el_val_t message);
el_val_t safety_detect_positive_level(el_val_t message);
el_val_t safety_general_hard_phrases(void);
el_val_t safety_hard_directive(el_val_t hard_type);
el_val_t safety_log_bell(el_val_t level, el_val_t reason, el_val_t input_summary);
@@ -1007,13 +1031,19 @@ el_val_t sem_to_spec(el_val_t frame);
el_val_t sem_to_spec_full(el_val_t frame, el_val_t verb, el_val_t tense, el_val_t aspect);
el_val_t session_auto_title(el_val_t session_id, el_val_t first_message);
el_val_t session_create(el_val_t body);
el_val_t session_create_cleanup(el_val_t session_id);
el_val_t session_delete(el_val_t session_id);
el_val_t session_exists(el_val_t session_id);
el_val_t session_get(el_val_t session_id);
el_val_t session_hist_load(el_val_t session_id);
el_val_t session_hist_save(el_val_t session_id, el_val_t hist);
el_val_t session_list(void);
el_val_t session_make_content(el_val_t id, el_val_t title, el_val_t created_at, el_val_t updated_at, el_val_t folder);
el_val_t session_preload_bullets(el_val_t nodes, el_val_t max_bullets, el_val_t snip_len);
el_val_t session_search(el_val_t query);
el_val_t session_summary_autogenerate(el_val_t hist);
el_val_t session_summary_write(el_val_t summary_text);
el_val_t session_summary_write_dated(el_val_t summary_text, el_val_t label);
el_val_t session_title_from_message(el_val_t message);
el_val_t session_update_meta_timestamp(el_val_t session_id);
el_val_t session_update_patch(el_val_t session_id, el_val_t body);
Generated Vendored
-25003
View File
File diff suppressed because it is too large Load Diff
Generated Vendored Executable
BIN
View File
Binary file not shown.
Generated Vendored
+259 -28681
View File
File diff suppressed because one or more lines are too long
Generated Vendored
+219 -27617
View File
File diff suppressed because one or more lines are too long