6 """ |
6 """ |
7 Module implementing a widget showing the chat with the 'ollama' server. |
7 Module implementing a widget showing the chat with the 'ollama' server. |
8 """ |
8 """ |
9 |
9 |
10 from PyQt6.QtCore import Qt, QTimer, pyqtSlot |
10 from PyQt6.QtCore import Qt, QTimer, pyqtSlot |
11 from PyQt6.QtWidgets import QVBoxLayout, QWidget |
11 from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QWidget |
12 |
12 |
13 from .OllamaChatMessageBox import OllamaChatMessageBox |
13 from .OllamaChatMessageBox import OllamaChatMessageBox |
14 from .Ui_OllamaChatWidget import Ui_OllamaChatWidget |
14 from .Ui_OllamaChatWidget import Ui_OllamaChatWidget |
15 |
15 |
16 |
16 |
40 self.headerLabel.setText( |
40 self.headerLabel.setText( |
41 self.tr("<b>{0} - {1}</b>", "title, model name").format(title, model) |
41 self.tr("<b>{0} - {1}</b>", "title, model name").format(title, model) |
42 ) |
42 ) |
43 |
43 |
44 self.__messagesLayout = QVBoxLayout() |
44 self.__messagesLayout = QVBoxLayout() |
45 self.__messagesLayout.setContentsMargins(4, 4, 4, 4) |
45 if parent is None: |
|
46 self.__messagesLayout.setContentsMargins(4, 4, 4, 4) |
|
47 else: |
|
48 self.__messagesLayout.setContentsMargins(0, 0, 0, 0) |
46 self.__messagesLayout.setAlignment(Qt.AlignmentFlag.AlignTop) |
49 self.__messagesLayout.setAlignment(Qt.AlignmentFlag.AlignTop) |
47 self.chatMessagesWidget.setLayout(self.__messagesLayout) |
50 self.chatMessagesWidget.setLayout(self.__messagesLayout) |
48 |
51 |
49 def addMessage(self, role, message): |
52 def addMessage(self, role, message, scrollToBottom=True): |
50 """ |
53 """ |
51 Public method to add a new message. |
54 Public method to add a new message. |
52 |
55 |
53 @param role role of the message sender (one of 'user' or 'assistant') |
56 @param role role of the message sender (one of 'user' or 'assistant') |
54 @type str |
57 @type str |
55 @param message message text |
58 @param message message text |
56 @type str |
59 @type str |
|
60 @param scrollToBottom flag indicating to scroll the view to the bottom |
|
61 (defaults to True) |
|
62 @type bool (optional) |
57 """ |
63 """ |
58 msgWidget = OllamaChatMessageBox(role=role, message=message) |
64 msgWidget = OllamaChatMessageBox(role=role, message=message) |
59 self.__messagesLayout.addWidget(msgWidget) |
65 self.__messagesLayout.addWidget(msgWidget) |
60 |
66 |
61 QTimer.singleShot(0, self.__scrollChatToBottom) |
67 if scrollToBottom: |
|
68 QTimer.singleShot(100, self.__scrollChatToBottom) |
62 |
69 |
63 def appendMessage(self, message): |
70 def appendMessage(self, message): |
64 """ |
71 """ |
65 Public method to append a given message to the bottom most message box. |
72 Public method to append a given message to the bottom most message box. |
66 |
73 |
100 """ |
107 """ |
101 msgBox = self.__messagesLayout.itemAt( |
108 msgBox = self.__messagesLayout.itemAt( |
102 self.__messagesLayout.count() - 1 |
109 self.__messagesLayout.count() - 1 |
103 ).widget() |
110 ).widget() |
104 return msgBox.getMessage() |
111 return msgBox.getMessage() |
|
112 |
|
113 def clear(self): |
|
114 """ |
|
115 Public method to clear the list of messages. |
|
116 """ |
|
117 while not self.__messagesLayout.isEmpty(): |
|
118 itm = self.__messagesLayout.takeAt(0) |
|
119 itm.widget().deleteLater() |
|
120 |
|
121 scrollbar = self.chatMessagesScrollArea.verticalScrollBar() |
|
122 scrollbar.setValue(0) |
|
123 |
|
124 |
|
125 class OllamaChatDialog(QDialog): |
|
126 """ |
|
127 Class implementing a dialog showing the chat with the 'ollama' server. |
|
128 """ |
|
129 |
|
130 def __init__(self, hid, title, model, parent=None): |
|
131 """ |
|
132 Constructor |
|
133 |
|
134 @param hid ID of the chat history |
|
135 @type str |
|
136 @param title title of the chat |
|
137 @type str |
|
138 @param model model name used for the chat |
|
139 @type str |
|
140 @param parent reference to the parent widget (defaults to None) |
|
141 @type QWidget (optional) |
|
142 """ |
|
143 super().__init__(parent) |
|
144 |
|
145 self.__layout = QVBoxLayout(self) |
|
146 self.__chatWidget = OllamaChatWidget( |
|
147 hid=hid, title=title, model=model, parent=self |
|
148 ) |
|
149 self.__layout.addWidget(self.__chatWidget) |
|
150 self.__buttonBox = QDialogButtonBox( |
|
151 QDialogButtonBox.StandardButton.Close, Qt.Orientation.Horizontal, self |
|
152 ) |
|
153 self.__buttonBox.rejected.connect(self.reject) |
|
154 self.__layout.addWidget(self.__buttonBox) |
|
155 |
|
156 self.setModal(False) |
|
157 self.setSizeGripEnabled(True) |
|
158 self.resize(600, 750) |
|
159 |
|
160 def getHistoryId(self): |
|
161 """ |
|
162 Public method to get the history ID of this chat. |
|
163 |
|
164 @return DESCRIPTION |
|
165 @rtype TYPE |
|
166 """ |
|
167 return self.__chatWidget.getHistoryId() |
|
168 |
|
169 def setHistory(self, messages): |
|
170 """ |
|
171 Public method to add a list of messages to the view. |
|
172 |
|
173 @param messages list of chat messages |
|
174 @type list[dict[str, str]] |
|
175 """ |
|
176 self.__chatWidget.clear() |
|
177 |
|
178 for message in messages: |
|
179 self.__chatWidget.addMessage( |
|
180 role=message["role"], message=message["content"], scrollToBottom=False |
|
181 ) |