Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
341d30b
feat(streaming): update task output while polling, display form if th…
julien-nc May 13, 2026
931d137
feat(streaming): show notify and cancel buttons in the task header wh…
julien-nc May 13, 2026
4754395
feat(streaming): adjust chat UI to display intermediate/streaming mes…
julien-nc May 13, 2026
b87b94e
make the dialog initial width 70%
julien-nc May 13, 2026
e675534
add a loading icon in the output form while streaming
julien-nc May 13, 2026
6b5090d
add @nextcloud/notify_push
julien-nc May 13, 2026
ff7ed6f
feat(streaming): use notify_push to get the polled task's output
julien-nc May 13, 2026
c13c7ce
feat(streaming): use notify_push to get the polled chat message gener…
julien-nc May 13, 2026
22e64e7
start listening to notify_push messages when loading a task in the ge…
julien-nc May 18, 2026
8cc369a
prevent listening notify push msgs twice for the same task after swit…
julien-nc May 18, 2026
9b36ff6
regenerate openapi specs, fix psalm issue
julien-nc May 18, 2026
ad1e110
add simple pulse animation to output fields when streaming
julien-nc May 18, 2026
e02c6d8
start listening to notify_push messages when loading a task from a no…
julien-nc May 19, 2026
20c87fc
add pulse animation to 'getting results...' label
julien-nc May 19, 2026
fe88435
disable all animations when prefers-reduced-motion is enabled
julien-nc May 19, 2026
c5184d1
remove form header title blink animation, use the copy button in text…
julien-nc May 19, 2026
7a1f037
polish chat UI
julien-nc May 20, 2026
f115fac
make sure we handle the case where there is no push message body
julien-nc May 20, 2026
929d9e9
do not update the output when polling while streaming
julien-nc May 20, 2026
06d155a
fix small old mistakes
julien-nc May 20, 2026
597edcf
handle the cases where there is no selected task in AssistantPage or …
julien-nc May 20, 2026
800d0e5
scroll output text fields to bottom while streaming
julien-nc May 21, 2026
674b29a
nothing
julien-nc May 28, 2026
5b16a98
do not update the chat task output if we know notify_push is available
julien-nc Jun 1, 2026
0862807
use NcNoteCard for the running action buttons in the classic form whi…
julien-nc Jun 2, 2026
33106d8
use notify_push to update the task statuses
julien-nc Jun 5, 2026
f0377fd
adjust notify push messages
julien-nc Jun 5, 2026
05145e3
fix potential issues when switching tasks (reset status) and fix canS…
julien-nc Jun 5, 2026
a38121d
feat(streaming): Implement pseudo-streaming
marcelklehr Jun 10, 2026
082fad7
prefer streaming when scheduling in the generic form and when schedul…
julien-nc Jun 11, 2026
4fc1097
fix scroll
julien-nc Jun 11, 2026
76e9f61
prevent auto-scrolling after the user has manually scrolled while a t…
julien-nc Jun 11, 2026
6089a63
feat(streaming): Display streamed tool calls / sources dynamically
marcelklehr Jun 11, 2026
0ebdc5d
Merge branch 'main' into enh/noid/streaming
marcelklehr Jun 11, 2026
6c97360
fix psalm issues
julien-nc Jun 12, 2026
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
11 changes: 9 additions & 2 deletions lib/Controller/ChattyLLMController.php
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ public function regenerateForSession(int $sessionId, int $messageId): JSONRespon
*
* @param int $taskId The message generation task ID
* @param int $sessionId The chat session ID
* @return JSONResponse<Http::STATUS_OK, AssistantChatAgencyMessage, array{}>|JSONResponse<Http::STATUS_EXPECTATION_FAILED, array{task_status: int, slow_pickup: bool}, array{}>|JSONResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_UNAUTHORIZED|Http::STATUS_BAD_REQUEST|Http::STATUS_NOT_FOUND, array{error: string}, array{}>
* @return JSONResponse<Http::STATUS_OK, AssistantChatAgencyMessage, array{}>|JSONResponse<Http::STATUS_EXPECTATION_FAILED, array{task_status: int, slow_pickup: bool, task_output?: array<string, list<numeric|string>|numeric|string>|null}, array{}>|JSONResponse<Http::STATUS_INTERNAL_SERVER_ERROR|Http::STATUS_UNAUTHORIZED|Http::STATUS_BAD_REQUEST|Http::STATUS_NOT_FOUND, array{error: string}, array{}>
* @throws MultipleObjectsReturnedException
* @throws \OCP\DB\Exception
*
Expand Down Expand Up @@ -601,7 +601,14 @@ public function checkMessageGenerationTask(int $taskId, int $sessionId): JSONRes
} elseif ($task->getstatus() === Task::STATUS_RUNNING || $task->getstatus() === Task::STATUS_SCHEDULED) {
$startTime = $task->getStartedAt() ?? time();
$slowPickup = ($task->getScheduledAt() + (60 * 5)) < $startTime;
return new JSONResponse(['task_status' => $task->getstatus(), 'slow_pickup' => $slowPickup], Http::STATUS_EXPECTATION_FAILED);
$responsePayload = [
'task_status' => $task->getstatus(),
'slow_pickup' => $slowPickup,
];
if ($task->getstatus() === Task::STATUS_RUNNING) {
$responsePayload['task_output'] = $task->getOutput();
}
return new JSONResponse($responsePayload, Http::STATUS_EXPECTATION_FAILED);
} elseif ($task->getstatus() === Task::STATUS_FAILED || $task->getstatus() === Task::STATUS_CANCELLED) {
return new JSONResponse(['error' => 'task_failed_or_canceled', 'task_status' => $task->getstatus()], Http::STATUS_BAD_REQUEST);
}
Expand Down
4 changes: 4 additions & 0 deletions lib/Service/ChatService.php
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,8 @@ private function scheduleLLMChatTask(
$input['memories'] = $this->sessionSummaryService->getMemories($userId);
}
$task = new Task(TextToTextChat::ID, $input, Application::APP_ID . ':chatty-llm', $userId, $customId);
/** @psalm-suppress UndefinedMethod */
$task->setPreferStreaming(true);
try {
$this->taskProcessingManager->scheduleTask($task);
} catch (PreConditionNotMetException $e) {
Expand Down Expand Up @@ -700,6 +702,8 @@ private function scheduleAgencyTask(
$userId,
$customId
);
/** @psalm-suppress UndefinedMethod */
$task->setPreferStreaming(true);
try {
$this->taskProcessingManager->scheduleTask($task);
} catch (PreConditionNotMetException $e) {
Expand Down
27 changes: 27 additions & 0 deletions openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -4874,6 +4874,33 @@
},
"slow_pickup": {
"type": "boolean"
},
"task_output": {
"type": "object",
"nullable": true,
"additionalProperties": {
"oneOf": [
{
"type": "array",
"items": {
"oneOf": [
{
"type": "number"
},
{
"type": "string"
}
]
}
},
{
"type": "number"
},
{
"type": "string"
}
]
}
}
}
}
Expand Down
59 changes: 37 additions & 22 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"@nextcloud/initial-state": "^3.0.0",
"@nextcloud/l10n": "^3.4.0",
"@nextcloud/moment": "^1.3.1",
"@nextcloud/notify_push": "^1.4.0",
"@nextcloud/router": "^3.0.0",
"@nextcloud/vue": "^9.0.0-rc.5",
"@primeuix/themes": "^2.0.3",
Expand Down
Loading
Loading