pygpt-net 2.5.14__py3-none-any.whl → 2.5.15__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. pygpt_net/CHANGELOG.txt +6 -0
  2. pygpt_net/__init__.py +3 -3
  3. pygpt_net/controller/chat/input.py +9 -2
  4. pygpt_net/controller/lang/mapping.py +4 -2
  5. pygpt_net/controller/model/__init__.py +3 -1
  6. pygpt_net/controller/model/importer.py +337 -0
  7. pygpt_net/controller/settings/editor.py +3 -0
  8. pygpt_net/core/models/__init__.py +6 -3
  9. pygpt_net/core/models/ollama.py +7 -2
  10. pygpt_net/data/config/config.json +9 -4
  11. pygpt_net/data/config/models.json +22 -22
  12. pygpt_net/data/locale/locale.de.ini +18 -0
  13. pygpt_net/data/locale/locale.en.ini +19 -2
  14. pygpt_net/data/locale/locale.es.ini +18 -0
  15. pygpt_net/data/locale/locale.fr.ini +18 -0
  16. pygpt_net/data/locale/locale.it.ini +18 -0
  17. pygpt_net/data/locale/locale.pl.ini +19 -1
  18. pygpt_net/data/locale/locale.uk.ini +18 -0
  19. pygpt_net/data/locale/locale.zh.ini +17 -0
  20. pygpt_net/item/model.py +5 -1
  21. pygpt_net/provider/core/model/json_file.py +3 -0
  22. pygpt_net/provider/core/model/patch.py +24 -1
  23. pygpt_net/provider/llms/ollama.py +7 -2
  24. pygpt_net/provider/llms/ollama_custom.py +693 -0
  25. pygpt_net/ui/dialog/models_importer.py +82 -0
  26. pygpt_net/ui/dialogs.py +3 -1
  27. pygpt_net/ui/menu/config.py +18 -7
  28. pygpt_net/ui/widget/dialog/model_importer.py +55 -0
  29. pygpt_net/ui/widget/lists/model_importer.py +151 -0
  30. {pygpt_net-2.5.14.dist-info → pygpt_net-2.5.15.dist-info}/METADATA +68 -8
  31. {pygpt_net-2.5.14.dist-info → pygpt_net-2.5.15.dist-info}/RECORD +34 -29
  32. {pygpt_net-2.5.14.dist-info → pygpt_net-2.5.15.dist-info}/LICENSE +0 -0
  33. {pygpt_net-2.5.14.dist-info → pygpt_net-2.5.15.dist-info}/WHEEL +0 -0
  34. {pygpt_net-2.5.14.dist-info → pygpt_net-2.5.15.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # ================================================== #
4
+ # This file is a part of PYGPT package #
5
+ # Website: https://pygpt.net #
6
+ # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
+ # MIT License #
8
+ # Created By : Marcin Szczygliński #
9
+ # Updated Date: 2025.06.24 02:00:00 #
10
+ # ================================================== #
11
+ from PySide6 import QtCore
12
+ from PySide6.QtWidgets import QPushButton, QHBoxLayout, QVBoxLayout, QLabel
13
+
14
+ from pygpt_net.ui.widget.lists.model_importer import ModelImporter
15
+ from pygpt_net.ui.widget.dialog.model_importer import ModelImporterOllamaDialog
16
+ from pygpt_net.utils import trans
17
+
18
+
19
+ class ModelsImporter:
20
+ def __init__(self, window=None):
21
+ """
22
+ Models importer dialog
23
+
24
+ :param window: Window instance
25
+ """
26
+ self.window = window
27
+ self.dialog_id = "models.importer"
28
+
29
+ def setup(self, idx=None):
30
+ """
31
+ Setup dialog
32
+
33
+ :param idx: current model tab index
34
+ """
35
+ # models
36
+ self.window.ui.nodes['models.importer.editor'] = ModelImporter(self.window)
37
+
38
+ self.window.ui.nodes['models.importer.btn.refresh'] = \
39
+ QPushButton(trans("dialog.models.importer.btn.refresh"))
40
+ self.window.ui.nodes['models.importer.btn.cancel'] = \
41
+ QPushButton(trans("dialog.models.importer.btn.cancel"))
42
+ self.window.ui.nodes['models.importer.btn.save'] = \
43
+ QPushButton(trans("dialog.models.importer.btn.save"))
44
+
45
+ self.window.ui.nodes['models.importer.btn.refresh'].clicked.connect(
46
+ lambda: self.window.controller.model.importer.refresh(reload=True))
47
+ self.window.ui.nodes['models.importer.btn.cancel'].clicked.connect(
48
+ lambda: self.window.controller.model.importer.cancel())
49
+ self.window.ui.nodes['models.importer.btn.save'].clicked.connect(
50
+ lambda: self.window.controller.model.importer.save())
51
+
52
+ # set enter key to save button
53
+ self.window.ui.nodes['models.importer.btn.refresh'].setAutoDefault(False)
54
+ self.window.ui.nodes['models.importer.btn.cancel'].setAutoDefault(False)
55
+ self.window.ui.nodes['models.importer.btn.save'].setAutoDefault(True)
56
+
57
+ # footer buttons
58
+ footer = QHBoxLayout()
59
+ footer.addWidget(self.window.ui.nodes['models.importer.btn.refresh'])
60
+ footer.addWidget(self.window.ui.nodes['models.importer.btn.cancel'])
61
+ footer.addWidget(self.window.ui.nodes['models.importer.btn.save'])
62
+
63
+ self.window.ui.nodes["models.importer.url"] = QLabel("S")
64
+ self.window.ui.nodes["models.importer.url"].setAlignment(QtCore.Qt.AlignRight)
65
+ self.window.ui.nodes["models.importer.url"].setContentsMargins(10, 10, 10, 10)
66
+
67
+ main_layout = QVBoxLayout()
68
+ main_layout.addWidget(self.window.ui.nodes["models.importer.url"])
69
+ main_layout.addWidget(self.window.ui.nodes['models.importer.editor'])
70
+
71
+ self.window.ui.nodes["models.importer.status"] = QLabel("S")
72
+ self.window.ui.nodes["models.importer.status"].setAlignment(QtCore.Qt.AlignCenter)
73
+ self.window.ui.nodes["models.importer.status"].setContentsMargins(10, 10, 10, 10)
74
+
75
+ layout = QVBoxLayout()
76
+ layout.addLayout(main_layout) # list
77
+ layout.addWidget(self.window.ui.nodes["models.importer.status"])
78
+ layout.addLayout(footer) # bottom buttons (save, defaults)
79
+
80
+ self.window.ui.dialog[self.dialog_id] = ModelImporterOllamaDialog(self.window, self.dialog_id)
81
+ self.window.ui.dialog[self.dialog_id].setLayout(layout)
82
+ self.window.ui.dialog[self.dialog_id].setWindowTitle(trans('dialog.models.importer'))
pygpt_net/ui/dialogs.py CHANGED
@@ -6,7 +6,7 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2024.11.26 02:00:00 #
9
+ # Updated Date: 2025.06.24 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import threading
@@ -26,6 +26,7 @@ from pygpt_net.ui.dialog.image import Image
26
26
  from pygpt_net.ui.dialog.license import License
27
27
  from pygpt_net.ui.dialog.logger import Logger
28
28
  from pygpt_net.ui.dialog.models import Models
29
+ from pygpt_net.ui.dialog.models_importer import ModelsImporter
29
30
  from pygpt_net.ui.dialog.plugins import Plugins
30
31
  from pygpt_net.ui.dialog.preset import Preset
31
32
  from pygpt_net.ui.dialog.preset_plugins import PresetPlugins
@@ -101,6 +102,7 @@ class Dialogs:
101
102
  self.window.plugin_settings = Plugins(self.window)
102
103
  self.window.plugin_presets = PresetPlugins(self.window)
103
104
  self.window.model_settings = Models(self.window)
105
+ self.window.model_importer = ModelsImporter(self.window)
104
106
  self.window.assistant_store = AssistantVectorStore(self.window)
105
107
 
106
108
  self.window.ui.dialog['alert'] = AlertDialog(self.window)
@@ -6,7 +6,7 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2024.12.07 21:00:00 #
9
+ # Updated Date: 2025.06.24 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import os
@@ -38,11 +38,25 @@ class Config:
38
38
  trans("menu.config.settings"), self.window)
39
39
  self.window.ui.menu['config.settings'].setMenuRole(QAction.MenuRole.NoRole)
40
40
 
41
- self.window.ui.menu['config.models'] = QAction(QIcon(":/icons/settings_filled.svg"),
42
- trans("menu.config.models"), self.window)
41
+ self.window.ui.menu['config.models'] = QMenu(trans("menu.config.models"), self.window)
43
42
 
44
43
  self.window.ui.menu['config.access'] = QAction(QIcon(":/icons/accessibility.svg"),
45
44
  trans("menu.config.access"), self.window)
45
+ self.window.ui.menu['config.access'].setMenuRole(QAction.MenuRole.NoRole)
46
+
47
+ # models
48
+ self.window.ui.menu['config.models.edit'] = QAction(QIcon(":/icons/settings_filled.svg"),
49
+ trans("menu.config.models.edit"), self.window)
50
+ self.window.ui.menu['config.models.edit'].triggered.connect(
51
+ lambda: self.window.controller.model.editor.toggle_editor())
52
+ self.window.ui.menu['config.models.import.ollama'] = QAction(QIcon(":/icons/reload.svg"),
53
+ trans("menu.config.models.import.ollama"), self.window)
54
+ self.window.ui.menu['config.models.import.ollama'].triggered.connect(
55
+ lambda: self.window.controller.model.importer.toggle_editor())
56
+
57
+ self.window.ui.menu['config.models'].addAction(self.window.ui.menu['config.models.edit'])
58
+ self.window.ui.menu['config.models'].addAction(self.window.ui.menu['config.models.import.ollama'])
59
+
46
60
 
47
61
  css_dir = os.path.join(self.window.core.config.path, 'css')
48
62
  css_files = os.listdir(css_dir)
@@ -125,9 +139,6 @@ class Config:
125
139
  self.window.ui.menu['config.settings'].triggered.connect(
126
140
  lambda: self.window.controller.settings.toggle_editor('settings'))
127
141
 
128
- self.window.ui.menu['config.models'].triggered.connect(
129
- lambda: self.window.controller.model.editor.toggle_editor())
130
-
131
142
  self.window.ui.menu['config.access'].triggered.connect(
132
143
  lambda: self.window.controller.settings.open_section('access'))
133
144
 
@@ -145,7 +156,7 @@ class Config:
145
156
 
146
157
  self.window.ui.menu['menu.config'] = self.window.menuBar().addMenu(trans("menu.config"))
147
158
  self.window.ui.menu['menu.config'].addAction(self.window.ui.menu['config.settings'])
148
- self.window.ui.menu['menu.config'].addAction(self.window.ui.menu['config.models'])
159
+ self.window.ui.menu['menu.config'].addMenu(self.window.ui.menu['config.models'])
149
160
  self.window.ui.menu['menu.config'].addAction(self.window.ui.menu['config.access'])
150
161
 
151
162
  self.window.ui.menu['menu.config'].addMenu(self.window.ui.menu['menu.theme'])
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # ================================================== #
4
+ # This file is a part of PYGPT package #
5
+ # Website: https://pygpt.net #
6
+ # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
+ # MIT License #
8
+ # Created By : Marcin Szczygliński #
9
+ # Updated Date: 2025.06.24 02:00:00 #
10
+ # ================================================== #
11
+
12
+ from PySide6.QtCore import Qt
13
+ from .base import BaseDialog
14
+
15
+
16
+ class ModelImporterOllamaDialog(BaseDialog):
17
+ def __init__(self, window=None, id=None):
18
+ """
19
+ Model importer dialog
20
+
21
+ :param window: main window
22
+ :param id: settings id
23
+ """
24
+ super(ModelImporterOllamaDialog, self).__init__(window, id)
25
+ self.window = window
26
+ self.id = id
27
+
28
+ def closeEvent(self, event):
29
+ """
30
+ Close event
31
+
32
+ :param event: close event
33
+ """
34
+ self.window.controller.model.importer.dialog = False
35
+ self.window.controller.model.update()
36
+ super(ModelImporterOllamaDialog, self).closeEvent(event)
37
+
38
+ def keyPressEvent(self, event):
39
+ """
40
+ Key press event
41
+
42
+ :param event: key press event
43
+ """
44
+ if event.key() == Qt.Key_Escape:
45
+ self.cleanup()
46
+ self.close() # close dialog when the Esc key is pressed.
47
+ else:
48
+ super(ModelImporterOllamaDialog, self).keyPressEvent(event)
49
+
50
+ def cleanup(self):
51
+ """
52
+ Cleanup on close
53
+ """
54
+ self.window.controller.model.importer.dialog = False
55
+ self.window.controller.model.update()
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # ================================================== #
4
+ # This file is a part of PYGPT package #
5
+ # Website: https://pygpt.net #
6
+ # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
+ # MIT License #
8
+ # Created By : Marcin Szczygliński #
9
+ # Updated Date: 2025.06.24 02:00:00 #
10
+ # ================================================== #
11
+
12
+ from PySide6 import QtCore
13
+ from PySide6.QtGui import QStandardItemModel
14
+ from PySide6.QtWidgets import QWidget, QHBoxLayout, QPushButton, QVBoxLayout, QLabel, QCheckBox
15
+
16
+ from pygpt_net.ui.widget.lists.base import BaseList
17
+ from pygpt_net.utils import trans
18
+ import pygpt_net.icons_rc
19
+
20
+ class ModelImporter(QWidget):
21
+ def __init__(self, window=None):
22
+ """
23
+ Models importer widget
24
+
25
+ :param window: main window
26
+ """
27
+ super(ModelImporter, self).__init__(window)
28
+ self.window = window
29
+ self.id = "models.importer"
30
+ self.layout = self.setup()
31
+ self.window.ui.models["models.importer.available"] = self.create_model(self.window)
32
+ self.window.ui.nodes["models.importer.available"].setModel(self.window.ui.models["models.importer.available"])
33
+ self.window.ui.nodes["models.importer.available"].selectionModel().selectionChanged.connect(
34
+ lambda: self.window.controller.model.importer.change_available()
35
+ )
36
+ self.window.ui.models["models.importer.current"] = self.create_model(self.window)
37
+ self.window.ui.nodes["models.importer.current"].setModel(self.window.ui.models["models.importer.current"])
38
+ self.window.ui.nodes["models.importer.current"].selectionModel().selectionChanged.connect(
39
+ lambda: self.window.controller.model.importer.change_current()
40
+ )
41
+ self.setLayout(self.layout)
42
+
43
+ def create_model(self, parent) -> QStandardItemModel:
44
+ """
45
+ Create model
46
+
47
+ :param parent: parent widget
48
+ :return: QStandardItemModel
49
+ """
50
+ return QStandardItemModel(0, 1, parent)
51
+
52
+ def setup(self):
53
+ """Setup layout"""
54
+ layout = QHBoxLayout()
55
+ arrows_layout = QVBoxLayout()
56
+ self.window.ui.nodes["models.importer.add"] = QPushButton(">")
57
+ self.window.ui.nodes["models.importer.add"].clicked.connect(
58
+ lambda: self.window.controller.model.importer.add()
59
+ )
60
+ self.window.ui.nodes["models.importer.remove"] = QPushButton("<")
61
+ self.window.ui.nodes["models.importer.remove"].clicked.connect(
62
+ lambda: self.window.controller.model.importer.remove()
63
+ )
64
+ self.window.ui.nodes["models.importer.add"].setEnabled(False) # initially disabled
65
+ self.window.ui.nodes["models.importer.remove"].setEnabled(False) # initially disabled
66
+ arrows_layout.addWidget(self.window.ui.nodes["models.importer.add"])
67
+ arrows_layout.addWidget(self.window.ui.nodes["models.importer.remove"])
68
+
69
+ self.window.ui.nodes["models.importer.available.label"] = QLabel(trans("models.importer.available.label"))
70
+ self.window.ui.nodes["models.importer.available"] = BaseList(self.window)
71
+ self.window.ui.nodes["models.importer.available"].clicked.disconnect()
72
+
73
+ self.window.ui.nodes["models.importer.current.label"] = QLabel(trans("models.importer.current.label"))
74
+ self.window.ui.nodes["models.importer.current"] = BaseList(self.window)
75
+ self.window.ui.nodes["models.importer.current"].clicked.disconnect()
76
+
77
+ self.window.ui.nodes["models.importer.available.all"] = QCheckBox(trans("models.importer.all"), self.window)
78
+ self.window.ui.nodes["models.importer.available.all"].clicked.connect(
79
+ lambda: self.window.controller.model.importer.toggle_all(
80
+ self.window.ui.nodes["models.importer.available.all"].isChecked())
81
+ )
82
+
83
+ available_layout = QVBoxLayout()
84
+ available_layout.addWidget(self.window.ui.nodes["models.importer.available.label"])
85
+ available_layout.addWidget(self.window.ui.nodes["models.importer.available"])
86
+ available_layout.addWidget(self.window.ui.nodes["models.importer.available.all"])
87
+
88
+ selected_layout = QVBoxLayout()
89
+ selected_layout.addWidget(self.window.ui.nodes["models.importer.current.label"])
90
+ selected_layout.addWidget(self.window.ui.nodes["models.importer.current"])
91
+
92
+ layout.addLayout(available_layout)
93
+ layout.addLayout(arrows_layout)
94
+ layout.addLayout(selected_layout)
95
+ return layout
96
+
97
+ def update_available(self, data):
98
+ """
99
+ Update available models
100
+
101
+ :param data: Data to update
102
+ """
103
+ id = "models.importer.available"
104
+ self.window.ui.nodes[id].backup_selection()
105
+ self.window.ui.models[id].removeRows(0, self.window.ui.models[id].rowCount())
106
+ i = 0
107
+ for n in data:
108
+ self.window.ui.models[id].insertRow(i)
109
+ name = data[n].id
110
+ if data[n].name != data[n].id:
111
+ name += f" --> {data[n].name}"
112
+ index = self.window.ui.models[id].index(i, 0)
113
+ tooltip = data[n].id
114
+ self.window.ui.models[id].setData(index, tooltip, QtCore.Qt.ToolTipRole)
115
+ self.window.ui.models[id].setData(self.window.ui.models[id].index(i, 0), name)
116
+ i += 1
117
+ self.window.ui.nodes[id].restore_selection()
118
+
119
+ def update_current(self, data):
120
+ """
121
+ Update current models
122
+
123
+ :param data: Data to update
124
+ """
125
+ id = "models.importer.current"
126
+ self.window.ui.nodes[id].backup_selection()
127
+ self.window.ui.models[id].removeRows(0, self.window.ui.models[id].rowCount())
128
+ i = 0
129
+ for n in data:
130
+ self.window.ui.models[id].insertRow(i)
131
+ name = data[n].id
132
+ if data[n].name != data[n].id:
133
+ name += f" --> {data[n].name}"
134
+ if data[n].imported:
135
+ name = "* " + name # mark imported models
136
+ index = self.window.ui.models[id].index(i, 0)
137
+ tooltip = data[n].id
138
+ self.window.ui.models[id].setData(index, tooltip, QtCore.Qt.ToolTipRole)
139
+ self.window.ui.models[id].setData(self.window.ui.models[id].index(i, 0), name)
140
+ i += 1
141
+ self.window.ui.nodes[id].restore_selection()
142
+
143
+ def update_lists(self, available: dict, current: dict):
144
+ """
145
+ Update lists
146
+
147
+ :param available: data with available models
148
+ :param current: data with current models
149
+ """
150
+ self.update_available(available)
151
+ self.update_current(current)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pygpt-net
3
- Version: 2.5.14
3
+ Version: 2.5.15
4
4
  Summary: Desktop AI Assistant powered by models: OpenAI o1, GPT-4o, GPT-4, GPT-4 Vision, GPT-3.5, DALL-E 3, Llama 3, Mistral, Gemini, Claude, DeepSeek, Bielik, and other models supported by Langchain, Llama Index, and Ollama. Features include chatbot, text completion, image generation, vision analysis, speech-to-text, internet access, file handling, command execution and more.
5
5
  License: MIT
6
6
  Keywords: py_gpt,py-gpt,pygpt,desktop,app,o1,gpt,gpt4,gpt-4o,gpt-4v,gpt3.5,gpt-4,gpt-4-vision,gpt-3.5,llama3,mistral,gemini,deepseek,bielik,claude,tts,whisper,vision,chatgpt,dall-e,chat,chatbot,assistant,text completion,image generation,ai,api,openai,api key,langchain,llama-index,ollama,presets,ui,qt,pyside
@@ -100,7 +100,7 @@ Description-Content-Type: text/markdown
100
100
 
101
101
  [![pygpt](https://snapcraft.io/pygpt/badge.svg)](https://snapcraft.io/pygpt)
102
102
 
103
- Release: **2.5.14** | build: **2025-06-23** | Python: **>=3.10, <3.13**
103
+ Release: **2.5.15** | build: **2025-06-23** | Python: **>=3.10, <3.13**
104
104
 
105
105
  > Official website: https://pygpt.net | Documentation: https://pygpt.readthedocs.io
106
106
  >
@@ -1003,17 +1003,33 @@ The name of the currently active profile is shown as (Profile Name) in the windo
1003
1003
 
1004
1004
  ## Built-in models
1005
1005
 
1006
- PyGPT has built-in support for models (as of 2025-06-21):
1006
+ PyGPT has built-in support for models (as of 2025-06-24):
1007
1007
 
1008
1008
  - `bielik-11b-v2.3-instruct:Q4_K_M`
1009
1009
  - `chatgpt-4o-latest`
1010
1010
  - `claude-3-5-sonnet-20240620`
1011
- - `claude-3-opus-20240229`
1011
+ - `claude-3-7-sonnet`
1012
+ - `claude-3-opus`
1013
+ - `claude-3-opus`
1014
+ - `claude-opus-4-0`
1015
+ - `claude-sonnet-4-0`
1012
1016
  - `codellama`
1013
1017
  - `dall-e-2`
1014
1018
  - `dall-e-3`
1019
+ - `deepseek-chat`
1020
+ - `deepseek-r1:1.5b`
1021
+ - `deepseek-r1:14b`
1022
+ - `deepseek-r1:32b`
1023
+ - `deepseek-r1:670b`
1024
+ - `deepseek-r1:7b`
1025
+ - `deepseek-r1:671b`
1026
+ - `deepseek-reasoner`
1027
+ - `deepseek-v3:671b`
1015
1028
  - `gemini-1.5-flash`
1016
1029
  - `gemini-1.5-pro`
1030
+ - `gemini-2.0-flash-exp`
1031
+ - `gemini-2.5-flash`
1032
+ - `gemini-2.5-pro`
1017
1033
  - `gpt-3.5-turbo`
1018
1034
  - `gpt-3.5-turbo-1106`
1019
1035
  - `gpt-3.5-turbo-16k`
@@ -1026,6 +1042,9 @@ PyGPT has built-in support for models (as of 2025-06-21):
1026
1042
  - `gpt-4-turbo-2024-04-09`
1027
1043
  - `gpt-4-turbo-preview`
1028
1044
  - `gpt-4-vision-preview`
1045
+ - `gpt-4.1`
1046
+ - `gpt-4.1-mini`
1047
+ - `gpt-4.5-preview`
1029
1048
  - `gpt-4o`
1030
1049
  - `gpt-4o-2024-11-20`
1031
1050
  - `gpt-4o-audio-preview`
@@ -1036,8 +1055,21 @@ PyGPT has built-in support for models (as of 2025-06-21):
1036
1055
  - `llama3.1:70b`
1037
1056
  - `mistral`
1038
1057
  - `mistral-large`
1058
+ - `o1`
1039
1059
  - `o1-mini`
1040
- - `o1-preview`
1060
+ - `o1-pro`
1061
+ - `o3`
1062
+ - `o3-mini`
1063
+ - `o3-pro`
1064
+ - `qwen:7b`
1065
+ - `qwen2:7b`
1066
+ - `qwen2.5-coder:7b`
1067
+ - `r1` (Perplexity)
1068
+ - `sonar` (Perplexity)
1069
+ - `sonar-deep-research` (Perplexity)
1070
+ - `sonar-pro` (Perplexity)
1071
+ - `sonar-reasoning` (Perplexity)
1072
+ - `sonar-reasoning-pro` (Perplexity)
1041
1073
 
1042
1074
  All models are specified in the configuration file `models.json`, which you can customize.
1043
1075
  This file is located in your working directory. You can add new models provided directly by `OpenAI API`
@@ -1055,16 +1087,17 @@ There is built-in support for those LLM providers:
1055
1087
  - HuggingFace (huggingface)
1056
1088
  - Anthropic (anthropic)
1057
1089
  - Ollama (ollama)
1090
+ - Deepseek API (deepseek_api)
1058
1091
 
1059
1092
  ## How to use local or non-GPT models
1060
1093
 
1061
- ### Llama 3, Mistral, and other local models
1094
+ ### Llama 3, Mistral, DeepSeek, and other local models
1062
1095
 
1063
1096
  How to use locally installed Llama 3 or Mistral models:
1064
1097
 
1065
- 1) Choose a working mode: `Chat with Files` or `LangChain`.
1098
+ 1) Choose a working mode: `Chat with Files`.
1066
1099
 
1067
- 2) On the models list - select, edit, or add a new model (with `ollama` provider). You can edit the model settings through the menu `Config -> Models`, then configure the model parameters in the `advanced` section.
1100
+ 2) On the models list - select, edit, or add a new model (with `ollama` provider). You can edit the model settings through the menu `Config -> Models -> Edit`, then configure the model parameters in the `advanced` section.
1068
1101
 
1069
1102
  3) Download and install Ollama from here: https://github.com/ollama/ollama
1070
1103
 
@@ -1084,9 +1117,30 @@ For example, on Linux:
1084
1117
  - `codellama`
1085
1118
  - `mistral`
1086
1119
  - `llama2-uncensored`
1120
+ - `deepseek-r1`
1121
+
1122
+ etc.
1087
1123
 
1088
1124
  You can add more models by editing the models list.
1089
1125
 
1126
+ **Real-time importer**
1127
+
1128
+ You can also import models in real-time from a running Ollama instance using the `Config -> Models -> Import from Ollama` tool.
1129
+
1130
+ **Custom Ollama endpoint**
1131
+
1132
+ The default endpoint for Ollama is: http://localhost:11434
1133
+
1134
+ You can change it globally by setting the environment variable `OLLAMA_API_BASE` in `Settings -> General -> Advanced -> Application environment`.
1135
+
1136
+ You can also change the "base_url" for a specific model in its configuration:
1137
+
1138
+ `Config -> Models -> Edit`, then in the `Advanced -> [LlamaIndex] ENV Vars` section add the variable:
1139
+
1140
+ NAME: `OLLAMA_API_BASE`
1141
+ VALUE: `http://my_endpoint.com:11434`
1142
+
1143
+
1090
1144
  **List of all models supported by Ollama**
1091
1145
 
1092
1146
  https://ollama.com/library
@@ -4070,6 +4124,12 @@ may consume additional tokens that are not displayed in the main window.
4070
4124
 
4071
4125
  ## Recent changes:
4072
4126
 
4127
+ **2.5.15 (2025-06-24)**
4128
+
4129
+ - Added Ollama models importer in "Settings -> Models -> Import from Ollama".
4130
+ - Fixed Ollama provider in the newest LlamaIndex.
4131
+ - Added the ability to set a custom base URL for Ollama -> ENV: OLLAMA_API_BASE.
4132
+
4073
4133
  **2.5.14 (2025-06-23)**
4074
4134
 
4075
4135
  - Fix: crash if empty shortcuts in config.