Skip to content

Commit

Permalink
finalize context chat custom UI, change how inputs are reset on taskT…
Browse files Browse the repository at this point in the history
…ype change

Signed-off-by: Julien Veyssier <[email protected]>
  • Loading branch information
julien-nc committed Jul 11, 2024
1 parent 5cdd35f commit a23b3cf
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 35 deletions.
3 changes: 3 additions & 0 deletions src/components/AssistantFormInputs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<ChattyLLMInputForm v-if="selectedTaskTypeId === 'chatty-llm'" class="chatty-inputs" />
<ContextChatInputForm v-else-if="selectedTaskTypeId === 'context_chat:context_chat'"
:inputs="inputs"
:task-type="selectedTaskType"
@update:inputs="$emit('update:inputs', $event)" />
<div v-else class="assistant-inputs">
<div class="input-container">
Expand Down Expand Up @@ -63,9 +64,11 @@ export default {
methods: {
resetInputs() {
const inputs = {}
/*
Object.keys(this.selectedTaskType.inputShape).forEach(key => {
inputs[key] = null
})
*/
this.$emit('update:inputs', inputs)
// TODO do it with optional input shape as well
},
Expand Down
67 changes: 52 additions & 15 deletions src/components/ContextChat/ContextChatInputForm.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
<template>
<div class="scoped-cc-input-form">
<div class="cc-input-form">
<TextInput
:value="inputs.prompt"
:label="taskType.inputShape?.prompt?.name"
:placeholder="taskType.inputShape?.prompt?.description"
:title="taskType.inputShape?.prompt?.description"
:is-output="false"
@update:value="onInputsChanged({ prompt: $event })" />
<NcCheckboxRadioSwitch :checked.sync="sccEnabled" @update:checked="onUpdateSccEnabled">
{{ t('assistant', 'Selective context') }}
</NcCheckboxRadioSwitch>
Expand Down Expand Up @@ -29,14 +36,14 @@
<NcButton
type="secondary"
:disabled="scopeListMetaArray.length === 0"
@click="onInputsChanged({ scopeListMeta: ''})">
@click="onInputsChanged({ scopeListMeta: '[]'})">
<template #icon>
<PlaylistRemoveIcon />
</template>
{{ tStrings['Clear Selection'] }}
</NcButton>
</div>
<div class="selector-form">
<div v-if="sccEnabled" class="selector-form">
<div v-if="inputs.scopeType === ScopeType.SOURCE" class="sources-form">
<NcButton
type="secondary"
Expand All @@ -55,7 +62,7 @@
:dropdown-should-open="() => false"
:label-outside="true"
:no-wrap="false"
@input="onInputsChanged({ scopeListMeta: JSON.stringify($event) })">
@input="onScopeListMetaChange">
<template #selected-option="option">
<NcAvatar
:size="24"
Expand All @@ -78,7 +85,7 @@
:label-outside="true"
:append-to-body="false"
:options="providerOptions"
@input="onInputsChanged({ scopeListMeta: JSON.stringify($event) })">
@input="onScopeListMetaChange">
<template #option="option">
<div class="select-option">
<NcAvatar
Expand All @@ -104,7 +111,6 @@
</NcSelect>
</div>
</div>
<!-- TODO TEXT input -->
</div>
</template>
Expand All @@ -117,11 +123,14 @@ import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js'
import TextInput from '../fields/TextInput.vue'
import axios from '@nextcloud/axios'
import { getFilePickerBuilder, showError } from '@nextcloud/dialogs'
import { generateUrl } from '@nextcloud/router'
const _ScopeType = Object.freeze({
NONE: 'none',
SOURCE: 'source',
PROVIDER: 'provider',
})
Expand Down Expand Up @@ -174,6 +183,7 @@ export default {
name: 'ContextChatInputForm',
components: {
TextInput,
FileDocumentIcon,
NcAvatar,
NcButton,
Expand All @@ -187,6 +197,10 @@ export default {
type: Object,
required: true,
},
taskType: {
type: Object,
required: true,
},
},
emits: ['update:inputs'],
Expand All @@ -200,7 +214,7 @@ export default {
providersLoading: false,
defaultProviderKey: 'files__default',
sccEnabled: !!this.inputs.scopeType && !!this.inputs.scopeList,
sccEnabled: !!this.inputs.scopeType && this.inputs.scopeType !== _ScopeType.NONE && !!this.inputs.scopeList,
}
},
Expand All @@ -209,8 +223,12 @@ export default {
if (!this.inputs.scopeListMeta) {
return []
}
// TODO trycatch
return JSON.parse(this.inputs.scopeListMeta)
try {
return JSON.parse(this.inputs.scopeListMeta)
} catch (error) {
console.error('failed to parse scopeListMeta', error)
return []
}
},
},
Expand All @@ -226,6 +244,16 @@ export default {
console.error('Error fetching default provider key:', error)
showError(t('assistant', 'Error fetching default provider key'))
})
// initialize the inputs if necessary
if (Object.keys(this.inputs).length === 0) {
this.$emit('update:inputs', {
prompt: '',
scopeType: _ScopeType.NONE,
scopeList: [],
scopeListMeta: '[]',
})
}
},
methods: {
Expand Down Expand Up @@ -279,12 +307,12 @@ export default {
{ fileId: fileId.substring(`${this.defaultProviderKey}: `.length) },
)
},
onUpdateSccEnabled() {
onUpdateSccEnabled(enabled) {
this.$emit('update:inputs', {
prompt: this.inputs.prompt,
scopeType: _ScopeType.SOURCE,
scopeType: enabled ? _ScopeType.SOURCE : _ScopeType.NONE,
scopeList: [],
scopeListMeta: '',
scopeListMeta: '[]',
})
},
onScopeTypeChanged(value) {
Expand All @@ -295,9 +323,16 @@ export default {
this.onInputsChanged({
scopeType: value,
scopeList: [],
scopeListMeta: '',
scopeListMeta: '[]',
})
},
onScopeListMetaChange(value) {
try {
this.onInputsChanged({ scopeListMeta: JSON.stringify(value) })
} catch (error) {
console.error('Failed to change scopeListMeta', error)
}
},
onInputsChanged(changedInputs) {
this.$emit('update:inputs', {
...this.inputs,
Expand All @@ -309,8 +344,10 @@ export default {
</script>
<style lang="scss" scoped>
.scoped-cc-input-form {
padding: 12px;
.cc-input-form {
display: flex;
flex-direction: column;
gap: 12px;
.line {
display: flex;
Expand Down
49 changes: 29 additions & 20 deletions src/components/fields/ListOfTextsField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,27 @@
<h3 :title="field.description">
{{ field.name }}
</h3>
<div v-for="(v, i) in arrayValue"
:key="fieldKey + '-' + i"
class="text-list--item">
<TextInput
class="text-input"
:value="v ?? ''"
:is-output="isOutput"
:label="field.name"
:placeholder="field.description"
:title="field.description"
@update:value="onItemValueChanged(i, $event)" />
<NcButton v-if="!isOutput"
class="delete-button"
type="secondary"
@click="onDeleteItem(i)">
<template #icon>
<DeleteIcon />
</template>
</NcButton>
<div class="text-list-field--items">
<div v-for="(v, i) in arrayValue"
:key="fieldKey + '-' + i"
class="text-list--item">
<TextInput
class="text-input"
:value="v ?? ''"
:is-output="isOutput"
:label="field.name"
:placeholder="field.description"
:title="field.description"
@update:value="onItemValueChanged(i, $event)" />
<NcButton v-if="!isOutput"
class="delete-button"
type="secondary"
@click="onDeleteItem(i)">
<template #icon>
<DeleteIcon />
</template>
</NcButton>
</div>
</div>
<NcButton v-if="!isOutput"
class="more-button"
Expand Down Expand Up @@ -117,5 +119,12 @@ export default {
</script>
<style lang="scss">
// nothing yet
.text-list-field {
&--items {
display: flex;
flex-direction: column;
gap: 12px;
}
}
</style>

0 comments on commit a23b3cf

Please sign in to comment.