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: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"nextcloud/ocp": "dev-master",
"nextcloud/openapi-extractor": "^1.0.0",
"phpunit/phpunit": "^9.5",
"psalm/phar": "6.4.0"
"psalm/phar": "6.7"
},
"config": {
"sort-packages": true,
Expand Down
14 changes: 7 additions & 7 deletions composer.lock

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

18 changes: 14 additions & 4 deletions lib/Controller/ChattyLLMController.php
Original file line number Diff line number Diff line change
Expand Up @@ -500,11 +500,15 @@ public function generateForSession(int $sessionId, int $agencyConfirm = 0): JSON

$lastAttachments = $lastUserMessage->jsonSerialize()['attachments'];
$audioAttachment = $lastAttachments[0] ?? null;
// see https://github.com/vimeo/psalm/issues/7980
$isContextAgentAudioAvailable = false;
if (class_exists('OCP\\TaskProcessing\\TaskTypes\\ContextAgentAudioInteraction')) {
$isContextAgentAudioAvailable = isset($this->taskProcessingManager->getAvailableTaskTypes()[\OCP\TaskProcessing\TaskTypes\ContextAgentAudioInteraction::ID]);
}
if ($audioAttachment !== null
&& isset($audioAttachment['type'])
&& $audioAttachment['type'] === 'Audio'
&& class_exists('OCP\\TaskProcessing\\TaskTypes\\ContextAgentAudioInteraction')
&& isset($this->taskProcessingManager->getAvailableTaskTypes()[\OCP\TaskProcessing\TaskTypes\ContextAgentAudioInteraction::ID])
&& $isContextAgentAudioAvailable
) {
// audio agency
$fileId = $audioAttachment['file_id'];
Expand Down Expand Up @@ -536,11 +540,14 @@ public function generateForSession(int $sessionId, int $agencyConfirm = 0): JSON

$lastAttachments = $lastUserMessage->jsonSerialize()['attachments'];
$audioAttachment = $lastAttachments[0] ?? null;
$isAudioToAudioAvailable = false;
if (class_exists('OCP\\TaskProcessing\\TaskTypes\\AudioToAudioChat')) {
$isAudioToAudioAvailable = isset($this->taskProcessingManager->getAvailableTaskTypes()[\OCP\TaskProcessing\TaskTypes\AudioToAudioChat::ID]);
}
if ($audioAttachment !== null
&& isset($audioAttachment['type'])
&& $audioAttachment['type'] === 'Audio'
&& class_exists('OCP\\TaskProcessing\\TaskTypes\\AudioToAudioChat')
&& isset($this->taskProcessingManager->getAvailableTaskTypes()[\OCP\TaskProcessing\TaskTypes\AudioToAudioChat::ID])
&& $isAudioToAudioAvailable
) {
// for an audio chat task, let's try to get the remote audio IDs for all the previous audio messages
$history = $this->getAudioHistory($history);
Expand Down Expand Up @@ -1006,6 +1013,7 @@ private function scheduleAgencyTask(string $content, int $confirmation, string $
'confirmation' => $confirmation,
'conversation_token' => $conversationToken,
];
/** @psalm-suppress UndefinedClass */
$task = new Task(
\OCP\TaskProcessing\TaskTypes\ContextAgentInteraction::ID,
$taskInput,
Expand All @@ -1027,6 +1035,7 @@ private function scheduleAudioChatTask(
'system_prompt' => $systemPrompt,
'history' => $history,
];
/** @psalm-suppress UndefinedClass */
$task = new Task(
\OCP\TaskProcessing\TaskTypes\AudioToAudioChat::ID,
$input,
Expand All @@ -1048,6 +1057,7 @@ private function scheduleAgencyAudioTask(
'confirmation' => $confirmation,
'conversation_token' => $conversationToken,
];
/** @psalm-suppress UndefinedClass */
$task = new Task(
\OCP\TaskProcessing\TaskTypes\ContextAgentAudioInteraction::ID,
$taskInput,
Expand Down
6 changes: 5 additions & 1 deletion lib/Listener/ChattyLLMTaskListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ public function handle(Event $event): void {
} else {
$content = trim($taskOutput['output'] ?? '');
$message->setContent($content);
// the task is not an audio one, but we might still need to Tts the answer
// if it is a response to a ContextAgentInteraction confirmation that was asked about an audio message
$this->runTtsIfNeeded($sessionId, $message, $taskTypeId, $task->getUserId());
}
try {
Expand Down Expand Up @@ -135,7 +137,8 @@ public function handle(Event $event): void {
* @return void
*/
private function runTtsIfNeeded(int $sessionId, Message $message, string $taskTypeId, ?string $userId): void {
if ($taskTypeId !== \OCP\TaskProcessing\TaskTypes\ContextAgentInteraction::ID) {
if (!class_exists('OCP\\TaskProcessing\\TaskTypes\\ContextAgentInteraction')
|| $taskTypeId !== \OCP\TaskProcessing\TaskTypes\ContextAgentInteraction::ID) {
return;
}
// is the last non-empty user message an audio one?
Expand All @@ -157,6 +160,7 @@ private function runTtsIfNeeded(int $sessionId, Message $message, string $taskTy
*/
private function runTtsTask(Message $message, ?string $userId): void {
try {
/** @psalm-suppress UndefinedClass */
$task = new Task(
\OCP\TaskProcessing\TaskTypes\TextToSpeech::ID,
['input' => $message->getContent()],
Expand Down
44 changes: 28 additions & 16 deletions lib/Service/AssistantService.php
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,19 @@ public function cancelNotifyWhenReady(int $taskId, string $userId): void {

public function isAudioChatAvailable(): bool {
$availableTaskTypes = $this->taskProcessingManager->getAvailableTaskTypes();
$ttsAvailable = false;
// see https://github.com/vimeo/psalm/issues/7980
if (class_exists('OCP\\TaskProcessing\\TaskTypes\\TextToSpeech')) {
$ttsAvailable = array_key_exists(\OCP\TaskProcessing\TaskTypes\TextToSpeech::ID, $availableTaskTypes);
}
$audioToAudioAvailable = false;
if (class_exists('OCP\\TaskProcessing\\TaskTypes\\AudioToAudioChat')) {
$audioToAudioAvailable = array_key_exists(\OCP\TaskProcessing\TaskTypes\AudioToAudioChat::ID, $availableTaskTypes);
}
// we have at least the simple audio chat task type and the 3 sub task types available
return class_exists('OCP\\TaskProcessing\\TaskTypes\\AudioToAudioChat')
&& array_key_exists(\OCP\TaskProcessing\TaskTypes\AudioToAudioChat::ID, $availableTaskTypes)
return $audioToAudioAvailable
&& $ttsAvailable
&& array_key_exists(AudioToText::ID, $availableTaskTypes)
&& class_exists('OCP\\TaskProcessing\\TaskTypes\\TextToSpeech')
&& array_key_exists(\OCP\TaskProcessing\TaskTypes\TextToSpeech::ID, $availableTaskTypes)
&& array_key_exists(TextToTextChat::ID, $availableTaskTypes);
}

Expand Down Expand Up @@ -291,21 +298,26 @@ public function getAvailableTaskTypes(): array {
if ($taskTypeArray['isInternal'] ?? false) {
continue;
}
if (class_exists('OCP\\TaskProcessing\\TaskTypes\\TextToTextChatWithTools')
&& $typeId === \OCP\TaskProcessing\TaskTypes\TextToTextChatWithTools::ID) {
continue;
// see https://github.com/vimeo/psalm/issues/7980
if (class_exists('OCP\\TaskProcessing\\TaskTypes\\TextToTextChatWithTools')) {
if ($typeId === \OCP\TaskProcessing\TaskTypes\TextToTextChatWithTools::ID) {
continue;
}
}
if (class_exists('OCP\\TaskProcessing\\TaskTypes\\ContextAgentInteraction')
&& $typeId === \OCP\TaskProcessing\TaskTypes\ContextAgentInteraction::ID) {
continue;
if (class_exists('OCP\\TaskProcessing\\TaskTypes\\ContextAgentInteraction')) {
if ($typeId === \OCP\TaskProcessing\TaskTypes\ContextAgentInteraction::ID) {
continue;
}
}
if (class_exists('OCP\\TaskProcessing\\TaskTypes\\ContextAgentAudioInteraction')
&& $typeId === \OCP\TaskProcessing\TaskTypes\ContextAgentAudioInteraction::ID) {
continue;
if (class_exists('OCP\\TaskProcessing\\TaskTypes\\ContextAgentAudioInteraction')) {
if ($typeId === \OCP\TaskProcessing\TaskTypes\ContextAgentAudioInteraction::ID) {
continue;
}
}
if (class_exists('OCP\\TaskProcessing\\TaskTypes\\AudioToAudioChat')
&& $typeId === \OCP\TaskProcessing\TaskTypes\AudioToAudioChat::ID) {
continue;
if (class_exists('OCP\\TaskProcessing\\TaskTypes\\AudioToAudioChat')) {
if ($typeId === \OCP\TaskProcessing\TaskTypes\AudioToAudioChat::ID) {
continue;
}
}
}
if ($typeId === TextToTextChat::ID) {
Expand Down
3 changes: 3 additions & 0 deletions lib/TaskProcessing/AudioToAudioChatProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public function getName(): string {
}

public function getTaskTypeId(): string {
/** @psalm-suppress UndefinedClass */
return AudioToAudioChat::ID;
}

Expand Down Expand Up @@ -134,6 +135,8 @@ public function process(?string $userId, array $input, callable $reportProgress)

// text to speech
try {
// this provider is not declared if TextToSpeech does not exist so we know it's fine
/** @psalm-suppress UndefinedClass */
$task = new Task(
TextToSpeech::ID,
['input' => $llmResult],
Expand Down
3 changes: 3 additions & 0 deletions lib/TaskProcessing/ContextAgentAudioInteractionProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public function getName(): string {
}

public function getTaskTypeId(): string {
/** @psalm-suppress UndefinedClass */
return ContextAgentAudioInteraction::ID;
}

Expand Down Expand Up @@ -115,6 +116,7 @@ public function process(?string $userId, array $input, callable $reportProgress)

// context agent
try {
/** @psalm-suppress UndefinedClass */
$task = new Task(
ContextAgentInteraction::ID,
[
Expand All @@ -134,6 +136,7 @@ public function process(?string $userId, array $input, callable $reportProgress)
if ($agencyTaskOutput['output'] !== '') {
// text to speech
try {
/** @psalm-suppress UndefinedClass */
$task = new Task(
TextToSpeech::ID,
['input' => $agencyTaskOutput['output']],
Expand Down
8 changes: 2 additions & 6 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
findUnusedBaselineEntry="true"
findUnusedCode="false"
resolveFromConfigFile="true"
ensureOverrideAttribute="false"
strictBinaryOperands="false"
phpVersion="8.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
Expand All @@ -35,12 +37,6 @@
<referencedClass name="Symfony\Component\Console\Input\InputInterface" />
<referencedClass name="Symfony\Component\Console\Output\OutputInterface" />
<referencedClass name="OC\User\NoUserException" />
<referencedClass name="OCP\TaskProcessing\EShapeType" />
<referencedClass name="OCP\TaskProcessing\TaskTypes\ContextAgentInteraction" />
<referencedClass name="OCP\TaskProcessing\TaskTypes\TextToTextChatWithTools" />
<referencedClass name="OCP\TaskProcessing\TaskTypes\TextToSpeech" />
<referencedClass name="OCP\TaskProcessing\TaskTypes\AudioToAudioChat" />
<referencedClass name="OCP\TaskProcessing\TaskTypes\ContextAgentAudioInteraction" />
</errorLevel>
</UndefinedClass>
<UndefinedDocblockClass>
Expand Down