From 9f004e741ac8b1170d4da441a128b5794b78087e Mon Sep 17 00:00:00 2001 From: Julien Veyssier Date: Tue, 29 Sep 2026 17:38:51 +0200 Subject: [PATCH 1/3] add extra conversation_id input to scheduled chat tasks if the current provider has it in its optional input shape Signed-off-by: Julien Veyssier --- lib/Service/ChatService.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/Service/ChatService.php b/lib/Service/ChatService.php index 1f27de531..185ed9b62 100644 --- a/lib/Service/ChatService.php +++ b/lib/Service/ChatService.php @@ -752,6 +752,9 @@ private function scheduleLLMChatTask( if (isset($this->taskProcessingManager->getAvailableTaskTypes()[TextToTextChat::ID]['optionalInputShape']['memories'])) { $input['memories'] = $this->sessionSummaryService->getMemories($userId); } + if (isset($this->taskProcessingManager->getAvailableTaskTypes()[TextToTextChat::ID]['optionalInputShape']['conversation_id'])) { + $input['conversation_id'] = (string)$sessionId; + } $task = new Task(TextToTextChat::ID, $input, Application::APP_ID . ':chatty-llm', $userId, $customId); /** @psalm-suppress UndefinedMethod */ $task->setPreferStreaming(true); @@ -795,6 +798,10 @@ private function scheduleMultimodalChatTask( 'tool_message' => '', ]; /** @psalm-suppress UndefinedClass */ + if (isset($this->taskProcessingManager->getAvailableTaskTypes()[\OCP\TaskProcessing\TaskTypes\MultimodalChatWithTools::ID]['optionalInputShape']['conversation_id'])) { + $input['conversation_id'] = (string)$sessionId; + } + /** @psalm-suppress UndefinedClass */ $task = new Task(\OCP\TaskProcessing\TaskTypes\MultimodalChatWithTools::ID, $input, Application::APP_ID . ':chatty-llm', $userId, $customId); /** @psalm-suppress UndefinedMethod */ $task->setPreferStreaming(true); @@ -936,6 +943,10 @@ private function scheduleAudioChatTask( $input['memories'] = $this->sessionSummaryService->getMemories($userId); } /** @psalm-suppress UndefinedClass */ + if (isset($this->taskProcessingManager->getAvailableTaskTypes()[\OCP\TaskProcessing\TaskTypes\AudioToAudioChat::ID]['optionalInputShape']['conversation_id'])) { + $input['conversation_id'] = (string)$sessionId; + } + /** @psalm-suppress UndefinedClass */ $task = new Task( \OCP\TaskProcessing\TaskTypes\AudioToAudioChat::ID, $input, From 0171e4abc491b45d7bb1b2eed43610073fc37ffe Mon Sep 17 00:00:00 2001 From: Julien Veyssier Date: Thu, 8 Oct 2026 11:27:23 +0200 Subject: [PATCH 2/3] fix: use a different conversation_id for title generation, do not include memories in title generation task Signed-off-by: Julien Veyssier --- lib/Service/ChatService.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/Service/ChatService.php b/lib/Service/ChatService.php index 185ed9b62..b1131b07b 100644 --- a/lib/Service/ChatService.php +++ b/lib/Service/ChatService.php @@ -749,11 +749,12 @@ private function scheduleLLMChatTask( 'system_prompt' => $systemPrompt, 'history' => $history, ]; - if (isset($this->taskProcessingManager->getAvailableTaskTypes()[TextToTextChat::ID]['optionalInputShape']['memories'])) { + if ($isMessage && isset($this->taskProcessingManager->getAvailableTaskTypes()[TextToTextChat::ID]['optionalInputShape']['memories'])) { $input['memories'] = $this->sessionSummaryService->getMemories($userId); } if (isset($this->taskProcessingManager->getAvailableTaskTypes()[TextToTextChat::ID]['optionalInputShape']['conversation_id'])) { - $input['conversation_id'] = (string)$sessionId; + // the title generation must not join the conversation state of the chat itself + $input['conversation_id'] = $isMessage ? (string)$sessionId : $sessionId . '-title'; } $task = new Task(TextToTextChat::ID, $input, Application::APP_ID . ':chatty-llm', $userId, $customId); /** @psalm-suppress UndefinedMethod */ From 32f39ff5d57f84c392989e9c04ea3f0cae9958de Mon Sep 17 00:00:00 2001 From: Julien Veyssier Date: Thu, 8 Oct 2026 14:05:01 +0200 Subject: [PATCH 3/3] define the conversation_id when scheduling chat-related tasks Signed-off-by: Julien Veyssier --- lib/Service/ChatService.php | 39 +++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/lib/Service/ChatService.php b/lib/Service/ChatService.php index b1131b07b..6bd97b66b 100644 --- a/lib/Service/ChatService.php +++ b/lib/Service/ChatService.php @@ -726,6 +726,21 @@ private function checkIfSessionIsThinking(?string $userId, string $customId): vo } } + /** + * Give a chat task the conversation ID of its session, but only when the + * provider of the task type declares a conversation ID as an optional input + * slot. Providers generate a throwaway ID for the requests we leave unset. + * + * @param array $input + * @return array + */ + private function addConversationId(array $input, string $taskTypeId, string $conversationId): array { + if (isset($this->taskProcessingManager->getAvailableTaskTypes()[$taskTypeId]['optionalInputShape']['conversation_id'])) { + $input['conversation_id'] = $conversationId; + } + return $input; + } + /** * Schedule a Chat task * @@ -752,10 +767,12 @@ private function scheduleLLMChatTask( if ($isMessage && isset($this->taskProcessingManager->getAvailableTaskTypes()[TextToTextChat::ID]['optionalInputShape']['memories'])) { $input['memories'] = $this->sessionSummaryService->getMemories($userId); } - if (isset($this->taskProcessingManager->getAvailableTaskTypes()[TextToTextChat::ID]['optionalInputShape']['conversation_id'])) { - // the title generation must not join the conversation state of the chat itself - $input['conversation_id'] = $isMessage ? (string)$sessionId : $sessionId . '-title'; - } + // the title generation must not join the conversation state of the chat itself + $input = $this->addConversationId( + $input, + TextToTextChat::ID, + $isMessage ? (string)$sessionId : $sessionId . '-title', + ); $task = new Task(TextToTextChat::ID, $input, Application::APP_ID . ':chatty-llm', $userId, $customId); /** @psalm-suppress UndefinedMethod */ $task->setPreferStreaming(true); @@ -799,9 +816,7 @@ private function scheduleMultimodalChatTask( 'tool_message' => '', ]; /** @psalm-suppress UndefinedClass */ - if (isset($this->taskProcessingManager->getAvailableTaskTypes()[\OCP\TaskProcessing\TaskTypes\MultimodalChatWithTools::ID]['optionalInputShape']['conversation_id'])) { - $input['conversation_id'] = (string)$sessionId; - } + $input = $this->addConversationId($input, \OCP\TaskProcessing\TaskTypes\MultimodalChatWithTools::ID, (string)$sessionId); /** @psalm-suppress UndefinedClass */ $task = new Task(\OCP\TaskProcessing\TaskTypes\MultimodalChatWithTools::ID, $input, Application::APP_ID . ':chatty-llm', $userId, $customId); /** @psalm-suppress UndefinedMethod */ @@ -846,6 +861,8 @@ private function scheduleAgencyTask( $taskInput['memories'] = $this->sessionSummaryService->getMemories($userId); } /** @psalm-suppress UndefinedClass */ + $taskInput = $this->addConversationId($taskInput, \OCP\TaskProcessing\TaskTypes\ContextAgentInteraction::ID, (string)$sessionId); + /** @psalm-suppress UndefinedClass */ $task = new Task( \OCP\TaskProcessing\TaskTypes\ContextAgentInteraction::ID, $taskInput, @@ -895,6 +912,8 @@ private function scheduleAgencyMultimodalTask( ]; $taskInput['memories'] = $this->sessionSummaryService->getMemories($userId); /** @psalm-suppress UndefinedClass */ + $taskInput = $this->addConversationId($taskInput, \OCP\TaskProcessing\TaskTypes\MultimodalContextAgentInteraction::ID, (string)$sessionId); + /** @psalm-suppress UndefinedClass */ $task = new Task( \OCP\TaskProcessing\TaskTypes\MultimodalContextAgentInteraction::ID, $taskInput, @@ -944,9 +963,7 @@ private function scheduleAudioChatTask( $input['memories'] = $this->sessionSummaryService->getMemories($userId); } /** @psalm-suppress UndefinedClass */ - if (isset($this->taskProcessingManager->getAvailableTaskTypes()[\OCP\TaskProcessing\TaskTypes\AudioToAudioChat::ID]['optionalInputShape']['conversation_id'])) { - $input['conversation_id'] = (string)$sessionId; - } + $input = $this->addConversationId($input, \OCP\TaskProcessing\TaskTypes\AudioToAudioChat::ID, (string)$sessionId); /** @psalm-suppress UndefinedClass */ $task = new Task( \OCP\TaskProcessing\TaskTypes\AudioToAudioChat::ID, @@ -995,6 +1012,8 @@ private function scheduleAgencyAudioTask( $taskInput['memories'] = $this->sessionSummaryService->getMemories($userId); } /** @psalm-suppress UndefinedClass */ + $taskInput = $this->addConversationId($taskInput, \OCP\TaskProcessing\TaskTypes\ContextAgentAudioInteraction::ID, (string)$sessionId); + /** @psalm-suppress UndefinedClass */ $task = new Task( \OCP\TaskProcessing\TaskTypes\ContextAgentAudioInteraction::ID, $taskInput,