mirror of
https://github.com/nomic-ai/gpt4all.git
synced 2024-10-01 01:06:10 -04:00
Provide an abstraction to break up the settings dialog into managable pieces.
This commit is contained in:
parent
7f252b4970
commit
1cd734efdc
@ -89,7 +89,6 @@ qt_add_qml_module(chat
|
|||||||
main.qml
|
main.qml
|
||||||
qml/ChatDrawer.qml
|
qml/ChatDrawer.qml
|
||||||
qml/CollectionsDialog.qml
|
qml/CollectionsDialog.qml
|
||||||
qml/LocalDocs.qml
|
|
||||||
qml/ModelDownloaderDialog.qml
|
qml/ModelDownloaderDialog.qml
|
||||||
qml/NetworkDialog.qml
|
qml/NetworkDialog.qml
|
||||||
qml/NewVersionDialog.qml
|
qml/NewVersionDialog.qml
|
||||||
@ -99,6 +98,10 @@ qt_add_qml_module(chat
|
|||||||
qml/PopupDialog.qml
|
qml/PopupDialog.qml
|
||||||
qml/AboutDialog.qml
|
qml/AboutDialog.qml
|
||||||
qml/Theme.qml
|
qml/Theme.qml
|
||||||
|
qml/GenerationSettings.qml
|
||||||
|
qml/ApplicationSettings.qml
|
||||||
|
qml/LocalDocsSettings.qml
|
||||||
|
qml/MySettingsTab.qml
|
||||||
qml/MyButton.qml
|
qml/MyButton.qml
|
||||||
qml/MyComboBox.qml
|
qml/MyComboBox.qml
|
||||||
qml/MyDirectoryField.qml
|
qml/MyDirectoryField.qml
|
||||||
|
231
gpt4all-chat/qml/ApplicationSettings.qml
Normal file
231
gpt4all-chat/qml/ApplicationSettings.qml
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
import QtCore
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Controls.Basic
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Dialogs
|
||||||
|
import modellist
|
||||||
|
import mysettings
|
||||||
|
|
||||||
|
MySettingsTab {
|
||||||
|
title: qsTr("Application")
|
||||||
|
contentItem: GridLayout {
|
||||||
|
id: applicationSettingsTabInner
|
||||||
|
columns: 3
|
||||||
|
rowSpacing: 10
|
||||||
|
columnSpacing: 10
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: defaultModelLabel
|
||||||
|
text: qsTr("Default model:")
|
||||||
|
color: theme.textColor
|
||||||
|
Layout.row: 1
|
||||||
|
Layout.column: 0
|
||||||
|
}
|
||||||
|
MyComboBox {
|
||||||
|
id: comboBox
|
||||||
|
Layout.row: 1
|
||||||
|
Layout.column: 1
|
||||||
|
Layout.minimumWidth: 350
|
||||||
|
model: ModelList.userDefaultModelList
|
||||||
|
Accessible.role: Accessible.ComboBox
|
||||||
|
Accessible.name: qsTr("ComboBox for displaying/picking the default model")
|
||||||
|
Accessible.description: qsTr("Use this for picking the default model to use; the first item is the current default model")
|
||||||
|
function updateModel() {
|
||||||
|
comboBox.currentIndex = comboBox.indexOfValue(MySettings.userDefaultModel);
|
||||||
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
comboBox.updateModel()
|
||||||
|
}
|
||||||
|
Connections {
|
||||||
|
target: MySettings
|
||||||
|
function onUserDefaultModelChanged() {
|
||||||
|
comboBox.updateModel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onActivated: {
|
||||||
|
MySettings.userDefaultModel = comboBox.currentText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FolderDialog {
|
||||||
|
id: modelPathDialog
|
||||||
|
title: "Please choose a directory"
|
||||||
|
currentFolder: "file://" + MySettings.modelPath
|
||||||
|
onAccepted: {
|
||||||
|
MySettings.modelPath = selectedFolder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: modelPathLabel
|
||||||
|
text: qsTr("Download path:")
|
||||||
|
color: theme.textColor
|
||||||
|
Layout.row: 2
|
||||||
|
Layout.column: 0
|
||||||
|
}
|
||||||
|
MyDirectoryField {
|
||||||
|
id: modelPathDisplayField
|
||||||
|
text: MySettings.modelPath
|
||||||
|
implicitWidth: 300
|
||||||
|
Layout.row: 2
|
||||||
|
Layout.column: 1
|
||||||
|
Layout.fillWidth: true
|
||||||
|
ToolTip.text: qsTr("Path where model files will be downloaded to")
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
Accessible.role: Accessible.ToolTip
|
||||||
|
Accessible.name: modelPathDisplayField.text
|
||||||
|
Accessible.description: ToolTip.text
|
||||||
|
onEditingFinished: {
|
||||||
|
if (isValid) {
|
||||||
|
MySettings.modelPath = modelPathDisplayField.text
|
||||||
|
} else {
|
||||||
|
text = MySettings.modelPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MyButton {
|
||||||
|
Layout.row: 2
|
||||||
|
Layout.column: 2
|
||||||
|
text: qsTr("Browse")
|
||||||
|
Accessible.description: qsTr("Opens a folder picker dialog to choose where to save model files")
|
||||||
|
onClicked: modelPathDialog.open()
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: nThreadsLabel
|
||||||
|
text: qsTr("CPU Threads:")
|
||||||
|
color: theme.textColor
|
||||||
|
Layout.row: 3
|
||||||
|
Layout.column: 0
|
||||||
|
}
|
||||||
|
MyTextField {
|
||||||
|
text: MySettings.threadCount
|
||||||
|
color: theme.textColor
|
||||||
|
ToolTip.text: qsTr("Amount of processing threads to use, a setting of 0 will use the lesser of 4 or your number of CPU threads")
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
Layout.row: 3
|
||||||
|
Layout.column: 1
|
||||||
|
validator: IntValidator {
|
||||||
|
bottom: 1
|
||||||
|
}
|
||||||
|
onEditingFinished: {
|
||||||
|
var val = parseInt(text)
|
||||||
|
if (!isNaN(val)) {
|
||||||
|
MySettings.threadCount = val
|
||||||
|
focus = false
|
||||||
|
} else {
|
||||||
|
text = MySettings.threadCount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Accessible.role: Accessible.EditableText
|
||||||
|
Accessible.name: nThreadsLabel.text
|
||||||
|
Accessible.description: ToolTip.text
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: saveChatsLabel
|
||||||
|
text: qsTr("Save chats to disk:")
|
||||||
|
color: theme.textColor
|
||||||
|
Layout.row: 4
|
||||||
|
Layout.column: 0
|
||||||
|
}
|
||||||
|
MyCheckBox {
|
||||||
|
id: saveChatsBox
|
||||||
|
Layout.row: 4
|
||||||
|
Layout.column: 1
|
||||||
|
checked: MySettings.saveChats
|
||||||
|
onClicked: {
|
||||||
|
Network.sendSaveChatsToggled(saveChatsBox.checked);
|
||||||
|
MySettings.saveChats = !MySettings.saveChats
|
||||||
|
}
|
||||||
|
ToolTip.text: qsTr("WARNING: Saving chats to disk can be ~2GB per chat")
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: saveChatGPTChatsLabel
|
||||||
|
text: qsTr("Save ChatGPT chats to disk:")
|
||||||
|
color: theme.textColor
|
||||||
|
Layout.row: 5
|
||||||
|
Layout.column: 0
|
||||||
|
}
|
||||||
|
MyCheckBox {
|
||||||
|
id: saveChatGPTChatsBox
|
||||||
|
Layout.row: 5
|
||||||
|
Layout.column: 1
|
||||||
|
checked: MySettings.saveChatGPTChats
|
||||||
|
onClicked: {
|
||||||
|
MySettings.saveChatGPTChats = !MySettings.saveChatGPTChats
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: serverChatLabel
|
||||||
|
text: qsTr("Enable API server:")
|
||||||
|
color: theme.textColor
|
||||||
|
Layout.row: 6
|
||||||
|
Layout.column: 0
|
||||||
|
}
|
||||||
|
MyCheckBox {
|
||||||
|
id: serverChatBox
|
||||||
|
Layout.row: 6
|
||||||
|
Layout.column: 1
|
||||||
|
checked: MySettings.serverChat
|
||||||
|
onClicked: {
|
||||||
|
MySettings.serverChat = !MySettings.serverChat
|
||||||
|
}
|
||||||
|
ToolTip.text: qsTr("WARNING: This enables the gui to act as a local REST web server(OpenAI API compliant) for API requests and will increase your RAM usage as well")
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
Layout.row: 7
|
||||||
|
Layout.column: 0
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: 1
|
||||||
|
color: theme.dialogBorder
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
Layout.row: 9
|
||||||
|
Layout.column: 0
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.columnSpan: 3
|
||||||
|
height: 1
|
||||||
|
color: theme.dialogBorder
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: gpuOverrideLabel
|
||||||
|
text: qsTr("Force Metal (macOS+arm):")
|
||||||
|
color: theme.textColor
|
||||||
|
Layout.row: 8
|
||||||
|
Layout.column: 0
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
Layout.row: 8
|
||||||
|
Layout.column: 1
|
||||||
|
Layout.columnSpan: 2
|
||||||
|
MyCheckBox {
|
||||||
|
id: gpuOverrideBox
|
||||||
|
checked: MySettings.forceMetal
|
||||||
|
onClicked: {
|
||||||
|
MySettings.forceMetal = !MySettings.forceMetal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: warningLabel
|
||||||
|
Layout.maximumWidth: 730
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
color: theme.textErrorColor
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
text: qsTr("WARNING: On macOS with arm (M1+) this setting forces usage of the GPU. Can cause crashes if the model requires more RAM than the system supports. Because of crash possibility the setting will not persist across restarts of the application. This has no effect on non-macs or intel.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MyButton {
|
||||||
|
Layout.row: 10
|
||||||
|
Layout.column: 1
|
||||||
|
Layout.columnSpan: 2
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: qsTr("Restore Defaults")
|
||||||
|
Accessible.description: qsTr("Restores the settings dialog to a default state")
|
||||||
|
onClicked: {
|
||||||
|
MySettings.restoreApplicationDefaults();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
302
gpt4all-chat/qml/GenerationSettings.qml
Normal file
302
gpt4all-chat/qml/GenerationSettings.qml
Normal file
@ -0,0 +1,302 @@
|
|||||||
|
import QtCore
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Controls.Basic
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import localdocs
|
||||||
|
import mysettings
|
||||||
|
|
||||||
|
MySettingsTab {
|
||||||
|
title: qsTr("Generation")
|
||||||
|
contentItem: GridLayout {
|
||||||
|
id: generationSettingsTabInner
|
||||||
|
columns: 2
|
||||||
|
rowSpacing: 10
|
||||||
|
columnSpacing: 10
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: tempLabel
|
||||||
|
text: qsTr("Temperature:")
|
||||||
|
color: theme.textColor
|
||||||
|
Layout.row: 0
|
||||||
|
Layout.column: 0
|
||||||
|
}
|
||||||
|
MyTextField {
|
||||||
|
text: MySettings.temperature
|
||||||
|
color: theme.textColor
|
||||||
|
ToolTip.text: qsTr("Temperature increases the chances of choosing less likely tokens.\nNOTE: Higher temperature gives more creative but less predictable outputs.")
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
Layout.row: 0
|
||||||
|
Layout.column: 1
|
||||||
|
validator: DoubleValidator {
|
||||||
|
locale: "C"
|
||||||
|
}
|
||||||
|
onEditingFinished: {
|
||||||
|
var val = parseFloat(text)
|
||||||
|
if (!isNaN(val)) {
|
||||||
|
MySettings.temperature = val
|
||||||
|
focus = false
|
||||||
|
} else {
|
||||||
|
text = MySettings.temperature
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Accessible.role: Accessible.EditableText
|
||||||
|
Accessible.name: tempLabel.text
|
||||||
|
Accessible.description: ToolTip.text
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: topPLabel
|
||||||
|
text: qsTr("Top P:")
|
||||||
|
color: theme.textColor
|
||||||
|
Layout.row: 1
|
||||||
|
Layout.column: 0
|
||||||
|
}
|
||||||
|
MyTextField {
|
||||||
|
text: MySettings.topP
|
||||||
|
color: theme.textColor
|
||||||
|
ToolTip.text: qsTr("Only the most likely tokens up to a total probability of top_p can be chosen.\nNOTE: Prevents choosing highly unlikely tokens, aka Nucleus Sampling")
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
Layout.row: 1
|
||||||
|
Layout.column: 1
|
||||||
|
validator: DoubleValidator {
|
||||||
|
locale: "C"
|
||||||
|
}
|
||||||
|
onEditingFinished: {
|
||||||
|
var val = parseFloat(text)
|
||||||
|
if (!isNaN(val)) {
|
||||||
|
MySettings.topP = val
|
||||||
|
focus = false
|
||||||
|
} else {
|
||||||
|
text = MySettings.topP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Accessible.role: Accessible.EditableText
|
||||||
|
Accessible.name: topPLabel.text
|
||||||
|
Accessible.description: ToolTip.text
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: topKLabel
|
||||||
|
text: qsTr("Top K:")
|
||||||
|
color: theme.textColor
|
||||||
|
Layout.row: 2
|
||||||
|
Layout.column: 0
|
||||||
|
}
|
||||||
|
MyTextField {
|
||||||
|
text: MySettings.topK
|
||||||
|
color: theme.textColor
|
||||||
|
ToolTip.text: qsTr("Only the top K most likely tokens will be chosen from")
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
Layout.row: 2
|
||||||
|
Layout.column: 1
|
||||||
|
validator: IntValidator {
|
||||||
|
bottom: 1
|
||||||
|
}
|
||||||
|
onEditingFinished: {
|
||||||
|
var val = parseInt(text)
|
||||||
|
if (!isNaN(val)) {
|
||||||
|
MySettings.topK = val
|
||||||
|
focus = false
|
||||||
|
} else {
|
||||||
|
text = MySettings.topK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Accessible.role: Accessible.EditableText
|
||||||
|
Accessible.name: topKLabel.text
|
||||||
|
Accessible.description: ToolTip.text
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: maxLengthLabel
|
||||||
|
text: qsTr("Max Length:")
|
||||||
|
color: theme.textColor
|
||||||
|
Layout.row: 3
|
||||||
|
Layout.column: 0
|
||||||
|
}
|
||||||
|
MyTextField {
|
||||||
|
text: MySettings.maxLength
|
||||||
|
color: theme.textColor
|
||||||
|
ToolTip.text: qsTr("Maximum length of response in tokens")
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
Layout.row: 3
|
||||||
|
Layout.column: 1
|
||||||
|
validator: IntValidator {
|
||||||
|
bottom: 1
|
||||||
|
}
|
||||||
|
onEditingFinished: {
|
||||||
|
var val = parseInt(text)
|
||||||
|
if (!isNaN(val)) {
|
||||||
|
MySettings.maxLength = val
|
||||||
|
focus = false
|
||||||
|
} else {
|
||||||
|
text = MySettings.maxLength
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Accessible.role: Accessible.EditableText
|
||||||
|
Accessible.name: maxLengthLabel.text
|
||||||
|
Accessible.description: ToolTip.text
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: batchSizeLabel
|
||||||
|
text: qsTr("Prompt Batch Size:")
|
||||||
|
color: theme.textColor
|
||||||
|
Layout.row: 4
|
||||||
|
Layout.column: 0
|
||||||
|
}
|
||||||
|
MyTextField {
|
||||||
|
text: MySettings.promptBatchSize
|
||||||
|
color: theme.textColor
|
||||||
|
ToolTip.text: qsTr("Amount of prompt tokens to process at once.\nNOTE: Higher values can speed up reading prompts but will use more RAM")
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
Layout.row: 4
|
||||||
|
Layout.column: 1
|
||||||
|
validator: IntValidator {
|
||||||
|
bottom: 1
|
||||||
|
}
|
||||||
|
onEditingFinished: {
|
||||||
|
var val = parseInt(text)
|
||||||
|
if (!isNaN(val)) {
|
||||||
|
MySettings.promptBatchSize = val
|
||||||
|
focus = false
|
||||||
|
} else {
|
||||||
|
text = MySettings.promptBatchSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Accessible.role: Accessible.EditableText
|
||||||
|
Accessible.name: batchSizeLabel.text
|
||||||
|
Accessible.description: ToolTip.text
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: repeatPenaltyLabel
|
||||||
|
text: qsTr("Repeat Penalty:")
|
||||||
|
color: theme.textColor
|
||||||
|
Layout.row: 5
|
||||||
|
Layout.column: 0
|
||||||
|
}
|
||||||
|
MyTextField {
|
||||||
|
text: MySettings.repeatPenalty
|
||||||
|
color: theme.textColor
|
||||||
|
ToolTip.text: qsTr("Amount to penalize repetitiveness of the output")
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
Layout.row: 5
|
||||||
|
Layout.column: 1
|
||||||
|
validator: DoubleValidator {
|
||||||
|
locale: "C"
|
||||||
|
}
|
||||||
|
onEditingFinished: {
|
||||||
|
var val = parseFloat(text)
|
||||||
|
if (!isNaN(val)) {
|
||||||
|
MySettings.repeatPenalty = val
|
||||||
|
focus = false
|
||||||
|
} else {
|
||||||
|
text = MySettings.repeatPenalty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Accessible.role: Accessible.EditableText
|
||||||
|
Accessible.name: repeatPenaltyLabel.text
|
||||||
|
Accessible.description: ToolTip.text
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
id: repeatPenaltyTokensLabel
|
||||||
|
text: qsTr("Repeat Penalty Tokens:")
|
||||||
|
color: theme.textColor
|
||||||
|
Layout.row: 6
|
||||||
|
Layout.column: 0
|
||||||
|
}
|
||||||
|
MyTextField {
|
||||||
|
text: MySettings.repeatPenaltyTokens
|
||||||
|
color: theme.textColor
|
||||||
|
ToolTip.text: qsTr("How far back in output to apply repeat penalty")
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
Layout.row: 6
|
||||||
|
Layout.column: 1
|
||||||
|
validator: IntValidator {
|
||||||
|
bottom: 1
|
||||||
|
}
|
||||||
|
onEditingFinished: {
|
||||||
|
var val = parseInt(text)
|
||||||
|
if (!isNaN(val)) {
|
||||||
|
MySettings.repeatPenaltyTokens = val
|
||||||
|
focus = false
|
||||||
|
} else {
|
||||||
|
text = MySettings.repeatPenaltyTokens
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Accessible.role: Accessible.EditableText
|
||||||
|
Accessible.name: repeatPenaltyTokensLabel.text
|
||||||
|
Accessible.description: ToolTip.text
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.row: 7
|
||||||
|
Layout.column: 0
|
||||||
|
Layout.topMargin: 10
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
spacing: 20
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: promptTemplateLabel
|
||||||
|
text: qsTr("Prompt Template:")
|
||||||
|
color: theme.textColor
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: promptTemplateLabelHelp
|
||||||
|
Layout.maximumWidth: promptTemplateLabel.width
|
||||||
|
visible: templateTextArea.text.indexOf(
|
||||||
|
"%1") === -1
|
||||||
|
color: theme.textErrorColor
|
||||||
|
text: qsTr("Must contain the string \"%1\" to be replaced with the user's input.")
|
||||||
|
wrapMode: TextArea.Wrap
|
||||||
|
Accessible.role: Accessible.EditableText
|
||||||
|
Accessible.name: text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
Layout.row: 7
|
||||||
|
Layout.column: 1
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: 200
|
||||||
|
color: "transparent"
|
||||||
|
clip: true
|
||||||
|
ScrollView {
|
||||||
|
id: templateScrollView
|
||||||
|
anchors.fill: parent
|
||||||
|
TextArea {
|
||||||
|
id: templateTextArea
|
||||||
|
text: MySettings.promptTemplate
|
||||||
|
color: theme.textColor
|
||||||
|
background: Rectangle {
|
||||||
|
implicitWidth: 150
|
||||||
|
color: theme.backgroundLighter
|
||||||
|
radius: 10
|
||||||
|
}
|
||||||
|
padding: 10
|
||||||
|
wrapMode: TextArea.Wrap
|
||||||
|
onTextChanged: {
|
||||||
|
if (templateTextArea.text.indexOf("%1") !== -1) {
|
||||||
|
MySettings.promptTemplate = text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bottomPadding: 10
|
||||||
|
Accessible.role: Accessible.EditableText
|
||||||
|
Accessible.name: promptTemplateLabel.text
|
||||||
|
Accessible.description: promptTemplateLabelHelp.text
|
||||||
|
ToolTip.text: qsTr("The prompt template partially determines how models will respond to prompts.\nNOTE: A longer, detailed template can lead to higher quality answers, but can also slow down generation.")
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MyButton {
|
||||||
|
Layout.row: 8
|
||||||
|
Layout.column: 1
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: qsTr("Restore Defaults")
|
||||||
|
Accessible.description: qsTr("Restores the settings dialog to a default state")
|
||||||
|
onClicked: {
|
||||||
|
MySettings.restoreGenerationDefaults();
|
||||||
|
templateTextArea.text = MySettings.promptTemplate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,294 +0,0 @@
|
|||||||
import QtCore
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Controls.Basic
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import QtQuick.Dialogs
|
|
||||||
import localdocs
|
|
||||||
import mysettings
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property alias collection: collection.text
|
|
||||||
property alias folder_path: folderEdit.text
|
|
||||||
|
|
||||||
FolderDialog {
|
|
||||||
id: folderDialog
|
|
||||||
title: "Please choose a directory"
|
|
||||||
currentFolder: StandardPaths.writableLocation(StandardPaths.HomeLocation)
|
|
||||||
onAccepted: {
|
|
||||||
root.folder_path = selectedFolder
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: addCollection
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
height: collection.height + 20
|
|
||||||
color: theme.backgroundDark
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.left: parent.left
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MyButton {
|
|
||||||
id: browseButton
|
|
||||||
text: qsTr("Browse")
|
|
||||||
onClicked: {
|
|
||||||
folderDialog.open();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ScrollView {
|
|
||||||
id: scrollView
|
|
||||||
anchors.top: addCollection.bottom
|
|
||||||
anchors.bottom: gridLayout.top
|
|
||||||
anchors.bottomMargin: 20
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
clip: true
|
|
||||||
contentHeight: 300
|
|
||||||
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
|
|
||||||
|
|
||||||
background: Rectangle {
|
|
||||||
color: theme.backgroundLighter
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
width: Math.max(removeButton.width, busyIndicator.width)
|
|
||||||
height: Math.max(removeButton.height, busyIndicator.height)
|
|
||||||
MyButton {
|
|
||||||
id: removeButton
|
|
||||||
anchors.centerIn: parent
|
|
||||||
text: qsTr("Remove")
|
|
||||||
visible: !item.removing && installed
|
|
||||||
onClicked: {
|
|
||||||
item.removing = true
|
|
||||||
LocalDocs.removeFolder(collection, folder_path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MyBusyIndicator {
|
|
||||||
id: busyIndicator
|
|
||||||
anchors.centerIn: parent
|
|
||||||
visible: item.removing || !installed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GridLayout {
|
|
||||||
id: gridLayout
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
columns: 3
|
|
||||||
rowSpacing: 10
|
|
||||||
columnSpacing: 10
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: chunkLabel
|
|
||||||
Layout.row: 1
|
|
||||||
Layout.column: 0
|
|
||||||
color: theme.textColor
|
|
||||||
text: qsTr("Document snippet size (characters):")
|
|
||||||
}
|
|
||||||
|
|
||||||
MyTextField {
|
|
||||||
id: chunkSizeTextField
|
|
||||||
Layout.row: 1
|
|
||||||
Layout.column: 1
|
|
||||||
ToolTip.text: qsTr("Number of characters per document snippet.\nNOTE: larger numbers increase likelihood of factual responses, but also result in slower generation.")
|
|
||||||
ToolTip.visible: hovered
|
|
||||||
text: MySettings.localDocsChunkSize
|
|
||||||
validator: IntValidator {
|
|
||||||
bottom: 1
|
|
||||||
}
|
|
||||||
onEditingFinished: {
|
|
||||||
var val = parseInt(text)
|
|
||||||
if (!isNaN(val)) {
|
|
||||||
MySettings.localDocsChunkSize = val
|
|
||||||
focus = false
|
|
||||||
} else {
|
|
||||||
text = MySettings.localDocsChunkSize
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: contextItemsPerPrompt
|
|
||||||
Layout.row: 2
|
|
||||||
Layout.column: 0
|
|
||||||
color: theme.textColor
|
|
||||||
text: qsTr("Document snippets per prompt:")
|
|
||||||
}
|
|
||||||
|
|
||||||
MyTextField {
|
|
||||||
Layout.row: 2
|
|
||||||
Layout.column: 1
|
|
||||||
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.")
|
|
||||||
ToolTip.visible: hovered
|
|
||||||
text: MySettings.localDocsRetrievalSize
|
|
||||||
validator: IntValidator {
|
|
||||||
bottom: 1
|
|
||||||
}
|
|
||||||
onEditingFinished: {
|
|
||||||
var val = parseInt(text)
|
|
||||||
if (!isNaN(val)) {
|
|
||||||
MySettings.localDocsRetrievalSize = val
|
|
||||||
focus = false
|
|
||||||
} else {
|
|
||||||
text = MySettings.localDocsRetrievalSize
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: warningLabel
|
|
||||||
Layout.row: 1
|
|
||||||
Layout.column: 2
|
|
||||||
Layout.rowSpan: 2
|
|
||||||
Layout.maximumWidth: 520
|
|
||||||
Layout.alignment: Qt.AlignTop
|
|
||||||
color: theme.textErrorColor
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
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) }
|
|
||||||
}
|
|
||||||
|
|
||||||
MyButton {
|
|
||||||
id: restoreDefaultsButton
|
|
||||||
Layout.row: 4
|
|
||||||
Layout.column: 1
|
|
||||||
Layout.columnSpan: 2
|
|
||||||
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: {
|
|
||||||
MySettings.restoreLocalDocsDefaults();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
293
gpt4all-chat/qml/LocalDocsSettings.qml
Normal file
293
gpt4all-chat/qml/LocalDocsSettings.qml
Normal file
@ -0,0 +1,293 @@
|
|||||||
|
import QtCore
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Controls.Basic
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Dialogs
|
||||||
|
import localdocs
|
||||||
|
import mysettings
|
||||||
|
|
||||||
|
MySettingsTab {
|
||||||
|
title: qsTr("LocalDocs Plugin (BETA)")
|
||||||
|
contentItem: ColumnLayout {
|
||||||
|
id: root
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
property alias collection: collection.text
|
||||||
|
property alias folder_path: folderEdit.text
|
||||||
|
|
||||||
|
FolderDialog {
|
||||||
|
id: folderDialog
|
||||||
|
title: "Please choose a directory"
|
||||||
|
currentFolder: StandardPaths.writableLocation(StandardPaths.HomeLocation)
|
||||||
|
onAccepted: {
|
||||||
|
root.folder_path = selectedFolder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: collection.height + 20
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MyButton {
|
||||||
|
id: browseButton
|
||||||
|
text: qsTr("Browse")
|
||||||
|
onClicked: {
|
||||||
|
folderDialog.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollView {
|
||||||
|
id: scrollView
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.bottomMargin: 20
|
||||||
|
clip: true
|
||||||
|
contentHeight: 300
|
||||||
|
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: theme.backgroundLighter
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
width: Math.max(removeButton.width, busyIndicator.width)
|
||||||
|
height: Math.max(removeButton.height, busyIndicator.height)
|
||||||
|
MyButton {
|
||||||
|
id: removeButton
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: qsTr("Remove")
|
||||||
|
visible: !item.removing && installed
|
||||||
|
onClicked: {
|
||||||
|
item.removing = true
|
||||||
|
LocalDocs.removeFolder(collection, folder_path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MyBusyIndicator {
|
||||||
|
id: busyIndicator
|
||||||
|
anchors.centerIn: parent
|
||||||
|
visible: item.removing || !installed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GridLayout {
|
||||||
|
id: gridLayout
|
||||||
|
Layout.fillWidth: true
|
||||||
|
columns: 3
|
||||||
|
rowSpacing: 10
|
||||||
|
columnSpacing: 10
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is here just to stretch out the third column
|
||||||
|
Rectangle {
|
||||||
|
Layout.row: 3
|
||||||
|
Layout.column: 2
|
||||||
|
Layout.fillWidth: true
|
||||||
|
height: 1
|
||||||
|
color: theme.dialogBorder
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: chunkLabel
|
||||||
|
Layout.row: 1
|
||||||
|
Layout.column: 0
|
||||||
|
color: theme.textColor
|
||||||
|
text: qsTr("Document snippet size (characters):")
|
||||||
|
}
|
||||||
|
|
||||||
|
MyTextField {
|
||||||
|
id: chunkSizeTextField
|
||||||
|
Layout.row: 1
|
||||||
|
Layout.column: 1
|
||||||
|
ToolTip.text: qsTr("Number of characters per document snippet.\nNOTE: larger numbers increase likelihood of factual responses, but also result in slower generation.")
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
text: MySettings.localDocsChunkSize
|
||||||
|
validator: IntValidator {
|
||||||
|
bottom: 1
|
||||||
|
}
|
||||||
|
onEditingFinished: {
|
||||||
|
var val = parseInt(text)
|
||||||
|
if (!isNaN(val)) {
|
||||||
|
MySettings.localDocsChunkSize = val
|
||||||
|
focus = false
|
||||||
|
} else {
|
||||||
|
text = MySettings.localDocsChunkSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: contextItemsPerPrompt
|
||||||
|
Layout.row: 2
|
||||||
|
Layout.column: 0
|
||||||
|
color: theme.textColor
|
||||||
|
text: qsTr("Document snippets per prompt:")
|
||||||
|
}
|
||||||
|
|
||||||
|
MyTextField {
|
||||||
|
Layout.row: 2
|
||||||
|
Layout.column: 1
|
||||||
|
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.")
|
||||||
|
ToolTip.visible: hovered
|
||||||
|
text: MySettings.localDocsRetrievalSize
|
||||||
|
validator: IntValidator {
|
||||||
|
bottom: 1
|
||||||
|
}
|
||||||
|
onEditingFinished: {
|
||||||
|
var val = parseInt(text)
|
||||||
|
if (!isNaN(val)) {
|
||||||
|
MySettings.localDocsRetrievalSize = val
|
||||||
|
focus = false
|
||||||
|
} else {
|
||||||
|
text = MySettings.localDocsRetrievalSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: warningLabel
|
||||||
|
Layout.row: 1
|
||||||
|
Layout.column: 2
|
||||||
|
Layout.rowSpan: 2
|
||||||
|
Layout.maximumWidth: 520
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
color: theme.textErrorColor
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
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) }
|
||||||
|
}
|
||||||
|
|
||||||
|
MyButton {
|
||||||
|
id: restoreDefaultsButton
|
||||||
|
Layout.row: 4
|
||||||
|
Layout.column: 1
|
||||||
|
Layout.columnSpan: 2
|
||||||
|
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: {
|
||||||
|
MySettings.restoreLocalDocsDefaults();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
46
gpt4all-chat/qml/MySettingsTab.qml
Normal file
46
gpt4all-chat/qml/MySettingsTab.qml
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import QtCore
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Controls.Basic
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
Item {
|
||||||
|
property string title: ""
|
||||||
|
property Item contentItem: null
|
||||||
|
|
||||||
|
onContentItemChanged: function() {
|
||||||
|
if (contentItem) {
|
||||||
|
contentItem.parent = tabInner;
|
||||||
|
contentItem.anchors.left = tabInner.left;
|
||||||
|
contentItem.anchors.right = tabInner.right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollView {
|
||||||
|
id: root
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
padding: 15
|
||||||
|
rightPadding: 20
|
||||||
|
contentWidth: availableWidth
|
||||||
|
contentHeight: tabInner.height
|
||||||
|
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
|
||||||
|
|
||||||
|
Theme {
|
||||||
|
id: theme
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: 'transparent'
|
||||||
|
border.color: theme.tabBorder
|
||||||
|
border.width: 1
|
||||||
|
radius: 2
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: tabInner
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,6 @@ import QtQuick.Controls.Basic
|
|||||||
import QtQuick.Dialogs
|
import QtQuick.Dialogs
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import Qt.labs.folderlistmodel
|
import Qt.labs.folderlistmodel
|
||||||
import chatlistmodel
|
|
||||||
import download
|
import download
|
||||||
import modellist
|
import modellist
|
||||||
import network
|
import network
|
||||||
@ -30,21 +29,10 @@ Dialog {
|
|||||||
Network.sendSettingsDialog();
|
Network.sendSettingsDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
property var currentChat: ChatListModel.currentChat
|
|
||||||
|
|
||||||
Theme {
|
Theme {
|
||||||
id: theme
|
id: theme
|
||||||
}
|
}
|
||||||
|
|
||||||
function restoreGenerationDefaults() {
|
|
||||||
MySettings.restoreGenerationDefaults();
|
|
||||||
templateTextArea.text = MySettings.promptTemplate
|
|
||||||
}
|
|
||||||
|
|
||||||
function restoreApplicationDefaults() {
|
|
||||||
MySettings.restoreApplicationDefaults();
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
Accessible.role: Accessible.Dialog
|
Accessible.role: Accessible.Dialog
|
||||||
Accessible.name: qsTr("Settings dialog")
|
Accessible.name: qsTr("Settings dialog")
|
||||||
@ -187,576 +175,18 @@ Dialog {
|
|||||||
|
|
||||||
StackLayout {
|
StackLayout {
|
||||||
anchors.top: settingsTabBar.bottom
|
anchors.top: settingsTabBar.bottom
|
||||||
anchors.topMargin: -1
|
anchors.left: parent.left
|
||||||
width: parent.width
|
anchors.right: parent.right
|
||||||
height: availableHeight
|
anchors.bottom: parent.bottom
|
||||||
currentIndex: settingsTabBar.currentIndex
|
currentIndex: settingsTabBar.currentIndex
|
||||||
|
|
||||||
Item {
|
GenerationSettings {
|
||||||
id: generationSettingsTab
|
|
||||||
ScrollView {
|
|
||||||
background: Rectangle {
|
|
||||||
color: 'transparent'
|
|
||||||
border.color: theme.tabBorder
|
|
||||||
border.width: 1
|
|
||||||
radius: 2
|
|
||||||
}
|
|
||||||
padding: 10
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height - 30
|
|
||||||
contentWidth: availableWidth - 20
|
|
||||||
contentHeight: generationSettingsTabInner.implicitHeight + 40
|
|
||||||
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
|
|
||||||
|
|
||||||
GridLayout {
|
|
||||||
id: generationSettingsTabInner
|
|
||||||
anchors.margins: 10
|
|
||||||
columns: 2
|
|
||||||
rowSpacing: 10
|
|
||||||
columnSpacing: 10
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: tempLabel
|
|
||||||
text: qsTr("Temperature:")
|
|
||||||
color: theme.textColor
|
|
||||||
Layout.row: 0
|
|
||||||
Layout.column: 0
|
|
||||||
}
|
|
||||||
MyTextField {
|
|
||||||
text: MySettings.temperature
|
|
||||||
color: theme.textColor
|
|
||||||
ToolTip.text: qsTr("Temperature increases the chances of choosing less likely tokens.\nNOTE: Higher temperature gives more creative but less predictable outputs.")
|
|
||||||
ToolTip.visible: hovered
|
|
||||||
Layout.row: 0
|
|
||||||
Layout.column: 1
|
|
||||||
validator: DoubleValidator {
|
|
||||||
locale: "C"
|
|
||||||
}
|
|
||||||
onEditingFinished: {
|
|
||||||
var val = parseFloat(text)
|
|
||||||
if (!isNaN(val)) {
|
|
||||||
MySettings.temperature = val
|
|
||||||
focus = false
|
|
||||||
} else {
|
|
||||||
text = MySettings.temperature
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Accessible.role: Accessible.EditableText
|
|
||||||
Accessible.name: tempLabel.text
|
|
||||||
Accessible.description: ToolTip.text
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: topPLabel
|
|
||||||
text: qsTr("Top P:")
|
|
||||||
color: theme.textColor
|
|
||||||
Layout.row: 1
|
|
||||||
Layout.column: 0
|
|
||||||
}
|
|
||||||
MyTextField {
|
|
||||||
text: MySettings.topP
|
|
||||||
color: theme.textColor
|
|
||||||
ToolTip.text: qsTr("Only the most likely tokens up to a total probability of top_p can be chosen.\nNOTE: Prevents choosing highly unlikely tokens, aka Nucleus Sampling")
|
|
||||||
ToolTip.visible: hovered
|
|
||||||
Layout.row: 1
|
|
||||||
Layout.column: 1
|
|
||||||
validator: DoubleValidator {
|
|
||||||
locale: "C"
|
|
||||||
}
|
|
||||||
onEditingFinished: {
|
|
||||||
var val = parseFloat(text)
|
|
||||||
if (!isNaN(val)) {
|
|
||||||
MySettings.topP = val
|
|
||||||
focus = false
|
|
||||||
} else {
|
|
||||||
text = MySettings.topP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Accessible.role: Accessible.EditableText
|
|
||||||
Accessible.name: topPLabel.text
|
|
||||||
Accessible.description: ToolTip.text
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: topKLabel
|
|
||||||
text: qsTr("Top K:")
|
|
||||||
color: theme.textColor
|
|
||||||
Layout.row: 2
|
|
||||||
Layout.column: 0
|
|
||||||
}
|
|
||||||
MyTextField {
|
|
||||||
text: MySettings.topK
|
|
||||||
color: theme.textColor
|
|
||||||
ToolTip.text: qsTr("Only the top K most likely tokens will be chosen from")
|
|
||||||
ToolTip.visible: hovered
|
|
||||||
Layout.row: 2
|
|
||||||
Layout.column: 1
|
|
||||||
validator: IntValidator {
|
|
||||||
bottom: 1
|
|
||||||
}
|
|
||||||
onEditingFinished: {
|
|
||||||
var val = parseInt(text)
|
|
||||||
if (!isNaN(val)) {
|
|
||||||
MySettings.topK = val
|
|
||||||
focus = false
|
|
||||||
} else {
|
|
||||||
text = MySettings.topK
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Accessible.role: Accessible.EditableText
|
|
||||||
Accessible.name: topKLabel.text
|
|
||||||
Accessible.description: ToolTip.text
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: maxLengthLabel
|
|
||||||
text: qsTr("Max Length:")
|
|
||||||
color: theme.textColor
|
|
||||||
Layout.row: 3
|
|
||||||
Layout.column: 0
|
|
||||||
}
|
|
||||||
MyTextField {
|
|
||||||
text: MySettings.maxLength
|
|
||||||
color: theme.textColor
|
|
||||||
ToolTip.text: qsTr("Maximum length of response in tokens")
|
|
||||||
ToolTip.visible: hovered
|
|
||||||
Layout.row: 3
|
|
||||||
Layout.column: 1
|
|
||||||
validator: IntValidator {
|
|
||||||
bottom: 1
|
|
||||||
}
|
|
||||||
onEditingFinished: {
|
|
||||||
var val = parseInt(text)
|
|
||||||
if (!isNaN(val)) {
|
|
||||||
MySettings.maxLength = val
|
|
||||||
focus = false
|
|
||||||
} else {
|
|
||||||
text = MySettings.maxLength
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Accessible.role: Accessible.EditableText
|
|
||||||
Accessible.name: maxLengthLabel.text
|
|
||||||
Accessible.description: ToolTip.text
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: batchSizeLabel
|
|
||||||
text: qsTr("Prompt Batch Size:")
|
|
||||||
color: theme.textColor
|
|
||||||
Layout.row: 4
|
|
||||||
Layout.column: 0
|
|
||||||
}
|
|
||||||
MyTextField {
|
|
||||||
text: MySettings.promptBatchSize
|
|
||||||
color: theme.textColor
|
|
||||||
ToolTip.text: qsTr("Amount of prompt tokens to process at once.\nNOTE: Higher values can speed up reading prompts but will use more RAM")
|
|
||||||
ToolTip.visible: hovered
|
|
||||||
Layout.row: 4
|
|
||||||
Layout.column: 1
|
|
||||||
validator: IntValidator {
|
|
||||||
bottom: 1
|
|
||||||
}
|
|
||||||
onEditingFinished: {
|
|
||||||
var val = parseInt(text)
|
|
||||||
if (!isNaN(val)) {
|
|
||||||
MySettings.promptBatchSize = val
|
|
||||||
focus = false
|
|
||||||
} else {
|
|
||||||
text = MySettings.promptBatchSize
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Accessible.role: Accessible.EditableText
|
|
||||||
Accessible.name: batchSizeLabel.text
|
|
||||||
Accessible.description: ToolTip.text
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: repeatPenaltyLabel
|
|
||||||
text: qsTr("Repeat Penalty:")
|
|
||||||
color: theme.textColor
|
|
||||||
Layout.row: 5
|
|
||||||
Layout.column: 0
|
|
||||||
}
|
|
||||||
MyTextField {
|
|
||||||
text: MySettings.repeatPenalty
|
|
||||||
color: theme.textColor
|
|
||||||
ToolTip.text: qsTr("Amount to penalize repetitiveness of the output")
|
|
||||||
ToolTip.visible: hovered
|
|
||||||
Layout.row: 5
|
|
||||||
Layout.column: 1
|
|
||||||
validator: DoubleValidator {
|
|
||||||
locale: "C"
|
|
||||||
}
|
|
||||||
onEditingFinished: {
|
|
||||||
var val = parseFloat(text)
|
|
||||||
if (!isNaN(val)) {
|
|
||||||
MySettings.repeatPenalty = val
|
|
||||||
focus = false
|
|
||||||
} else {
|
|
||||||
text = MySettings.repeatPenalty
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Accessible.role: Accessible.EditableText
|
|
||||||
Accessible.name: repeatPenaltyLabel.text
|
|
||||||
Accessible.description: ToolTip.text
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: repeatPenaltyTokensLabel
|
|
||||||
text: qsTr("Repeat Penalty Tokens:")
|
|
||||||
color: theme.textColor
|
|
||||||
Layout.row: 6
|
|
||||||
Layout.column: 0
|
|
||||||
}
|
|
||||||
MyTextField {
|
|
||||||
text: MySettings.repeatPenaltyTokens
|
|
||||||
color: theme.textColor
|
|
||||||
ToolTip.text: qsTr("How far back in output to apply repeat penalty")
|
|
||||||
ToolTip.visible: hovered
|
|
||||||
Layout.row: 6
|
|
||||||
Layout.column: 1
|
|
||||||
validator: IntValidator {
|
|
||||||
bottom: 1
|
|
||||||
}
|
|
||||||
onEditingFinished: {
|
|
||||||
var val = parseInt(text)
|
|
||||||
if (!isNaN(val)) {
|
|
||||||
MySettings.repeatPenaltyTokens = val
|
|
||||||
focus = false
|
|
||||||
} else {
|
|
||||||
text = MySettings.repeatPenaltyTokens
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Accessible.role: Accessible.EditableText
|
|
||||||
Accessible.name: repeatPenaltyTokensLabel.text
|
|
||||||
Accessible.description: ToolTip.text
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
Layout.row: 7
|
|
||||||
Layout.column: 0
|
|
||||||
Layout.topMargin: 10
|
|
||||||
Layout.alignment: Qt.AlignTop
|
|
||||||
spacing: 20
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: promptTemplateLabel
|
|
||||||
text: qsTr("Prompt Template:")
|
|
||||||
color: theme.textColor
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: promptTemplateLabelHelp
|
|
||||||
Layout.maximumWidth: promptTemplateLabel.width
|
|
||||||
visible: templateTextArea.text.indexOf(
|
|
||||||
"%1") === -1
|
|
||||||
color: theme.textErrorColor
|
|
||||||
text: qsTr("Must contain the string \"%1\" to be replaced with the user's input.")
|
|
||||||
wrapMode: TextArea.Wrap
|
|
||||||
Accessible.role: Accessible.EditableText
|
|
||||||
Accessible.name: text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
Layout.row: 7
|
|
||||||
Layout.column: 1
|
|
||||||
Layout.fillWidth: true
|
|
||||||
height: 200
|
|
||||||
color: "transparent"
|
|
||||||
clip: true
|
|
||||||
ScrollView {
|
|
||||||
id: templateScrollView
|
|
||||||
anchors.fill: parent
|
|
||||||
TextArea {
|
|
||||||
id: templateTextArea
|
|
||||||
text: MySettings.promptTemplate
|
|
||||||
color: theme.textColor
|
|
||||||
background: Rectangle {
|
|
||||||
implicitWidth: 150
|
|
||||||
color: theme.backgroundLighter
|
|
||||||
radius: 10
|
|
||||||
}
|
|
||||||
padding: 10
|
|
||||||
wrapMode: TextArea.Wrap
|
|
||||||
onTextChanged: {
|
|
||||||
if (templateTextArea.text.indexOf("%1") !== -1) {
|
|
||||||
MySettings.promptTemplate = text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bottomPadding: 10
|
|
||||||
Accessible.role: Accessible.EditableText
|
|
||||||
Accessible.name: promptTemplateLabel.text
|
|
||||||
Accessible.description: promptTemplateLabelHelp.text
|
|
||||||
ToolTip.text: qsTr("The prompt template partially determines how models will respond to prompts.\nNOTE: A longer, detailed template can lead to higher quality answers, but can also slow down generation.")
|
|
||||||
ToolTip.visible: hovered
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MyButton {
|
|
||||||
Layout.row: 8
|
|
||||||
Layout.column: 1
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: qsTr("Restore Defaults")
|
|
||||||
Accessible.description: qsTr("Restores the settings dialog to a default state")
|
|
||||||
onClicked: {
|
|
||||||
settingsDialog.restoreGenerationDefaults()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Item {
|
|
||||||
id: applicationSettingsTab
|
|
||||||
ScrollView {
|
|
||||||
background: Rectangle {
|
|
||||||
color: 'transparent'
|
|
||||||
border.color: theme.tabBorder
|
|
||||||
border.width: 1
|
|
||||||
radius: 2
|
|
||||||
}
|
|
||||||
padding: 10
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height - 30
|
|
||||||
contentWidth: availableWidth - 20
|
|
||||||
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
|
|
||||||
|
|
||||||
GridLayout {
|
ApplicationSettings {
|
||||||
anchors.margins: 10
|
|
||||||
columns: 3
|
|
||||||
rowSpacing: 10
|
|
||||||
columnSpacing: 10
|
|
||||||
anchors.fill: parent
|
|
||||||
Label {
|
|
||||||
id: defaultModelLabel
|
|
||||||
text: qsTr("Default model:")
|
|
||||||
color: theme.textColor
|
|
||||||
Layout.row: 1
|
|
||||||
Layout.column: 0
|
|
||||||
}
|
|
||||||
MyComboBox {
|
|
||||||
id: comboBox
|
|
||||||
Layout.row: 1
|
|
||||||
Layout.column: 1
|
|
||||||
Layout.minimumWidth: 350
|
|
||||||
model: ModelList.userDefaultModelList
|
|
||||||
Accessible.role: Accessible.ComboBox
|
|
||||||
Accessible.name: qsTr("ComboBox for displaying/picking the default model")
|
|
||||||
Accessible.description: qsTr("Use this for picking the default model to use; the first item is the current default model")
|
|
||||||
function updateModel() {
|
|
||||||
comboBox.currentIndex = comboBox.indexOfValue(MySettings.userDefaultModel);
|
|
||||||
}
|
|
||||||
Component.onCompleted: {
|
|
||||||
comboBox.updateModel()
|
|
||||||
}
|
|
||||||
Connections {
|
|
||||||
target: MySettings
|
|
||||||
function onUserDefaultModelChanged() {
|
|
||||||
comboBox.updateModel()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onActivated: {
|
|
||||||
MySettings.userDefaultModel = comboBox.currentText
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FolderDialog {
|
|
||||||
id: modelPathDialog
|
|
||||||
title: "Please choose a directory"
|
|
||||||
currentFolder: "file://" + MySettings.modelPath
|
|
||||||
onAccepted: {
|
|
||||||
MySettings.modelPath = selectedFolder
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: modelPathLabel
|
|
||||||
text: qsTr("Download path:")
|
|
||||||
color: theme.textColor
|
|
||||||
Layout.row: 2
|
|
||||||
Layout.column: 0
|
|
||||||
}
|
|
||||||
MyDirectoryField {
|
|
||||||
id: modelPathDisplayField
|
|
||||||
text: MySettings.modelPath
|
|
||||||
implicitWidth: 300
|
|
||||||
Layout.row: 2
|
|
||||||
Layout.column: 1
|
|
||||||
Layout.fillWidth: true
|
|
||||||
ToolTip.text: qsTr("Path where model files will be downloaded to")
|
|
||||||
ToolTip.visible: hovered
|
|
||||||
Accessible.role: Accessible.ToolTip
|
|
||||||
Accessible.name: modelPathDisplayField.text
|
|
||||||
Accessible.description: ToolTip.text
|
|
||||||
onEditingFinished: {
|
|
||||||
if (isValid) {
|
|
||||||
MySettings.modelPath = modelPathDisplayField.text
|
|
||||||
} else {
|
|
||||||
text = MySettings.modelPath
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MyButton {
|
|
||||||
Layout.row: 2
|
|
||||||
Layout.column: 2
|
|
||||||
text: qsTr("Browse")
|
|
||||||
Accessible.description: qsTr("Opens a folder picker dialog to choose where to save model files")
|
|
||||||
onClicked: modelPathDialog.open()
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: nThreadsLabel
|
|
||||||
text: qsTr("CPU Threads:")
|
|
||||||
color: theme.textColor
|
|
||||||
Layout.row: 3
|
|
||||||
Layout.column: 0
|
|
||||||
}
|
|
||||||
MyTextField {
|
|
||||||
text: MySettings.threadCount
|
|
||||||
color: theme.textColor
|
|
||||||
ToolTip.text: qsTr("Amount of processing threads to use, a setting of 0 will use the lesser of 4 or your number of CPU threads")
|
|
||||||
ToolTip.visible: hovered
|
|
||||||
Layout.row: 3
|
|
||||||
Layout.column: 1
|
|
||||||
validator: IntValidator {
|
|
||||||
bottom: 1
|
|
||||||
}
|
|
||||||
onEditingFinished: {
|
|
||||||
var val = parseInt(text)
|
|
||||||
if (!isNaN(val)) {
|
|
||||||
MySettings.threadCount = val
|
|
||||||
focus = false
|
|
||||||
} else {
|
|
||||||
text = MySettings.threadCount
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Accessible.role: Accessible.EditableText
|
|
||||||
Accessible.name: nThreadsLabel.text
|
|
||||||
Accessible.description: ToolTip.text
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: saveChatsLabel
|
|
||||||
text: qsTr("Save chats to disk:")
|
|
||||||
color: theme.textColor
|
|
||||||
Layout.row: 4
|
|
||||||
Layout.column: 0
|
|
||||||
}
|
|
||||||
MyCheckBox {
|
|
||||||
id: saveChatsBox
|
|
||||||
Layout.row: 4
|
|
||||||
Layout.column: 1
|
|
||||||
checked: MySettings.saveChats
|
|
||||||
onClicked: {
|
|
||||||
Network.sendSaveChatsToggled(saveChatsBox.checked);
|
|
||||||
MySettings.saveChats = !MySettings.saveChats
|
|
||||||
}
|
|
||||||
ToolTip.text: qsTr("WARNING: Saving chats to disk can be ~2GB per chat")
|
|
||||||
ToolTip.visible: hovered
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: saveChatGPTChatsLabel
|
|
||||||
text: qsTr("Save ChatGPT chats to disk:")
|
|
||||||
color: theme.textColor
|
|
||||||
Layout.row: 5
|
|
||||||
Layout.column: 0
|
|
||||||
}
|
|
||||||
MyCheckBox {
|
|
||||||
id: saveChatGPTChatsBox
|
|
||||||
Layout.row: 5
|
|
||||||
Layout.column: 1
|
|
||||||
checked: MySettings.saveChatGPTChats
|
|
||||||
onClicked: {
|
|
||||||
MySettings.saveChatGPTChats = !MySettings.saveChatGPTChats
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: serverChatLabel
|
|
||||||
text: qsTr("Enable API server:")
|
|
||||||
color: theme.textColor
|
|
||||||
Layout.row: 6
|
|
||||||
Layout.column: 0
|
|
||||||
}
|
|
||||||
MyCheckBox {
|
|
||||||
id: serverChatBox
|
|
||||||
Layout.row: 6
|
|
||||||
Layout.column: 1
|
|
||||||
checked: MySettings.serverChat
|
|
||||||
onClicked: {
|
|
||||||
MySettings.serverChat = !MySettings.serverChat
|
|
||||||
}
|
|
||||||
ToolTip.text: qsTr("WARNING: This enables the gui to act as a local REST web server(OpenAI API compliant) for API requests and will increase your RAM usage as well")
|
|
||||||
ToolTip.visible: hovered
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
Layout.row: 7
|
|
||||||
Layout.column: 0
|
|
||||||
Layout.columnSpan: 3
|
|
||||||
Layout.fillWidth: true
|
|
||||||
height: 1
|
|
||||||
color: theme.dialogBorder
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
Layout.row: 9
|
|
||||||
Layout.column: 0
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.columnSpan: 3
|
|
||||||
height: 1
|
|
||||||
color: theme.dialogBorder
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: gpuOverrideLabel
|
|
||||||
text: qsTr("Force Metal (macOS+arm):")
|
|
||||||
color: theme.textColor
|
|
||||||
Layout.row: 8
|
|
||||||
Layout.column: 0
|
|
||||||
}
|
|
||||||
RowLayout {
|
|
||||||
Layout.row: 8
|
|
||||||
Layout.column: 1
|
|
||||||
Layout.columnSpan: 2
|
|
||||||
MyCheckBox {
|
|
||||||
id: gpuOverrideBox
|
|
||||||
checked: MySettings.forceMetal
|
|
||||||
onClicked: {
|
|
||||||
MySettings.forceMetal = !MySettings.forceMetal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Label {
|
|
||||||
id: warningLabel
|
|
||||||
Layout.maximumWidth: 730
|
|
||||||
Layout.alignment: Qt.AlignTop
|
|
||||||
color: theme.textErrorColor
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
text: qsTr("WARNING: On macOS with arm (M1+) this setting forces usage of the GPU. Can cause crashes if the model requires more RAM than the system supports. Because of crash possibility the setting will not persist across restarts of the application. This has no effect on non-macs or intel.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MyButton {
|
|
||||||
Layout.row: 10
|
|
||||||
Layout.column: 1
|
|
||||||
Layout.columnSpan: 2
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: qsTr("Restore Defaults")
|
|
||||||
Accessible.description: qsTr("Restores the settings dialog to a default state")
|
|
||||||
onClicked: {
|
|
||||||
settingsDialog.restoreApplicationDefaults()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Item {
|
|
||||||
id: localDocsTab
|
|
||||||
ScrollView {
|
|
||||||
background: Rectangle {
|
|
||||||
color: 'transparent'
|
|
||||||
border.color: theme.tabBorder
|
|
||||||
border.width: 1
|
|
||||||
radius: 2
|
|
||||||
}
|
|
||||||
padding: 10
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height - 30
|
|
||||||
contentWidth: availableWidth - 20
|
|
||||||
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
|
|
||||||
|
|
||||||
LocalDocs {
|
LocalDocsSettings {
|
||||||
anchors.margins: 10
|
|
||||||
anchors.fill: parent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user