2023-05-23 18:05:04 +03:00
import QtCore
2023-05-22 16:03:06 +03:00
import QtQuick
import QtQuick . Controls
import QtQuick . Controls . Basic
import QtQuick . Layouts
2023-05-23 18:05:04 +03:00
import QtQuick . Dialogs
2023-05-23 05:13:42 +03:00
import localdocs
2023-05-22 16:03:06 +03:00
2023-05-23 05:13:42 +03:00
Item {
2023-05-23 18:05:04 +03:00
id: root
2023-05-24 03:26:31 +03:00
2023-06-03 05:52:55 +03:00
property alias collection: collection . text
property alias folder_path: folderEdit . text
2023-05-23 18:05:04 +03:00
2023-05-24 03:26:31 +03:00
property int defaultChunkSize: 256
property int defaultRetrievalSize: 3
property alias chunkSize: settings . chunkSize
property alias retrievalSize: settings . retrievalSize
Settings {
id: settings
category: "localdocs"
property int chunkSize: root . defaultChunkSize
property int retrievalSize: root . defaultRetrievalSize
}
function restoreLocalDocsDefaults ( ) {
settings . chunkSize = root . defaultChunkSize
settings . retrievalSize = root . defaultRetrievalSize
LocalDocs . chunkSize = settings . chunkSize
LocalDocs . retrievalSize = settings . retrievalSize
settings . sync ( )
}
2023-05-23 18:05:04 +03:00
FolderDialog {
id: folderDialog
title: "Please choose a directory"
2023-05-25 18:13:02 +03:00
currentFolder: StandardPaths . writableLocation ( StandardPaths . HomeLocation )
2023-05-23 18:05:04 +03:00
onAccepted: {
root . folder_path = selectedFolder
2023-05-23 05:13:42 +03:00
}
2023-05-22 16:03:06 +03:00
}
2023-05-23 18:05:04 +03:00
Rectangle {
id: addCollection
anchors.left: parent . left
anchors.right: parent . right
height: collection . height + 20
color: theme . backgroundDark
2023-05-23 05:13:42 +03:00
2023-06-26 19:58:33 +03:00
RowLayout {
2023-05-23 18:05:04 +03:00
anchors.verticalCenter: parent . verticalCenter
anchors.left: parent . left
2023-06-26 19:58:33 +03:00
anchors.right: parent . right
spacing: 10
MyTextField {
id: collection
width: 225
horizontalAlignment: Text . AlignJustify
color: theme . textColor
placeholderText: qsTr ( "Collection name..." )
placeholderTextColor: theme . mutedTextColor
ToolTip.text: qsTr ( "Name of the collection to add (Required)" )
ToolTip.visible: hovered
Accessible.role: Accessible . EditableText
Accessible.name: collection . text
Accessible.description: ToolTip . text
function showError ( ) {
collection . placeholderTextColor = theme . textErrorColor
}
onTextChanged: {
collection . placeholderTextColor = theme . mutedTextColor
}
2023-06-26 19:17:49 +03:00
}
2023-05-23 05:13:42 +03:00
2023-06-26 19:58:33 +03:00
MyDirectoryField {
id: folderEdit
Layout.fillWidth: true
text: root . folder_path
placeholderText: qsTr ( "Folder path..." )
placeholderTextColor: theme . mutedTextColor
ToolTip.text: qsTr ( "Folder path to documents (Required)" )
ToolTip.visible: hovered
function showError ( ) {
folderEdit . placeholderTextColor = theme . textErrorColor
}
onTextChanged: {
folderEdit . placeholderTextColor = theme . mutedTextColor
}
2023-06-26 19:17:49 +03:00
}
2023-05-23 05:13:42 +03:00
2023-06-26 19:58:33 +03:00
MyButton {
id: browseButton
text: qsTr ( "Browse" )
onClicked: {
folderDialog . open ( ) ;
}
2023-05-23 18:05:04 +03:00
}
2023-05-23 05:13:42 +03:00
2023-06-26 19:58:33 +03:00
MyButton {
id: addButton
text: qsTr ( "Add" )
Accessible.role: Accessible . Button
Accessible.name: text
Accessible.description: qsTr ( "Add button" )
onClicked: {
var isError = false ;
if ( root . collection === "" ) {
isError = true ;
collection . showError ( ) ;
}
if ( root . folder_path === "" || ! folderEdit . isValid ) {
isError = true ;
folderEdit . showError ( ) ;
}
if ( isError )
return ;
LocalDocs . addFolder ( root . collection , root . folder_path )
root . collection = ""
root . folder_path = ""
collection . clear ( )
2023-06-26 19:17:49 +03:00
}
2023-05-23 18:05:04 +03:00
}
2023-05-22 16:03:06 +03:00
}
2023-05-23 05:13:42 +03:00
}
ScrollView {
id: scrollView
2023-05-23 18:05:04 +03:00
anchors.top: addCollection . bottom
anchors.bottom: gridLayout . top
anchors.bottomMargin: 20
2023-05-23 05:13:42 +03:00
anchors.left: parent . left
anchors.right: parent . right
clip: true
contentHeight: 300
ScrollBar.vertical.policy: ScrollBar . AlwaysOn
background: Rectangle {
color: theme . backgroundLighter
2023-05-22 16:03:06 +03:00
}
2023-05-23 05:13:42 +03:00
ListView {
id: listView
model: LocalDocs . localDocsModel
boundsBehavior: Flickable . StopAtBounds
delegate: Rectangle {
id: item
width: listView . width
height: buttons . height + 20
color: index % 2 === 0 ? theme.backgroundLight : theme . backgroundLighter
property bool removing: false
Text {
id: collectionId
anchors.verticalCenter: parent . verticalCenter
anchors.left: parent . left
anchors.margins: 20
text: collection
elide: Text . ElideRight
color: theme . textColor
width: 200
}
Text {
id: folderId
anchors.left: collectionId . right
anchors.margins: 20
anchors.verticalCenter: parent . verticalCenter
text: folder_path
elide: Text . ElideRight
color: theme . textColor
}
Item {
id: buttons
anchors.right: parent . right
anchors.verticalCenter: parent . verticalCenter
anchors.margins: 20
2023-05-23 18:05:04 +03:00
width: Math . max ( removeButton . width , busyIndicator . width )
2023-05-23 05:13:42 +03:00
height: Math . max ( removeButton . height , busyIndicator . height )
MyButton {
id: removeButton
2023-05-23 18:05:04 +03:00
anchors.centerIn: parent
2023-05-23 05:13:42 +03:00
text: qsTr ( "Remove" )
2023-06-03 17:08:59 +03:00
visible: ! item . removing && installed
2023-05-23 05:13:42 +03:00
onClicked: {
item . removing = true
LocalDocs . removeFolder ( collection , folder_path )
}
}
2023-06-01 02:28:09 +03:00
MyBusyIndicator {
2023-05-23 05:13:42 +03:00
id: busyIndicator
2023-05-23 18:05:04 +03:00
anchors.centerIn: parent
2023-06-03 17:08:59 +03:00
visible: item . removing || ! installed
2023-05-23 05:13:42 +03:00
}
}
}
}
}
2023-05-23 18:05:04 +03:00
GridLayout {
id: gridLayout
2023-05-23 05:13:42 +03:00
anchors.bottom: parent . bottom
2023-05-23 18:05:04 +03:00
anchors.left: parent . left
anchors.right: parent . right
columns: 3
rowSpacing: 10
columnSpacing: 10
2023-06-26 19:58:33 +03:00
Rectangle {
Layout.row: 0
Layout.column: 0
Layout.fillWidth: true
Layout.columnSpan: 3
height: 1
color: theme . dialogBorder
}
Rectangle {
Layout.row: 3
Layout.column: 0
Layout.fillWidth: true
Layout.columnSpan: 3
height: 1
color: theme . dialogBorder
}
2023-05-23 18:05:04 +03:00
Label {
id: chunkLabel
2023-06-26 19:58:33 +03:00
Layout.row: 1
2023-05-23 18:05:04 +03:00
Layout.column: 0
color: theme . textColor
text: qsTr ( "Document snippet size (characters):" )
2023-05-23 05:13:42 +03:00
}
2023-05-23 18:05:04 +03:00
MyTextField {
id: chunkSizeTextField
2023-06-26 19:58:33 +03:00
Layout.row: 1
2023-05-23 18:05:04 +03:00
Layout.column: 1
2023-05-23 21:51:14 +03:00
ToolTip.text: qsTr ( "Number of characters per document snippet.\nNOTE: larger numbers increase likelihood of factual responses, but also result in slower generation." )
2023-05-23 18:05:04 +03:00
ToolTip.visible: hovered
2023-05-24 03:26:31 +03:00
text: settings . chunkSize . toString ( )
validator: IntValidator {
bottom: 1
}
onEditingFinished: {
var val = parseInt ( text )
if ( ! isNaN ( val ) ) {
settings . chunkSize = val
settings . sync ( )
focus = false
LocalDocs . chunkSize = settings . chunkSize
} else {
text = settings . chunkSize . toString ( )
}
}
2023-05-23 18:05:04 +03:00
}
Label {
id: contextItemsPerPrompt
2023-06-26 19:58:33 +03:00
Layout.row: 2
2023-05-23 18:05:04 +03:00
Layout.column: 0
color: theme . textColor
2023-06-26 19:58:33 +03:00
text: qsTr ( "Document snippets per prompt:" )
2023-05-23 18:05:04 +03:00
}
MyTextField {
2023-06-26 19:58:33 +03:00
Layout.row: 2
2023-05-23 18:05:04 +03:00
Layout.column: 1
2023-05-23 21:51:14 +03:00
ToolTip.text: qsTr ( "Best N matches of retrieved document snippets to add to the context for prompt.\nNOTE: larger numbers increase likelihood of factual responses, but also result in slower generation." )
2023-05-23 18:05:04 +03:00
ToolTip.visible: hovered
2023-05-24 03:26:31 +03:00
text: settings . retrievalSize . toString ( )
validator: IntValidator {
bottom: 1
}
onEditingFinished: {
var val = parseInt ( text )
if ( ! isNaN ( val ) ) {
settings . retrievalSize = val
settings . sync ( )
focus = false
LocalDocs . retrievalSize = settings . retrievalSize
} else {
text = settings . retrievalSize . toString ( )
}
}
2023-05-23 18:05:04 +03:00
}
2023-06-26 19:58:33 +03:00
Label {
id: warningLabel
Layout.row: 1
Layout.column: 2
Layout.rowSpan: 2
2023-06-26 20:37:18 +03:00
Layout.maximumWidth: 520
2023-06-26 19:58:33 +03:00
Layout.alignment: Qt . AlignTop
color: theme . textErrorColor
wrapMode: Text . WordWrap
2023-06-26 20:37:18 +03:00
text: qsTr ( "Warning: Advanced usage only. Values too large may cause localdocs failure, extremely slow responses or failure to respond at all. Roughly speaking, the {N chars x N snippets} are added to the model's context window. More info <a href=\"https://docs.gpt4all.io/gpt4all_chat.html#localdocs-beta-plugin-chat-with-your-data\">here.</a>" )
onLinkActivated: function ( link ) { Qt . openUrlExternally ( link ) }
2023-06-26 19:58:33 +03:00
}
2023-05-23 18:05:04 +03:00
MyButton {
id: restoreDefaultsButton
2023-06-26 19:58:33 +03:00
Layout.row: 4
2023-05-23 18:05:04 +03:00
Layout.column: 1
2023-06-26 19:58:33 +03:00
Layout.columnSpan: 2
2023-05-23 18:05:04 +03:00
Layout.fillWidth: true
text: qsTr ( "Restore Defaults" )
Accessible.role: Accessible . Button
Accessible.name: text
Accessible.description: qsTr ( "Restores the settings dialog to a default state" )
onClicked: {
2023-05-24 03:26:31 +03:00
root . restoreLocalDocsDefaults ( ) ;
2023-05-23 18:05:04 +03:00
}
2023-05-22 16:03:06 +03:00
}
}
}