mirror of
https://github.com/nomic-ai/gpt4all.git
synced 2025-09-12 14:01:38 +00:00
Huge change that completely revamps the settings dialog and implements
per model settings as well as the ability to clone a model into a "character." This also implements system prompts as well as quite a few bugfixes for instance this fixes chatgpt.
This commit is contained in:
@@ -6,8 +6,12 @@ import QtQuick.Layouts
|
||||
import QtQuick.Dialogs
|
||||
import modellist
|
||||
import mysettings
|
||||
import network
|
||||
|
||||
MySettingsTab {
|
||||
onRestoreDefaultsClicked: {
|
||||
MySettings.restoreApplicationDefaults();
|
||||
}
|
||||
title: qsTr("Application")
|
||||
contentItem: GridLayout {
|
||||
id: applicationSettingsTabInner
|
||||
@@ -26,7 +30,9 @@ MySettingsTab {
|
||||
id: comboBox
|
||||
Layout.row: 1
|
||||
Layout.column: 1
|
||||
Layout.columnSpan: 2
|
||||
Layout.minimumWidth: 350
|
||||
Layout.fillWidth: true
|
||||
model: ModelList.userDefaultModelList
|
||||
Accessible.role: Accessible.ComboBox
|
||||
Accessible.name: qsTr("ComboBox for displaying/picking the default model")
|
||||
@@ -178,25 +184,30 @@ MySettingsTab {
|
||||
Layout.columnSpan: 3
|
||||
Layout.fillWidth: true
|
||||
height: 1
|
||||
color: theme.dialogBorder
|
||||
color: theme.tabBorder
|
||||
}
|
||||
}
|
||||
advancedSettings: GridLayout {
|
||||
columns: 3
|
||||
rowSpacing: 10
|
||||
columnSpacing: 10
|
||||
Rectangle {
|
||||
Layout.row: 9
|
||||
Layout.row: 2
|
||||
Layout.column: 0
|
||||
Layout.fillWidth: true
|
||||
Layout.columnSpan: 3
|
||||
height: 1
|
||||
color: theme.dialogBorder
|
||||
color: theme.tabBorder
|
||||
}
|
||||
Label {
|
||||
id: gpuOverrideLabel
|
||||
text: qsTr("Force Metal (macOS+arm):")
|
||||
color: theme.textColor
|
||||
Layout.row: 8
|
||||
Layout.row: 1
|
||||
Layout.column: 0
|
||||
}
|
||||
RowLayout {
|
||||
Layout.row: 8
|
||||
Layout.row: 1
|
||||
Layout.column: 1
|
||||
Layout.columnSpan: 2
|
||||
MyCheckBox {
|
||||
@@ -206,24 +217,18 @@ MySettingsTab {
|
||||
MySettings.forceMetal = !MySettings.forceMetal
|
||||
}
|
||||
}
|
||||
Label {
|
||||
id: warningLabel
|
||||
Layout.maximumWidth: 730
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
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();
|
||||
Layout.minimumHeight: warningLabel.height
|
||||
Label {
|
||||
id: warningLabel
|
||||
width: parent.width
|
||||
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.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,302 +0,0 @@
|
||||
import QtCore
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import QtQuick.Layouts
|
||||
import localdocs
|
||||
import mysettings
|
||||
|
||||
MySettingsTab {
|
||||
title: qsTr("Presets")
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -6,8 +6,13 @@ import QtQuick.Layouts
|
||||
import QtQuick.Dialogs
|
||||
import localdocs
|
||||
import mysettings
|
||||
import network
|
||||
|
||||
MySettingsTab {
|
||||
onRestoreDefaultsClicked: {
|
||||
MySettings.restoreLocalDocsDefaults();
|
||||
}
|
||||
|
||||
title: qsTr("LocalDocs Plugin (BETA)")
|
||||
contentItem: ColumnLayout {
|
||||
id: root
|
||||
@@ -25,101 +30,95 @@ MySettingsTab {
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Item {
|
||||
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();
|
||||
height: row.height
|
||||
RowLayout {
|
||||
id: row
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
height: collection.height
|
||||
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
|
||||
}
|
||||
if (root.folder_path === "" || !folderEdit.isValid) {
|
||||
isError = true;
|
||||
folderEdit.showError();
|
||||
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()
|
||||
}
|
||||
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: 10
|
||||
clip: true
|
||||
contentHeight: 300
|
||||
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
|
||||
|
||||
background: Rectangle {
|
||||
color: theme.backgroundLighter
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
ColumnLayout {
|
||||
spacing: 0
|
||||
Repeater {
|
||||
model: LocalDocs.localDocsModel
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
delegate: Rectangle {
|
||||
id: item
|
||||
width: listView.width
|
||||
Layout.fillWidth: true
|
||||
height: buttons.height + 20
|
||||
color: index % 2 === 0 ? theme.backgroundLight : theme.backgroundLighter
|
||||
color: index % 2 === 0 ? theme.backgroundDark : theme.backgroundDarker
|
||||
property bool removing: false
|
||||
|
||||
Text {
|
||||
@@ -136,6 +135,7 @@ MySettingsTab {
|
||||
Text {
|
||||
id: folderId
|
||||
anchors.left: collectionId.right
|
||||
anchors.right: buttons.left
|
||||
anchors.margins: 20
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: folder_path
|
||||
@@ -170,124 +170,99 @@ MySettingsTab {
|
||||
}
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
id: gridLayout
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
columns: 3
|
||||
rowSpacing: 10
|
||||
columnSpacing: 10
|
||||
height: 1
|
||||
color: theme.tabBorder
|
||||
}
|
||||
}
|
||||
advancedSettings: GridLayout {
|
||||
id: gridLayout
|
||||
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.tabBorder
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
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:")
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
onEditingFinished: {
|
||||
var val = parseInt(text)
|
||||
if (!isNaN(val)) {
|
||||
MySettings.localDocsRetrievalSize = val
|
||||
focus = false
|
||||
} else {
|
||||
text = MySettings.localDocsRetrievalSize
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.row: 1
|
||||
Layout.column: 2
|
||||
Layout.rowSpan: 2
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Layout.minimumHeight: warningLabel.height
|
||||
Label {
|
||||
id: warningLabel
|
||||
Layout.row: 1
|
||||
Layout.column: 2
|
||||
Layout.rowSpan: 2
|
||||
Layout.maximumWidth: 520
|
||||
Layout.alignment: Qt.AlignTop
|
||||
width: parent.width
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -83,7 +83,7 @@ Dialog {
|
||||
|
||||
Text {
|
||||
textFormat: Text.StyledText
|
||||
text: "<h2>" + (name !== "" ? name : filename) + "</h2>"
|
||||
text: "<h2>" + name + "</h2>"
|
||||
Layout.row: 0
|
||||
Layout.column: 0
|
||||
Layout.topMargin: 20
|
||||
@@ -329,12 +329,14 @@ Dialog {
|
||||
Layout.topMargin: 20
|
||||
Layout.leftMargin: 20
|
||||
Layout.minimumWidth: 150
|
||||
Layout.maximumWidth: textMetrics.width + 25
|
||||
Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
|
||||
color: theme.textColor
|
||||
background: Rectangle {
|
||||
color: theme.backgroundLighter
|
||||
radius: 10
|
||||
}
|
||||
wrapMode: Text.WrapAnywhere
|
||||
function showError() {
|
||||
openaiKey.placeholderTextColor = theme.textErrorColor
|
||||
}
|
||||
@@ -346,6 +348,11 @@ Dialog {
|
||||
Accessible.role: Accessible.EditableText
|
||||
Accessible.name: placeholderText
|
||||
Accessible.description: qsTr("Whether the file hash is being calculated")
|
||||
TextMetrics {
|
||||
id: textMetrics
|
||||
font: openaiKey.font
|
||||
text: openaiKey.placeholderText
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,27 +3,665 @@ import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Basic
|
||||
import QtQuick.Layouts
|
||||
import localdocs
|
||||
import modellist
|
||||
import mysettings
|
||||
|
||||
MySettingsTab {
|
||||
title: qsTr("Models")
|
||||
onRestoreDefaultsClicked: {
|
||||
MySettings.restoreModelDefaults(root.currentModelInfo);
|
||||
}
|
||||
title: qsTr("Model/Character Settings")
|
||||
contentItem: GridLayout {
|
||||
id: generationSettingsTabInner
|
||||
columns: 2
|
||||
id: root
|
||||
columns: 3
|
||||
rowSpacing: 10
|
||||
columnSpacing: 10
|
||||
|
||||
MyButton {
|
||||
Layout.row: 8
|
||||
Layout.column: 1
|
||||
property var currentModelName: comboBox.currentText
|
||||
property var currentModelId: comboBox.currentValue
|
||||
property var currentModelInfo: ModelList.modelInfo(root.currentModelId)
|
||||
|
||||
Label {
|
||||
id: label
|
||||
Layout.row: 0
|
||||
Layout.column: 0
|
||||
text: qsTr("Model/Character:")
|
||||
color: theme.textColor
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
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
|
||||
Layout.row: 1
|
||||
Layout.column: 0
|
||||
Layout.columnSpan: 2
|
||||
height: label.height + 20
|
||||
spacing: 10
|
||||
|
||||
MyComboBox {
|
||||
id: comboBox
|
||||
Layout.fillWidth: true
|
||||
model: ModelList.installedModels
|
||||
valueRole: "id"
|
||||
textRole: "name"
|
||||
currentIndex: 0
|
||||
contentItem: Text {
|
||||
leftPadding: 10
|
||||
rightPadding: 20
|
||||
text: comboBox.currentText
|
||||
font: comboBox.font
|
||||
color: theme.textColor
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
delegate: ItemDelegate {
|
||||
width: comboBox.width
|
||||
contentItem: Text {
|
||||
text: name
|
||||
color: theme.textColor
|
||||
font: comboBox.font
|
||||
elide: Text.ElideRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
background: Rectangle {
|
||||
color: highlighted ? theme.backgroundLight : theme.backgroundDark
|
||||
}
|
||||
highlighted: comboBox.highlightedIndex === index
|
||||
}
|
||||
}
|
||||
|
||||
MyButton {
|
||||
id: cloneButton
|
||||
text: qsTr("Clone")
|
||||
onClicked: {
|
||||
var id = ModelList.clone(root.currentModelInfo);
|
||||
comboBox.currentIndex = comboBox.indexOfValue(id);
|
||||
}
|
||||
}
|
||||
|
||||
MyButton {
|
||||
id: removeButton
|
||||
enabled: root.currentModelInfo.isClone
|
||||
text: qsTr("Remove")
|
||||
onClicked: {
|
||||
ModelList.remove(root.currentModelInfo);
|
||||
comboBox.currentIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.row: 2
|
||||
Layout.column: 0
|
||||
Layout.topMargin: 15
|
||||
spacing: 10
|
||||
Label {
|
||||
id: uniqueNameLabel
|
||||
text: qsTr("Unique Name:")
|
||||
color: theme.textColor
|
||||
}
|
||||
Label {
|
||||
id: uniqueNameLabelHelp
|
||||
visible: false
|
||||
text: qsTr("Must contain a non-empty unique name that does not match any existing model/character.")
|
||||
color: theme.textErrorColor
|
||||
wrapMode: TextArea.Wrap
|
||||
}
|
||||
}
|
||||
|
||||
MyTextField {
|
||||
id: uniqueNameField
|
||||
text: root.currentModelName
|
||||
enabled: root.currentModelInfo.isClone || root.currentModelInfo.description === ""
|
||||
color: enabled ? theme.textColor : theme.mutedTextColor
|
||||
Layout.row: 3
|
||||
Layout.column: 0
|
||||
Layout.columnSpan: 2
|
||||
Layout.fillWidth: true
|
||||
Connections {
|
||||
target: MySettings
|
||||
function onNameChanged() {
|
||||
uniqueNameField.text = root.currentModelInfo.name;
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: root
|
||||
function onCurrentModelInfoChanged() {
|
||||
uniqueNameField.text = root.currentModelInfo.name;
|
||||
}
|
||||
}
|
||||
onTextChanged: {
|
||||
if (text !== "" && ModelList.isUniqueName(text)) {
|
||||
MySettings.setModelName(root.currentModelInfo, text);
|
||||
}
|
||||
uniqueNameLabelHelp.visible = root.currentModelInfo.name !== "" &&
|
||||
(text === "" || (text !== root.currentModelInfo.name && !ModelList.isUniqueName(text)));
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Model File:")
|
||||
color: theme.textColor
|
||||
Layout.row: 4
|
||||
Layout.column: 0
|
||||
Layout.topMargin: 15
|
||||
}
|
||||
|
||||
MyTextField {
|
||||
text: root.currentModelInfo.filename
|
||||
enabled: false
|
||||
color: enabled ? theme.textColor : theme.mutedTextColor
|
||||
Layout.row: 5
|
||||
Layout.column: 0
|
||||
Layout.columnSpan: 2
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Label {
|
||||
visible: !root.currentModelInfo.isChatGPT
|
||||
text: qsTr("System Prompt:")
|
||||
color: theme.textColor
|
||||
Layout.row: 6
|
||||
Layout.column: 0
|
||||
Layout.topMargin: 15
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: systemPrompt
|
||||
visible: !root.currentModelInfo.isChatGPT
|
||||
Layout.row: 7
|
||||
Layout.column: 0
|
||||
Layout.columnSpan: 2
|
||||
Layout.fillWidth: true
|
||||
color: "transparent"
|
||||
Layout.minimumHeight: Math.max(150, systemPromptArea.contentHeight + 20)
|
||||
TextArea {
|
||||
id: systemPromptArea
|
||||
anchors.fill: parent
|
||||
text: root.currentModelInfo.systemPrompt
|
||||
color: theme.textColor
|
||||
background: Rectangle {
|
||||
implicitWidth: 150
|
||||
color: theme.backgroundDark
|
||||
radius: 10
|
||||
}
|
||||
padding: 10
|
||||
wrapMode: TextArea.Wrap
|
||||
Connections {
|
||||
target: MySettings
|
||||
function onSystemPromptChanged() {
|
||||
systemPromptArea.text = root.currentModelInfo.systemPrompt;
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: root
|
||||
function onCurrentModelInfoChanged() {
|
||||
systemPromptArea.text = root.currentModelInfo.systemPrompt;
|
||||
}
|
||||
}
|
||||
onTextChanged: {
|
||||
MySettings.setModelSystemPrompt(root.currentModelInfo, text)
|
||||
}
|
||||
bottomPadding: 10
|
||||
Accessible.role: Accessible.EditableText
|
||||
ToolTip.text: qsTr("The systemPrompt allows instructions to the model at the beginning of a chat.\nNOTE: A longer, detailed system prompt can lead to higher quality answers, but can also slow down generation.")
|
||||
ToolTip.visible: hovered
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.row: 8
|
||||
Layout.column: 0
|
||||
Layout.columnSpan: 2
|
||||
Layout.topMargin: 15
|
||||
spacing: 10
|
||||
Label {
|
||||
id: promptTemplateLabel
|
||||
text: qsTr("Prompt Template:")
|
||||
color: theme.textColor
|
||||
}
|
||||
Label {
|
||||
id: promptTemplateLabelHelp
|
||||
text: qsTr("Must contain the string \"%1\" to be replaced with the user's input.")
|
||||
color: theme.textErrorColor
|
||||
visible: templateTextArea.text.indexOf("%1") === -1
|
||||
wrapMode: TextArea.Wrap
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: promptTemplate
|
||||
Layout.row: 9
|
||||
Layout.column: 0
|
||||
Layout.columnSpan: 2
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumHeight: Math.max(150, templateTextArea.contentHeight + 20)
|
||||
color: "transparent"
|
||||
clip: true
|
||||
TextArea {
|
||||
id: templateTextArea
|
||||
anchors.fill: parent
|
||||
text: root.currentModelInfo.promptTemplate
|
||||
color: theme.textColor
|
||||
background: Rectangle {
|
||||
implicitWidth: 150
|
||||
color: theme.backgroundDark
|
||||
radius: 10
|
||||
}
|
||||
padding: 10
|
||||
wrapMode: TextArea.Wrap
|
||||
Connections {
|
||||
target: MySettings
|
||||
function onPromptTemplateChanged() {
|
||||
templateTextArea.text = root.currentModelInfo.promptTemplate;
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: root
|
||||
function onCurrentModelInfoChanged() {
|
||||
templateTextArea.text = root.currentModelInfo.promptTemplate;
|
||||
}
|
||||
}
|
||||
onTextChanged: {
|
||||
if (templateTextArea.text.indexOf("%1") !== -1) {
|
||||
MySettings.setModelPromptTemplate(root.currentModelInfo, 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
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: optionalImageRect
|
||||
visible: false // FIXME: for later
|
||||
Layout.row: 2
|
||||
Layout.column: 1
|
||||
Layout.rowSpan: 5
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.fillHeight: true
|
||||
Layout.maximumWidth: height
|
||||
Layout.topMargin: 35
|
||||
Layout.bottomMargin: 35
|
||||
Layout.leftMargin: 35
|
||||
width: 3000
|
||||
border.width: 1
|
||||
border.color: theme.tabBorder
|
||||
radius: 10
|
||||
color: "transparent"
|
||||
Item {
|
||||
anchors.centerIn: parent
|
||||
height: childrenRect.height
|
||||
Image {
|
||||
id: img
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 100
|
||||
height: 100
|
||||
source: "qrc:/gpt4all/icons/image.svg"
|
||||
}
|
||||
Text {
|
||||
text: qsTr("Add\noptional image")
|
||||
anchors.top: img.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
wrapMode: TextArea.Wrap
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
color: theme.mutedTextColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Generation Settings")
|
||||
color: theme.textColor
|
||||
Layout.row: 10
|
||||
Layout.column: 0
|
||||
Layout.columnSpan: 2
|
||||
Layout.topMargin: 15
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.minimumWidth: promptTemplate.width
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
font.pixelSize: theme.fontSizeLarger
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
Layout.row: 11
|
||||
Layout.column: 0
|
||||
Layout.columnSpan: 2
|
||||
Layout.topMargin: 15
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: promptTemplate.width
|
||||
columns: 4
|
||||
rowSpacing: 10
|
||||
columnSpacing: 10
|
||||
|
||||
Label {
|
||||
id: tempLabel
|
||||
text: qsTr("Temperature:")
|
||||
color: theme.textColor
|
||||
Layout.row: 0
|
||||
Layout.column: 0
|
||||
}
|
||||
|
||||
MyTextField {
|
||||
id: temperatureField
|
||||
text: root.currentModelInfo.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"
|
||||
}
|
||||
Connections {
|
||||
target: MySettings
|
||||
function onTemperatureChanged() {
|
||||
temperatureField.text = root.currentModelInfo.temperature;
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: root
|
||||
function onCurrentModelInfoChanged() {
|
||||
temperatureField.text = root.currentModelInfo.temperature;
|
||||
}
|
||||
}
|
||||
onEditingFinished: {
|
||||
var val = parseFloat(text)
|
||||
if (!isNaN(val)) {
|
||||
MySettings.setModelTemperature(root.currentModelInfo, val)
|
||||
focus = false
|
||||
} else {
|
||||
text = root.currentModelInfo.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: 0
|
||||
Layout.column: 2
|
||||
}
|
||||
MyTextField {
|
||||
id: topPField
|
||||
text: root.currentModelInfo.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: 0
|
||||
Layout.column: 3
|
||||
validator: DoubleValidator {
|
||||
locale: "C"
|
||||
}
|
||||
Connections {
|
||||
target: MySettings
|
||||
function onTopPChanged() {
|
||||
topPField.text = root.currentModelInfo.topP;
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: root
|
||||
function onCurrentModelInfoChanged() {
|
||||
topPField.text = root.currentModelInfo.topP;
|
||||
}
|
||||
}
|
||||
onEditingFinished: {
|
||||
var val = parseFloat(text)
|
||||
if (!isNaN(val)) {
|
||||
MySettings.setModelTopP(root.currentModelInfo, val)
|
||||
focus = false
|
||||
} else {
|
||||
text = root.currentModelInfo.topP
|
||||
}
|
||||
}
|
||||
Accessible.role: Accessible.EditableText
|
||||
Accessible.name: topPLabel.text
|
||||
Accessible.description: ToolTip.text
|
||||
}
|
||||
Label {
|
||||
id: topKLabel
|
||||
visible: !root.currentModelInfo.isChatGPT
|
||||
text: qsTr("Top K:")
|
||||
color: theme.textColor
|
||||
Layout.row: 1
|
||||
Layout.column: 0
|
||||
}
|
||||
MyTextField {
|
||||
id: topKField
|
||||
visible: !root.currentModelInfo.isChatGPT
|
||||
text: root.currentModelInfo.topK
|
||||
color: theme.textColor
|
||||
ToolTip.text: qsTr("Only the top K most likely tokens will be chosen from")
|
||||
ToolTip.visible: hovered
|
||||
Layout.row: 1
|
||||
Layout.column: 1
|
||||
validator: IntValidator {
|
||||
bottom: 1
|
||||
}
|
||||
Connections {
|
||||
target: MySettings
|
||||
function onTopKChanged() {
|
||||
topKField.text = root.currentModelInfo.topK;
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: root
|
||||
function onCurrentModelInfoChanged() {
|
||||
topKField.text = root.currentModelInfo.topK;
|
||||
}
|
||||
}
|
||||
onEditingFinished: {
|
||||
var val = parseInt(text)
|
||||
if (!isNaN(val)) {
|
||||
MySettings.setModelTopK(root.currentModelInfo, val)
|
||||
focus = false
|
||||
} else {
|
||||
text = root.currentModelInfo.topK
|
||||
}
|
||||
}
|
||||
Accessible.role: Accessible.EditableText
|
||||
Accessible.name: topKLabel.text
|
||||
Accessible.description: ToolTip.text
|
||||
}
|
||||
Label {
|
||||
id: maxLengthLabel
|
||||
visible: !root.currentModelInfo.isChatGPT
|
||||
text: qsTr("Max Length:")
|
||||
color: theme.textColor
|
||||
Layout.row: 1
|
||||
Layout.column: 2
|
||||
}
|
||||
MyTextField {
|
||||
id: maxLengthField
|
||||
visible: !root.currentModelInfo.isChatGPT
|
||||
text: root.currentModelInfo.maxLength
|
||||
color: theme.textColor
|
||||
ToolTip.text: qsTr("Maximum length of response in tokens")
|
||||
ToolTip.visible: hovered
|
||||
Layout.row: 1
|
||||
Layout.column: 3
|
||||
validator: IntValidator {
|
||||
bottom: 1
|
||||
}
|
||||
Connections {
|
||||
target: MySettings
|
||||
function onMaxLengthChanged() {
|
||||
maxLengthField.text = root.currentModelInfo.maxLength;
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: root
|
||||
function onCurrentModelInfoChanged() {
|
||||
maxLengthField.text = root.currentModelInfo.maxLength;
|
||||
}
|
||||
}
|
||||
onEditingFinished: {
|
||||
var val = parseInt(text)
|
||||
if (!isNaN(val)) {
|
||||
MySettings.setModelMaxLength(root.currentModelInfo, val)
|
||||
focus = false
|
||||
} else {
|
||||
text = root.currentModelInfo.maxLength
|
||||
}
|
||||
}
|
||||
Accessible.role: Accessible.EditableText
|
||||
Accessible.name: maxLengthLabel.text
|
||||
Accessible.description: ToolTip.text
|
||||
}
|
||||
|
||||
Label {
|
||||
id: batchSizeLabel
|
||||
visible: !root.currentModelInfo.isChatGPT
|
||||
text: qsTr("Prompt Batch Size:")
|
||||
color: theme.textColor
|
||||
Layout.row: 2
|
||||
Layout.column: 0
|
||||
}
|
||||
MyTextField {
|
||||
id: batchSizeField
|
||||
visible: !root.currentModelInfo.isChatGPT
|
||||
text: root.currentModelInfo.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: 2
|
||||
Layout.column: 1
|
||||
validator: IntValidator {
|
||||
bottom: 1
|
||||
}
|
||||
Connections {
|
||||
target: MySettings
|
||||
function onPromptBatchSizeChanged() {
|
||||
batchSizeField.text = root.currentModelInfo.promptBatchSize;
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: root
|
||||
function onCurrentModelInfoChanged() {
|
||||
batchSizeField.text = root.currentModelInfo.promptBatchSize;
|
||||
}
|
||||
}
|
||||
onEditingFinished: {
|
||||
var val = parseInt(text)
|
||||
if (!isNaN(val)) {
|
||||
MySettings.setModelPromptBatchSize(root.currentModelInfo, val)
|
||||
focus = false
|
||||
} else {
|
||||
text = root.currentModelInfo.promptBatchSize
|
||||
}
|
||||
}
|
||||
Accessible.role: Accessible.EditableText
|
||||
Accessible.name: batchSizeLabel.text
|
||||
Accessible.description: ToolTip.text
|
||||
}
|
||||
Label {
|
||||
id: repeatPenaltyLabel
|
||||
visible: !root.currentModelInfo.isChatGPT
|
||||
text: qsTr("Repeat Penalty:")
|
||||
color: theme.textColor
|
||||
Layout.row: 2
|
||||
Layout.column: 2
|
||||
}
|
||||
MyTextField {
|
||||
id: repeatPenaltyField
|
||||
visible: !root.currentModelInfo.isChatGPT
|
||||
text: root.currentModelInfo.repeatPenalty
|
||||
color: theme.textColor
|
||||
ToolTip.text: qsTr("Amount to penalize repetitiveness of the output")
|
||||
ToolTip.visible: hovered
|
||||
Layout.row: 2
|
||||
Layout.column: 3
|
||||
validator: DoubleValidator {
|
||||
locale: "C"
|
||||
}
|
||||
Connections {
|
||||
target: MySettings
|
||||
function onRepeatPenaltyChanged() {
|
||||
repeatPenaltyField.text = root.currentModelInfo.repeatPenalty;
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: root
|
||||
function onCurrentModelInfoChanged() {
|
||||
repeatPenaltyField.text = root.currentModelInfo.repeatPenalty;
|
||||
}
|
||||
}
|
||||
onEditingFinished: {
|
||||
var val = parseFloat(text)
|
||||
if (!isNaN(val)) {
|
||||
MySettings.setModelRepeatPenalty(root.currentModelInfo, val)
|
||||
focus = false
|
||||
} else {
|
||||
text = root.currentModelInfo.repeatPenalty
|
||||
}
|
||||
}
|
||||
Accessible.role: Accessible.EditableText
|
||||
Accessible.name: repeatPenaltyLabel.text
|
||||
Accessible.description: ToolTip.text
|
||||
}
|
||||
Label {
|
||||
id: repeatPenaltyTokensLabel
|
||||
visible: !root.currentModelInfo.isChatGPT
|
||||
text: qsTr("Repeat Penalty Tokens:")
|
||||
color: theme.textColor
|
||||
Layout.row: 3
|
||||
Layout.column: 0
|
||||
}
|
||||
MyTextField {
|
||||
id: repeatPenaltyTokenField
|
||||
visible: !root.currentModelInfo.isChatGPT
|
||||
text: root.currentModelInfo.repeatPenaltyTokens
|
||||
color: theme.textColor
|
||||
ToolTip.text: qsTr("How far back in output to apply repeat penalty")
|
||||
ToolTip.visible: hovered
|
||||
Layout.row: 3
|
||||
Layout.column: 1
|
||||
validator: IntValidator {
|
||||
bottom: 1
|
||||
}
|
||||
Connections {
|
||||
target: MySettings
|
||||
function onRepeatPenaltyTokensChanged() {
|
||||
repeatPenaltyTokenField.text = root.currentModelInfo.repeatPenaltyTokens;
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: root
|
||||
function onCurrentModelInfoChanged() {
|
||||
repeatPenaltyTokenField.text = root.currentModelInfo.repeatPenaltyTokens;
|
||||
}
|
||||
}
|
||||
onEditingFinished: {
|
||||
var val = parseInt(text)
|
||||
if (!isNaN(val)) {
|
||||
MySettings.setModelRepeatPenaltyTokens(root.currentModelInfo, val)
|
||||
focus = false
|
||||
} else {
|
||||
text = root.currentModelInfo.repeatPenaltyTokens
|
||||
}
|
||||
}
|
||||
Accessible.role: Accessible.EditableText
|
||||
Accessible.name: repeatPenaltyTokensLabel.text
|
||||
Accessible.description: ToolTip.text
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.row: 12
|
||||
Layout.column: 0
|
||||
Layout.columnSpan: 2
|
||||
Layout.topMargin: 15
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: promptTemplate.width
|
||||
height: 1
|
||||
color: theme.tabBorder
|
||||
}
|
||||
}
|
||||
}
|
@@ -17,7 +17,7 @@ Button {
|
||||
border.color: myButton.down ? theme.backgroundLightest : theme.buttonBorder
|
||||
border.width: 2
|
||||
radius: 10
|
||||
color: myButton.hovered ? theme.backgroundLighter : theme.backgroundLight
|
||||
color: myButton.hovered ? theme.backgroundDark : theme.backgroundDarkest
|
||||
}
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: text
|
||||
|
@@ -9,14 +9,13 @@ ComboBox {
|
||||
padding: 10
|
||||
Accessible.role: Accessible.ComboBox
|
||||
contentItem: Text {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
id: text
|
||||
leftPadding: 10
|
||||
rightPadding: 20
|
||||
text: comboBox.displayText
|
||||
font: comboBox.font
|
||||
color: theme.textColor
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
delegate: ItemDelegate {
|
||||
|
@@ -11,7 +11,7 @@ TextField {
|
||||
color: text === "" || isValid ? theme.textColor : theme.textErrorColor
|
||||
background: Rectangle {
|
||||
implicitWidth: 150
|
||||
color: theme.backgroundLighter
|
||||
color: theme.backgroundDark
|
||||
radius: 10
|
||||
}
|
||||
}
|
||||
|
@@ -12,71 +12,56 @@ Item {
|
||||
id: theme
|
||||
}
|
||||
|
||||
property alias title: titleLabel.text
|
||||
property ListModel tabTitlesModel: ListModel { }
|
||||
property list<Component> tabs: [ ]
|
||||
|
||||
Canvas {
|
||||
id: canvas
|
||||
anchors.fill: parent
|
||||
contextType: "2d"
|
||||
onPaint: {
|
||||
var context = getContext("2d");
|
||||
context.reset();
|
||||
context.lineWidth = 2;
|
||||
context.moveTo(stackLayout.x, stackLayout.y);
|
||||
context.lineTo(stackLayout.x, stackLayout.y + stackLayout.height);
|
||||
context.lineTo(stackLayout.x + stackLayout.width, stackLayout.y + stackLayout.height);
|
||||
context.lineTo(stackLayout.x + stackLayout.width, stackLayout.y);
|
||||
context.lineTo(/*settingsTabBar.currentItem.x + */settingsTabBar.currentItem.width, stackLayout.y);
|
||||
context.strokeStyle = theme.tabBorder;
|
||||
context.stroke();
|
||||
}
|
||||
Label {
|
||||
id: titleLabel
|
||||
anchors.top: parent.top
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
color: theme.textColor
|
||||
padding: 10
|
||||
font.bold: true
|
||||
font.pixelSize: theme.fontSizeLarger
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.top: titleLabel.bottom
|
||||
anchors.leftMargin: 15
|
||||
anchors.rightMargin: 15
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
height: 1
|
||||
color: theme.tabBorder
|
||||
}
|
||||
|
||||
TabBar {
|
||||
id: settingsTabBar
|
||||
width: parent.width / 1.25
|
||||
anchors.top: titleLabel.bottom
|
||||
anchors.topMargin: 15
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: parent.width / 1.75
|
||||
z: 200
|
||||
visible: tabTitlesModel.count > 1
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
}
|
||||
Repeater {
|
||||
model: settingsStack.tabTitlesModel
|
||||
TabButton {
|
||||
id: tabButton
|
||||
padding: 10
|
||||
contentItem: IconLabel {
|
||||
color: theme.textColor
|
||||
font.bold: tabButton.checked
|
||||
text: model.title
|
||||
}
|
||||
background: Rectangle {
|
||||
color: tabButton.checked ? theme.backgroundDarkest : theme.backgroundLight
|
||||
// Rectangle {
|
||||
// anchors.top: parent.top
|
||||
// anchors.left: parent.left
|
||||
// anchors.right: parent.right
|
||||
// height: tabButton.checked
|
||||
// color: theme.tabBorder
|
||||
// }
|
||||
// Rectangle {
|
||||
// anchors.bottom: parent.bottom
|
||||
// anchors.left: parent.left
|
||||
// anchors.right: parent.right
|
||||
// height: !tabButton.checked
|
||||
// color: theme.tabBorder
|
||||
// }
|
||||
// Rectangle {
|
||||
// anchors.top: parent.top
|
||||
// anchors.bottom: parent.bottom
|
||||
// anchors.left: parent.left
|
||||
// width: tabButton.checked
|
||||
// color: theme.tabBorder
|
||||
// }
|
||||
// Rectangle {
|
||||
// anchors.top: parent.top
|
||||
// anchors.bottom: parent.bottom
|
||||
// anchors.right: parent.right
|
||||
// width: tabButton.checked
|
||||
// color: theme.tabBorder
|
||||
// }
|
||||
color: "transparent"
|
||||
border.width: 1
|
||||
border.color: tabButton.checked ? theme.tabBorder : "transparent"
|
||||
radius: 10
|
||||
}
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: model.title
|
||||
@@ -84,9 +69,31 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: dividerTabBar
|
||||
visible: tabTitlesModel.count > 1
|
||||
anchors.top: settingsTabBar.bottom
|
||||
anchors.topMargin: 15
|
||||
anchors.bottomMargin: 15
|
||||
anchors.leftMargin: 15
|
||||
anchors.rightMargin: 15
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
height: 1
|
||||
color: theme.tabBorder
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "transparent"
|
||||
radius: 10
|
||||
border.width: 1
|
||||
border.color: theme.tabBorder
|
||||
}
|
||||
|
||||
StackLayout {
|
||||
id: stackLayout
|
||||
anchors.top: tabTitlesModel.count > 1 ? settingsTabBar.bottom : parent.top
|
||||
anchors.top: tabTitlesModel.count > 1 ? dividerTabBar.bottom : titleLabel.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
|
@@ -5,42 +5,87 @@ import QtQuick.Controls.Basic
|
||||
import QtQuick.Layouts
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property string title: ""
|
||||
property Item contentItem: null
|
||||
property Item advancedSettings: null
|
||||
signal restoreDefaultsClicked
|
||||
|
||||
onContentItemChanged: function() {
|
||||
if (contentItem) {
|
||||
contentItem.parent = tabInner;
|
||||
contentItem.anchors.left = tabInner.left;
|
||||
contentItem.anchors.right = tabInner.right;
|
||||
contentItem.parent = contentInner;
|
||||
contentItem.anchors.left = contentInner.left;
|
||||
contentItem.anchors.right = contentInner.right;
|
||||
}
|
||||
}
|
||||
|
||||
onAdvancedSettingsChanged: function() {
|
||||
if (advancedSettings) {
|
||||
advancedSettings.parent = advancedInner;
|
||||
advancedSettings.anchors.left = advancedInner.left;
|
||||
advancedSettings.anchors.right = advancedInner.right;
|
||||
}
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
id: root
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
padding: 15
|
||||
rightPadding: 20
|
||||
contentWidth: availableWidth
|
||||
contentHeight: tabInner.height
|
||||
contentHeight: innerColumn.height
|
||||
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
|
||||
|
||||
Theme {
|
||||
id: theme
|
||||
}
|
||||
|
||||
// background: Rectangle {
|
||||
// color: 'transparent'
|
||||
// border.color: theme.tabBorder
|
||||
// border.width: 1
|
||||
// radius: 10
|
||||
// }
|
||||
|
||||
Column {
|
||||
id: tabInner
|
||||
ColumnLayout {
|
||||
id: innerColumn
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.margins: 15
|
||||
spacing: 10
|
||||
Column {
|
||||
id: contentInner
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Column {
|
||||
id: advancedInner
|
||||
visible: false
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
height: restoreDefaultsButton.height
|
||||
MyButton {
|
||||
id: restoreDefaultsButton
|
||||
anchors.left: parent.left
|
||||
width: implicitWidth
|
||||
text: qsTr("Restore Defaults")
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: text
|
||||
Accessible.description: qsTr("Restores the settings dialog to a default state")
|
||||
onClicked: {
|
||||
root.restoreDefaultsClicked();
|
||||
}
|
||||
}
|
||||
MyButton {
|
||||
id: advancedSettingsButton
|
||||
anchors.right: parent.right
|
||||
visible: root.advancedSettings
|
||||
width: implicitWidth
|
||||
text: !advancedInner.visible ? qsTr("Advanced Settings") : qsTr("Hide Advanced Settings")
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: text
|
||||
Accessible.description: qsTr("Shows/hides the advanced settings")
|
||||
onClicked: {
|
||||
advancedInner.visible = !advancedInner.visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ TextField {
|
||||
padding: 10
|
||||
background: Rectangle {
|
||||
implicitWidth: 150
|
||||
color: theme.backgroundLighter
|
||||
color: theme.backgroundDark
|
||||
radius: 10
|
||||
}
|
||||
}
|
@@ -14,7 +14,6 @@ import mysettings
|
||||
Dialog {
|
||||
id: settingsDialog
|
||||
modal: true
|
||||
opacity: 0.9
|
||||
padding: 20
|
||||
bottomPadding: 30
|
||||
background: Rectangle {
|
||||
@@ -38,7 +37,7 @@ Dialog {
|
||||
ListModel {
|
||||
id: stacksModel
|
||||
ListElement {
|
||||
title: "Generation"
|
||||
title: "Models"
|
||||
}
|
||||
ListElement {
|
||||
title: "Application"
|
||||
@@ -67,7 +66,6 @@ Dialog {
|
||||
id: item
|
||||
width: listView.width
|
||||
height: titleLabel.height + 25
|
||||
// color: index % 2 === 0 ? theme.backgroundLight : theme.backgroundLighter
|
||||
color: "transparent"
|
||||
border.color: theme.backgroundLighter
|
||||
border.width: index == listView.currentIndex ? 1 : 0
|
||||
@@ -78,6 +76,7 @@ Dialog {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.margins: 20
|
||||
font.bold: index == listView.currentIndex
|
||||
text: title
|
||||
elide: Text.ElideRight
|
||||
color: theme.textColor
|
||||
@@ -101,19 +100,21 @@ Dialog {
|
||||
currentIndex: listView.currentIndex
|
||||
|
||||
MySettingsStack {
|
||||
title: qsTr("Model/Character Settings")
|
||||
tabs: [
|
||||
Component { ModelSettings { } },
|
||||
Component { GenerationSettings { } }
|
||||
Component { ModelSettings { } }
|
||||
]
|
||||
}
|
||||
|
||||
MySettingsStack {
|
||||
title: qsTr("Application General Settings")
|
||||
tabs: [
|
||||
Component { ApplicationSettings { } }
|
||||
]
|
||||
}
|
||||
|
||||
MySettingsStack {
|
||||
title: qsTr("LocalDocs Plugin (BETA) Settings")
|
||||
tabs: [
|
||||
Component { LocalDocsSettings { } }
|
||||
]
|
||||
|
@@ -7,9 +7,9 @@ QtObject {
|
||||
property color textAccent: "#8e8ea0"
|
||||
property color mutedTextColor: backgroundLightest
|
||||
property color textErrorColor: "red"
|
||||
property color backgroundDarkest: "#202123"
|
||||
property color backgroundDarker: "#222326"
|
||||
property color backgroundDark: "#242528"
|
||||
property color backgroundDarkest: "#1c1f21"
|
||||
property color backgroundDarker: "#1e2123"
|
||||
property color backgroundDark: "#222527"
|
||||
property color backgroundLight: "#343541"
|
||||
property color backgroundLighter: "#444654"
|
||||
property color backgroundLightest: "#7d7d8e"
|
||||
|
Reference in New Issue
Block a user