Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@
['name' => 'chattyLLM#newSession', 'url' => '/chat/sessions', 'verb' => 'POST', 'postfix' => 'restful'],
['name' => 'chattyLLM#updateChatSession', 'url' => '/chat/sessions/{sessionId}', 'verb' => 'PUT', 'postfix' => 'restful'],
['name' => 'chattyLLM#deleteSession', 'url' => '/chat/sessions/{sessionId}', 'verb' => 'DELETE', 'postfix' => 'restful'],
['name' => 'chattyLLM#deleteSessions', 'url' => '/chat/sessions', 'verb' => 'DELETE', 'postfix' => 'restful'],

['name' => 'chattyLLM#newSession', 'url' => '/chat/new_session', 'verb' => 'PUT'],
['name' => 'chattyLLM#updateSessionTitle', 'url' => '/chat/update_session', 'verb' => 'PATCH'],
['name' => 'chattyLLM#deleteSession', 'url' => '/chat/delete_session', 'verb' => 'DELETE'],
['name' => 'chattyLLM#deleteSessions', 'url' => '/chat/delete_sessions', 'verb' => 'DELETE'],
['name' => 'chattyLLM#getSessions', 'url' => '/chat/sessions', 'verb' => 'GET'],
['name' => 'chattyLLM#newMessage', 'url' => '/chat/new_message', 'verb' => 'PUT'],
['name' => 'chattyLLM#deleteMessage', 'url' => '/chat/delete_message', 'verb' => 'DELETE'],
Expand Down
30 changes: 30 additions & 0 deletions lib/Controller/ChattyLLMController.php
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,36 @@ public function deleteSession(int $sessionId): JSONResponse {
}
}

/**
* Delete chat sessions
*
* Delete several chat sessions by ID
*
* @param list<int> $sessionIds The session IDs
* @return JSONResponse<Http::STATUS_OK, list{}, array{}>|JSONResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_UNAUTHORIZED|Http::STATUS_BAD_REQUEST, array{error: string}, array{}>
*
* 200: The sessions have been deleted successfully
* 400: The list of session IDs is empty or invalid
* 401: Not logged in
*/
#[NoAdminRequired]
#[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['chat_api'])]
public function deleteSessions(array $sessionIds): JSONResponse {
if ($sessionIds === []) {
return new JSONResponse(['error' => $this->l10n->t('Invalid session IDs')], Http::STATUS_BAD_REQUEST);
}
try {
// we don't delete the tasks
$this->chatService->deleteSessions($this->userId, $sessionIds);
return new JSONResponse();
} catch (InternalException $e) {
$this->logger->warning('Failed to delete the chat sessions', ['exception' => $e]);
return new JSONResponse(['error' => $this->l10n->t('Failed to delete the chat sessions')], Http::STATUS_INTERNAL_SERVER_ERROR);
} catch (\OCA\Assistant\Service\UnauthorizedException $e) {
return new JSONResponse(['error' => $this->l10n->t('User not logged in')], Http::STATUS_UNAUTHORIZED);
}
}

/**
* Get chat sessions
*
Expand Down
17 changes: 17 additions & 0 deletions lib/Db/ChattyLLM/MessageMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,23 @@ public function deleteMessagesBySession(int $sessionId): void {
$qb->executeStatement();
}

/**
* @param list<int> $sessionIds
* @throws \OCP\DB\Exception
* @throws \RuntimeException
* @return void
*/
public function deleteMessagesBySessions(array $sessionIds): void {
$qb = $this->db->getQueryBuilder();
$qb->delete($this->getTableName())
->where($qb->expr()->in('session_id', $qb->createParameter('ids')));

foreach (array_chunk($sessionIds, IQueryBuilder::MAX_IN_PARAMETERS) as $chunk) {
$qb->setParameter('ids', $chunk, IQueryBuilder::PARAM_INT_ARRAY);
$qb->executeStatement();
}
}

/**
* @param int $sessionId
* @param integer $messageId
Expand Down
37 changes: 37 additions & 0 deletions lib/Db/ChattyLLM/SessionMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,43 @@ public function deleteSession(string $userId, int $sessionId) {
$qb->executeStatement();
}

/**
* @param string $userId
* @param list<int> $sessionIds
* @return list<Session>
* @throws \OCP\DB\Exception
*/
public function getUserSessionsByIds(string $userId, array $sessionIds): array {
$sessions = [];
foreach (array_chunk($sessionIds, IQueryBuilder::MAX_IN_PARAMETERS) as $chunk) {
$qb = $this->db->getQueryBuilder();
$qb->select(Session::$columns)
->from($this->getTableName())
->where($qb->expr()->eq('user_id', $qb->createPositionalParameter($userId, IQueryBuilder::PARAM_STR)))
->andWhere($qb->expr()->in('id', $qb->createPositionalParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
$sessions = array_merge($sessions, $this->findEntities($qb));
}
return $sessions;
}
Comment thread
WSHAPER marked this conversation as resolved.

/**
* @param string $userId
* @param list<int> $sessionIds
* @throws \OCP\DB\Exception
* @throws \RuntimeException
*/
public function deleteSessionsByUser(string $userId, array $sessionIds): void {
$qb = $this->db->getQueryBuilder();
$qb->delete($this->getTableName())
->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId, IQueryBuilder::PARAM_STR)))
->andWhere($qb->expr()->in('id', $qb->createParameter('ids')));

foreach (array_chunk($sessionIds, IQueryBuilder::MAX_IN_PARAMETERS) as $chunk) {
$qb->setParameter('ids', $chunk, IQueryBuilder::PARAM_INT_ARRAY);
$qb->executeStatement();
}
}

/**
* @throws \OCP\DB\Exception
*/
Expand Down
43 changes: 43 additions & 0 deletions lib/Service/ChatService.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use OCP\DB\Exception;
use OCP\Exceptions\AppConfigTypeConflictException;
use OCP\IAppConfig;
use OCP\IDBConnection;
use OCP\IL10N;
use OCP\IUserManager;
use OCP\TaskProcessing\Exception\PreConditionNotMetException;
Expand All @@ -36,6 +37,7 @@ public function __construct(
private readonly IL10N $l10n,
private readonly SessionMapper $sessionMapper,
private readonly MessageMapper $messageMapper,
private readonly IDBConnection $db,
private readonly SessionSummaryService $sessionSummaryService,
private readonly IManager $taskProcessingManager,
private readonly LoggerInterface $logger,
Expand Down Expand Up @@ -152,6 +154,47 @@ public function deleteSession(?string $userId, int $sessionId): void {
}
}

/**
* @param string|null $userId
* @param list<int> $sessionIds
* @throws InternalException
* @throws UnauthorizedException
*/
public function deleteSessions(?string $userId, array $sessionIds): void {
if ($userId === null) {
throw new UnauthorizedException($this->l10n->t('Unauthorized'));
}

$sessionIds = array_values(array_unique(array_map(static function ($sessionId) {
return (int)$sessionId;
}, $sessionIds)));

if ($sessionIds === []) {
return;
}

try {
$ownedSessions = $this->sessionMapper->getUserSessionsByIds($userId, $sessionIds);
$ownedSessionIds = array_map(static function (Session $session) {
return $session->getId();
}, $ownedSessions);

if ($ownedSessionIds === []) {
return;
}

$this->db->beginTransaction();
$this->sessionMapper->deleteSessionsByUser($userId, $ownedSessionIds);
$this->messageMapper->deleteMessagesBySessions($ownedSessionIds);
$this->db->commit();
Comment thread
coderabbitai[bot] marked this conversation as resolved.
} catch (Exception|\RuntimeException $e) {
if ($this->db->inTransaction()) {
$this->db->rollBack();
}
throw new InternalException(previous: $e);
}
}

/**
* @throws InternalException
*/
Expand Down
Loading
Loading