Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 99c5ce6e94 | |||
| b210013891 | |||
| 635daaca9c | |||
| 9f9f271e78 | |||
| 3ad9dc7df7 | |||
| cec2aa7168 | |||
| f47c92a71a |
@@ -1688,12 +1688,25 @@ fn handle_chat_agentic(body: String) -> String {
|
|||||||
let safe_msg: String = json_safe(message)
|
let safe_msg: String = json_safe(message)
|
||||||
let safe_sys: String = json_safe(system)
|
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.
|
// 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 prior_messages: String = if agentic_hist_len > 0 {
|
||||||
let inner: String = str_slice(agentic_hist, 1, str_len(agentic_hist) - 1)
|
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 {
|
} else {
|
||||||
"[{\"role\":\"user\",\"content\":\"" + safe_msg + "\"}]"
|
"[{\"role\":\"user\",\"content\":" + cur_user_content + "}]"
|
||||||
}
|
}
|
||||||
let messages: String = prior_messages
|
let messages: String = prior_messages
|
||||||
let api_url: String = "https://api.anthropic.com/v1/messages"
|
let api_url: String = "https://api.anthropic.com/v1/messages"
|
||||||
|
|||||||
@@ -335,6 +335,12 @@ fn handle_connectors(method: String, clean: String, body: String) -> String {
|
|||||||
if str_eq(clean, "/api/connectors/oauth/start") {
|
if str_eq(clean, "/api/connectors/oauth/start") {
|
||||||
return connectd_post("/mcp/oauth/start", body)
|
return connectd_post("/mcp/oauth/start", body)
|
||||||
}
|
}
|
||||||
|
// Call a connector tool directly (pre-chat), e.g. WhatsApp get_pairing_qr / get_login_status for
|
||||||
|
// the pairing UI. Body: {"name":"mcp__<server>__<tool>","input":{...}}. Keeps the app on the
|
||||||
|
// app->soul->connectd path (the UI never hits connectd directly) and works for remote/hosted apps.
|
||||||
|
if str_eq(clean, "/api/connectors/call") {
|
||||||
|
return connectd_post("/mcp/call", body)
|
||||||
|
}
|
||||||
return "{\"ok\":false,\"error\":\"unknown connectors route\"}"
|
return "{\"ok\":false,\"error\":\"unknown connectors route\"}"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -459,7 +465,10 @@ fn handle_request(method: String, path: String, body: String) -> String {
|
|||||||
return handle_api_inspect_graph(method, path, body)
|
return handle_api_inspect_graph(method, path, body)
|
||||||
}
|
}
|
||||||
if str_starts_with(clean, "/api/neuron/list/") {
|
if str_starts_with(clean, "/api/neuron/list/") {
|
||||||
let node_type: String = str_slice(clean, 16, str_len(clean))
|
// Offset 17 = len("/api/neuron/list/"). Was 16, which left a leading "/" on node_type
|
||||||
|
// ("/BacklogItem"), so engram_scan_nodes_by_type_json matched nothing → list/<type>
|
||||||
|
// returned [] for EVERY type (broke backlog/typed-node listing app- and tool-wide).
|
||||||
|
let node_type: String = str_slice(clean, 17, str_len(clean))
|
||||||
return handle_api_list_typed(node_type, path, body)
|
return handle_api_list_typed(node_type, path, body)
|
||||||
}
|
}
|
||||||
if str_starts_with(clean, "/api/neuron/recall") {
|
if str_starts_with(clean, "/api/neuron/recall") {
|
||||||
|
|||||||
Reference in New Issue
Block a user