Big updates to the UI.

This commit is contained in:
Adam Treat 2023-04-10 23:34:34 -04:00
parent be65e91c7d
commit a56a258099
7 changed files with 273 additions and 90 deletions

View File

@ -21,7 +21,11 @@ qt_add_qml_module(chat
URI gpt4all-chat
VERSION 1.0
QML_FILES main.qml
RESOURCES icons/send_message.svg icons/stop_generating.svg icons/regenerate.svg
RESOURCES
icons/send_message.svg
icons/stop_generating.svg
icons/regenerate.svg
icons/logo.svg
)
set_target_properties(chat PROPERTIES
@ -46,7 +50,7 @@ install(TARGETS chat DESTINATION bin COMPONENT ${COMPONENT_NAME_MAIN})
set(CPACK_GENERATOR "IFW")
if(${CMAKE_SYSTEM_NAME} MATCHES Linux)
find_program(LINUXDEPLOYQT linuxdeployqt HINTS ${_qt_bin_dir})
set(LINUXDEPLOYQT "/home/atreat/dev/linuxdeployqt/build/tools/linuxdeployqt/linuxdeployqt")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/deploy-qt-linux.cmake.in"
"${CMAKE_BINARY_DIR}/cmake/deploy-qt-linux.cmake" @ONLY)
set(CPACK_PRE_BUILD_SCRIPTS ${CMAKE_BINARY_DIR}/cmake/deploy-qt-linux.cmake)
@ -81,6 +85,10 @@ cpack_add_component(${COMPONENT_NAME_MAIN} DOWNLOADED)
cpack_ifw_configure_component(${COMPONENT_NAME_MAIN} ESSENTIAL FORCED_INSTALLATION)
cpack_ifw_configure_component(${COMPONENT_NAME_MAIN} LICENSES "GPL-3.0 LICENSE" ${CPACK_RESOURCE_FILE_LICENSE})
if (WIN32)
cpack_ifw_add_repository("GPT4AllRepository" URL "/path/to/repo/gpt4all-chat/install/windows/")
endif (WIN32)
if(${CMAKE_SYSTEM_NAME} MATCHES Linux)
cpack_ifw_add_repository("GPT4AllRepository" URL "http://localhost/linux/repository")
elseif(${CMAKE_SYSTEM_NAME} MATCHES Windows)
cpack_ifw_add_repository("GPT4AllRepository" URL "http://localhost/windows/repository")
elseif(${CMAKE_SYSTEM_NAME} MATCHES Darwin)
cpack_ifw_add_repository("GPT4AllRepository" URL "http://localhost/mac/repository")
endif()

View File

@ -1,6 +1,6 @@
set(LINDEPLOYQT "@WINDEPLOYQT@")
set(LINUXDEPLOYQT "@LINUXDEPLOYQT@")
set(COMPONENT_NAME_MAIN "@COMPONENT_NAME_MAIN@")
set(CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@")
execute_process(COMMAND ${WINDEPLOYQT} --qmldir ${CMAKE_CURRENT_SOURCE_DIR} ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/packages/${COMPONENT_NAME_MAIN}/data/bin)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/models/ggml-model-q4_0.bin
execute_process(COMMAND ${LINUXDEPLOYQT} ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/packages/${COMPONENT_NAME_MAIN}/data/bin/chat -verbose=2)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
DESTINATION ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/packages/${COMPONENT_NAME_MAIN}/data/bin)

View File

@ -1,6 +1,6 @@
set(WINDEPLOYQT "@WINDEPLOYQT@")
set(WINDEPLOYQT "@MACDEPLOYQT@")
set(COMPONENT_NAME_MAIN "@COMPONENT_NAME_MAIN@")
set(CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@")
execute_process(COMMAND ${WINDEPLOYQT} --qmldir ${CMAKE_CURRENT_SOURCE_DIR} ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/packages/${COMPONENT_NAME_MAIN}/data/bin)
execute_process(COMMAND ${MACDEPLOYQT} --qmldir ${CMAKE_CURRENT_SOURCE_DIR} ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/packages/${COMPONENT_NAME_MAIN}/data/bin)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/models/ggml-model-q4_0.bin
DESTINATION ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/packages/${COMPONENT_NAME_MAIN}/data/bin)

17
icons/logo.svg Normal file
View File

@ -0,0 +1,17 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 130" width="200" height="260">
<!-- Smaller Cool Robot Ears (behind the head, thinner stroke) -->
<path d="M14,35 Q10,45 14,55 L6,55 Q2,45 6,35 Z" fill="#e0d6ff" stroke="#9171c1" stroke-width="1"/>
<path d="M96,35 Q100,45 96,55 L86,55 Q90,45 86,35 Z" fill="#e0d6ff" stroke="#9171c1" stroke-width="1"/>
<!-- Head with a very thin stroke -->
<path d="M20,10 L76,10 Q80,10 84,20 L94,80 Q90,90 86,90 L14,90 Q10,90 6,80 L16,20 Q20,10 24,10 Z" fill="#e0d6ff" stroke="#9171c1" stroke-width="0.5"/>
<!-- Eyes -->
<circle cx="35" cy="40" r="8" fill="#ffffff"/>
<circle cx="65" cy="40" r="8" fill="#ffffff"/>
<circle cx="35" cy="40" r="5" fill="#9171c1"/>
<circle cx="65" cy="40" r="5" fill="#9171c1"/>
<!-- Wider Smile -->
<path d="M25,60 Q50,70 75,60" stroke="#9171c1" stroke-width="2" fill="none"/>
<!-- Wider and More Prominent Antenna -->
<line x1="50" y1="10" x2="50" y2="-5" stroke="#9171c1" stroke-width="6"/>
<circle cx="50" cy="-5" r="8" fill="#e0d6ff" stroke="#9171c1" stroke-width="2"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

22
llm.cpp
View File

@ -3,6 +3,7 @@
#include <QCoreApplication>
#include <QDir>
#include <QFile>
#include <QProcess>
#include <QResource>
#include <fstream>
@ -143,3 +144,24 @@ void LLM::responseStopped()
m_responseInProgress = false;
emit responseInProgressChanged();
}
bool LLM::checkForUpdates() const
{
#if defined(Q_OS_LINUX)
QString tool("MaintenanceTool");
#elif defined(Q_OS_WINDOWS)
QString tool("MaintenanceTool.exe");
#elif defined(Q_OS_DARWIN)
QString tool("MaintenanceTool.app/Contents/MacOS/MaintenanceTool");
#endif
QString fileName = QCoreApplication::applicationDirPath()
+ QDir::separator() + ".." + QDir::separator() + tool;
if (!QFileInfo::exists(fileName)) {
qDebug() << "Couldn't find tool at" << fileName << "so cannot check for updates!";
return false;
}
return QProcess::startDetached(fileName);
}

2
llm.h
View File

@ -61,6 +61,8 @@ public:
QString response() const;
bool responseInProgress() const { return m_responseInProgress; }
Q_INVOKABLE bool checkForUpdates() const;
Q_SIGNALS:
void isModelLoadedChanged();
void responseChanged();

294
main.qml
View File

@ -9,76 +9,221 @@ Window {
height: 720
visible: true
title: qsTr("GPT4All Chat")
color: "#d1d5db"
// Rectangle {
// id: conversationList
// width: 300
// anchors.left: parent.left
// anchors.top: parent.top
// anchors.bottom: parent.bottom
// color: "#202123"
TextField {
id: header
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
height: 100
color: "#d1d5db"
padding: 20
font.pixelSize: 24
text: "GPT4ALL Model: gpt4all-j"
background: Rectangle {
color: "#202123"
}
focus: false
horizontalAlignment: TextInput.AlignHCenter
}
// Button {
// id: newChat
// text: qsTr("New chat")
// anchors.top: parent.top
// anchors.left: parent.left
// anchors.right: parent.right
// anchors.margins: 15
// padding: 15
// background: Rectangle {
// opacity: .5
// border.color: "#7d7d8e"
// border.width: 1
// radius: 10
// color: "#343541"
// }
// }
// }
Image {
anchors.verticalCenter: header.baseline
x: parent.width / 2 + 163
width: 50
height: 65
source: "qrc:/gpt4all-chat/icons/logo.svg"
z: 300
}
Button {
id: drawerButton
anchors.left: parent.left
anchors.top: parent.top
anchors.topMargin: 30
anchors.leftMargin: 30
width: 60
height: 40
z: 200
padding: 15
background: Item {
anchors.fill: parent
Rectangle {
id: bar1
color: "#7d7d8e"
width: parent.width
height: 8
radius: 2
antialiasing: true
}
Rectangle {
id: bar2
anchors.centerIn: parent
color: "#7d7d8e"
width: parent.width
height: 8
radius: 2
antialiasing: true
}
Rectangle {
id: bar3
anchors.bottom: parent.bottom
color: "#7d7d8e"
width: parent.width
height: 8
radius: 2
antialiasing: true
}
}
onClicked: {
drawer.visible = !drawer.visible
}
}
Button {
id: resetContextButton
anchors.right: parent.right
anchors.top: parent.top
anchors.topMargin: 30
anchors.rightMargin: 30
width: 60
height: 40
z: 200
padding: 15
background: Item {
anchors.fill: parent
Image {
anchors.centerIn: parent
width: 40
height: 40
source: "qrc:/gpt4all-chat/icons/regenerate.svg"
}
}
onClicked: {
LLM.stopGenerating()
LLM.resetContext()
chatModel.clear()
}
}
Dialog {
id: checkForUpdatesError
anchors.centerIn: parent
modal: false
opacity: 0.9
Text {
horizontalAlignment: Text.AlignJustify
text: qsTr("ERROR: Update system could not find the MaintenanceTool used<br>
to check for updates!<br><br>
Did you install this application using the online installer? If so,<br>
the MaintenanceTool executable should be located one directory<br>
above where this application resides on your filesystem.<br><br>
If you can't start it manually, then I'm afraid you'll have to<br>
reinstall.")
color: "#d1d5db"
}
background: Rectangle {
anchors.fill: parent
color: "#202123"
border.width: 1
border.color: "white"
radius: 10
}
}
Drawer {
id: drawer
y: header.height
width: 0.3 * window.width
height: window.height - y
modal: false
opacity: 0.9
background: Rectangle {
height: parent.height
color: "#202123"
}
Item {
anchors.fill: parent
anchors.margins: 30
Label {
id: conversationList
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
wrapMode: Text.WordWrap
text: qsTr("Chat lists of specific conversations coming soon! Check back often for new features :)")
}
Label {
id: discordLink
textFormat: Text.RichText
anchors.left: parent.left
anchors.right: parent.right
anchors.top: conversationList.bottom
anchors.topMargin: 20
wrapMode: Text.WordWrap
text: qsTr("Check out our discord channel <a href=\"https://discord.gg/4M2QFmTt2k\">https://discord.gg/4M2QFmTt2k</a>")
onLinkActivated: { Qt.openUrlExternally("https://discord.gg/4M2QFmTt2k") }
}
Label {
id: nomicProps
textFormat: Text.RichText
anchors.left: parent.left
anchors.right: parent.right
anchors.top: discordLink.bottom
anchors.topMargin: 20
wrapMode: Text.WordWrap
text: qsTr("Thanks to <a href=\"https://home.nomic.ai\">nomic.ai</a> and the community for contributing such great work!")
onLinkActivated: { Qt.openUrlExternally("https://home.nomic.ai") }
}
Button {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
padding: 15
contentItem: Text {
text: qsTr("Check for updates...")
horizontalAlignment: Text.AlignHCenter
color: "#d1d5db"
}
background: Rectangle {
opacity: .5
border.color: "#7d7d8e"
border.width: 1
radius: 10
color: "#343541"
}
onClicked: {
if (!LLM.checkForUpdates())
checkForUpdatesError.open()
}
}
}
}
Rectangle {
id: conversation
color: "#343541"
// anchors.left: conversationList.right
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.top: parent.top
Button {
id: resetContextButton
anchors.right: parent.right
anchors.top: parent.top
anchors.topMargin: 30
anchors.rightMargin: 30
width: 60
height: 60
z: 200
padding: 15
background: Item {
anchors.fill: parent
Rectangle {
anchors.fill: parent
color: "#343541"
border.color: "#7d7d8e"
border.width: 1
opacity: 0.5
radius: 10
}
Image {
anchors.fill: parent
anchors.margins: 15
source: "qrc:/gpt4all-chat/icons/regenerate.svg"
}
}
onClicked: {
LLM.stopGenerating()
LLM.resetContext()
chatModel.clear()
}
}
anchors.top: header.bottom
ScrollView {
id: scrollView
@ -100,20 +245,6 @@ Window {
ListView {
id: listView
anchors.fill: parent
header: TextField {
id: modelName
width: parent.width
color: "#d1d5db"
padding: 20
font.pixelSize: 24
text: "Model: GPT4ALL-J-6B-4bit"
background: Rectangle {
color: "#444654"
}
focus: false
horizontalAlignment: TextInput.AlignHCenter
}
model: chatModel
delegate: TextArea {
text: currentResponse ? LLM.response : value
@ -190,7 +321,6 @@ Window {
source: LLM.responseInProgress ? "qrc:/gpt4all-chat/icons/stop_generating.svg" : "qrc:/gpt4all-chat/icons/regenerate.svg"
}
leftPadding: 50
text: LLM.responseInProgress ? qsTr("Stop generating") : qsTr("Regenerate response")
onClicked: {
if (LLM.responseInProgress)
LLM.stopGenerating()
@ -210,6 +340,10 @@ Window {
anchors.horizontalCenter: textInput.horizontalCenter
anchors.bottomMargin: 40
padding: 15
contentItem: Text {
text: LLM.responseInProgress ? qsTr("Stop generating") : qsTr("Regenerate response")
color: "#d1d5db"
}
background: Rectangle {
opacity: .5
border.color: "#7d7d8e"
@ -247,10 +381,10 @@ Window {
chatModel.append({"name": qsTr("Prompt: "), "currentResponse": false, "value": textInput.text})
chatModel.append({"name": qsTr("Response: "), "currentResponse": true, "value": "", "prompt": prompt})
// var contextPrompt;
// for (var i = 0; i < chatModel.count; ++i)
// contextPrompt += chatModel.get(i).value + "\n";
// prompt = contextPrompt + textInput.text + "\n"
// var contextPrompt;
// for (var i = 0; i < chatModel.count; ++i)
// contextPrompt += chatModel.get(i).value + "\n";
// prompt = contextPrompt + textInput.text + "\n"
LLM.resetResponse()
LLM.prompt(prompt)