Skip to content

Commit 9318dfc

Browse files
committed
Implement scheduled tasks ui
Signed-off-by: Lukas Schaefer <lukas@lschaefer.xyz>
1 parent 26da8eb commit 9318dfc

8 files changed

Lines changed: 222 additions & 51 deletions

File tree

lib/Controller/ChattyLLMController.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -318,9 +318,9 @@ public function deleteSession(int $sessionId): JSONResponse {
318318
*/
319319
#[NoAdminRequired]
320320
#[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['chat_api'])]
321-
public function getSessions(): JSONResponse {
321+
public function getSessions(?bool $isAssignment = false): JSONResponse {
322322
try {
323-
$sessions = $this->chatService->getSessionsForUser($this->userId);
323+
$sessions = $this->chatService->getSessionsForUser($this->userId, $isAssignment);
324324
/** @var list<AssistantChatSession> $serializedSessions */
325325
$serializedSessions = array_map(static function ($session) {
326326
return $session->jsonSerialize();
@@ -380,6 +380,7 @@ public function newMessage(
380380
* @param int $sessionId The session ID
381381
* @param int $limit The max number of messages to return
382382
* @param int $cursor The index of the first result to return
383+
* @param bool $hideUserMessages Whether to hide user messages from the response
383384
* @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{}>
384385
*
385386
* 200: The message list has been successfully obtained
@@ -388,9 +389,9 @@ public function newMessage(
388389
*/
389390
#[NoAdminRequired]
390391
#[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT, tags: ['chat_api'])]
391-
public function getMessages(int $sessionId, int $limit = 20, int $cursor = 0): JSONResponse {
392+
public function getMessages(int $sessionId, int $limit = 20, int $cursor = 0, bool $hideUserMessages = false): JSONResponse {
392393
try {
393-
$messages = $this->chatService->getSessionMessages($this->userId, $sessionId, $limit, $cursor);
394+
$messages = $this->chatService->getSessionMessages($this->userId, $sessionId, $limit, $cursor, $hideUserMessages);
394395
return new JSONResponse(array_map(static function (Message $message) {
395396
return $message->jsonSerialize();
396397
}, $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 bool $hideUserMessages
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, bool $hideUserMessages = false): 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 ($hideUserMessages) {
96+
$qb->andWhere($qb->expr()->neq('role', $qb->createPositionalParameter(Message::ROLE_HUMAN, 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: 4 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
}
@@ -250,7 +250,7 @@ public function createMessage(?string $userId, int $sessionId, string $role, str
250250
* @throws NotFoundException
251251
* @throws UnauthorizedException
252252
*/
253-
public function getSessionMessages(?string $userId, int $sessionId, int $limit = 20, int $cursor = 0): array {
253+
public function getSessionMessages(?string $userId, int $sessionId, int $limit = 20, int $cursor = 0, bool $hideUserMessages = false): array {
254254
if ($userId === null) {
255255
throw new UnauthorizedException($this->l10n->t('Unauthorized'));
256256
}
@@ -268,7 +268,7 @@ public function getSessionMessages(?string $userId, int $sessionId, int $limit =
268268

269269
/** @var list<Message> $messages */
270270
try {
271-
$messages = $this->messageMapper->getMessages($sessionId, $cursor, $limit);
271+
$messages = $this->messageMapper->getMessages($sessionId, $cursor, $limit, $hideUserMessages);
272272
} catch (Exception $e) {
273273
throw new InternalException(previous: $e);
274274
}

src/components/AssistantTextProcessingForm.vue

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717
:options="sortedTaskTypes"
1818
@update:model-value="onTaskTypeUserChange" />
1919
<div class="task-input-output-form">
20-
<ChattyLLMInputForm v-if="mySelectedTaskTypeId === 'chatty-llm'" class="chatty-inputs" />
20+
<ChattyLLMInputForm v-if="['chatty-llm', 'assignments'].includes(mySelectedTaskTypeId)"
21+
:is-assignment="mySelectedTaskTypeId === 'assignments'"
22+
class="chatty-inputs"
23+
@open-chat="onOpenChatFromAssignment" />
2124
<div v-else class="container chatty-inputs">
2225
<NcAppNavigation>
2326
<NcAppNavigationList>
@@ -516,6 +519,9 @@ export default {
516519
this.loadingTaskTypes = false
517520
})
518521
},
522+
onOpenChatFromAssignment() {
523+
this.mySelectedTaskTypeId = CHAT_TASK_TYPE_ID
524+
},
519525
onTaskTypeUserChange() {
520526
this.$emit('new-task')
521527

0 commit comments

Comments
 (0)