Thu, 29 Aug 2024 13:11:59 +0200
Implemented the 'ollama' interface configuration page.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OllamaInterface/ConfigurationPage/OllamaPage.py Thu Aug 29 13:11:59 2024 +0200 @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2024 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing the 'ollama' interface configuration page. +""" + +from eric7.Preferences.ConfigurationPages.ConfigurationPageBase import ( + ConfigurationPageBase, +) + +from .Ui_OllamaPage import Ui_OllamaPage + + +class OllamaPage(ConfigurationPageBase, Ui_OllamaPage): + """ + Class implementing the 'ollama' interface configuration page. + """ + + def __init__(self, plugin): + """ + Constructor + + @param plugin reference to the plugin object + @type PluginOllamaInterface + """ + super().__init__() + self.setupUi(self) + self.setObjectName("OllamaPage") + + self.__plugin = plugin + + # set initial values + self.serverSchemeComboBox.setCurrentText( + self.__plugin.getPreferences("OllamaScheme") + ) + self.serverHostEdit.setText(self.__plugin.getPreferences("OllamaHost")) + self.serverPortSpinBox.setValue(self.__plugin.getPreferences("OllamaPort")) + + self.localServerPortSpinBox.setValue( + self.__plugin.getPreferences("OllamaLocalPort") + ) + + self.modelLibraryUrlEdit.setText( + self.__plugin.getPreferences("OllamaModelLibraryUrl") + ) + + self.heartbeatSpinBox.setValue( + self.__plugin.getPreferences("OllamaHeartbeatInterval") + ) + self.streamingChatCheckBox.setChecked( + self.__plugin.getPreferences("StreamingChatResponse") + ) + + def save(self): + """ + Public slot to save the 'ollama' interface configuration. + """ + self.__plugin.setPreferences( + "OllamaScheme", self.serverSchemeComboBox.currentText() + ) + self.__plugin.setPreferences( + "OllamaHost", self.serverHostEdit.text() + ) + self.__plugin.setPreferences( + "OllamaPort", self.serverPortSpinBox.value() + ) + + self.__plugin.setPreferences( + "OllamaLocalPort", self.localServerPortSpinBox.value() + ) + + self.__plugin.setPreferences( + "OllamaModelLibraryUrl", self.modelLibraryUrlEdit.text() + ) + + self.__plugin.setPreferences( + "OllamaHeartbeatInterval", self.heartbeatSpinBox.value() + ) + self.__plugin.setPreferences( + "StreamingChatResponse", self.streamingChatCheckBox.isChecked() + )
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OllamaInterface/ConfigurationPage/OllamaPage.ui Thu Aug 29 13:11:59 2024 +0200 @@ -0,0 +1,280 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>OllamaPage</class> + <widget class="QWidget" name="OllamaPage"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>557</width> + <height>464</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="headerLabel"> + <property name="text"> + <string><b>Configure 'ollama' Interface</b></string> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line9_3"> + <property name="frameShape"> + <enum>QFrame::HLine</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Sunken</enum> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Server URL</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Scheme:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="serverSchemeComboBox"> + <property name="toolTip"> + <string>Select the scheme of the 'ollama' server URL.</string> + </property> + <item> + <property name="text"> + <string>http</string> + </property> + </item> + <item> + <property name="text"> + <string>https</string> + </property> + </item> + </widget> + </item> + <item row="0" column="2"> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>387</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Host:</string> + </property> + </widget> + </item> + <item row="1" column="1" colspan="2"> + <widget class="QLineEdit" name="serverHostEdit"> + <property name="toolTip"> + <string>Enter the host name of the 'ollama' server.</string> + </property> + <property name="clearButtonEnabled"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Port:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QSpinBox" name="serverPortSpinBox"> + <property name="toolTip"> + <string>Enter the port of the 'ollama' server URL.</string> + </property> + <property name="showGroupSeparator" stdset="0"> + <bool>true</bool> + </property> + <property name="minimum"> + <number>10000</number> + </property> + <property name="maximum"> + <number>65535</number> + </property> + </widget> + </item> + <item row="2" column="2"> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>387</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Local Server</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Port:</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="localServerPortSpinBox"> + <property name="toolTip"> + <string>Enter the port of the local 'ollama' server.</string> + </property> + <property name="showGroupSeparator" stdset="0"> + <bool>true</bool> + </property> + <property name="minimum"> + <number>10000</number> + </property> + <property name="maximum"> + <number>65535</number> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_4"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>408</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox_3"> + <property name="title"> + <string>Model Library</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>URL:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="modelLibraryUrlEdit"> + <property name="toolTip"> + <string>Enter the URL of the 'ollama' model library.</string> + </property> + <property name="clearButtonEnabled"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>Heartbeat Timer:</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="heartbeatSpinBox"> + <property name="toolTip"> + <string>Enter the heartbeat timeout value (0 = disable).</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="specialValueText"> + <string>Disabled</string> + </property> + <property name="suffix"> + <string> s</string> + </property> + <property name="maximum"> + <number>30</number> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <widget class="QCheckBox" name="streamingChatCheckBox"> + <property name="text"> + <string>Use streaming chat response</string> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>59</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <tabstops> + <tabstop>serverSchemeComboBox</tabstop> + <tabstop>serverHostEdit</tabstop> + <tabstop>serverPortSpinBox</tabstop> + <tabstop>localServerPortSpinBox</tabstop> + <tabstop>modelLibraryUrlEdit</tabstop> + <tabstop>heartbeatSpinBox</tabstop> + <tabstop>streamingChatCheckBox</tabstop> + </tabstops> + <resources/> + <connections/> +</ui>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OllamaInterface/ConfigurationPage/Ui_OllamaPage.py Thu Aug 29 13:11:59 2024 +0200 @@ -0,0 +1,138 @@ +# Form implementation generated from reading ui file 'OllamaInterface/ConfigurationPage/OllamaPage.ui' +# +# Created by: PyQt6 UI code generator 6.7.1 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class Ui_OllamaPage(object): + def setupUi(self, OllamaPage): + OllamaPage.setObjectName("OllamaPage") + OllamaPage.resize(557, 464) + self.verticalLayout = QtWidgets.QVBoxLayout(OllamaPage) + self.verticalLayout.setObjectName("verticalLayout") + self.headerLabel = QtWidgets.QLabel(parent=OllamaPage) + self.headerLabel.setObjectName("headerLabel") + self.verticalLayout.addWidget(self.headerLabel) + self.line9_3 = QtWidgets.QFrame(parent=OllamaPage) + self.line9_3.setFrameShape(QtWidgets.QFrame.Shape.HLine) + self.line9_3.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) + self.line9_3.setFrameShape(QtWidgets.QFrame.Shape.HLine) + self.line9_3.setObjectName("line9_3") + self.verticalLayout.addWidget(self.line9_3) + self.groupBox = QtWidgets.QGroupBox(parent=OllamaPage) + self.groupBox.setObjectName("groupBox") + self.gridLayout = QtWidgets.QGridLayout(self.groupBox) + self.gridLayout.setObjectName("gridLayout") + self.label = QtWidgets.QLabel(parent=self.groupBox) + self.label.setObjectName("label") + self.gridLayout.addWidget(self.label, 0, 0, 1, 1) + self.serverSchemeComboBox = QtWidgets.QComboBox(parent=self.groupBox) + self.serverSchemeComboBox.setObjectName("serverSchemeComboBox") + self.serverSchemeComboBox.addItem("") + self.serverSchemeComboBox.addItem("") + self.gridLayout.addWidget(self.serverSchemeComboBox, 0, 1, 1, 1) + spacerItem = QtWidgets.QSpacerItem(387, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.gridLayout.addItem(spacerItem, 0, 2, 1, 1) + self.label_2 = QtWidgets.QLabel(parent=self.groupBox) + self.label_2.setObjectName("label_2") + self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1) + self.serverHostEdit = QtWidgets.QLineEdit(parent=self.groupBox) + self.serverHostEdit.setClearButtonEnabled(True) + self.serverHostEdit.setObjectName("serverHostEdit") + self.gridLayout.addWidget(self.serverHostEdit, 1, 1, 1, 2) + self.label_3 = QtWidgets.QLabel(parent=self.groupBox) + self.label_3.setObjectName("label_3") + self.gridLayout.addWidget(self.label_3, 2, 0, 1, 1) + self.serverPortSpinBox = QtWidgets.QSpinBox(parent=self.groupBox) + self.serverPortSpinBox.setProperty("showGroupSeparator", True) + self.serverPortSpinBox.setMinimum(10000) + self.serverPortSpinBox.setMaximum(65535) + self.serverPortSpinBox.setObjectName("serverPortSpinBox") + self.gridLayout.addWidget(self.serverPortSpinBox, 2, 1, 1, 1) + spacerItem1 = QtWidgets.QSpacerItem(387, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.gridLayout.addItem(spacerItem1, 2, 2, 1, 1) + self.verticalLayout.addWidget(self.groupBox) + self.groupBox_2 = QtWidgets.QGroupBox(parent=OllamaPage) + self.groupBox_2.setObjectName("groupBox_2") + self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.groupBox_2) + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.label_4 = QtWidgets.QLabel(parent=self.groupBox_2) + self.label_4.setObjectName("label_4") + self.horizontalLayout_2.addWidget(self.label_4) + self.localServerPortSpinBox = QtWidgets.QSpinBox(parent=self.groupBox_2) + self.localServerPortSpinBox.setProperty("showGroupSeparator", True) + self.localServerPortSpinBox.setMinimum(10000) + self.localServerPortSpinBox.setMaximum(65535) + self.localServerPortSpinBox.setObjectName("localServerPortSpinBox") + self.horizontalLayout_2.addWidget(self.localServerPortSpinBox) + spacerItem2 = QtWidgets.QSpacerItem(408, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout_2.addItem(spacerItem2) + self.verticalLayout.addWidget(self.groupBox_2) + self.groupBox_3 = QtWidgets.QGroupBox(parent=OllamaPage) + self.groupBox_3.setObjectName("groupBox_3") + self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.groupBox_3) + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + self.label_5 = QtWidgets.QLabel(parent=self.groupBox_3) + self.label_5.setObjectName("label_5") + self.horizontalLayout_3.addWidget(self.label_5) + self.modelLibraryUrlEdit = QtWidgets.QLineEdit(parent=self.groupBox_3) + self.modelLibraryUrlEdit.setClearButtonEnabled(True) + self.modelLibraryUrlEdit.setObjectName("modelLibraryUrlEdit") + self.horizontalLayout_3.addWidget(self.modelLibraryUrlEdit) + self.verticalLayout.addWidget(self.groupBox_3) + self.horizontalLayout = QtWidgets.QHBoxLayout() + self.horizontalLayout.setObjectName("horizontalLayout") + self.label_6 = QtWidgets.QLabel(parent=OllamaPage) + self.label_6.setObjectName("label_6") + self.horizontalLayout.addWidget(self.label_6) + self.heartbeatSpinBox = QtWidgets.QSpinBox(parent=OllamaPage) + self.heartbeatSpinBox.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight|QtCore.Qt.AlignmentFlag.AlignTrailing|QtCore.Qt.AlignmentFlag.AlignVCenter) + self.heartbeatSpinBox.setMaximum(30) + self.heartbeatSpinBox.setObjectName("heartbeatSpinBox") + self.horizontalLayout.addWidget(self.heartbeatSpinBox) + spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.horizontalLayout.addItem(spacerItem3) + self.verticalLayout.addLayout(self.horizontalLayout) + self.streamingChatCheckBox = QtWidgets.QCheckBox(parent=OllamaPage) + self.streamingChatCheckBox.setObjectName("streamingChatCheckBox") + self.verticalLayout.addWidget(self.streamingChatCheckBox) + spacerItem4 = QtWidgets.QSpacerItem(20, 59, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + self.verticalLayout.addItem(spacerItem4) + + self.retranslateUi(OllamaPage) + QtCore.QMetaObject.connectSlotsByName(OllamaPage) + OllamaPage.setTabOrder(self.serverSchemeComboBox, self.serverHostEdit) + OllamaPage.setTabOrder(self.serverHostEdit, self.serverPortSpinBox) + OllamaPage.setTabOrder(self.serverPortSpinBox, self.localServerPortSpinBox) + OllamaPage.setTabOrder(self.localServerPortSpinBox, self.modelLibraryUrlEdit) + OllamaPage.setTabOrder(self.modelLibraryUrlEdit, self.heartbeatSpinBox) + OllamaPage.setTabOrder(self.heartbeatSpinBox, self.streamingChatCheckBox) + + def retranslateUi(self, OllamaPage): + _translate = QtCore.QCoreApplication.translate + self.headerLabel.setText(_translate("OllamaPage", "<b>Configure \'ollama\' Interface</b>")) + self.groupBox.setTitle(_translate("OllamaPage", "Server URL")) + self.label.setText(_translate("OllamaPage", "Scheme:")) + self.serverSchemeComboBox.setToolTip(_translate("OllamaPage", "Select the scheme of the \'ollama\' server URL.")) + self.serverSchemeComboBox.setItemText(0, _translate("OllamaPage", "http")) + self.serverSchemeComboBox.setItemText(1, _translate("OllamaPage", "https")) + self.label_2.setText(_translate("OllamaPage", "Host:")) + self.serverHostEdit.setToolTip(_translate("OllamaPage", "Enter the host name of the \'ollama\' server.")) + self.label_3.setText(_translate("OllamaPage", "Port:")) + self.serverPortSpinBox.setToolTip(_translate("OllamaPage", "Enter the port of the \'ollama\' server URL.")) + self.groupBox_2.setTitle(_translate("OllamaPage", "Local Server")) + self.label_4.setText(_translate("OllamaPage", "Port:")) + self.localServerPortSpinBox.setToolTip(_translate("OllamaPage", "Enter the port of the local \'ollama\' server.")) + self.groupBox_3.setTitle(_translate("OllamaPage", "Model Library")) + self.label_5.setText(_translate("OllamaPage", "URL:")) + self.modelLibraryUrlEdit.setToolTip(_translate("OllamaPage", "Enter the URL of the \'ollama\' model library.")) + self.label_6.setText(_translate("OllamaPage", "Heartbeat Timer:")) + self.heartbeatSpinBox.setToolTip(_translate("OllamaPage", "Enter the heartbeat timeout value (0 = disable).")) + self.heartbeatSpinBox.setSpecialValueText(_translate("OllamaPage", "Disabled")) + self.heartbeatSpinBox.setSuffix(_translate("OllamaPage", " s")) + self.streamingChatCheckBox.setText(_translate("OllamaPage", "Use streaming chat response"))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OllamaInterface/ConfigurationPage/__init__.py Thu Aug 29 13:11:59 2024 +0200 @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2024 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Package implementing the configuration page. +"""
--- a/PluginAiOllama.epj Thu Aug 29 13:11:10 2024 +0200 +++ b/PluginAiOllama.epj Thu Aug 29 13:11:59 2024 +0200 @@ -198,6 +198,7 @@ "makefile": "OTHERS" }, "FORMS": [ + "OllamaInterface/ConfigurationPage/OllamaPage.ui", "OllamaInterface/OllamaChatWidget.ui", "OllamaInterface/OllamaDetailedModelsDialog.ui", "OllamaInterface/OllamaHistoryWidget.ui", @@ -296,6 +297,9 @@ "RESOURCES": [], "SOURCES": [ "OllamaInterface/AutoResizeTextBrowser.py", + "OllamaInterface/ConfigurationPage/OllamaPage.py", + "OllamaInterface/ConfigurationPage/Ui_OllamaPage.py", + "OllamaInterface/ConfigurationPage/__init__.py", "OllamaInterface/OllamaChatMessageBox.py", "OllamaInterface/OllamaChatWidget.py", "OllamaInterface/OllamaClient.py",
--- a/PluginAiOllama.py Thu Aug 29 13:11:10 2024 +0200 +++ b/PluginAiOllama.py Thu Aug 29 13:11:59 2024 +0200 @@ -9,7 +9,7 @@ import os -from PyQt6.QtCore import QObject, Qt, QTranslator, pyqtSignal +from PyQt6.QtCore import QCoreApplication, QObject, Qt, QTranslator, pyqtSignal from PyQt6.QtGui import QKeySequence from eric7 import Globals, Preferences @@ -50,17 +50,20 @@ ollamaInterfacePluginObject = None -def pageCreationFunction(configDlg): +def createOllamaPage(_configDlg): """ - Function to create the Translator configuration page. + Function to create the 'ollama' interface' configuration page. - @param configDlg reference to the configuration dialog + @param _configDlg reference to the configuration dialog @type ConfigurationWidget @return reference to the configuration page - @rtype TranslatorPage + @rtype OllamaPage """ - # TODO: not implemented yet - page = None # change this line to create the configuration page + from OllamaInterface.ConfigurationPage.OllamaPage import OllamaPage + + global ollamaInterfacePluginObject + + page = OllamaPage(ollamaInterfacePluginObject) return page @@ -71,12 +74,16 @@ @return dictionary containing the relevant data @rtype dict """ - # TODO: not implemented yet + usesDarkPalette = ericApp().usesDarkPalette() + iconSuffix = "dark" if usesDarkPalette else "light" + return { - "<unique key>": [ - "<display string>", - "<pixmap filename>", - pageCreationFunction, + "ollamaPage": [ + QCoreApplication.translate( + "PluginOllamaInterface", "ollama AI Interface" + ), + os.path.join("OllamaInterface", "icons", "ollama22-{0}".format(iconSuffix)), + createOllamaPage, None, None, ], @@ -282,6 +289,14 @@ self.PreferencesKey + "/" + key, self.__defaults[key] ) ) + elif key in ("OllamaHost", "OllamaModelLibraryUrl"): + value = Preferences.Prefs.settings.value( + self.PreferencesKey + "/" + key, self.__defaults[key] + ) + if not value: + # use default value if empty + value = self.__defaults[key] + return value else: return Preferences.Prefs.settings.value( self.PreferencesKey + "/" + key, self.__defaults[key]