Files
myron 27a0259e64 Phase 10: Memory Core — auto-extraction knowledge graph
- reactor.py v9.0.0+: memory_extract + memory_store handlers (21 handlers)
  - handle_memory_extract: Haiku-powered fact extraction from conversations
  - handle_memory_store: explicit memory insertion from voice commands
  - FastAPI: /memory/facts CRUD, /memory/context (relevance retrieval), /memory/stats
- chat.php: Tier 0.9k voice commands (remember/forget/recall/memory status)
  - Memory context injected into Groq + Claude system prompts
  - Auto-trigger memory_extract after every LLM response (async, non-blocking)
- memory.php: new API endpoint proxying Arc Reactor memory routes
- api.php: added memory route
- admin/index.php: MEMORY CORE nav + tab (browse by category, search, add/delete facts)
- index.html: MEMORY count in bottom bar (polls every 60s)
2026-06-11 12:33:05 +00:00

82 lines
2.9 KiB
PHP

<?php
/**
* JARVIS Memory Core API
*/
require_once __DIR__ . '/../../api/lib/db.php';
$action = $_GET['action'] ?? '';
$data = json_decode(file_get_contents('php://input'), true) ?? [];
function memArcGet(string $path): array {
$ch = curl_init('http://127.0.0.1:7474' . $path);
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>5]);
$raw = curl_exec($ch); curl_close($ch);
return json_decode($raw, true) ?: [];
}
function memArcPost(string $path, array $body): array {
$ch = curl_init('http://127.0.0.1:7474' . $path);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER=>true, CURLOPT_POST=>true, CURLOPT_TIMEOUT=>5,
CURLOPT_POSTFIELDS => json_encode($body),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
]);
$raw = curl_exec($ch); curl_close($ch);
return json_decode($raw, true) ?: [];
}
function memArcDelete(string $path): array {
$ch = curl_init('http://127.0.0.1:7474' . $path);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER=>true, CURLOPT_CUSTOMREQUEST=>'DELETE', CURLOPT_TIMEOUT=>5,
]);
$raw = curl_exec($ch); curl_close($ch);
return json_decode($raw, true) ?: ['ok' => true];
}
switch ($action) {
case 'list':
$limit = min((int)($_GET['limit'] ?? 100), 500);
$category = $_GET['category'] ?? '';
$search = $_GET['search'] ?? '';
$qs = http_build_query(array_filter(['limit'=>$limit,'category'=>$category,'search'=>$search]));
echo json_encode(memArcGet('/memory/facts' . ($qs ? '?'.$qs : '')));
break;
case 'stats':
echo json_encode(memArcGet('/memory/stats'));
break;
case 'context':
$msg = $_GET['message'] ?? '';
$limit = (int)($_GET['limit'] ?? 12);
$qs = http_build_query(['message'=>$msg,'limit'=>$limit]);
echo json_encode(memArcGet('/memory/context?' . $qs));
break;
case 'store':
$subject = trim($data['subject'] ?? '');
$predicate = trim($data['predicate'] ?? 'is');
$object = trim($data['object'] ?? '');
$category = $data['category'] ?? 'fact';
if (!$subject || !$object) { http_response_code(400); echo json_encode(['error'=>'subject and object required']); break; }
echo json_encode(memArcPost('/memory/facts', ['subject'=>$subject,'predicate'=>$predicate,'object'=>$object,'category'=>$category]));
break;
case 'delete':
$id = (int)($_GET['id'] ?? 0);
if (!$id) { http_response_code(400); echo json_encode(['error'=>'Missing id']); break; }
echo json_encode(memArcDelete('/memory/facts/' . $id));
break;
case 'clear':
$category = $_GET['category'] ?? '';
$qs = $category ? '?category=' . urlencode($category) : '';
echo json_encode(memArcDelete('/memory/facts' . $qs));
break;
default:
http_response_code(404);
echo json_encode(['error' => 'Unknown memory action: ' . $action]);
}