true, CURLOPT_TIMEOUT => 3]); $r = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($code !== 200) { $ch2 = curl_init("$QDRANT/collections/$COLLECTION"); curl_setopt_array($ch2, [ CURLOPT_CUSTOMREQUEST => "PUT", CURLOPT_POSTFIELDS => json_encode(["vectors" => ["size" => 384, "distance" => "Cosine"]]), CURLOPT_HTTPHEADER => ["Content-Type: application/json"], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5, ]); curl_exec($ch2); curl_close($ch2); } } // Embed text via Ollama all-minilm function embed($text) { global $OLLAMA; $ch = curl_init("$OLLAMA/api/embeddings"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode(["model" => "all-minilm", "prompt" => $text]), CURLOPT_HTTPHEADER => ["Content-Type: application/json"], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10, ]); $r = curl_exec($ch); curl_close($ch); $d = json_decode($r, true); return $d["embedding"] ?? null; } ensureCollection(); switch ($action) { case "remember": $key = $input["key"] ?? "mem_" . time(); $value = $input["value"] ?? ""; $context = $input["context"] ?? "general"; $timestamp = date("c"); if (empty($value)) { echo json_encode(["error" => "value required"]); exit; } $vector = embed($value); if (!$vector) { echo json_encode(["error" => "embedding failed"]); exit; } $point = [ "id" => abs(crc32($key)), "vector" => $vector, "payload" => [ "key" => $key, "value" => $value, "context" => $context, "timestamp" => $timestamp, "type" => "memory", ], ]; $ch = curl_init("$QDRANT/collections/wevia_memory/points"); curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => "PUT", CURLOPT_POSTFIELDS => json_encode(["points" => [$point]]), CURLOPT_HTTPHEADER => ["Content-Type: application/json"], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5, ]); $r = curl_exec($ch); curl_close($ch); echo json_encode(["status" => "remembered", "key" => $key, "id" => abs(crc32($key))]); break; case "recall": $q = $_GET["q"] ?? $input["query"] ?? ""; $limit = (int)($_GET["limit"] ?? 5); if (empty($q)) { echo json_encode(["error" => "query required"]); exit; } $vector = embed($q); if (!$vector) { echo json_encode(["error" => "embedding failed"]); exit; } $ch = curl_init("$QDRANT/collections/wevia_memory/points/search"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode(["vector" => $vector, "limit" => $limit, "with_payload" => true]), CURLOPT_HTTPHEADER => ["Content-Type: application/json"], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5, ]); $r = curl_exec($ch); curl_close($ch); $d = json_decode($r, true); $memories = []; foreach ($d["result"] ?? [] as $pt) { $memories[] = [ "key" => $pt["payload"]["key"] ?? "", "value" => $pt["payload"]["value"] ?? "", "context" => $pt["payload"]["context"] ?? "", "score" => round($pt["score"], 3), "timestamp" => $pt["payload"]["timestamp"] ?? "", ]; } echo json_encode(["query" => $q, "memories" => $memories, "count" => count($memories)]); break; case "list": $limit = (int)($_GET["limit"] ?? 20); $ch = curl_init("$QDRANT/collections/wevia_memory/points/scroll"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode(["limit" => $limit, "with_payload" => true]), CURLOPT_HTTPHEADER => ["Content-Type: application/json"], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5, ]); $r = curl_exec($ch); curl_close($ch); $d = json_decode($r, true); $memories = []; foreach ($d["result"]["points"] ?? [] as $pt) { $memories[] = $pt["payload"]; } echo json_encode(["memories" => $memories, "count" => count($memories)]); break; case "forget": $key = $input["key"] ?? ""; if (empty($key)) { echo json_encode(["error" => "key required"]); exit; } $id = abs(crc32($key)); $ch = curl_init("$QDRANT/collections/wevia_memory/points/delete"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode(["points" => [$id]]), CURLOPT_HTTPHEADER => ["Content-Type: application/json"], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5, ]); curl_exec($ch); curl_close($ch); echo json_encode(["status" => "forgotten", "key" => $key]); break; case "stats": $ch = curl_init("$QDRANT/collections/wevia_memory"); curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 3]); $r = curl_exec($ch); curl_close($ch); $d = json_decode($r, true); echo json_encode([ "collection" => "wevia_memory", "points" => $d["result"]["points_count"] ?? 0, "vectors" => $d["result"]["vectors_count"] ?? 0, "status" => $d["result"]["status"] ?? "unknown", ]); break; }