From 771b83d3a06803c8a5998d6dfd8dfceb95c606d0 Mon Sep 17 00:00:00 2001 From: MichelleAntunes Date: Thu, 13 Aug 2026 12:16:53 +0200 Subject: [PATCH 1/9] Add dedicated input form for Context Chat Multi task type Signed-off-by: MichelleAntunes --- src/components/AssistantFormInputs.vue | 7 + .../ContextChat/ContextChatMultiInputForm.vue | 525 ++++++++++++++++++ 2 files changed, 532 insertions(+) create mode 100644 src/components/ContextChat/ContextChatMultiInputForm.vue diff --git a/src/components/AssistantFormInputs.vue b/src/components/AssistantFormInputs.vue index d3bf6916..6b9b8669 100644 --- a/src/components/AssistantFormInputs.vue +++ b/src/components/AssistantFormInputs.vue @@ -7,6 +7,11 @@ :inputs="inputs" :task-type="selectedTaskType" @update:inputs="$emit('update:inputs', $event)" /> + +
import ContextChatInputForm from './ContextChat/ContextChatInputForm.vue' import TaskTypeFields from './fields/TaskTypeFields.vue' +import ContextChatMultiInputForm from './ContextChat/ContextChatMultiInputForm.vue' export default { name: 'AssistantFormInputs', components: { ContextChatInputForm, TaskTypeFields, + ContextChatMultiInputForm, }, props: { inputs: { diff --git a/src/components/ContextChat/ContextChatMultiInputForm.vue b/src/components/ContextChat/ContextChatMultiInputForm.vue new file mode 100644 index 00000000..fce3c59b --- /dev/null +++ b/src/components/ContextChat/ContextChatMultiInputForm.vue @@ -0,0 +1,525 @@ + + + + + + From f7f6fab0694c82e57cf4cb3586150c83972af11c Mon Sep 17 00:00:00 2001 From: MichelleAntunes Date: Thu, 13 Aug 2026 13:36:36 +0200 Subject: [PATCH 2/9] Add dedicated output form for Context Chat Multi task type Signed-off-by: MichelleAntunes --- src/components/AssistantFormOutputs.vue | 6 + .../ContextChatMultiOutputForm.vue | 171 ++++++++++++++++++ 2 files changed, 177 insertions(+) create mode 100644 src/components/ContextChat/ContextChatMultiOutputForm.vue diff --git a/src/components/AssistantFormOutputs.vue b/src/components/AssistantFormOutputs.vue index 00bad9df..2daec117 100644 --- a/src/components/AssistantFormOutputs.vue +++ b/src/components/AssistantFormOutputs.vue @@ -12,6 +12,10 @@ class="output-fields" :output-shape="selectedTaskType.outputShape" :output="outputs" /> + + + + + + From 075137a0bfa103d3ee6b3f60871ecceb513dba20 Mon Sep 17 00:00:00 2001 From: MichelleAntunes Date: Thu, 13 Aug 2026 15:55:28 +0200 Subject: [PATCH 3/9] Cap number of questions in Multi input at 20, matching backend limit Signed-off-by: MichelleAntunes --- .../ContextChat/ContextChatMultiInputForm.vue | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/components/ContextChat/ContextChatMultiInputForm.vue b/src/components/ContextChat/ContextChatMultiInputForm.vue index fce3c59b..b4a1f825 100644 --- a/src/components/ContextChat/ContextChatMultiInputForm.vue +++ b/src/components/ContextChat/ContextChatMultiInputForm.vue @@ -38,11 +38,16 @@ + + {{ t('assistant', 'You can ask up to {max} questions at once.', { max: MAX_QUESTIONS }) }} +
{{ t('assistant', 'Selective context') }} @@ -178,6 +183,12 @@ const _ScopeType = Object.freeze({ PROVIDER: 'provider', }) +// Keep in sync with MAX_MULTI_QUESTIONS in +// context_chat_backend/controller.py and task_fetcher.py — any question +// beyond this count is silently dropped by the backend, so the UI must +// not let the person add more than this. +const MAX_QUESTIONS = 20 + const _tStrings = { [_ScopeType.SOURCE]: t('assistant', 'Select Files/Folders'), [_ScopeType.PROVIDER]: t('assistant', 'Select Providers'), @@ -255,6 +266,7 @@ export default { return { ScopeType: _ScopeType, tStrings: _tStrings, + MAX_QUESTIONS, providerOptions: [], providersLoading: false, @@ -266,6 +278,9 @@ export default { }, computed: { + atMaxQuestions() { + return (this.inputs.questions?.length ?? 0) >= MAX_QUESTIONS + }, scopeListMetaArray() { if (!this.inputs.scopeListMeta) { return [] @@ -379,6 +394,9 @@ export default { this.onInputsChanged({ questions: newQuestions }) }, onAddQuestion() { + if (this.atMaxQuestions) { + return + } const newQuestions = [...(this.inputs.questions ?? []), ''] this.onInputsChanged({ questions: newQuestions }) }, From e84c9ce822f84f450c0e8e3933daef84c36abd69 Mon Sep 17 00:00:00 2001 From: MichelleAntunes Date: Thu, 13 Aug 2026 16:00:19 +0200 Subject: [PATCH 4/9] Show first question and remaining count in Multi task list sidebar Signed-off-by: MichelleAntunes --- src/components/TaskListItem.vue | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/components/TaskListItem.vue b/src/components/TaskListItem.vue index 59091eb4..6fb8a976 100644 --- a/src/components/TaskListItem.vue +++ b/src/components/TaskListItem.vue @@ -181,6 +181,13 @@ export default { const nbGeneratedImages = this.task.output?.length ?? 0 return n('assistant', '{n} image generated', '{n} images generated', nbGeneratedImages, { n: nbGeneratedImages }) } + if (this.task.type === 'context_chat:context_chat_multi') { + const questions = this.task.input.questions ?? [] + const extraCount = questions.length - 1 + return extraCount > 0 + ? n('assistant', '+{extraCount} more question', '+{extraCount} more questions', extraCount, { extraCount }) + : '' + } return this.textOutputPreview } else if (this.task.status === TASK_STATUS_STRING.scheduled) { if (this.isText2Image) { @@ -203,6 +210,10 @@ export default { return statusTitles[this.task.status] ?? t('assistant', 'Unknown status') }, textInputPreview() { + if (this.task.type === 'context_chat:context_chat_multi') { + const questions = this.task.input.questions ?? [] + return questions.length > 0 ? questions[0] : '' + } const textInputs = [] Object.keys(this.taskType.inputShape).forEach(key => { const field = this.taskType.inputShape[key] From 54eaec198c2da7c54bf3565d1051a0034f2b90f3 Mon Sep 17 00:00:00 2001 From: MichelleAntunes Date: Wed, 26 Aug 2026 10:27:47 +0200 Subject: [PATCH 5/9] Add debug log to match original, tighten onDeleteQuestion guard to match UI minimum Signed-off-by: MichelleAntunes --- src/components/ContextChat/ContextChatMultiInputForm.vue | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/ContextChat/ContextChatMultiInputForm.vue b/src/components/ContextChat/ContextChatMultiInputForm.vue index b4a1f825..a84a6f9d 100644 --- a/src/components/ContextChat/ContextChatMultiInputForm.vue +++ b/src/components/ContextChat/ContextChatMultiInputForm.vue @@ -175,8 +175,6 @@ import { getFilePickerBuilder, showError } from '@nextcloud/dialogs' import { generateUrl } from '@nextcloud/router' import { loadState } from '@nextcloud/initial-state' -// Kept identical to ContextChatInputForm.vue's ScopeType so the two -// components stay compatible with the same backend scope contract. const _ScopeType = Object.freeze({ NONE: 'none', SOURCE: 'source', @@ -336,6 +334,7 @@ export default { return this.scopeListMetaArray.some((item) => item.id === scopeId) }, chooseDialogCallback(nodes) { + console.debug('nodes:', nodes) const addedScopeListMeta = [] for (const node of nodes) { const scopeId = `${this.defaultProviderKey}: ${node.fileid}` @@ -385,8 +384,8 @@ export default { }, onDeleteQuestion(i) { const questions = this.inputs.questions ?? [] - // always keep at least one (possibly empty) question field visible - if (questions.length <= 1) { + // always keep at least two (possibly empty) question field visible + if (questions.length <= 2) { return } const newQuestions = questions.slice() From 8202e0e93b5f0e1eed12748559747bd331fde364 Mon Sep 17 00:00:00 2001 From: MichelleAntunes Date: Tue, 25 Aug 2026 15:58:27 +0200 Subject: [PATCH 6/9] Start Multi input with 2 empty questions, matching the 2-question minimum Signed-off-by: MichelleAntunes --- src/components/ContextChat/ContextChatMultiInputForm.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/ContextChat/ContextChatMultiInputForm.vue b/src/components/ContextChat/ContextChatMultiInputForm.vue index a84a6f9d..c1e404f8 100644 --- a/src/components/ContextChat/ContextChatMultiInputForm.vue +++ b/src/components/ContextChat/ContextChatMultiInputForm.vue @@ -27,7 +27,7 @@ - {{ t('assistant', 'You can ask up to {max} questions at once.', { max: MAX_QUESTIONS }) }} + {{ t('assistant', 'You can ask up to {max} questions at once.', { max: taskType.inputShapeDefaults?.maxQuestions ?? 20 }) }}
@@ -181,11 +181,6 @@ const _ScopeType = Object.freeze({ PROVIDER: 'provider', }) -// Keep in sync with MAX_MULTI_QUESTIONS in -// context_chat_backend/controller.py and task_fetcher.py — any question -// beyond this count is silently dropped by the backend, so the UI must -// not let the person add more than this. -const MAX_QUESTIONS = 20 const _tStrings = { [_ScopeType.SOURCE]: t('assistant', 'Select Files/Folders'), @@ -264,8 +259,6 @@ export default { return { ScopeType: _ScopeType, tStrings: _tStrings, - MAX_QUESTIONS, - providerOptions: [], providersLoading: false, defaultProviderKey: 'files__default', @@ -277,7 +270,7 @@ export default { computed: { atMaxQuestions() { - return (this.inputs.questions?.length ?? 0) >= MAX_QUESTIONS + return (this.inputs.questions?.length ?? 0) >= (this.taskType.inputShapeDefaults?.maxQuestions ?? 20) }, scopeListMetaArray() { if (!this.inputs.scopeListMeta) { From dad62b24e9bcc261486f0b60e757b20563e804c7 Mon Sep 17 00:00:00 2001 From: MichelleAntunes Date: Wed, 26 Aug 2026 13:37:36 +0200 Subject: [PATCH 8/9] Remove extra blank line Signed-off-by: MichelleAntunes --- src/components/ContextChat/ContextChatMultiInputForm.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/ContextChat/ContextChatMultiInputForm.vue b/src/components/ContextChat/ContextChatMultiInputForm.vue index b4967005..7ef11c4f 100644 --- a/src/components/ContextChat/ContextChatMultiInputForm.vue +++ b/src/components/ContextChat/ContextChatMultiInputForm.vue @@ -181,7 +181,6 @@ const _ScopeType = Object.freeze({ PROVIDER: 'provider', }) - const _tStrings = { [_ScopeType.SOURCE]: t('assistant', 'Select Files/Folders'), [_ScopeType.PROVIDER]: t('assistant', 'Select Providers'), From bb8d73fb68cd73a538a6f3170abbebdb14ec096c Mon Sep 17 00:00:00 2001 From: MichelleAntunes Date: Wed, 26 Aug 2026 14:01:21 +0200 Subject: [PATCH 9/9] Fix New Task not resetting questions when inputShapeDefaults is present Signed-off-by: MichelleAntunes --- src/components/ContextChat/ContextChatMultiInputForm.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ContextChat/ContextChatMultiInputForm.vue b/src/components/ContextChat/ContextChatMultiInputForm.vue index 7ef11c4f..b7bba82f 100644 --- a/src/components/ContextChat/ContextChatMultiInputForm.vue +++ b/src/components/ContextChat/ContextChatMultiInputForm.vue @@ -288,7 +288,7 @@ export default { this.onTaskTypeChange() }, inputs(newValue) { - if (Object.keys(newValue).length === 0) { + if (!newValue.questions) { this.onInputsReset() } },