chore(dist): compile PRs #56/#57/#58 into soul.c
Neuron Soul CI / build (push) Has been cancelled
Deploy Soul to GKE / deploy (push) Has been cancelled

- PR #56: vision in agentic chat path (image content block)
- PR #57: /api/connectors/call route — proxy connector tool calls
- PR #58: /api/neuron/list/<type> off-by-one fix (str_slice 16->17)

Live-verified: list/BacklogItem returns 50 nodes (was 0 before #58 fix).
Binary size: 3.8MB.
This commit is contained in:
2026-06-28 12:29:52 -05:00
parent ada8af1ccc
commit a77578e243
5 changed files with 147 additions and 78 deletions
Generated Vendored
+67 -62
View File
File diff suppressed because one or more lines are too long
Generated Vendored
+4 -6
View File
@@ -163,11 +163,6 @@ el_val_t session_update_patch(el_val_t session_id, el_val_t body);
el_val_t session_search(el_val_t query);
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 init_soul_edges(void);
el_val_t load_identity_context(void);
el_val_t seed_persona_from_env(void);
el_val_t emit_session_start_event(void);
el_val_t layered_cycle(el_val_t raw_input);
el_val_t rate_limit_check(el_val_t ip, el_val_t path);
el_val_t strip_query(el_val_t path);
el_val_t err_404(el_val_t path);
@@ -405,6 +400,9 @@ el_val_t handle_connectors(el_val_t method, el_val_t clean, el_val_t body) {
if (str_eq(clean, EL_STR("/api/connectors/oauth/start"))) {
return connectd_post(EL_STR("/mcp/oauth/start"), body);
}
if (str_eq(clean, EL_STR("/api/connectors/call"))) {
return connectd_post(EL_STR("/mcp/call"), body);
}
return EL_STR("{\"ok\":false,\"error\":\"unknown connectors route\"}");
return 0;
}
@@ -513,7 +511,7 @@ el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body) {
return handle_api_inspect_graph(method, path, body);
}
if (str_starts_with(clean, EL_STR("/api/neuron/list/"))) {
el_val_t node_type = str_slice(clean, 16, str_len(clean));
el_val_t node_type = str_slice(clean, 17, str_len(clean));
return handle_api_list_typed(node_type, path, body);
}
if (str_starts_with(clean, EL_STR("/api/neuron/recall"))) {
Generated Vendored
+4 -3
View File
@@ -1,4 +1,5 @@
// auto-generated by elc --emit-header — do not edit
extern fn rate_limit_check(ip: String, path: String) -> String
extern fn strip_query(path: String) -> String
extern fn err_404(path: String) -> String
extern fn err_405(method: String, path: String) -> String
@@ -8,7 +9,7 @@ extern fn route_imprint_contextual(body: String) -> String
extern fn route_imprint_user(body: String) -> String
extern fn route_synthesize(body: String) -> String
extern fn handle_dharma_recv(body: String) -> String
extern fn route_sessions() -> String
extern fn parse_session_id_from_path(path: String) -> String
extern fn parse_session_subpath(path: String) -> String
extern fn connectd_get(suffix: String) -> String
extern fn connectd_post(suffix: String, body: String) -> String
extern fn handle_connectors(method: String, clean: String, body: String) -> String
extern fn handle_request(method: String, path: String, body: String) -> String
Generated Vendored
+67 -2
View File
@@ -1164,6 +1164,9 @@ el_val_t handle_dharma_recv(el_val_t body);
el_val_t route_sessions(void);
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 connectd_get(el_val_t suffix);
el_val_t connectd_post(el_val_t suffix, el_val_t body);
el_val_t handle_connectors(el_val_t method, el_val_t clean, el_val_t body);
el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body);
el_val_t init_soul_edges(void);
el_val_t load_identity_context(void);
@@ -27287,7 +27290,12 @@ el_val_t handle_chat_agentic(el_val_t body) {
el_val_t tools_json = agentic_tools_all();
el_val_t safe_msg = json_safe(message);
el_val_t safe_sys = json_safe(system);
el_val_t prior_messages = ({ el_val_t _if_result_50 = 0; if ((agentic_hist_len > 0)) { el_val_t inner = str_slice(agentic_hist, 1, (str_len(agentic_hist) - 1)); _if_result_50 = (el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("["), inner), EL_STR(",{\"role\":\"user\",\"content\":\"")), safe_msg), EL_STR("\"}]"))); } else { _if_result_50 = (el_str_concat(el_str_concat(EL_STR("[{\"role\":\"user\",\"content\":\""), safe_msg), EL_STR("\"}]"))); } _if_result_50; });
/* PR#56: vision support in agentic chat — send image content block when present */
el_val_t img_b64 = json_get(body, EL_STR("image"));
el_val_t img_mt_raw = json_get(body, EL_STR("image_media_type"));
el_val_t img_mt = ({ el_val_t _if_result_v1 = 0; if (str_eq(img_mt_raw, EL_STR(""))) { _if_result_v1 = (EL_STR("image/png")); } else { _if_result_v1 = (img_mt_raw); } _if_result_v1; });
el_val_t cur_user_content = ({ el_val_t _if_result_v2 = 0; if (str_eq(img_b64, EL_STR(""))) { _if_result_v2 = (el_str_concat(el_str_concat(EL_STR("\""), safe_msg), EL_STR("\""))); } else { _if_result_v2 = (el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("[{\"type\":\"text\",\"text\":\""), safe_msg), EL_STR("\"},{\"type\":\"image\",\"source\":{\"type\":\"base64\",\"media_type\":\"")), img_mt), EL_STR("\",\"data\":\"")), img_b64), EL_STR("\"}}]"))); } _if_result_v2; });
el_val_t prior_messages = ({ el_val_t _if_result_50 = 0; if ((agentic_hist_len > 0)) { el_val_t inner = str_slice(agentic_hist, 1, (str_len(agentic_hist) - 1)); _if_result_50 = (el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("["), inner), EL_STR(",{\"role\":\"user\",\"content\":")), cur_user_content), EL_STR("}]"))); } else { _if_result_50 = (el_str_concat(el_str_concat(EL_STR("[{\"role\":\"user\",\"content\":"), cur_user_content), EL_STR("}]"))); } _if_result_50; });
el_val_t messages = prior_messages;
el_val_t api_url = EL_STR("https://api.anthropic.com/v1/messages");
el_val_t h = el_map_new(0);
@@ -28890,6 +28898,57 @@ el_val_t parse_session_subpath(el_val_t path) {
return 0;
}
/* PR#57: connectors subsystem — neuron-connectd bridge on :7771 */
el_val_t connectd_get(el_val_t suffix) {
el_val_t out = exec_capture(el_str_concat(EL_STR("curl -s --max-time 5 http://127.0.0.1:7771"), suffix));
if (str_eq(out, EL_STR(""))) {
return EL_STR("{\"ok\":false,\"error\":\"connector bridge unreachable (neuron-connectd on :7771)\"}");
}
return out;
return 0;
}
el_val_t connectd_post(el_val_t suffix, el_val_t body) {
el_val_t eff = ({ el_val_t _if_result_cd1 = 0; if (str_eq(body, EL_STR(""))) { _if_result_cd1 = (EL_STR("{}")); } else { _if_result_cd1 = (body); } _if_result_cd1; });
el_val_t tmp = el_str_concat(el_str_concat(EL_STR("/tmp/neuron-connectors-req-"), int_to_str(time_now())), EL_STR(".json"));
fs_write(tmp, eff);
el_val_t out = exec_capture(el_str_concat(el_str_concat(el_str_concat(EL_STR("curl -s --max-time 20 -X POST http://127.0.0.1:7771"), suffix), EL_STR(" -H 'Content-Type: application/json' -d @")), tmp));
if (str_eq(out, EL_STR(""))) {
return EL_STR("{\"ok\":false,\"error\":\"connector bridge unreachable (neuron-connectd on :7771)\"}");
}
return out;
return 0;
}
el_val_t handle_connectors(el_val_t method, el_val_t clean, el_val_t body) {
if (str_eq(method, EL_STR("GET"))) {
return connectd_get(EL_STR("/mcp/servers"));
}
if (str_eq(clean, EL_STR("/api/connectors/add"))) {
return connectd_post(EL_STR("/mcp/servers/add"), body);
}
if (str_eq(clean, EL_STR("/api/connectors/toggle"))) {
return connectd_post(EL_STR("/mcp/servers/toggle"), body);
}
if (str_eq(clean, EL_STR("/api/connectors/auto-approve"))) {
return connectd_post(EL_STR("/mcp/servers/auto-approve"), body);
}
if (str_eq(clean, EL_STR("/api/connectors/remove"))) {
return connectd_post(EL_STR("/mcp/servers/remove"), body);
}
if (str_eq(clean, EL_STR("/api/connectors/secret"))) {
return connectd_post(EL_STR("/mcp/servers/secret"), body);
}
if (str_eq(clean, EL_STR("/api/connectors/oauth/start"))) {
return connectd_post(EL_STR("/mcp/oauth/start"), body);
}
if (str_eq(clean, EL_STR("/api/connectors/call"))) {
return connectd_post(EL_STR("/mcp/call"), body);
}
return EL_STR("{\"ok\":false,\"error\":\"unknown connectors route\"}");
return 0;
}
el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body) {
el_val_t clean = strip_query(path);
if (str_eq(method, EL_STR("POST")) && str_eq(clean, EL_STR("/dharma/recv"))) {
@@ -28989,12 +29048,15 @@ el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body) {
return handle_api_inspect_graph(method, path, body);
}
if (str_starts_with(clean, EL_STR("/api/neuron/list/"))) {
el_val_t node_type = str_slice(clean, 16, str_len(clean));
el_val_t node_type = str_slice(clean, 17, str_len(clean)); /* PR#58: was 16, left leading "/" on node_type */
return handle_api_list_typed(node_type, path, body);
}
if (str_starts_with(clean, EL_STR("/api/neuron/recall"))) {
return handle_api_recall(method, path, body);
}
if (str_starts_with(clean, EL_STR("/api/connectors"))) {
return handle_connectors(method, clean, body);
}
return err_404(clean);
}
if (str_eq(method, EL_STR("POST"))) {
@@ -29128,6 +29190,9 @@ el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body) {
if (str_eq(clean, EL_STR("/api/neuron/cultivate"))) {
return handle_api_cultivate(body);
}
if (str_starts_with(clean, EL_STR("/api/connectors"))) {
return handle_connectors(method, clean, body);
}
return err_404(clean);
}
if (str_eq(method, EL_STR("DELETE"))) {
+5 -5
View File
@@ -1,6 +1,6 @@
// auto-generated by elc --emit-header - do not edit
// auto-generated by elc --emit-header do not edit
extern fn rate_limit_check(ip: String, path: String) -> String
extern fn strip_query(path: String) -> String
extern fn flag_true(body: String, key: String) -> Bool
extern fn err_404(path: String) -> String
extern fn err_405(method: String, path: String) -> String
extern fn route_health() -> String
@@ -9,7 +9,7 @@ extern fn route_imprint_contextual(body: String) -> String
extern fn route_imprint_user(body: String) -> String
extern fn route_synthesize(body: String) -> String
extern fn handle_dharma_recv(body: String) -> String
extern fn route_sessions() -> String
extern fn parse_session_id_from_path(path: String) -> String
extern fn parse_session_subpath(path: String) -> String
extern fn connectd_get(suffix: String) -> String
extern fn connectd_post(suffix: String, body: String) -> String
extern fn handle_connectors(method: String, clean: String, body: String) -> String
extern fn handle_request(method: String, path: String, body: String) -> String