pygpt-net 2.6.0.post1__py3-none-any.whl → 2.6.1__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 +4 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/app.py +13 -9
- pygpt_net/controller/chat/response.py +5 -1
- pygpt_net/controller/model/editor.py +45 -4
- pygpt_net/controller/presets/editor.py +71 -16
- pygpt_net/controller/presets/presets.py +4 -3
- pygpt_net/core/agents/provider.py +2 -1
- pygpt_net/core/agents/runner.py +114 -8
- pygpt_net/core/agents/runners/helpers.py +3 -2
- pygpt_net/core/agents/runners/llama_workflow.py +176 -22
- pygpt_net/core/agents/runners/loop.py +22 -13
- pygpt_net/core/experts/experts.py +17 -23
- pygpt_net/core/idx/chat.py +24 -34
- pygpt_net/core/idx/response.py +5 -2
- pygpt_net/core/locale/locale.py +73 -45
- pygpt_net/core/render/web/body.py +152 -207
- pygpt_net/core/render/web/renderer.py +4 -2
- pygpt_net/data/config/config.json +2 -2
- pygpt_net/data/config/models.json +2 -2
- pygpt_net/data/locale/locale.de.ini +10 -8
- pygpt_net/data/locale/locale.en.ini +10 -8
- pygpt_net/data/locale/locale.es.ini +10 -8
- pygpt_net/data/locale/locale.fr.ini +10 -8
- pygpt_net/data/locale/locale.it.ini +10 -8
- pygpt_net/data/locale/locale.pl.ini +10 -8
- pygpt_net/data/locale/locale.uk.ini +10 -8
- pygpt_net/data/locale/locale.zh.ini +10 -8
- pygpt_net/item/ctx.py +2 -1
- pygpt_net/plugin/cmd_files/worker.py +19 -16
- pygpt_net/provider/agents/base.py +4 -1
- pygpt_net/provider/agents/llama_index/codeact_workflow.py +95 -0
- pygpt_net/provider/agents/llama_index/legacy/__init__.py +0 -0
- pygpt_net/provider/agents/llama_index/{openai.py → legacy/openai.py} +2 -2
- pygpt_net/provider/agents/llama_index/{openai_assistant.py → legacy/openai_assistant.py} +2 -2
- pygpt_net/provider/agents/llama_index/{planner.py → legacy/planner.py} +3 -3
- pygpt_net/provider/agents/llama_index/{react.py → legacy/react.py} +3 -3
- pygpt_net/provider/agents/llama_index/openai_workflow.py +52 -0
- pygpt_net/provider/agents/llama_index/planner_workflow.py +115 -0
- pygpt_net/provider/agents/llama_index/react_workflow.py +6 -4
- pygpt_net/provider/agents/llama_index/workflow/__init__.py +0 -0
- pygpt_net/provider/agents/llama_index/{codeact_agent_custom.py → workflow/codeact.py} +124 -8
- pygpt_net/provider/agents/llama_index/workflow/events.py +24 -0
- pygpt_net/provider/agents/llama_index/workflow/openai.py +634 -0
- pygpt_net/provider/agents/llama_index/workflow/planner.py +601 -0
- pygpt_net/provider/agents/openai/agent.py +1 -0
- pygpt_net/provider/agents/openai/agent_b2b.py +2 -0
- pygpt_net/provider/agents/openai/agent_planner.py +1 -0
- pygpt_net/provider/agents/openai/agent_with_experts.py +1 -0
- pygpt_net/provider/agents/openai/agent_with_experts_feedback.py +1 -0
- pygpt_net/provider/agents/openai/agent_with_feedback.py +1 -0
- pygpt_net/provider/agents/openai/evolve.py +1 -0
- pygpt_net/provider/core/preset/patch.py +11 -17
- pygpt_net/ui/widget/lists/experts.py +3 -2
- {pygpt_net-2.6.0.post1.dist-info → pygpt_net-2.6.1.dist-info}/METADATA +14 -6
- {pygpt_net-2.6.0.post1.dist-info → pygpt_net-2.6.1.dist-info}/RECORD +59 -53
- pygpt_net/data/config/presets/agent_react_workflow.json +0 -34
- pygpt_net/provider/agents/llama_index/code_act.py +0 -58
- {pygpt_net-2.6.0.post1.dist-info → pygpt_net-2.6.1.dist-info}/LICENSE +0 -0
- {pygpt_net-2.6.0.post1.dist-info → pygpt_net-2.6.1.dist-info}/WHEEL +0 -0
- {pygpt_net-2.6.0.post1.dist-info → pygpt_net-2.6.1.dist-info}/entry_points.txt +0 -0
pygpt_net/CHANGELOG.txt
CHANGED
pygpt_net/__init__.py
CHANGED
|
@@ -6,15 +6,15 @@
|
|
|
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.08.
|
|
9
|
+
# Updated Date: 2025.08.14 00:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
__author__ = "Marcin Szczygliński"
|
|
13
13
|
__copyright__ = "Copyright 2025, Marcin Szczygliński"
|
|
14
14
|
__credits__ = ["Marcin Szczygliński"]
|
|
15
15
|
__license__ = "MIT"
|
|
16
|
-
__version__ = "2.6.
|
|
17
|
-
__build__ = "2025-08-
|
|
16
|
+
__version__ = "2.6.1"
|
|
17
|
+
__build__ = "2025-08-14"
|
|
18
18
|
__maintainer__ = "Marcin Szczygliński"
|
|
19
19
|
__github__ = "https://github.com/szczyglis-dev/py-gpt"
|
|
20
20
|
__report__ = "https://github.com/szczyglis-dev/py-gpt/issues"
|
pygpt_net/app.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: 2025.08.
|
|
9
|
+
# Updated Date: 2025.08.14 01:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import os
|
|
@@ -72,12 +72,14 @@ from pygpt_net.plugin.agent import Plugin as AgentPlugin
|
|
|
72
72
|
from pygpt_net.plugin.mailer import Plugin as MailerPlugin
|
|
73
73
|
|
|
74
74
|
# agents (Llama-index)
|
|
75
|
-
from pygpt_net.provider.agents.llama_index.openai import OpenAIAgent
|
|
76
|
-
from pygpt_net.provider.agents.llama_index.openai_assistant import OpenAIAssistantAgent
|
|
77
|
-
from pygpt_net.provider.agents.llama_index.planner import PlannerAgent
|
|
78
|
-
from pygpt_net.provider.agents.llama_index.
|
|
75
|
+
# from pygpt_net.provider.agents.llama_index.legacy.openai import OpenAIAgent
|
|
76
|
+
from pygpt_net.provider.agents.llama_index.legacy.openai_assistant import OpenAIAssistantAgent
|
|
77
|
+
# from pygpt_net.provider.agents.llama_index.legacy.planner import PlannerAgent
|
|
78
|
+
from pygpt_net.provider.agents.llama_index.planner_workflow import PlannerAgent as PlannerWorkflowAgent
|
|
79
|
+
from pygpt_net.provider.agents.llama_index.openai_workflow import OpenAIAgent as OpenAIWorkflowAgent
|
|
80
|
+
# from pygpt_net.provider.agents.llama_index.legacy.react import ReactAgent
|
|
79
81
|
from pygpt_net.provider.agents.llama_index.react_workflow import ReactWorkflowAgent
|
|
80
|
-
from pygpt_net.provider.agents.llama_index.
|
|
82
|
+
from pygpt_net.provider.agents.llama_index.codeact_workflow import CodeActAgent
|
|
81
83
|
from pygpt_net.provider.agents.openai.agent import Agent as OpenAIAgentsBase
|
|
82
84
|
from pygpt_net.provider.agents.openai.agent_with_experts import Agent as OpenAIAgentsExperts
|
|
83
85
|
from pygpt_net.provider.agents.openai.agent_with_experts_feedback import Agent as OpenAIAgentsExpertsFeedback
|
|
@@ -420,10 +422,12 @@ def run(**kwargs):
|
|
|
420
422
|
launcher.add_vector_store(store)
|
|
421
423
|
|
|
422
424
|
# register base agents
|
|
423
|
-
launcher.add_agent(OpenAIAgent()) # llama-index
|
|
425
|
+
# launcher.add_agent(OpenAIAgent()) # llama-index
|
|
426
|
+
launcher.add_agent(OpenAIWorkflowAgent()) # llama-index
|
|
424
427
|
launcher.add_agent(OpenAIAssistantAgent()) # llama-index
|
|
425
|
-
launcher.add_agent(PlannerAgent()) # llama-index
|
|
426
|
-
launcher.add_agent(
|
|
428
|
+
# launcher.add_agent(PlannerAgent()) # llama-index
|
|
429
|
+
launcher.add_agent(PlannerWorkflowAgent()) # llama-index
|
|
430
|
+
# launcher.add_agent(ReactAgent()) # llama-index
|
|
427
431
|
launcher.add_agent(ReactWorkflowAgent()) # llama-index
|
|
428
432
|
launcher.add_agent(CodeActAgent()) # llama-index
|
|
429
433
|
launcher.add_agent(OpenAIAgentsBase()) # openai-agents
|
|
@@ -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.08.
|
|
9
|
+
# Updated Date: 2025.08.14 01:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from typing import Dict, Any
|
|
@@ -164,6 +164,7 @@ class Response:
|
|
|
164
164
|
:param context: BridgeContext
|
|
165
165
|
:param extra: Extra data
|
|
166
166
|
"""
|
|
167
|
+
global_mode = self.window.core.config.get('mode', MODE_AGENT_LLAMA)
|
|
167
168
|
ctx = context.ctx
|
|
168
169
|
if self.window.controller.kernel.stopped():
|
|
169
170
|
output = ctx.output
|
|
@@ -266,6 +267,9 @@ class Response:
|
|
|
266
267
|
self.window.dispatch(event)
|
|
267
268
|
|
|
268
269
|
# if continue reasoning
|
|
270
|
+
if global_mode not in [MODE_AGENT_LLAMA, MODE_AGENT_OPENAI]:
|
|
271
|
+
return # no agent mode, nothing to do
|
|
272
|
+
|
|
269
273
|
if ctx.extra is None or (type(ctx.extra) == dict and "agent_finish" not in ctx.extra):
|
|
270
274
|
self.window.update_status(trans("status.agent.reasoning"))
|
|
271
275
|
self.window.controller.chat.common.lock_input() # lock input, re-enable stop button
|
|
@@ -6,10 +6,11 @@
|
|
|
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.08.14 01:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import copy
|
|
13
|
+
import json
|
|
13
14
|
from typing import Optional, Any
|
|
14
15
|
|
|
15
16
|
from pygpt_net.core.events import Event
|
|
@@ -107,7 +108,14 @@ class Editor:
|
|
|
107
108
|
"description": "model.llama_index.env.desc",
|
|
108
109
|
"advanced": True,
|
|
109
110
|
},
|
|
111
|
+
"extra_json": {
|
|
112
|
+
"type": "textarea",
|
|
113
|
+
"label": "model.extra",
|
|
114
|
+
"description": "model.extra.desc",
|
|
115
|
+
"advanced": True,
|
|
116
|
+
},
|
|
110
117
|
}
|
|
118
|
+
self.custom_fields = ["extra_json"]
|
|
111
119
|
|
|
112
120
|
def get_options(self):
|
|
113
121
|
"""
|
|
@@ -220,8 +228,12 @@ class Editor:
|
|
|
220
228
|
model = self.window.core.models.items[self.current]
|
|
221
229
|
data_dict = model.to_dict()
|
|
222
230
|
for key in options:
|
|
223
|
-
|
|
224
|
-
|
|
231
|
+
if key in data_dict:
|
|
232
|
+
value = data_dict[key]
|
|
233
|
+
options[key]["value"] = value
|
|
234
|
+
|
|
235
|
+
# custom fields
|
|
236
|
+
options["extra_json"]["value"] = json.dumps(model.extra, indent=4) if model.extra else ""
|
|
225
237
|
|
|
226
238
|
if self.current is not None and self.current in self.window.core.models.items:
|
|
227
239
|
self.set_tab_by_id(self.current)
|
|
@@ -229,15 +241,24 @@ class Editor:
|
|
|
229
241
|
# load and apply options to config dialog
|
|
230
242
|
self.window.controller.config.load_options("model", options)
|
|
231
243
|
|
|
232
|
-
def save(
|
|
244
|
+
def save(
|
|
245
|
+
self,
|
|
246
|
+
persist: bool = True,
|
|
247
|
+
force: bool = False
|
|
248
|
+
):
|
|
233
249
|
"""
|
|
234
250
|
Save models editor
|
|
235
251
|
|
|
236
252
|
:param persist: persist to file and close dialog
|
|
253
|
+
:param force: force save without validation
|
|
237
254
|
"""
|
|
238
255
|
options = copy.deepcopy(self.get_options()) # copy options
|
|
239
256
|
data_dict = {}
|
|
257
|
+
|
|
258
|
+
# base fields
|
|
240
259
|
for key in options:
|
|
260
|
+
if key in self.custom_fields:
|
|
261
|
+
continue
|
|
241
262
|
value = self.window.controller.config.get_value(
|
|
242
263
|
parent_id="model",
|
|
243
264
|
key=key,
|
|
@@ -245,6 +266,26 @@ class Editor:
|
|
|
245
266
|
)
|
|
246
267
|
data_dict[key] = value
|
|
247
268
|
|
|
269
|
+
# custom fields
|
|
270
|
+
if "extra_json" in options:
|
|
271
|
+
extra_json = self.window.controller.config.get_value(
|
|
272
|
+
parent_id="model",
|
|
273
|
+
key="extra_json",
|
|
274
|
+
option=options["extra_json"],
|
|
275
|
+
)
|
|
276
|
+
try:
|
|
277
|
+
if extra_json:
|
|
278
|
+
decoded = json.loads(extra_json)
|
|
279
|
+
data_dict["extra"] = decoded
|
|
280
|
+
else:
|
|
281
|
+
data_dict["extra"] = {}
|
|
282
|
+
except json.JSONDecodeError as error:
|
|
283
|
+
self.window.ui.dialogs.alert(
|
|
284
|
+
"JSON decoding error in 'extra' field. Please check the syntax:\n\n{}".format(error)
|
|
285
|
+
)
|
|
286
|
+
if not force:
|
|
287
|
+
return # if JSON is invalid, do not save
|
|
288
|
+
|
|
248
289
|
# update current model
|
|
249
290
|
if self.current in self.window.core.models.items:
|
|
250
291
|
self.window.core.models.items[self.current].from_dict(data_dict)
|
|
@@ -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.08.
|
|
9
|
+
# Updated Date: 2025.08.14 03:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import datetime
|
|
@@ -172,12 +172,22 @@ class Editor:
|
|
|
172
172
|
"label": "preset.agent_provider",
|
|
173
173
|
"description": "preset.agent_provider.desc",
|
|
174
174
|
"use": "agent_provider_llama",
|
|
175
|
+
"extra": {
|
|
176
|
+
"urls": {
|
|
177
|
+
"Help": "https://pygpt.readthedocs.io/en/latest/modes.html#agent-llamaindex"
|
|
178
|
+
},
|
|
179
|
+
}
|
|
175
180
|
},
|
|
176
181
|
"agent_provider_openai": {
|
|
177
182
|
"type": "combo",
|
|
178
183
|
"label": "preset.agent_provider",
|
|
179
184
|
"description": "preset.agent_provider.desc",
|
|
180
185
|
"use": "agent_provider_openai",
|
|
186
|
+
"extra": {
|
|
187
|
+
"urls": {
|
|
188
|
+
"Help": "https://pygpt.readthedocs.io/en/latest/modes.html#agent-openai"
|
|
189
|
+
},
|
|
190
|
+
}
|
|
181
191
|
},
|
|
182
192
|
"assistant_id": {
|
|
183
193
|
"type": "text",
|
|
@@ -255,6 +265,7 @@ class Editor:
|
|
|
255
265
|
|
|
256
266
|
# add hooks for config update in real-time
|
|
257
267
|
self.window.ui.add_hook("update.preset.prompt", self.hook_update)
|
|
268
|
+
self.window.ui.add_hook("update.preset.agent_provider", self.hook_update)
|
|
258
269
|
self.window.ui.add_hook("update.preset.agent_provider_openai", self.hook_update)
|
|
259
270
|
|
|
260
271
|
# register functions dictionary
|
|
@@ -275,7 +286,7 @@ class Editor:
|
|
|
275
286
|
if not self.tab_options_idx:
|
|
276
287
|
return
|
|
277
288
|
mode = self.window.core.config.get('mode')
|
|
278
|
-
if mode
|
|
289
|
+
if mode not in [MODE_AGENT_OPENAI, MODE_AGENT_LLAMA]:
|
|
279
290
|
# show base prompt
|
|
280
291
|
self.window.ui.tabs['preset.editor.extra'].setTabVisible(0, True)
|
|
281
292
|
# hide all tabs
|
|
@@ -303,12 +314,21 @@ class Editor:
|
|
|
303
314
|
# show base prompt
|
|
304
315
|
self.window.ui.tabs['preset.editor.extra'].setTabVisible(0, True)
|
|
305
316
|
return
|
|
317
|
+
|
|
306
318
|
mode = self.window.core.config.get('mode')
|
|
307
|
-
|
|
319
|
+
key_agent = ""
|
|
320
|
+
|
|
321
|
+
if mode in [MODE_AGENT_OPENAI, MODE_AGENT_LLAMA]:
|
|
322
|
+
# get current provider
|
|
323
|
+
if mode == MODE_AGENT_LLAMA:
|
|
324
|
+
key_agent = "agent_provider"
|
|
325
|
+
elif mode == MODE_AGENT_OPENAI:
|
|
326
|
+
key_agent = "agent_provider_openai"
|
|
327
|
+
|
|
308
328
|
current_provider = self.window.controller.config.get_value(
|
|
309
329
|
parent_id=self.id,
|
|
310
|
-
key=
|
|
311
|
-
option=self.options[
|
|
330
|
+
key=key_agent,
|
|
331
|
+
option=self.options[key_agent],
|
|
312
332
|
)
|
|
313
333
|
if current_provider is None or current_provider == "":
|
|
314
334
|
# show base prompt
|
|
@@ -344,22 +364,38 @@ class Editor:
|
|
|
344
364
|
|
|
345
365
|
:param preset: preset item
|
|
346
366
|
"""
|
|
347
|
-
|
|
367
|
+
mode = self.window.core.config.get('mode')
|
|
368
|
+
id = None
|
|
369
|
+
if mode == MODE_AGENT_OPENAI:
|
|
370
|
+
if preset.agent_provider_openai is None or preset.agent_provider_openai == "":
|
|
371
|
+
return
|
|
372
|
+
id = preset.agent_provider_openai
|
|
373
|
+
elif mode == MODE_AGENT_LLAMA:
|
|
374
|
+
if preset.agent_provider is None or preset.agent_provider == "":
|
|
375
|
+
return
|
|
376
|
+
id = preset.agent_provider
|
|
377
|
+
else:
|
|
348
378
|
return
|
|
349
379
|
|
|
350
380
|
# update options in UI
|
|
351
|
-
id = preset.agent_provider_openai
|
|
352
381
|
agent = self.window.core.agents.provider.get(id)
|
|
353
382
|
if not agent:
|
|
354
383
|
return
|
|
355
384
|
if not preset.extra or id not in preset.extra:
|
|
356
385
|
return
|
|
386
|
+
|
|
357
387
|
data_dict = preset.extra[id]
|
|
358
388
|
option_tabs = agent.get_options()
|
|
359
389
|
for option_tab_id in data_dict:
|
|
360
|
-
|
|
390
|
+
parent_key = ""
|
|
391
|
+
if mode == MODE_AGENT_OPENAI:
|
|
392
|
+
parent_key = preset.agent_provider_openai
|
|
393
|
+
elif mode == MODE_AGENT_LLAMA:
|
|
394
|
+
parent_key = preset.agent_provider
|
|
395
|
+
option_key = "agent." + parent_key + "." + option_tab_id
|
|
361
396
|
if option_key not in self.window.ui.config:
|
|
362
397
|
continue
|
|
398
|
+
|
|
363
399
|
extra_options = option_tabs.get(option_tab_id, {}).get('options', {})
|
|
364
400
|
for key in extra_options:
|
|
365
401
|
value = data_dict[option_tab_id].get(key, None)
|
|
@@ -390,7 +426,7 @@ class Editor:
|
|
|
390
426
|
if not self.tab_options_idx:
|
|
391
427
|
return
|
|
392
428
|
mode = self.window.core.config.get('mode')
|
|
393
|
-
if mode
|
|
429
|
+
if mode not in [MODE_AGENT_OPENAI, MODE_AGENT_LLAMA]:
|
|
394
430
|
return
|
|
395
431
|
|
|
396
432
|
# load defaults for all tabs
|
|
@@ -427,13 +463,18 @@ class Editor:
|
|
|
427
463
|
return
|
|
428
464
|
|
|
429
465
|
mode = self.window.core.config.get('mode')
|
|
430
|
-
if mode
|
|
466
|
+
if mode not in [MODE_AGENT_OPENAI, MODE_AGENT_LLAMA]:
|
|
431
467
|
return
|
|
432
468
|
|
|
433
469
|
preset = self.window.core.presets.get_by_uuid(self.current)
|
|
434
470
|
if not preset:
|
|
435
471
|
return
|
|
436
|
-
|
|
472
|
+
|
|
473
|
+
current_provider_id = None
|
|
474
|
+
if mode == MODE_AGENT_OPENAI:
|
|
475
|
+
current_provider_id = preset.agent_provider_openai if preset else None
|
|
476
|
+
elif mode == MODE_AGENT_LLAMA:
|
|
477
|
+
current_provider_id = preset.agent_provider if preset else None
|
|
437
478
|
|
|
438
479
|
# load defaults for all tabs
|
|
439
480
|
for id in self.tab_options_idx:
|
|
@@ -475,10 +516,18 @@ class Editor:
|
|
|
475
516
|
:param id: preset id
|
|
476
517
|
:param preset: preset item
|
|
477
518
|
"""
|
|
519
|
+
mode = self.window.core.config.get('mode')
|
|
478
520
|
exclude_ids = [
|
|
479
521
|
"__prompt__",
|
|
480
522
|
]
|
|
481
|
-
id =
|
|
523
|
+
id = None
|
|
524
|
+
if mode == MODE_AGENT_OPENAI:
|
|
525
|
+
id = preset.agent_provider_openai
|
|
526
|
+
elif mode == MODE_AGENT_LLAMA:
|
|
527
|
+
id = preset.agent_provider
|
|
528
|
+
else:
|
|
529
|
+
return
|
|
530
|
+
|
|
482
531
|
options = {}
|
|
483
532
|
agent = self.window.core.agents.provider.get(id)
|
|
484
533
|
if not agent:
|
|
@@ -568,14 +617,20 @@ class Editor:
|
|
|
568
617
|
:return: None
|
|
569
618
|
"""
|
|
570
619
|
mode = self.window.core.config.get('mode')
|
|
571
|
-
if mode
|
|
620
|
+
if mode not in [MODE_AGENT_OPENAI, MODE_AGENT_LLAMA]:
|
|
572
621
|
return
|
|
573
622
|
|
|
623
|
+
parent_key = ""
|
|
624
|
+
if mode == MODE_AGENT_OPENAI:
|
|
625
|
+
parent_key = "agent_provider_openai"
|
|
626
|
+
elif mode == MODE_AGENT_LLAMA:
|
|
627
|
+
parent_key = "agent_provider"
|
|
628
|
+
|
|
574
629
|
# get current provider
|
|
575
630
|
current_provider = self.window.controller.config.get_value(
|
|
576
631
|
parent_id=self.id,
|
|
577
|
-
key=
|
|
578
|
-
option=self.options[
|
|
632
|
+
key=parent_key,
|
|
633
|
+
option=self.options[parent_key],
|
|
579
634
|
)
|
|
580
635
|
if current_provider is None or current_provider == "":
|
|
581
636
|
return
|
|
@@ -624,7 +679,7 @@ class Editor:
|
|
|
624
679
|
self.window.controller.presets.from_global() # update current preset
|
|
625
680
|
|
|
626
681
|
# show/hide extra options
|
|
627
|
-
elif key
|
|
682
|
+
elif key in ["agent_provider_openai", "agent_provider"]:
|
|
628
683
|
self.toggle_extra_options_by_provider()
|
|
629
684
|
self.append_default_prompt()
|
|
630
685
|
self.load_extra_defaults_current()
|
|
@@ -6,12 +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.08.01
|
|
9
|
+
# Updated Date: 2025.08.14 01:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import re
|
|
13
13
|
from typing import Optional, List, Dict
|
|
14
14
|
|
|
15
|
+
from PySide6.QtCore import QTimer
|
|
15
16
|
from PySide6.QtGui import QTextCursor
|
|
16
17
|
from PySide6.QtWidgets import QTextEdit
|
|
17
18
|
|
|
@@ -529,7 +530,7 @@ class Presets:
|
|
|
529
530
|
if preset_id is not None and preset_id != "":
|
|
530
531
|
if preset_id in self.window.core.presets.items:
|
|
531
532
|
self.window.core.presets.enable(preset_id)
|
|
532
|
-
self.refresh
|
|
533
|
+
QTimer.singleShot(100, self.refresh) # delay refresh
|
|
533
534
|
|
|
534
535
|
def disable(self, idx: Optional[int] = None):
|
|
535
536
|
"""
|
|
@@ -543,7 +544,7 @@ class Presets:
|
|
|
543
544
|
if preset_id is not None and preset_id != "":
|
|
544
545
|
if preset_id in self.window.core.presets.items:
|
|
545
546
|
self.window.core.presets.disable(preset_id)
|
|
546
|
-
self.refresh
|
|
547
|
+
QTimer.singleShot(100, self.refresh) # delay refresh
|
|
547
548
|
|
|
548
549
|
def clear(self, force: bool = False):
|
|
549
550
|
"""
|
pygpt_net/core/agents/runner.py
CHANGED
|
@@ -6,11 +6,11 @@
|
|
|
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.08.03
|
|
9
|
+
# Updated Date: 2025.08.14 03:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import asyncio
|
|
13
|
-
from typing import Optional, Dict, Any
|
|
13
|
+
from typing import Optional, Dict, Any, Union
|
|
14
14
|
|
|
15
15
|
from llama_index.core.base.llms.types import ChatMessage, MessageRole
|
|
16
16
|
|
|
@@ -31,6 +31,8 @@ from .runners.llama_workflow import LlamaWorkflow
|
|
|
31
31
|
from .runners.openai_workflow import OpenAIWorkflow
|
|
32
32
|
from .runners.helpers import Helpers
|
|
33
33
|
from .runners.loop import Loop
|
|
34
|
+
from ...item.ctx import CtxItem
|
|
35
|
+
|
|
34
36
|
|
|
35
37
|
class Runner:
|
|
36
38
|
def __init__(self, window=None):
|
|
@@ -50,6 +52,9 @@ class Runner:
|
|
|
50
52
|
self.llama_steps = LlamaSteps(window)
|
|
51
53
|
self.llama_workflow = LlamaWorkflow(window)
|
|
52
54
|
self.openai_workflow = OpenAIWorkflow(window)
|
|
55
|
+
self.APPEND_SYSTEM_PROMPT_TO_MSG = [
|
|
56
|
+
"react", # llama-index
|
|
57
|
+
]
|
|
53
58
|
|
|
54
59
|
def call(
|
|
55
60
|
self,
|
|
@@ -107,12 +112,7 @@ class Runner:
|
|
|
107
112
|
tools = []
|
|
108
113
|
|
|
109
114
|
# append system prompt
|
|
110
|
-
if agent_id
|
|
111
|
-
"openai_agent_base", # openai-agents
|
|
112
|
-
"openai_agent_experts", # openai-agents
|
|
113
|
-
"openai_assistant", # llama-index
|
|
114
|
-
"code_act", # llama-index
|
|
115
|
-
]:
|
|
115
|
+
if agent_id in self.APPEND_SYSTEM_PROMPT_TO_MSG:
|
|
116
116
|
if system_prompt:
|
|
117
117
|
msg = ChatMessage(
|
|
118
118
|
role=MessageRole.SYSTEM,
|
|
@@ -178,6 +178,112 @@ class Runner:
|
|
|
178
178
|
self.last_error = e
|
|
179
179
|
return False
|
|
180
180
|
|
|
181
|
+
def call_once(
|
|
182
|
+
self,
|
|
183
|
+
context: BridgeContext,
|
|
184
|
+
extra: Dict[str, Any],
|
|
185
|
+
signals: BridgeSignals
|
|
186
|
+
) -> Union[CtxItem, bool, None]:
|
|
187
|
+
"""
|
|
188
|
+
Call an agent once (quick call to the agent)
|
|
189
|
+
|
|
190
|
+
:param context: BridgeContext
|
|
191
|
+
:param extra: extra data
|
|
192
|
+
:param signals: BridgeSignals
|
|
193
|
+
:return: CtxItem if success, True if stopped, None on error
|
|
194
|
+
"""
|
|
195
|
+
if self.window.controller.kernel.stopped():
|
|
196
|
+
return True # abort if stopped
|
|
197
|
+
|
|
198
|
+
agent_id = extra.get("agent_provider", "openai")
|
|
199
|
+
verbose = self.window.core.config.get("agent.llama.verbose", False)
|
|
200
|
+
|
|
201
|
+
try:
|
|
202
|
+
# prepare input ctx
|
|
203
|
+
ctx = context.ctx
|
|
204
|
+
ctx.extra["agent_input"] = True # mark as user input
|
|
205
|
+
ctx.extra["agent_output"] = True # mark as user input
|
|
206
|
+
ctx.agent_call = True # disables reply from plugin commands
|
|
207
|
+
prompt = context.prompt
|
|
208
|
+
|
|
209
|
+
# prepare agent
|
|
210
|
+
model = context.model
|
|
211
|
+
vector_store_idx = extra.get("agent_idx", None)
|
|
212
|
+
system_prompt = context.system_prompt
|
|
213
|
+
max_steps = self.window.core.config.get("agent.llama.steps", 10)
|
|
214
|
+
is_cmd = self.window.core.command.is_cmd(inline=False)
|
|
215
|
+
llm = self.window.core.idx.llm.get(model, stream=False)
|
|
216
|
+
workdir = self.window.core.config.get_workdir_prefix()
|
|
217
|
+
|
|
218
|
+
# tools
|
|
219
|
+
self.window.core.agents.tools.context = context
|
|
220
|
+
self.window.core.agents.tools.agent_idx = vector_store_idx
|
|
221
|
+
|
|
222
|
+
if "agent_tools" in extra:
|
|
223
|
+
tools = extra["agent_tools"] # use tools from extra if provided
|
|
224
|
+
else:
|
|
225
|
+
tools = self.window.core.agents.tools.prepare(context, extra, force=True)
|
|
226
|
+
|
|
227
|
+
if "agent_history" in extra:
|
|
228
|
+
history = extra["agent_history"]
|
|
229
|
+
else:
|
|
230
|
+
history = self.window.core.agents.memory.prepare(context)
|
|
231
|
+
|
|
232
|
+
# disable tools if cmd is not enabled
|
|
233
|
+
if not is_cmd:
|
|
234
|
+
tools = []
|
|
235
|
+
|
|
236
|
+
# append system prompt
|
|
237
|
+
if agent_id in self.APPEND_SYSTEM_PROMPT_TO_MSG:
|
|
238
|
+
if system_prompt:
|
|
239
|
+
msg = ChatMessage(
|
|
240
|
+
role=MessageRole.SYSTEM,
|
|
241
|
+
content=system_prompt,
|
|
242
|
+
)
|
|
243
|
+
history.insert(0, msg)
|
|
244
|
+
|
|
245
|
+
agent_kwargs = {
|
|
246
|
+
"context": context,
|
|
247
|
+
"tools": tools,
|
|
248
|
+
"llm": llm,
|
|
249
|
+
"model": model,
|
|
250
|
+
"chat_history": history,
|
|
251
|
+
"max_iterations": max_steps,
|
|
252
|
+
"verbose": verbose,
|
|
253
|
+
"system_prompt": system_prompt,
|
|
254
|
+
"are_commands": is_cmd,
|
|
255
|
+
"workdir": workdir,
|
|
256
|
+
"preset": context.preset if context else None,
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if self.window.core.agents.provider.has(agent_id):
|
|
260
|
+
provider = self.window.core.agents.provider.get(agent_id)
|
|
261
|
+
agent = provider.get_agent(self.window, agent_kwargs)
|
|
262
|
+
if verbose:
|
|
263
|
+
print("Using Agent: " + str(agent_id) + ", model: " + str(model.id))
|
|
264
|
+
else:
|
|
265
|
+
raise Exception("Agent not found: " + str(agent_id))
|
|
266
|
+
|
|
267
|
+
# run agent and return result
|
|
268
|
+
mode = provider.get_mode()
|
|
269
|
+
kwargs = {
|
|
270
|
+
"agent": agent,
|
|
271
|
+
"ctx": ctx,
|
|
272
|
+
"prompt": prompt,
|
|
273
|
+
"signals": signals,
|
|
274
|
+
"verbose": verbose,
|
|
275
|
+
"history": history,
|
|
276
|
+
"llm": llm,
|
|
277
|
+
}
|
|
278
|
+
# TODO: add support for other modes
|
|
279
|
+
if mode == AGENT_MODE_WORKFLOW:
|
|
280
|
+
return asyncio.run(self.llama_workflow.run_once(**kwargs))
|
|
281
|
+
|
|
282
|
+
except Exception as e:
|
|
283
|
+
self.window.core.debug.error(e)
|
|
284
|
+
self.last_error = e
|
|
285
|
+
return None
|
|
286
|
+
|
|
181
287
|
def get_error(self) -> Optional[Exception]:
|
|
182
288
|
"""
|
|
183
289
|
Get last error
|
|
@@ -6,12 +6,12 @@
|
|
|
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.08.
|
|
9
|
+
# Updated Date: 2025.08.14 01:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import copy
|
|
13
13
|
import re
|
|
14
|
-
import
|
|
14
|
+
import time
|
|
15
15
|
from typing import Optional, Tuple
|
|
16
16
|
|
|
17
17
|
from pygpt_net.core.bridge.context import BridgeContext
|
|
@@ -82,6 +82,7 @@ class Helpers:
|
|
|
82
82
|
# ctx.attachments = from_ctx.attachments # copy from parent if appended from plugins
|
|
83
83
|
# ctx.files = from_ctx.files # copy from parent if appended from plugins
|
|
84
84
|
ctx.extra = from_ctx.extra.copy() # copy extra data
|
|
85
|
+
ctx.output_timestamp = int(time.time()) # set output timestamp
|
|
85
86
|
return ctx
|
|
86
87
|
|
|
87
88
|
def send_stream(
|