Skip to content

Commit d467bc9

Browse files
authored
Merge pull request #550 from nextcloud/feat/assignments-frontend
Implement scheduled tasks ui
2 parents 64ab92b + 4528cae commit d467bc9

12 files changed

Lines changed: 555 additions & 142 deletions

lib/Controller/ChattyLLMController.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -311,16 +311,17 @@ public function deleteSession(int $sessionId): JSONResponse {
311311
*
312312
* Get all chat sessions for the current user
313313
*
314+
* @param bool|null $isAssignment Whether to get only the sessions for assignments (true) or not (false) defaults to false
314315
* @return JSONResponse<Http::STATUS_OK, list<AssistantChatSession>, array{}>|JSONResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_UNAUTHORIZED, array{error: string}, array{}>
315316
*
316317
* 200: The session list has been obtained successfully
317318
* 401: Not logged in
318319
*/
319320
#[NoAdminRequired]
320321
#[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['chat_api'])]
321-
public function getSessions(): JSONResponse {
322+
public function getSessions(?bool $isAssignment = false): JSONResponse {
322323
try {
323-
$sessions = $this->chatService->getSessionsForUser($this->userId);
324+
$sessions = $this->chatService->getSessionsForUser($this->userId, $isAssignment);
324325
/** @var list<AssistantChatSession> $serializedSessions */
325326
$serializedSessions = array_map(static function ($session) {
326327
return $session->jsonSerialize();
@@ -380,6 +381,7 @@ public function newMessage(
380381
* @param int $sessionId The session ID
381382
* @param int $limit The max number of messages to return
382383
* @param int $cursor The index of the first result to return
384+
* @param string $filterByRole Only role to include in the response
383385
* @return JSONResponse<Http::STATUS_OK, list<AssistantChatMessage>, array{}>|JSONResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_UNAUTHORIZED|Http::STATUS_NOT_FOUND, array{error: string}, array{}>
384386
*
385387
* 200: The message list has been successfully obtained
@@ -388,9 +390,9 @@ public function newMessage(
388390
*/
389391
#[NoAdminRequired]
390392
#[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['chat_api'])]
391-
public function getMessages(int $sessionId, int $limit = 20, int $cursor = 0): JSONResponse {
393+
public function getMessages(int $sessionId, int $limit = 20, int $cursor = 0, string $filterByRole = ''): JSONResponse {
392394
try {
393-
$messages = $this->chatService->getSessionMessages($this->userId, $sessionId, $limit, $cursor);
395+
$messages = $this->chatService->getSessionMessages($this->userId, $sessionId, $limit, $cursor, $filterByRole);
394396
return new JSONResponse(array_map(static function (Message $message) {
395397
return $message->jsonSerialize();
396398
}, $messages));

lib/Db/ChattyLLM/MessageMapper.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,22 @@ public function getLastNonEmptyHumanMessage(int $sessionId): Message {
8080
* @param int $sessionId
8181
* @param int $cursor
8282
* @param int $limit
83+
* @param string $filterByRole Only include messages with this role (empty to include all)
8384
* @return list<Message>
8485
* @throws \OCP\DB\Exception
8586
*/
86-
public function getMessages(int $sessionId, int $cursor, int $limit): array {
87+
public function getMessages(int $sessionId, int $cursor, int $limit, string $filterByRole = ''): array {
8788
$qb = $this->db->getQueryBuilder();
8889
$qb->select(Message::$columns)
8990
->from($this->getTableName())
9091
->where($qb->expr()->eq('session_id', $qb->createPositionalParameter($sessionId, IQueryBuilder::PARAM_INT)))
9192
->orderBy('id', 'DESC')
9293
->setFirstResult($cursor);
9394

95+
if ($filterByRole !== '') {
96+
$qb->andWhere($qb->expr()->eq('role', $qb->createPositionalParameter($filterByRole, IQueryBuilder::PARAM_STR)));
97+
}
98+
9499
if ($limit > 0) {
95100
$qb->setMaxResults($limit);
96101
}

lib/Db/ChattyLLM/SessionMapper.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,23 @@ public function getUserSessionForAssignment(string $userId, int $assignmentId):
8484

8585
/**
8686
* @param string $userId
87+
* @param bool $isAssignment
8788
* @return list<Session>
8889
* @throws \OCP\DB\Exception
8990
*/
90-
public function getUserSessions(string $userId): array {
91+
public function getUserSessions(string $userId, bool $isAssignment): array {
9192
$qb = $this->db->getQueryBuilder();
9293
$qb->select(Session::$columns)
9394
->from($this->getTableName())
9495
->where($qb->expr()->eq('user_id', $qb->createPositionalParameter($userId, IQueryBuilder::PARAM_STR)))
9596
->orderBy('timestamp', 'DESC');
9697

98+
if ($isAssignment) {
99+
$qb->andWhere($qb->expr()->isNotNull('assignment_id'));
100+
} else {
101+
$qb->andWhere($qb->expr()->isNull('assignment_id'));
102+
}
103+
97104
return $this->findEntities($qb);
98105
}
99106

lib/Service/AssistantService.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class AssistantService {
6464

6565
private const TASK_TYPE_PRIORITIES = [
6666
'chatty-llm' => 1,
67+
'assignments' => 1,
6768
TextToText::ID => 2,
6869
'context_chat:context_chat' => 3,
6970
'legacy:TextProcessing:OCA\ContextChat\TextProcessing\ContextChatTaskType' => 3,
@@ -287,6 +288,9 @@ private function getCategory(string $typeId): array {
287288
if (str_starts_with($typeId, 'chatty')) {
288289
$categoryId = 'chat';
289290
$categoryName = $this->l10n->t('Chat with AI');
291+
} elseif (str_starts_with($typeId, 'assignments')) {
292+
$categoryId = 'assignments';
293+
$categoryName = $this->l10n->t('Scheduled tasks');
290294
} elseif (str_starts_with($typeId, 'context_chat')) {
291295
$categoryId = 'context';
292296
$categoryName = $this->l10n->t('Context Chat');
@@ -435,6 +439,23 @@ public function getAvailableTaskTypes(): array {
435439
'priority' => self::TASK_TYPE_PRIORITIES['chatty-llm'] ?? 1000,
436440
'preferredProviderName' => $preferredProviderName,
437441
];
442+
// add the chattyUI assignments virtual task type
443+
$types[] = [
444+
'id' => 'assignments',
445+
'name' => $this->l10n->t('Scheduled tasks'),
446+
'description' => $this->l10n->t('Scheduled tasks'),
447+
'category' => $this->getCategory('assignments'),
448+
'inputShape' => [],
449+
'inputShapeEnumValues' => [],
450+
'inputShapeDefaults' => [],
451+
'outputShape' => [],
452+
'optionalInputShape' => [],
453+
'optionalInputShapeEnumValues' => [],
454+
'optionalInputShapeDefaults' => [],
455+
'optionalOutputShape' => [],
456+
'priority' => self::TASK_TYPE_PRIORITIES['assignments'] ?? 1000,
457+
'preferredProviderName' => $preferredProviderName,
458+
];
438459
// do not add the raw TextToTextChat type
439460
if (!self::DEBUG) {
440461
continue;

lib/Service/ChatService.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,12 @@ public function deleteSession(?string $userId, int $sessionId): void {
157157
* @throws InternalException
158158
* @throws UnauthorizedException
159159
*/
160-
public function getSessionsForUser(?string $userId): array {
160+
public function getSessionsForUser(?string $userId, bool $isAssignment): array {
161161
if ($userId === null) {
162162
throw new UnauthorizedException($this->l10n->t('Unauthorized'));
163163
}
164164
try {
165-
return $this->sessionMapper->getUserSessions($userId);
165+
return $this->sessionMapper->getUserSessions($userId, $isAssignment);
166166
} catch (Exception $e) {
167167
throw new InternalException(previous: $e);
168168
}
@@ -249,12 +249,13 @@ public function createMessage(?string $userId, int $sessionId, string $role, str
249249
}
250250

251251
/**
252+
* @param string $filterByRole Only include messages with this role (empty to include all)
252253
* @return list<Message>
253254
* @throws InternalException
254255
* @throws NotFoundException
255256
* @throws UnauthorizedException
256257
*/
257-
public function getSessionMessages(?string $userId, int $sessionId, int $limit = 20, int $cursor = 0): array {
258+
public function getSessionMessages(?string $userId, int $sessionId, int $limit = 20, int $cursor = 0, string $filterByRole = ''): array {
258259
if ($userId === null) {
259260
throw new UnauthorizedException($this->l10n->t('Unauthorized'));
260261
}
@@ -272,7 +273,7 @@ public function getSessionMessages(?string $userId, int $sessionId, int $limit =
272273

273274
/** @var list<Message> $messages */
274275
try {
275-
$messages = $this->messageMapper->getMessages($sessionId, $cursor, $limit);
276+
$messages = $this->messageMapper->getMessages($sessionId, $cursor, $limit, $filterByRole);
276277
} catch (Exception $e) {
277278
throw new InternalException(previous: $e);
278279
}

openapi.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2899,6 +2899,16 @@
28992899
}
29002900
],
29012901
"parameters": [
2902+
{
2903+
"name": "isAssignment",
2904+
"in": "query",
2905+
"description": "Whether to get only the sessions for assignments (true) or not (false) defaults to false",
2906+
"schema": {
2907+
"type": "boolean",
2908+
"nullable": true,
2909+
"default": false
2910+
}
2911+
},
29022912
{
29032913
"name": "OCS-APIRequest",
29042914
"in": "header",
@@ -4044,6 +4054,15 @@
40444054
"default": 0
40454055
}
40464056
},
4057+
{
4058+
"name": "filterByRole",
4059+
"in": "query",
4060+
"description": "Only role to include in the response",
4061+
"schema": {
4062+
"type": "string",
4063+
"default": ""
4064+
}
4065+
},
40474066
{
40484067
"name": "OCS-APIRequest",
40494068
"in": "header",

0 commit comments

Comments
 (0)