'Cannot create history file.' ]); exit; } } /*---------------------------------------------------------- - Helper ----------------------------------------------------------*/ function readChats() { $result = []; $fp = fopen(CHAT_HISTORY_FILE, 'c+'); if (!$fp) { return []; } flock($fp, LOCK_SH); while (($line = fgets($fp)) !== false) { $line = trim($line); if ($line === '') { continue; } $obj = json_decode($line, true); if (is_array($obj)) { $result[] = $obj; } } flock($fp, LOCK_UN); fclose($fp); return $result; } function writeChats($chats) { $fp = fopen(CHAT_HISTORY_FILE, 'w'); if (!$fp) { return false; } flock($fp, LOCK_EX); foreach ($chats as $chat) { fwrite($fp, json_encode($chat, JSON_UNESCAPED_UNICODE) . PHP_EOL); } fflush($fp); flock($fp, LOCK_UN); fclose($fp); return true; } function createTitle($messages) { foreach ($messages as $msg) { if (($msg['role'] ?? '') === 'user') { $title = trim($msg['content']); if (mb_strlen($title) > 60) { $title = mb_substr($title, 0, 60) . "..."; } return $title; } } return "Untitled Chat"; } /*---------------------------------------------------------- - Action ----------------------------------------------------------*/ $action = $_GET['action'] ?? ''; switch ($action) { /*------------------------------------------------------ - LIST ------------------------------------------------------*/ case 'list': $chats = readChats(); $list = []; foreach ($chats as $chat) { $list[] = [ 'id' => $chat['id'], 'title' => $chat['title'], 'created' => $chat['created'], 'model' => $chat['model'] ?? '' ]; } usort($list, function($a, $b) { return strcmp($b['created'], $a['created']); }); echo json_encode($list); exit; /*------------------------------------------------------ - LOAD ------------------------------------------------------*/ case 'load': $id = $_GET['id'] ?? ''; if ($id == '') { echo json_encode([ 'error' => 'Missing id.' ]); exit; } $chats = readChats(); foreach ($chats as $chat) { if ($chat['id'] === $id) { echo json_encode($chat); exit; } } echo json_encode([ 'error' => 'Chat not found.' ]); exit; /*------------------------------------------------------ - SAVE ------------------------------------------------------*/ case 'save': if ($_SERVER['REQUEST_METHOD'] !== 'POST') { echo json_encode([ 'error' => 'POST required.' ]); exit; } $input = json_decode(file_get_contents('php://input'), true); if (!is_array($input)) { echo json_encode([ 'error' => 'Invalid JSON.' ]); exit; } $messages = $input['messages'] ?? []; if (!is_array($messages) || count($messages) == 0) { echo json_encode([ 'error' => 'No messages.' ]); exit; } $id = $input['id'] ?? ''; if ($id == '') { $id = uniqid('', true); } $title = createTitle($messages); $model = $input['model'] ?? ''; $chat = [ 'id' => $id, 'title' => $title, 'created' => date('Y-m-d H:i:s'), 'model' => $model, 'messages' => $messages ]; $chats = readChats(); $found = false; foreach ($chats as &$existing) { if ($existing['id'] === $id) { $existing = $chat; $found = true; break; } } if (!$found) { $chats[] = $chat; } if (!writeChats($chats)) { echo json_encode([ 'error' => 'Unable to save.' ]); exit; } echo json_encode([ 'success' => true, 'id' => $id, 'title' => $title ]); exit; /*------------------------------------------------------ - DELETE ------------------------------------------------------*/ case 'delete': $id = $_GET['id'] ?? ''; if ($id == '') { echo json_encode([ 'error' => 'Missing id.' ]); exit; } $chats = readChats(); $newChats = []; foreach ($chats as $chat) { if ($chat['id'] !== $id) { $newChats[] = $chat; } } writeChats($newChats); echo json_encode([ 'success' => true ]); exit; /*------------------------------------------------------ - DEFAULT ------------------------------------------------------*/ default: echo json_encode([ 'error' => 'Unknown action.' ]); exit; }