pygpt-net 2.5.17__py3-none-any.whl → 2.5.18__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.
- pygpt_net/CHANGELOG.txt +7 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/controller/chat/common.py +4 -2
- pygpt_net/controller/chat/input.py +36 -27
- pygpt_net/controller/chat/stream.py +22 -2
- pygpt_net/controller/config/placeholder.py +1 -1
- pygpt_net/controller/model/__init__.py +1 -1
- pygpt_net/controller/model/editor.py +6 -1
- pygpt_net/controller/model/importer.py +4 -3
- pygpt_net/core/bridge/__init__.py +8 -4
- pygpt_net/core/command/__init__.py +10 -1
- pygpt_net/core/idx/chat.py +6 -1
- pygpt_net/core/image/__init__.py +15 -0
- pygpt_net/core/models/__init__.py +14 -6
- pygpt_net/core/models/ollama.py +4 -3
- pygpt_net/data/config/config.json +4 -3
- pygpt_net/data/config/models.json +205 -34
- pygpt_net/data/config/modes.json +10 -10
- pygpt_net/data/config/settings.json +22 -0
- pygpt_net/data/locale/locale.de.ini +1 -1
- pygpt_net/data/locale/locale.en.ini +6 -2
- pygpt_net/data/locale/locale.es.ini +1 -1
- pygpt_net/data/locale/locale.fr.ini +1 -1
- pygpt_net/data/locale/locale.pl.ini +1 -1
- pygpt_net/data/locale/locale.uk.ini +1 -1
- pygpt_net/data/locale/locale.zh.ini +1 -1
- pygpt_net/item/model.py +35 -1
- pygpt_net/provider/core/config/patch.py +7 -0
- pygpt_net/provider/core/model/json_file.py +4 -1
- pygpt_net/provider/core/model/patch.py +17 -1
- pygpt_net/provider/gpt/__init__.py +14 -0
- pygpt_net/provider/gpt/image.py +42 -8
- pygpt_net/provider/gpt/responses.py +22 -16
- pygpt_net/provider/llms/anthropic.py +3 -1
- pygpt_net/provider/llms/google.py +3 -1
- pygpt_net/provider/llms/hugging_face.py +3 -1
- pygpt_net/provider/llms/hugging_face_api.py +3 -1
- pygpt_net/provider/llms/ollama.py +9 -3
- pygpt_net/provider/llms/openai.py +7 -1
- pygpt_net/ui/dialog/preset.py +1 -1
- {pygpt_net-2.5.17.dist-info → pygpt_net-2.5.18.dist-info}/METADATA +13 -6
- {pygpt_net-2.5.17.dist-info → pygpt_net-2.5.18.dist-info}/RECORD +45 -45
- {pygpt_net-2.5.17.dist-info → pygpt_net-2.5.18.dist-info}/LICENSE +0 -0
- {pygpt_net-2.5.17.dist-info → pygpt_net-2.5.18.dist-info}/WHEEL +0 -0
- {pygpt_net-2.5.17.dist-info → pygpt_net-2.5.18.dist-info}/entry_points.txt +0 -0
@@ -1027,6 +1027,11 @@
|
|
1027
1027
|
"step": null,
|
1028
1028
|
"advanced": false,
|
1029
1029
|
"keys": [
|
1030
|
+
{"auto": "[gpt-image-1] auto"},
|
1031
|
+
{"1024x1024": "[gpt-image-1] 1024x1024"},
|
1032
|
+
{"1536x1024": "[gpt-image-1] 1536x1024"},
|
1033
|
+
{"1024x1536": "[gpt-image-1] 1024x1536"},
|
1034
|
+
{"1536x1024": "[gpt-image-1] 1536x1024"},
|
1030
1035
|
{"1792x1024": "[DALL-E 3] 1792x1024"},
|
1031
1036
|
{"1024x1792": "[DALL-E 3] 1024x1792"},
|
1032
1037
|
{"1024x1024": "[DALL-E 3] 1024x1024"},
|
@@ -1047,6 +1052,10 @@
|
|
1047
1052
|
"step": null,
|
1048
1053
|
"advanced": false,
|
1049
1054
|
"keys": [
|
1055
|
+
{"auto": "[gpt-image-1] auto"},
|
1056
|
+
{"high": "[gpt-image-1] high"},
|
1057
|
+
{"medium": "[gpt-image-1] medium"},
|
1058
|
+
{"medium": "[gpt-image-1] low"},
|
1050
1059
|
{"standard": "[DALL-E 3] standard"},
|
1051
1060
|
{"hd": "[DALL-E 3] hd"},
|
1052
1061
|
{"standard": "[DALL-E 2] standard"}
|
@@ -1211,6 +1220,19 @@
|
|
1211
1220
|
"step": null,
|
1212
1221
|
"advanced": false
|
1213
1222
|
},
|
1223
|
+
"remote_tools.image": {
|
1224
|
+
"section": "remote_tools",
|
1225
|
+
"type": "bool",
|
1226
|
+
"slider": false,
|
1227
|
+
"label": "settings.remote_tools.image",
|
1228
|
+
"description": "settings.remote_tools.image.desc",
|
1229
|
+
"value": true,
|
1230
|
+
"min": null,
|
1231
|
+
"max": null,
|
1232
|
+
"multiplier": null,
|
1233
|
+
"step": null,
|
1234
|
+
"advanced": false
|
1235
|
+
},
|
1214
1236
|
"llama.idx.list": {
|
1215
1237
|
"section": "llama-index",
|
1216
1238
|
"type": "dict",
|
@@ -989,7 +989,7 @@ tip.tokens.input = Token: Benutzereingabeaufforderung + Systemaufforderung + Kon
|
|
989
989
|
tip.toolbox.assistants = Die Liste der Assistenten zeigt die erstellten Assistenten, die auf dem entfernten Server arbeiten. Alle Änderungen werden mit dem entfernten Assistenten synchronisiert.
|
990
990
|
tip.toolbox.ctx = Erstellen Sie so viele Gesprächskontexte, wie Sie benötigen; Sie können jederzeit zu ihnen zurückkehren.
|
991
991
|
tip.toolbox.indexes = Durch das Indizieren von Gesprächen und Dateien können Sie das verfügbare Wissen mit Ihren eigenen Daten und Gesprächsverläufen erweitern.
|
992
|
-
tip.toolbox.mode = Sie können den Arbeitsmodus und das Modell in Echtzeit ändern.
|
992
|
+
tip.toolbox.mode = Sie können den Arbeitsmodus und das Modell in Echtzeit ändern.
|
993
993
|
tip.toolbox.presets = Erstellen Sie Voreinstellungen mit verschiedenen Konfigurationen, um schnell zwischen verschiedenen Einstellungen wie dem Systemprompt und anderen zu wechseln.
|
994
994
|
tip.toolbox.prompt = Die aktuelle Systemeingabeaufforderung kann in Echtzeit geändert werden. Um Werkzeuge aus Plugins zu aktivieren, aktivieren Sie die Option "+ Werkzeuge."
|
995
995
|
toolbox.agent.auto_stop.label = Automatischer Stopp
|
@@ -816,7 +816,7 @@ model.llama_index.mode.desc = Available sub-modes: chat
|
|
816
816
|
model.llama_index.provider = [LlamaIndex] Provider
|
817
817
|
model.llama_index.provider.desc = LLM provider to use in "Chat with Files" mode
|
818
818
|
model.mode = Mode(s)
|
819
|
-
model.mode.desc = Available modes: chat, completion, img
|
819
|
+
model.mode.desc = Available modes: chat (Chat), llama_index (Chat with Files), audio (Chat with Audio), research (Research), completion (Completion), img (Image), vision (Vision), assistant (Assistants), langchain (Langchain), agent_llama (Agent LlamaIndex), agent (Agent Autonomous), expert (Experts)
|
820
820
|
model.name = Name
|
821
821
|
models.importer.all = Show all
|
822
822
|
models.importer.available.label = Ollama models
|
@@ -829,6 +829,8 @@ models.importer.error.remove.no_model = No model selected to remove
|
|
829
829
|
models.importer.error.remove.not_exists = Model already exists in current list
|
830
830
|
models.importer.loaded = Ollama models loaded successfully.
|
831
831
|
models.importer.status.imported = Models imported successfully.
|
832
|
+
model.openai = OpenAI API
|
833
|
+
model.openai.desc = Supports native OpenAI API
|
832
834
|
model.tokens = Output tokens
|
833
835
|
model.tokens.desc = Max model output tokens
|
834
836
|
mode.research = Research (Perplexity)
|
@@ -1129,6 +1131,8 @@ settings.prompt.img = DALL-E: image generation
|
|
1129
1131
|
settings.prompt.img.desc = Prompt for generating prompts for DALL-E (if raw-mode is disabled). Image mode only.
|
1130
1132
|
settings.remote_tools.web_search = Web Search
|
1131
1133
|
settings.remote_tools.web_search.desc = Enable `web_search` remote tool in Chat mode / via OpenAI Responses API.
|
1134
|
+
settings.remote_tools.image = Image generation
|
1135
|
+
settings.remote_tools.image.desc = Enable `image_generation` remote tool in Chat mode / via OpenAI Responses API.
|
1132
1136
|
settings.render.code_syntax = Code syntax highlight
|
1133
1137
|
settings.render.engine = Rendering engine
|
1134
1138
|
settings.render.open_gl = OpenGL hardware acceleration
|
@@ -1238,7 +1242,7 @@ tip.tokens.input = Tokens: input prompt + system prompt + context + extra + atta
|
|
1238
1242
|
tip.toolbox.assistants = The list of assistants shows the assistants created and operating on the remote server. Any changes will be synchronized with the remote assistant.
|
1239
1243
|
tip.toolbox.ctx = Create as many conversation contexts as you need; you can return to them at any time.
|
1240
1244
|
tip.toolbox.indexes = By indexing conversations and files, you can expand the available knowledge with your own data and conversation history.
|
1241
|
-
tip.toolbox.mode = You can change the working mode and model in real-time.
|
1245
|
+
tip.toolbox.mode = You can change the working mode and model in real-time.
|
1242
1246
|
tip.toolbox.presets = Create presets with different configurations to quickly switch between various settings, such as the system prompt and others.
|
1243
1247
|
tip.toolbox.prompt = The current system prompt can be modified in real-time. To enable tools from plugins, enable the option "+ Tools."
|
1244
1248
|
toolbox.agent.auto_stop.label = Auto-stop
|
@@ -989,7 +989,7 @@ tip.tokens.input = Fichas: indicación del usuario + indicación del sistema + c
|
|
989
989
|
tip.toolbox.assistants = La lista de asistentes muestra los asistentes creados y operando en el servidor remoto. Cualquier cambio se sincronizará con el asistente remoto.
|
990
990
|
tip.toolbox.ctx = Crea tantos contextos de conversación como necesites; puedes volver a ellos en cualquier momento.
|
991
991
|
tip.toolbox.indexes = Al indexar conversaciones y archivos, puedes ampliar el conocimiento disponible con tus propios datos e historial de conversaciones.
|
992
|
-
tip.toolbox.mode = Puedes cambiar el modo de trabajo y el modelo en tiempo real.
|
992
|
+
tip.toolbox.mode = Puedes cambiar el modo de trabajo y el modelo en tiempo real.
|
993
993
|
tip.toolbox.presets = Crea preajustes con diferentes configuraciones para cambiar rápidamente entre varios ajustes, como el prompt del sistema y otros.
|
994
994
|
tip.toolbox.prompt = La solicitud del sistema actual se puede modificar en tiempo real. Para habilitar herramientas desde complementos, habilite la opción "+ Herramientas."
|
995
995
|
toolbox.agent.auto_stop.label = Auto-parada
|
@@ -989,7 +989,7 @@ tip.tokens.input = Jetons: invite de l'utilisateur + invite système + contexte
|
|
989
989
|
tip.toolbox.assistants = La liste des assistants montre les assistants créés et opérant sur le serveur distant. Tout changement sera synchronisé avec l'assistant distant.
|
990
990
|
tip.toolbox.ctx = Créez autant de contextes de conversation que vous en avez besoin ; vous pouvez y revenir à tout moment.
|
991
991
|
tip.toolbox.indexes = En indexant des conversations et des fichiers, vous pouvez étendre les connaissances disponibles avec vos propres données et historique de conversation.
|
992
|
-
tip.toolbox.mode = Vous pouvez changer le mode de travail et le modèle en temps réel.
|
992
|
+
tip.toolbox.mode = Vous pouvez changer le mode de travail et le modèle en temps réel.
|
993
993
|
tip.toolbox.presets = Créez des préréglages avec différentes configurations pour basculer rapidement entre divers réglages, tels que l'invite système et d'autres.
|
994
994
|
tip.toolbox.prompt = L'invite système actuelle peut être modifiée en temps réel. Pour activer les outils à partir des plugins, activez l'option "+ Outils."
|
995
995
|
toolbox.agent.auto_stop.label = Arrêt automatique
|
@@ -990,7 +990,7 @@ tip.tokens.input = Tokeny: prompt użytkownika + systemowy prompt + kontekst + d
|
|
990
990
|
tip.toolbox.assistants = Lista asystentów pokazuje asystentów stworzonych i działających na zdalnym serwerze. Wszelkie zmiany zostaną zsynchronizowane ze zdalnym asystentem.
|
991
991
|
tip.toolbox.ctx = Twórz tyle kontekstów rozmów, ile potrzebujesz; możesz do nich wrócić w dowolnym momencie.
|
992
992
|
tip.toolbox.indexes = Indeksując rozmowy i pliki, możesz rozszerzyć dostępną wiedzę o własne dane i historię rozmów.
|
993
|
-
tip.toolbox.mode = Możesz zmienić tryb pracy i model w czasie rzeczywistym.
|
993
|
+
tip.toolbox.mode = Możesz zmienić tryb pracy i model w czasie rzeczywistym.
|
994
994
|
tip.toolbox.presets = Twórz presety z różnymi konfiguracjami, aby szybko przełączać się między różnymi ustawieniami, takimi jak prompt systemowy i inne.
|
995
995
|
tip.toolbox.prompt = Aktualna podpowiedź systemu może być modyfikowana w czasie rzeczywistym. Aby włączyć narzędzia z wtyczek, włącz opcję "+ Narzędzia."
|
996
996
|
toolbox.agent.auto_stop.label = Auto-stop
|
@@ -989,7 +989,7 @@ tip.tokens.input = Токени: запит користувача + систе
|
|
989
989
|
tip.toolbox.assistants = Список асистентів показує асистентів, створених і що працюють на віддаленому сервері. Будь-які зміни будуть синхронізовані з віддаленим асистентом.
|
990
990
|
tip.toolbox.ctx = Створіть стільки контекстів розмов, як вам потрібно; ви можете повернутися до них у будь-який час.
|
991
991
|
tip.toolbox.indexes = Індексуючи розмови та файли, ви можете розширити доступні знання зі своїми власними даними та історією розмов.
|
992
|
-
tip.toolbox.mode = Ви можете змінити робочий режим та модель в реальному часі.
|
992
|
+
tip.toolbox.mode = Ви можете змінити робочий режим та модель в реальному часі.
|
993
993
|
tip.toolbox.presets = Створіть пресети з різними конфігураціями для швидкого перемикання між різними налаштуваннями, такими як системний сповіщення та інші.
|
994
994
|
tip.toolbox.prompt = Поточну системну підказку можна змінювати в режимі реального часу. Щоб увімкнути інструменти з плагінів, увімкніть опцію "+ Інструменти."
|
995
995
|
toolbox.agent.auto_stop.label = Авто-стоп
|
@@ -1104,7 +1104,7 @@ tip.tokens.input = 代币:用户输入提示 + 系统提示 + 上下文 + 额
|
|
1104
1104
|
tip.toolbox.assistants = 助手列表顯示在遠程服務器上創建和運行的助手。任何更改都將與遠程助手同步。
|
1105
1105
|
tip.toolbox.ctx = 創建所需數量的對話上下文;您隨時可以返回它們。
|
1106
1106
|
tip.toolbox.indexes = 通過索引對話和文件,您可以用自己的數據和對話歷史擴展可用知識。
|
1107
|
-
tip.toolbox.mode =
|
1107
|
+
tip.toolbox.mode = 您可以實時更換工作模式和模型。
|
1108
1108
|
tip.toolbox.presets = 創建具有不同配置的預設,以便快速切換不同設置,例如系統提示等。
|
1109
1109
|
tip.toolbox.prompt = 当前系统提示可以实时修改。要启用来自插件的工具,请启用“+ 工具”选项。
|
1110
1110
|
toolbox.agent.auto_stop.label = 自動停止
|
pygpt_net/item/model.py
CHANGED
@@ -6,11 +6,13 @@
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
7
7
|
# MIT License #
|
8
8
|
# Created By : Marcin Szczygliński #
|
9
|
-
# Updated Date: 2025.06.
|
9
|
+
# Updated Date: 2025.06.26 16:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import json
|
13
13
|
|
14
|
+
from pygpt_net.core.types import MODE_CHAT
|
15
|
+
|
14
16
|
|
15
17
|
class ModelItem:
|
16
18
|
def __init__(self, id=None):
|
@@ -29,6 +31,7 @@ class ModelItem:
|
|
29
31
|
self.tokens = 0
|
30
32
|
self.default = False
|
31
33
|
self.imported = False
|
34
|
+
self.openai = False # OpenAI API supported model
|
32
35
|
self.extra = {}
|
33
36
|
|
34
37
|
def from_dict(self, data: dict):
|
@@ -54,6 +57,8 @@ class ModelItem:
|
|
54
57
|
self.extra = data['extra']
|
55
58
|
if 'imported' in data:
|
56
59
|
self.imported = data['imported']
|
60
|
+
if 'openai' in data:
|
61
|
+
self.openai = data['openai']
|
57
62
|
|
58
63
|
# multimodal
|
59
64
|
if 'multimodal' in data:
|
@@ -105,6 +110,7 @@ class ModelItem:
|
|
105
110
|
data['multimodal'] = ','.join(self.multimodal)
|
106
111
|
data['extra'] = self.extra
|
107
112
|
data['imported'] = self.imported
|
113
|
+
data['openai'] = self.openai
|
108
114
|
|
109
115
|
data['langchain.provider'] = None
|
110
116
|
data['langchain.mode'] = ""
|
@@ -178,6 +184,9 @@ class ModelItem:
|
|
178
184
|
:param mode: Mode
|
179
185
|
:return: True if supported
|
180
186
|
"""
|
187
|
+
if mode == MODE_CHAT and not self.is_openai():
|
188
|
+
# only OpenAI models are supported for chat mode
|
189
|
+
return False
|
181
190
|
return mode in self.mode
|
182
191
|
|
183
192
|
def is_multimodal(self) -> bool:
|
@@ -188,6 +197,21 @@ class ModelItem:
|
|
188
197
|
"""
|
189
198
|
return len(self.multimodal) > 0
|
190
199
|
|
200
|
+
def is_openai(self) -> bool:
|
201
|
+
"""
|
202
|
+
Check if model is supported by OpenAI API
|
203
|
+
|
204
|
+
:return: True if OpenAI
|
205
|
+
"""
|
206
|
+
if (self.id.startswith("gpt-")
|
207
|
+
or self.id.startswith("chatgpt")
|
208
|
+
or self.id.startswith("o1")
|
209
|
+
or self.id.startswith("o3")
|
210
|
+
or self.id.startswith("o4")
|
211
|
+
or self.id.startswith("o5")):
|
212
|
+
return True
|
213
|
+
return False
|
214
|
+
|
191
215
|
def is_ollama(self) -> bool:
|
192
216
|
"""
|
193
217
|
Check if model is Ollama
|
@@ -196,6 +220,8 @@ class ModelItem:
|
|
196
220
|
"""
|
197
221
|
if self.llama_index is None:
|
198
222
|
return False
|
223
|
+
if self.llama_index.get("provider") is None:
|
224
|
+
return False
|
199
225
|
return "ollama" in self.llama_index.get("provider", "")
|
200
226
|
|
201
227
|
def get_ollama_model(self) -> str:
|
@@ -210,6 +236,14 @@ class ModelItem:
|
|
210
236
|
return arg["value"]
|
211
237
|
return ""
|
212
238
|
|
239
|
+
def get_llama_provider(self) -> str:
|
240
|
+
"""
|
241
|
+
Get Llama Index provider
|
242
|
+
|
243
|
+
:return: provider name
|
244
|
+
"""
|
245
|
+
return self.llama_index.get("provider", "")
|
246
|
+
|
213
247
|
def has_mode(self, mode: str) -> bool:
|
214
248
|
"""
|
215
249
|
Check if model has mode
|
@@ -1862,6 +1862,13 @@ class Patch:
|
|
1862
1862
|
data["remote_tools.web_search"] = True
|
1863
1863
|
updated = True
|
1864
1864
|
|
1865
|
+
# < 2.5.18
|
1866
|
+
if old < parse_version("2.5.18"):
|
1867
|
+
print("Migrating config from < 2.5.18...")
|
1868
|
+
if 'remote_tools.image' not in data:
|
1869
|
+
data["remote_tools.image"] = False
|
1870
|
+
updated = True
|
1871
|
+
|
1865
1872
|
# update file
|
1866
1873
|
migrated = False
|
1867
1874
|
if updated:
|
@@ -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: 2025.
|
9
|
+
# Updated Date: 2025.06.26 16:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import json
|
@@ -166,6 +166,7 @@ class JsonFileProvider(BaseProvider):
|
|
166
166
|
'multimodal': item.multimodal,
|
167
167
|
'extra': item.extra,
|
168
168
|
'imported': item.imported,
|
169
|
+
'openai': item.openai,
|
169
170
|
}
|
170
171
|
|
171
172
|
@staticmethod
|
@@ -198,6 +199,8 @@ class JsonFileProvider(BaseProvider):
|
|
198
199
|
item.extra = data['extra']
|
199
200
|
if 'imported' in data:
|
200
201
|
item.imported = data['imported']
|
202
|
+
if 'openai' in data:
|
203
|
+
item.openai = data['openai']
|
201
204
|
|
202
205
|
def dump(self, item: ModelItem) -> str:
|
203
206
|
"""
|
@@ -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: 2025.06.
|
9
|
+
# Updated Date: 2025.06.26 16:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from packaging.version import parse as parse_version, Version
|
@@ -550,6 +550,22 @@ class Patch:
|
|
550
550
|
del data[name_to_replace]
|
551
551
|
updated = True
|
552
552
|
|
553
|
+
# < 2.5.18 <--- update openai flag
|
554
|
+
if old < parse_version("2.5.18"):
|
555
|
+
print("Migrating models from < 2.5.18...")
|
556
|
+
for id in data:
|
557
|
+
model = data[id]
|
558
|
+
if (model.id.startswith("o1")
|
559
|
+
or model.id.startswith("o3")
|
560
|
+
or model.id.startswith("gpt-")
|
561
|
+
or model.id.startswith("chatgpt")
|
562
|
+
or model.id.startswith("dall-e")):
|
563
|
+
model.openai = True
|
564
|
+
if model.is_supported("llama_index"):
|
565
|
+
if "chat" not in model.mode:
|
566
|
+
model.mode.append("chat")
|
567
|
+
updated = True
|
568
|
+
|
553
569
|
# update file
|
554
570
|
if updated:
|
555
571
|
data = dict(sorted(data.items()))
|
@@ -8,6 +8,7 @@
|
|
8
8
|
# Created By : Marcin Szczygliński #
|
9
9
|
# Updated Date: 2025.06.25 02:00:00 #
|
10
10
|
# ================================================== #
|
11
|
+
import base64
|
11
12
|
|
12
13
|
from httpx_socks import SyncProxyTransport
|
13
14
|
|
@@ -271,6 +272,19 @@ class Gpt:
|
|
271
272
|
response.usage.input_tokens,
|
272
273
|
response.usage.output_tokens,
|
273
274
|
)
|
275
|
+
if mode == MODE_CHAT:
|
276
|
+
# if image generation call in responses API
|
277
|
+
image_data = [
|
278
|
+
output.result
|
279
|
+
for output in response.output
|
280
|
+
if output.type == "image_generation_call"
|
281
|
+
]
|
282
|
+
if image_data:
|
283
|
+
img_path = self.window.core.image.gen_unique_path(ctx)
|
284
|
+
image_base64 = image_data[0]
|
285
|
+
with open(img_path, "wb") as f:
|
286
|
+
f.write(base64.b64decode(image_base64))
|
287
|
+
ctx.images = [img_path]
|
274
288
|
return True
|
275
289
|
|
276
290
|
def quick_call(self, context: BridgeContext, extra: dict = None) -> str:
|
pygpt_net/provider/gpt/image.py
CHANGED
@@ -6,9 +6,9 @@
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
7
7
|
# MIT License #
|
8
8
|
# Created By : Marcin Szczygliński #
|
9
|
-
# Updated Date:
|
9
|
+
# Updated Date: 2025.06.26 18:00:00 #
|
10
10
|
# ================================================== #
|
11
|
-
|
11
|
+
import base64
|
12
12
|
import datetime
|
13
13
|
import os
|
14
14
|
from typing import Optional, Dict, Any
|
@@ -132,6 +132,7 @@ class ImageWorker(QObject, QRunnable):
|
|
132
132
|
self.allowed_max_num = {
|
133
133
|
"dall-e-2": 4,
|
134
134
|
"dall-e-3": 1,
|
135
|
+
"gpt-image-1": 1,
|
135
136
|
}
|
136
137
|
self.allowed_resolutions = {
|
137
138
|
"dall-e-2": [
|
@@ -144,6 +145,27 @@ class ImageWorker(QObject, QRunnable):
|
|
144
145
|
"1024x1792",
|
145
146
|
"1024x1024",
|
146
147
|
],
|
148
|
+
"gpt-image-1": [
|
149
|
+
"1536x1024",
|
150
|
+
"1024x1536",
|
151
|
+
"1024x1024",
|
152
|
+
"auto",
|
153
|
+
],
|
154
|
+
}
|
155
|
+
self.allowed_quality = {
|
156
|
+
"dall-e-2": [
|
157
|
+
"standard",
|
158
|
+
],
|
159
|
+
"dall-e-3": [
|
160
|
+
"standard",
|
161
|
+
"hd",
|
162
|
+
],
|
163
|
+
"gpt-image-1": [
|
164
|
+
"auto",
|
165
|
+
"high",
|
166
|
+
"medium",
|
167
|
+
"low",
|
168
|
+
],
|
147
169
|
}
|
148
170
|
|
149
171
|
@Slot()
|
@@ -188,6 +210,11 @@ class ImageWorker(QObject, QRunnable):
|
|
188
210
|
if resolution not in self.allowed_resolutions[self.model]:
|
189
211
|
resolution = self.allowed_resolutions[self.model][0]
|
190
212
|
|
213
|
+
quality = self.quality
|
214
|
+
if self.model in self.allowed_quality:
|
215
|
+
if quality not in self.allowed_quality[self.model]:
|
216
|
+
quality = self.allowed_quality[self.model][0]
|
217
|
+
|
191
218
|
# send to API
|
192
219
|
response = None
|
193
220
|
if self.model == "dall-e-2":
|
@@ -197,12 +224,12 @@ class ImageWorker(QObject, QRunnable):
|
|
197
224
|
n=self.num,
|
198
225
|
size=resolution,
|
199
226
|
)
|
200
|
-
elif self.model == "dall-e-3":
|
227
|
+
elif self.model == "dall-e-3" or self.model == "gpt-image-1":
|
201
228
|
response = self.client.images.generate(
|
202
229
|
model=self.model,
|
203
230
|
prompt=self.input_prompt,
|
204
231
|
n=self.num,
|
205
|
-
quality=
|
232
|
+
quality=quality,
|
206
233
|
size=resolution,
|
207
234
|
)
|
208
235
|
|
@@ -215,20 +242,27 @@ class ImageWorker(QObject, QRunnable):
|
|
215
242
|
for i in range(self.num):
|
216
243
|
if i >= len(response.data):
|
217
244
|
break
|
218
|
-
url = response.data[i].url
|
219
|
-
res = requests.get(url)
|
220
245
|
|
221
246
|
# generate filename
|
222
247
|
name = datetime.date.today().strftime(
|
223
248
|
"%Y-%m-%d") + "_" + datetime.datetime.now().strftime("%H-%M-%S") + "-" \
|
224
|
-
|
249
|
+
+ self.window.core.image.make_safe_filename(self.input_prompt) + "-" + str(i + 1) + ".png"
|
225
250
|
path = os.path.join(self.window.core.config.get_user_dir("img"), name)
|
226
251
|
|
227
252
|
msg = trans('img.status.downloading') + " (" + str(i + 1) + " / " + str(self.num) + ") -> " + str(path)
|
228
253
|
self.signals.status.emit(msg)
|
229
254
|
|
255
|
+
if response.data[i] is None:
|
256
|
+
self.signals.error.emit("API Error: empty image data")
|
257
|
+
return
|
258
|
+
if response.data[i].url: # dall-e 2 and 3 returns URL
|
259
|
+
res = requests.get(response.data[i].url)
|
260
|
+
data = res.content
|
261
|
+
else: # gpt-image-1 returns base64 encoded image
|
262
|
+
data = base64.b64decode(response.data[i].b64_json)
|
263
|
+
|
230
264
|
# save image
|
231
|
-
if self.window.core.image.save_image(path,
|
265
|
+
if data and self.window.core.image.save_image(path, data):
|
232
266
|
paths.append(path)
|
233
267
|
else:
|
234
268
|
self.signals.error.emit("Error saving image")
|
@@ -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: 2025.06.
|
9
|
+
# Updated Date: 2025.06.26 18:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import json
|
@@ -17,13 +17,11 @@ from pygpt_net.core.types import (
|
|
17
17
|
MODE_CHAT,
|
18
18
|
MODE_VISION,
|
19
19
|
MODE_AUDIO,
|
20
|
-
MODE_RESEARCH,
|
21
20
|
)
|
22
21
|
from pygpt_net.core.bridge.context import BridgeContext, MultimodalContext
|
23
22
|
from pygpt_net.item.ctx import CtxItem
|
24
23
|
from pygpt_net.item.model import ModelItem
|
25
24
|
|
26
|
-
from .utils import sanitize_name
|
27
25
|
from pygpt_net.item.attachment import AttachmentItem
|
28
26
|
|
29
27
|
|
@@ -38,6 +36,7 @@ class Responses:
|
|
38
36
|
self.input_tokens = 0
|
39
37
|
self.audio_prev_id = None
|
40
38
|
self.audio_prev_expires_ts = None
|
39
|
+
self.prev_response_id = None
|
41
40
|
|
42
41
|
def send(
|
43
42
|
self,
|
@@ -80,6 +79,7 @@ class Responses:
|
|
80
79
|
user_name=user_name,
|
81
80
|
multimodal_ctx=multimodal_ctx,
|
82
81
|
)
|
82
|
+
|
83
83
|
msg_tokens = self.window.core.tokens.from_messages(
|
84
84
|
messages,
|
85
85
|
model.id,
|
@@ -116,9 +116,15 @@ class Responses:
|
|
116
116
|
response_kwargs['reasoning']['effort'] = model.extra["reasoning_effort"]
|
117
117
|
|
118
118
|
# extend tools with external tools
|
119
|
-
if not model.id.startswith("o1")
|
119
|
+
if (not model.id.startswith("o1")
|
120
|
+
and not model.id.startswith("o3")):
|
120
121
|
if self.window.core.config.get("remote_tools.web_search", False):
|
121
122
|
tools.append({"type": "web_search_preview"})
|
123
|
+
if self.window.core.config.get("remote_tools.image", False):
|
124
|
+
tool = {"type": "image_generation"}
|
125
|
+
if stream:
|
126
|
+
tool["partial_images"] = 1 # required for streaming
|
127
|
+
tools.append(tool)
|
122
128
|
|
123
129
|
# tool calls are not supported for o1-mini and o1-preview
|
124
130
|
if (model.id is not None
|
@@ -126,18 +132,9 @@ class Responses:
|
|
126
132
|
if len(tools) > 0:
|
127
133
|
response_kwargs['tools'] = tools
|
128
134
|
|
129
|
-
#
|
130
|
-
if
|
131
|
-
|
132
|
-
voice_id = "alloy"
|
133
|
-
tmp_voice = self.window.core.plugins.get_option("audio_output", "openai_voice")
|
134
|
-
if tmp_voice:
|
135
|
-
voice_id = tmp_voice
|
136
|
-
response_kwargs["modalities"] = ["text", "audio"]
|
137
|
-
response_kwargs["audio"] = {
|
138
|
-
"voice": voice_id,
|
139
|
-
"format": "wav"
|
140
|
-
}
|
135
|
+
# attach previous response ID if available
|
136
|
+
if self.prev_response_id:
|
137
|
+
response_kwargs['previous_response_id'] = self.prev_response_id
|
141
138
|
|
142
139
|
response = client.responses.create(
|
143
140
|
input=messages,
|
@@ -145,6 +142,11 @@ class Responses:
|
|
145
142
|
stream=stream,
|
146
143
|
**response_kwargs,
|
147
144
|
)
|
145
|
+
|
146
|
+
# store previous response ID
|
147
|
+
if not stream and response:
|
148
|
+
ctx.msg_id = response.id
|
149
|
+
|
148
150
|
return response
|
149
151
|
|
150
152
|
def build(
|
@@ -172,6 +174,7 @@ class Responses:
|
|
172
174
|
:return: messages list
|
173
175
|
"""
|
174
176
|
messages = []
|
177
|
+
self.prev_response_id = None # reset
|
175
178
|
|
176
179
|
# tokens config
|
177
180
|
mode = MODE_CHAT
|
@@ -240,6 +243,9 @@ class Responses:
|
|
240
243
|
}
|
241
244
|
messages.append(msg)
|
242
245
|
|
246
|
+
if item.msg_id and (item.cmds is None or len(item.cmds) == 0): # if no cmds before
|
247
|
+
self.prev_response_id = item.msg_id # previous response ID to use in current input
|
248
|
+
|
243
249
|
# use vision and audio if available in current model
|
244
250
|
content = str(prompt)
|
245
251
|
if MODE_VISION in model.mode:
|
@@ -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:
|
9
|
+
# Updated Date: 2025.06.26 16:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from llama_index.llms.anthropic import Anthropic
|
@@ -47,4 +47,6 @@ class AnthropicLLM(BaseLLM):
|
|
47
47
|
:return: LLM provider instance
|
48
48
|
"""
|
49
49
|
args = self.parse_args(model.llama_index)
|
50
|
+
if "model" not in args:
|
51
|
+
args["model"] = model.id
|
50
52
|
return Anthropic(**args)
|
@@ -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: 2025.
|
9
|
+
# Updated Date: 2025.06.26 16:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from typing import Optional, List, Dict
|
@@ -51,6 +51,8 @@ class GoogleLLM(BaseLLM):
|
|
51
51
|
:return: LLM provider instance
|
52
52
|
"""
|
53
53
|
args = self.parse_args(model.llama_index)
|
54
|
+
if "model" not in args:
|
55
|
+
args["model"] = model.id
|
54
56
|
return Gemini(**args)
|
55
57
|
|
56
58
|
def get_embeddings_model(
|
@@ -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:
|
9
|
+
# Updated Date: 2025.06.26 16:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from langchain_community.llms import HuggingFaceHub
|
@@ -39,6 +39,8 @@ class HuggingFaceLLM(BaseLLM):
|
|
39
39
|
:return: LLM provider instance
|
40
40
|
"""
|
41
41
|
args = self.parse_args(model.langchain)
|
42
|
+
if "model" not in args:
|
43
|
+
args["model"] = model.id
|
42
44
|
return HuggingFaceHub(**args)
|
43
45
|
|
44
46
|
def chat(
|
@@ -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:
|
9
|
+
# Updated Date: 2025.06.26 16:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import os
|
@@ -44,6 +44,8 @@ class HuggingFaceApiLLM(BaseLLM):
|
|
44
44
|
:return: LLM provider instance
|
45
45
|
"""
|
46
46
|
args = self.parse_args(model.llama_index)
|
47
|
+
if "model" not in args:
|
48
|
+
args["model"] = model.id
|
47
49
|
return HuggingFaceInferenceAPI(**args)
|
48
50
|
|
49
51
|
def get_embeddings_model(
|