You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
242 lines
5.7 KiB
242 lines
5.7 KiB
<?php
|
|
|
|
header('Content-Type: application/json');
|
|
|
|
require_once __DIR__ . '/default.php';
|
|
|
|
/*----------------------------------------------------------
|
|
- Create storage file if necessary
|
|
----------------------------------------------------------*/
|
|
if (!file_exists(CHAT_HISTORY_FILE)) {
|
|
if (@file_put_contents(CHAT_HISTORY_FILE, '') === false) {
|
|
http_response_code(500);
|
|
echo json_encode([
|
|
'error' => '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;
|
|
}
|