From 6b0bbf2c0d15cf7e849214ff6fe2e2d6388cb655 Mon Sep 17 00:00:00 2001 From: zainabnaseer1164 Date: Mon, 2 Mar 2026 21:35:32 +0500 Subject: [PATCH 1/5] feat: Show provider information in the UI (#408) - Compute preferred provider per task type in AssistantService - Add preferredProviderName to task type API response - Display provider name next to task type title in assistant form Signed-off-by: zainabnaseer1164 Made-with: Cursor Signed-off-by: zainabnaseer1164 --- lib/ResponseDefinitions.php | 1 + lib/Service/AssistantService.php | 10 ++++++++++ src/components/AssistantTextProcessingForm.vue | 18 ++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/lib/ResponseDefinitions.php b/lib/ResponseDefinitions.php index be72deca..e7248ae0 100644 --- a/lib/ResponseDefinitions.php +++ b/lib/ResponseDefinitions.php @@ -30,6 +30,7 @@ * optionalOutputShape: array, * priority: integer, * category: array{id: string, name: string}, + * preferredProviderName: string|null, * } * * @psalm-type AssistantTaskProcessingTask = array{ diff --git a/lib/Service/AssistantService.php b/lib/Service/AssistantService.php index 99c88769..7dca19b4 100644 --- a/lib/Service/AssistantService.php +++ b/lib/Service/AssistantService.php @@ -336,6 +336,14 @@ public function getAvailableTaskTypes(): array { } /** @var string $typeId */ foreach ($availableTaskTypes as $typeId => $taskTypeArray) { + $preferredProviderName = null; + try { + $preferredProviderName = $this->taskProcessingManager->getPreferredProvider($typeId)->getName(); + } catch (TaskProcessingException $e) { + $this->logger->debug('Could not get preferred provider for task type ' . $typeId . ': ' . $e->getMessage()); + } catch (\Throwable $e) { + $this->logger->debug('Unexpected error while getting preferred provider for task type ' . $typeId . ': ' . $e->getMessage()); + } // skip chat, chat with tools and ContextAgent task types (not directly useful to the end user) if (!self::DEBUG) { // this appeared in 33, this is true if the task type class extends the IInternalTaskType @@ -383,6 +391,7 @@ public function getAvailableTaskTypes(): array { 'optionalInputShapeDefaults' => [], 'optionalOutputShape' => [], 'priority' => self::TASK_TYPE_PRIORITIES['chatty-llm'] ?? 1000, + 'preferredProviderName' => $preferredProviderName, ]; // do not add the raw TextToTextChat type if (!self::DEBUG) { @@ -392,6 +401,7 @@ public function getAvailableTaskTypes(): array { $taskTypeArray['id'] = $typeId; $taskTypeArray['priority'] = self::TASK_TYPE_PRIORITIES[$typeId] ?? 1000; $taskTypeArray['category'] = $this->getCategory($typeId); + $taskTypeArray['preferredProviderName'] = $preferredProviderName; if ($typeId === TextToText::ID) { $taskTypeArray['name'] = $this->l10n->t('Generate text'); diff --git a/src/components/AssistantTextProcessingForm.vue b/src/components/AssistantTextProcessingForm.vue index 9eab6770..3a999eb8 100644 --- a/src/components/AssistantTextProcessingForm.vue +++ b/src/components/AssistantTextProcessingForm.vue @@ -53,6 +53,10 @@
+ + {{ t('assistant', 'Provider:') }} {{ selectedTaskType.preferredProviderName }} +
Date: Wed, 4 Mar 2026 10:47:02 +0500 Subject: [PATCH 2/5] chore: add preferredProviderName to OpenAPI spec - Add preferredProviderName (string|null) to TaskProcessingTaskType schema - Matches API response for issue #408 Signed-off-by: zainabnaseer1164 Made-with: Cursor Signed-off-by: zainabnaseer1164 --- openapi.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openapi.json b/openapi.json index 851338be..b30017d3 100644 --- a/openapi.json +++ b/openapi.json @@ -487,6 +487,11 @@ "type": "string" } } + }, + "preferredProviderName": { + "type": "string", + "nullable": true, + "description": "Display name of the preferred provider for this task type" } } } From 52fb03875c3592161c7ac0da013b108ba0c4de2d Mon Sep 17 00:00:00 2001 From: zainabnaseer1164 Date: Wed, 4 Mar 2026 14:24:08 +0500 Subject: [PATCH 3/5] feat(ui): show provider in task type selector and fix standalone page load MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TaskTypeSelect: show 'TaskName · ProviderName' in dropdown and tooltip - ContextChatInputForm: default contextChatIndexingComplete to false for standalone page - AssistantTextProcessingForm: remove extra blank line (lint) Refs: #408 Made-with: Cursor Signed-off-by: zainabnaseer1164 --- .../AssistantTextProcessingForm.vue | 1 - .../ContextChat/ContextChatInputForm.vue | 2 +- src/components/TaskTypeSelect.vue | 21 +++++++++++++++---- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/components/AssistantTextProcessingForm.vue b/src/components/AssistantTextProcessingForm.vue index 3a999eb8..bf9d2450 100644 --- a/src/components/AssistantTextProcessingForm.vue +++ b/src/components/AssistantTextProcessingForm.vue @@ -605,7 +605,6 @@ export default { } } - .task-custom-select { width: 100%; } diff --git a/src/components/ContextChat/ContextChatInputForm.vue b/src/components/ContextChat/ContextChatInputForm.vue index 8c06d3eb..e7cad5b8 100644 --- a/src/components/ContextChat/ContextChatInputForm.vue +++ b/src/components/ContextChat/ContextChatInputForm.vue @@ -236,7 +236,7 @@ export default { defaultProviderKey: 'files__default', sccEnabled: !!this.inputs.scopeType && this.inputs.scopeType !== _ScopeType.NONE && !!this.inputs.scopeList, - indexingComplete: loadState('assistant', 'contextChatIndexingComplete'), + indexingComplete: loadState('assistant', 'contextChatIndexingComplete', false), } }, diff --git a/src/components/TaskTypeSelect.vue b/src/components/TaskTypeSelect.vue index bf05d00d..3fc2e272 100644 --- a/src/components/TaskTypeSelect.vue +++ b/src/components/TaskTypeSelect.vue @@ -17,13 +17,13 @@ - {{ t.name }} + {{ taskTypeLabel(t) }} @@ -197,6 +197,19 @@ export default { }, methods: { + taskTypeLabel(taskType) { + if (taskType.preferredProviderName) { + return `${taskType.name} · ${taskType.preferredProviderName}` + } + return taskType.name + }, + taskTypeTitle(taskType) { + const desc = taskType.description || '' + if (taskType.preferredProviderName) { + return `${desc} ${this.t('assistant', 'Provider:')} ${taskType.preferredProviderName}`.trim() + } + return desc + }, selectedTask(taskType) { return taskType.id === this.modelValue }, From 31d01747702ab223e8a1f950ff861e11521941f2 Mon Sep 17 00:00:00 2001 From: zainabnaseer1164 Date: Thu, 5 Mar 2026 14:18:07 +0500 Subject: [PATCH 4/5] chore: regenerate OpenAPI spec Run composer run openapi so committed spec matches CI generator. Signed-off-by: zainabnaseer1164 Made-with: Cursor --- openapi.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openapi.json b/openapi.json index b30017d3..2db53a8a 100644 --- a/openapi.json +++ b/openapi.json @@ -433,7 +433,8 @@ "outputShape", "optionalOutputShape", "priority", - "category" + "category", + "preferredProviderName" ], "properties": { "id": { @@ -490,8 +491,7 @@ }, "preferredProviderName": { "type": "string", - "nullable": true, - "description": "Display name of the preferred provider for this task type" + "nullable": true } } } From 2743c9e0973c9b00c80575650ab2f2ce3c6cdeb9 Mon Sep 17 00:00:00 2001 From: zainabnaseer1164 Date: Thu, 5 Mar 2026 14:34:34 +0500 Subject: [PATCH 5/5] fix(ui): show only task name in dropdown, keep provider in form title Per review: provider name only next to task type title, not in dropdown. Signed-off-by: zainabnaseer1164 Made-with: Cursor --- src/components/TaskTypeSelect.vue | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/components/TaskTypeSelect.vue b/src/components/TaskTypeSelect.vue index 3fc2e272..52b067f3 100644 --- a/src/components/TaskTypeSelect.vue +++ b/src/components/TaskTypeSelect.vue @@ -198,17 +198,10 @@ export default { methods: { taskTypeLabel(taskType) { - if (taskType.preferredProviderName) { - return `${taskType.name} · ${taskType.preferredProviderName}` - } return taskType.name }, taskTypeTitle(taskType) { - const desc = taskType.description || '' - if (taskType.preferredProviderName) { - return `${desc} ${this.t('assistant', 'Provider:')} ${taskType.preferredProviderName}`.trim() - } - return desc + return taskType.description || '' }, selectedTask(taskType) { return taskType.id === this.modelValue