pygpt-net 2.6.58__py3-none-any.whl → 2.6.60__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 (72) hide show
  1. pygpt_net/CHANGELOG.txt +10 -0
  2. pygpt_net/__init__.py +3 -3
  3. pygpt_net/app.py +9 -5
  4. pygpt_net/controller/__init__.py +1 -0
  5. pygpt_net/controller/presets/editor.py +442 -39
  6. pygpt_net/core/agents/custom/__init__.py +275 -0
  7. pygpt_net/core/agents/custom/debug.py +64 -0
  8. pygpt_net/core/agents/custom/factory.py +109 -0
  9. pygpt_net/core/agents/custom/graph.py +71 -0
  10. pygpt_net/core/agents/custom/llama_index/__init__.py +10 -0
  11. pygpt_net/core/agents/custom/llama_index/factory.py +89 -0
  12. pygpt_net/core/agents/custom/llama_index/router_streamer.py +106 -0
  13. pygpt_net/core/agents/custom/llama_index/runner.py +529 -0
  14. pygpt_net/core/agents/custom/llama_index/stream.py +56 -0
  15. pygpt_net/core/agents/custom/llama_index/utils.py +242 -0
  16. pygpt_net/core/agents/custom/logging.py +50 -0
  17. pygpt_net/core/agents/custom/memory.py +51 -0
  18. pygpt_net/core/agents/custom/router.py +116 -0
  19. pygpt_net/core/agents/custom/router_streamer.py +187 -0
  20. pygpt_net/core/agents/custom/runner.py +454 -0
  21. pygpt_net/core/agents/custom/schema.py +125 -0
  22. pygpt_net/core/agents/custom/utils.py +181 -0
  23. pygpt_net/core/agents/provider.py +72 -7
  24. pygpt_net/core/agents/runner.py +7 -4
  25. pygpt_net/core/agents/runners/helpers.py +1 -1
  26. pygpt_net/core/agents/runners/llama_workflow.py +3 -0
  27. pygpt_net/core/agents/runners/openai_workflow.py +8 -1
  28. pygpt_net/core/filesystem/parser.py +37 -24
  29. pygpt_net/{ui/widget/builder → core/node_editor}/__init__.py +2 -2
  30. pygpt_net/core/{builder → node_editor}/graph.py +11 -218
  31. pygpt_net/core/node_editor/models.py +111 -0
  32. pygpt_net/core/node_editor/types.py +76 -0
  33. pygpt_net/core/node_editor/utils.py +17 -0
  34. pygpt_net/core/render/web/renderer.py +10 -8
  35. pygpt_net/data/config/config.json +3 -3
  36. pygpt_net/data/config/models.json +3 -3
  37. pygpt_net/data/locale/locale.en.ini +4 -4
  38. pygpt_net/data/locale/plugin.cmd_system.en.ini +68 -0
  39. pygpt_net/item/agent.py +5 -1
  40. pygpt_net/item/preset.py +19 -1
  41. pygpt_net/plugin/cmd_system/config.py +377 -1
  42. pygpt_net/plugin/cmd_system/plugin.py +52 -8
  43. pygpt_net/plugin/cmd_system/runner.py +508 -32
  44. pygpt_net/plugin/cmd_system/winapi.py +481 -0
  45. pygpt_net/plugin/cmd_system/worker.py +88 -15
  46. pygpt_net/provider/agents/base.py +33 -2
  47. pygpt_net/provider/agents/llama_index/flow_from_schema.py +92 -0
  48. pygpt_net/provider/agents/llama_index/workflow/supervisor.py +0 -0
  49. pygpt_net/provider/agents/openai/flow_from_schema.py +96 -0
  50. pygpt_net/provider/core/agent/json_file.py +11 -5
  51. pygpt_net/provider/llms/openai.py +6 -4
  52. pygpt_net/tools/agent_builder/tool.py +217 -52
  53. pygpt_net/tools/agent_builder/ui/dialogs.py +119 -24
  54. pygpt_net/tools/agent_builder/ui/list.py +37 -10
  55. pygpt_net/tools/code_interpreter/ui/html.py +2 -1
  56. pygpt_net/ui/dialog/preset.py +16 -1
  57. pygpt_net/ui/main.py +1 -1
  58. pygpt_net/{core/builder → ui/widget/node_editor}/__init__.py +2 -2
  59. pygpt_net/ui/widget/node_editor/command.py +373 -0
  60. pygpt_net/ui/widget/node_editor/editor.py +2038 -0
  61. pygpt_net/ui/widget/node_editor/item.py +492 -0
  62. pygpt_net/ui/widget/node_editor/node.py +1205 -0
  63. pygpt_net/ui/widget/node_editor/utils.py +17 -0
  64. pygpt_net/ui/widget/node_editor/view.py +247 -0
  65. pygpt_net/ui/widget/textarea/web.py +1 -1
  66. {pygpt_net-2.6.58.dist-info → pygpt_net-2.6.60.dist-info}/METADATA +135 -61
  67. {pygpt_net-2.6.58.dist-info → pygpt_net-2.6.60.dist-info}/RECORD +69 -42
  68. pygpt_net/core/agents/custom.py +0 -150
  69. pygpt_net/ui/widget/builder/editor.py +0 -2001
  70. {pygpt_net-2.6.58.dist-info → pygpt_net-2.6.60.dist-info}/LICENSE +0 -0
  71. {pygpt_net-2.6.58.dist-info → pygpt_net-2.6.60.dist-info}/WHEEL +0 -0
  72. {pygpt_net-2.6.58.dist-info → pygpt_net-2.6.60.dist-info}/entry_points.txt +0 -0
@@ -6,229 +6,18 @@
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.09.19 00:00:00 #
9
+ # Updated Date: 2025.09.24 00:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from __future__ import annotations
13
13
  from typing import Dict, List, Optional, Tuple, Any
14
- from dataclasses import dataclass, field
15
- from uuid import uuid4
16
- from PySide6.QtCore import QObject, Signal
17
14
  import re
18
15
 
16
+ from PySide6.QtCore import QObject, Signal
19
17
 
20
- def gen_uuid() -> str:
21
- return str(uuid4())
22
-
23
-
24
- # ------------------------ Data models (pure data) ------------------------
25
-
26
- @dataclass
27
- class PropertyModel:
28
- uuid: str
29
- id: str
30
- type: str # "slot", "str", "int", "float", "bool", "combo", "text"
31
- name: str
32
- editable: bool = True
33
- value: Any = None
34
- allowed_inputs: int = 0 # 0 none, -1 unlimited, >0 limit
35
- allowed_outputs: int = 0 # 0 none, -1 unlimited, >0 limit
36
- options: Optional[List[str]] = None # for combo
37
-
38
- def to_dict(self) -> dict:
39
- return {
40
- "uuid": self.uuid,
41
- "id": self.id,
42
- "type": self.type,
43
- "name": self.name,
44
- "editable": self.editable,
45
- "value": self.value,
46
- "allowed_inputs": self.allowed_inputs,
47
- "allowed_outputs": self.allowed_outputs,
48
- "options": self.options or [],
49
- }
50
-
51
- @staticmethod
52
- def from_dict(d: dict) -> "PropertyModel":
53
- return PropertyModel(
54
- uuid=d.get("uuid", gen_uuid()),
55
- id=d["id"],
56
- type=d["type"],
57
- name=d.get("name", d["id"]),
58
- editable=d.get("editable", True),
59
- value=d.get("value"),
60
- allowed_inputs=d.get("allowed_inputs", 0),
61
- allowed_outputs=d.get("allowed_outputs", 0),
62
- options=d.get("options") or None,
63
- )
64
-
65
-
66
- @dataclass
67
- class NodeModel:
68
- uuid: str
69
- id: str
70
- name: str
71
- type: str
72
- properties: Dict[str, PropertyModel] = field(default_factory=dict)
73
-
74
- def to_dict(self) -> dict:
75
- return {
76
- "uuid": self.uuid,
77
- "id": self.id,
78
- "name": self.name,
79
- "type": self.type,
80
- "properties": {pid: p.to_dict() for pid, p in self.properties.items()},
81
- }
82
-
83
- @staticmethod
84
- def from_dict(d: dict) -> "NodeModel":
85
- props = {pid: PropertyModel.from_dict(pd) for pid, pd in d.get("properties", {}).items()}
86
- return NodeModel(
87
- uuid=d.get("uuid", gen_uuid()),
88
- id=d["id"],
89
- name=d.get("name", d["id"]),
90
- type=d["type"],
91
- properties=props,
92
- )
93
-
94
-
95
- @dataclass
96
- class ConnectionModel:
97
- uuid: str
98
- src_node: str
99
- src_prop: str
100
- dst_node: str
101
- dst_prop: str
102
-
103
- def to_dict(self) -> dict:
104
- return {
105
- "uuid": self.uuid,
106
- "src_node": self.src_node, "src_prop": self.src_prop,
107
- "dst_node": self.dst_node, "dst_prop": self.dst_prop,
108
- }
109
-
110
- @staticmethod
111
- def from_dict(d: dict) -> "ConnectionModel":
112
- return ConnectionModel(
113
- uuid=d.get("uuid", gen_uuid()),
114
- src_node=d["src_node"], src_prop=d["src_prop"],
115
- dst_node=d["dst_node"], dst_prop=d["dst_prop"],
116
- )
117
-
118
-
119
- # ------------------------ Types registry (templates) ------------------------
120
-
121
- @dataclass
122
- class PropertySpec:
123
- id: str
124
- type: str
125
- name: Optional[str] = None
126
- editable: bool = True
127
- value: Any = None
128
- allowed_inputs: int = 0
129
- allowed_outputs: int = 0
130
- options: Optional[List[str]] = None
131
-
132
-
133
- @dataclass
134
- class NodeTypeSpec:
135
- type_name: str
136
- title: Optional[str] = None
137
- properties: List[PropertySpec] = field(default_factory=list)
138
- # Below are optional extensions for agent-flow needs:
139
- base_id: Optional[str] = None # base prefix for friendly ids, e.g. "agent"
140
- export_kind: Optional[str] = None # short kind for export, e.g. "agent", "start"
141
- bg_color: Optional[str] = None # optional per-type background color (CSS/hex)
142
-
143
- class NodeTypeRegistry:
144
- """Registry for node type specifications. Extend/override in subclasses."""
145
- def __init__(self):
146
- self._types: Dict[str, NodeTypeSpec] = {}
147
- self._install_default_types()
148
-
149
- def register(self, spec: NodeTypeSpec):
150
- self._types[spec.type_name] = spec
151
-
152
- def types(self) -> List[str]:
153
- return list(self._types.keys())
154
-
155
- def get(self, type_name: str) -> Optional[NodeTypeSpec]:
156
- return self._types.get(type_name)
157
-
158
- def _install_default_types(self):
159
- # Example/basic nodes kept intact
160
- self.register(NodeTypeSpec(
161
- type_name="Value/Float",
162
- title="Float",
163
- properties=[
164
- PropertySpec(id="value", type="float", name="Value", editable=True, value=0.0,
165
- allowed_inputs=0, allowed_outputs=1),
166
- ]
167
- ))
168
- self.register(NodeTypeSpec(
169
- type_name="Math/Add",
170
- title="Add",
171
- properties=[
172
- PropertySpec(id="A", type="float", name="A", editable=True, value=0.0, allowed_inputs=1, allowed_outputs=0),
173
- PropertySpec(id="B", type="float", name="B", editable=True, value=0.0, allowed_inputs=1, allowed_outputs=0),
174
- PropertySpec(id="result", type="float", name="Result", editable=False, value=None, allowed_inputs=0, allowed_outputs=1),
175
- ]
176
- ))
177
- # Tip: to allow multiple connections to an input or output, set allowed_inputs/allowed_outputs to -1.
178
-
179
- # Agent-flow nodes
180
- # Start
181
- self.register(NodeTypeSpec(
182
- type_name="Flow/Start",
183
- title="Start",
184
- base_id="start",
185
- export_kind="start",
186
- bg_color="#2D5A27",
187
- properties=[
188
- PropertySpec(id="output", type="flow", name="Output", editable=False, allowed_inputs=0, allowed_outputs=1),
189
- # base_id will be auto-injected as read-only property at creation
190
- ],
191
- ))
192
- # Agent
193
- self.register(NodeTypeSpec(
194
- type_name="Flow/Agent",
195
- title="Agent",
196
- base_id="agent",
197
- export_kind="agent",
198
- bg_color="#304A6E",
199
- properties=[
200
- PropertySpec(id="name", type="str", name="Name", editable=True, value=""),
201
- PropertySpec(id="instruction", type="text", name="Instruction", editable=True, value=""),
202
- PropertySpec(id="remote_tools", type="bool", name="Remote tools", editable=True, value=True),
203
- PropertySpec(id="local_tools", type="bool", name="Local tools", editable=True, value=True),
204
- PropertySpec(id="input", type="flow", name="Input", editable=False, allowed_inputs=-1, allowed_outputs=0),
205
- PropertySpec(id="output", type="flow", name="Output", editable=False, allowed_inputs=0, allowed_outputs=1),
206
- PropertySpec(id="memory", type="memory", name="Memory", editable=False, allowed_inputs=0, allowed_outputs=1),
207
- ],
208
- ))
209
- # Memory
210
- self.register(NodeTypeSpec(
211
- type_name="Flow/Memory",
212
- title="Memory",
213
- base_id="mem",
214
- export_kind="memory",
215
- bg_color="#593E78",
216
- properties=[
217
- PropertySpec(id="name", type="str", name="Name", editable=True, value=""),
218
- PropertySpec(id="input", type="memory", name="Input", editable=False, allowed_inputs=-1, allowed_outputs=0),
219
- ],
220
- ))
221
- # End
222
- self.register(NodeTypeSpec(
223
- type_name="Flow/End",
224
- title="End",
225
- base_id="end",
226
- export_kind="end",
227
- bg_color="#6B2E2E",
228
- properties=[
229
- PropertySpec(id="input", type="flow", name="Input", editable=False, allowed_inputs=1, allowed_outputs=0),
230
- ],
231
- ))
18
+ from .models import NodeModel, ConnectionModel, PropertyModel
19
+ from .types import NodeTypeRegistry
20
+ from .utils import gen_uuid
232
21
 
233
22
 
234
23
  # ------------------------ Graph (Qt QObject + signals) ------------------------
@@ -412,8 +201,8 @@ class NodeGraph(QObject):
412
201
  for c in self.connections.values()]
413
202
  return {"nodes": nodes_out, "connections": conns_out}
414
203
 
415
- # --- Export to requested agent schema (list of nodes with slots/in-out) ---
416
- def to_agent_schema(self) -> List[dict]:
204
+ # --- Export to list schema (list of nodes with slots/in-out) ---
205
+ def to_list_schema(self) -> List[dict]:
417
206
  # Build helper maps
418
207
  uuid_to_node: Dict[str, NodeModel] = dict(self.nodes)
419
208
  uuid_to_id: Dict[str, str] = {u: n.id for u, n in uuid_to_node.items()}
@@ -474,5 +263,9 @@ class NodeGraph(QObject):
474
263
  def clear(self, silent: bool = False):
475
264
  self.nodes.clear()
476
265
  self.connections.clear()
266
+ # Reset counters to keep friendly IDs strictly per-layout.
267
+ # After a clear, numbering starts again from 1 for each base prefix.
268
+ self._node_counter = 1
269
+ self._id_counters.clear()
477
270
  if not silent:
478
271
  self.cleared.emit()
@@ -0,0 +1,111 @@
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.09.24 00:00:00 #
10
+ # ================================================== #
11
+
12
+ from __future__ import annotations
13
+ from typing import Dict, List, Optional, Any
14
+ from dataclasses import dataclass, field
15
+
16
+ from .utils import gen_uuid
17
+
18
+
19
+ # ------------------------ Data models (pure data) ------------------------
20
+
21
+ @dataclass
22
+ class PropertyModel:
23
+ uuid: str
24
+ id: str
25
+ type: str # "slot", "str", "int", "float", "bool", "combo", "text"
26
+ name: str
27
+ editable: bool = True
28
+ value: Any = None
29
+ allowed_inputs: int = 0 # 0 none, -1 unlimited, >0 limit
30
+ allowed_outputs: int = 0 # 0 none, -1 unlimited, >0 limit
31
+ options: Optional[List[str]] = None # for combo
32
+
33
+ def to_dict(self) -> dict:
34
+ return {
35
+ "uuid": self.uuid,
36
+ "id": self.id,
37
+ "type": self.type,
38
+ "name": self.name,
39
+ "editable": self.editable,
40
+ "value": self.value,
41
+ "allowed_inputs": self.allowed_inputs,
42
+ "allowed_outputs": self.allowed_outputs,
43
+ "options": self.options or [],
44
+ }
45
+
46
+ @staticmethod
47
+ def from_dict(d: dict) -> "PropertyModel":
48
+ return PropertyModel(
49
+ uuid=d.get("uuid", gen_uuid()),
50
+ id=d["id"],
51
+ type=d["type"],
52
+ name=d.get("name", d["id"]),
53
+ editable=d.get("editable", True),
54
+ value=d.get("value"),
55
+ allowed_inputs=d.get("allowed_inputs", 0),
56
+ allowed_outputs=d.get("allowed_outputs", 0),
57
+ options=d.get("options") or None,
58
+ )
59
+
60
+
61
+ @dataclass
62
+ class NodeModel:
63
+ uuid: str
64
+ id: str
65
+ name: str
66
+ type: str
67
+ properties: Dict[str, PropertyModel] = field(default_factory=dict)
68
+
69
+ def to_dict(self) -> dict:
70
+ return {
71
+ "uuid": self.uuid,
72
+ "id": self.id,
73
+ "name": self.name,
74
+ "type": self.type,
75
+ "properties": {pid: p.to_dict() for pid, p in self.properties.items()},
76
+ }
77
+
78
+ @staticmethod
79
+ def from_dict(d: dict) -> "NodeModel":
80
+ props = {pid: PropertyModel.from_dict(pd) for pid, pd in d.get("properties", {}).items()}
81
+ return NodeModel(
82
+ uuid=d.get("uuid", gen_uuid()),
83
+ id=d["id"],
84
+ name=d.get("name", d["id"]),
85
+ type=d["type"],
86
+ properties=props,
87
+ )
88
+
89
+
90
+ @dataclass
91
+ class ConnectionModel:
92
+ uuid: str
93
+ src_node: str
94
+ src_prop: str
95
+ dst_node: str
96
+ dst_prop: str
97
+
98
+ def to_dict(self) -> dict:
99
+ return {
100
+ "uuid": self.uuid,
101
+ "src_node": self.src_node, "src_prop": self.src_prop,
102
+ "dst_node": self.dst_node, "dst_prop": self.dst_prop,
103
+ }
104
+
105
+ @staticmethod
106
+ def from_dict(d: dict) -> "ConnectionModel":
107
+ return ConnectionModel(
108
+ uuid=d.get("uuid", gen_uuid()),
109
+ src_node=d["src_node"], src_prop=d["src_prop"],
110
+ dst_node=d["dst_node"], dst_prop=d["dst_prop"],
111
+ )
@@ -0,0 +1,76 @@
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.09.24 00:00:00 #
10
+ # ================================================== #
11
+
12
+ from __future__ import annotations
13
+ from typing import Dict, List, Optional, Any
14
+ from dataclasses import dataclass, field
15
+
16
+
17
+ # ------------------------ Types registry (templates) ------------------------
18
+
19
+ @dataclass
20
+ class PropertySpec:
21
+ id: str
22
+ type: str
23
+ name: Optional[str] = None
24
+ editable: bool = True
25
+ value: Any = None
26
+ allowed_inputs: int = 0
27
+ allowed_outputs: int = 0
28
+ options: Optional[List[str]] = None
29
+
30
+
31
+ @dataclass
32
+ class NodeTypeSpec:
33
+ type_name: str
34
+ title: Optional[str] = None
35
+ properties: List[PropertySpec] = field(default_factory=list)
36
+ # Below are optional extensions for agent-flow needs:
37
+ base_id: Optional[str] = None # base prefix for friendly ids, e.g. "agent"
38
+ export_kind: Optional[str] = None # short kind for export, e.g. "agent", "start"
39
+ bg_color: Optional[str] = None # optional per-type background color (CSS/hex)
40
+
41
+ class NodeTypeRegistry:
42
+ """Registry for node type specifications. Extend/override in subclasses."""
43
+ def __init__(self, empty: bool = False):
44
+ self._types: Dict[str, NodeTypeSpec] = {}
45
+ if not empty:
46
+ self._install_default_types()
47
+
48
+ def register(self, spec: NodeTypeSpec):
49
+ self._types[spec.type_name] = spec
50
+
51
+ def types(self) -> List[str]:
52
+ return list(self._types.keys())
53
+
54
+ def get(self, type_name: str) -> Optional[NodeTypeSpec]:
55
+ return self._types.get(type_name)
56
+
57
+ def _install_default_types(self):
58
+ # Example/basic nodes kept intact
59
+ self.register(NodeTypeSpec(
60
+ type_name="Value/Float",
61
+ title="Float",
62
+ properties=[
63
+ PropertySpec(id="value", type="float", name="Value", editable=True, value=0.0,
64
+ allowed_inputs=0, allowed_outputs=1),
65
+ ]
66
+ ))
67
+ self.register(NodeTypeSpec(
68
+ type_name="Math/Add",
69
+ title="Add",
70
+ properties=[
71
+ PropertySpec(id="A", type="float", name="A", editable=True, value=0.0, allowed_inputs=1, allowed_outputs=0),
72
+ PropertySpec(id="B", type="float", name="B", editable=True, value=0.0, allowed_inputs=1, allowed_outputs=0),
73
+ PropertySpec(id="result", type="float", name="Result", editable=False, value=None, allowed_inputs=0, allowed_outputs=1),
74
+ ]
75
+ ))
76
+ # Tip: to allow multiple connections to an input or output, set allowed_inputs/allowed_outputs to -1.
@@ -0,0 +1,17 @@
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.09.24 00:00:00 #
10
+ # ================================================== #
11
+
12
+ from __future__ import annotations
13
+ from uuid import uuid4
14
+
15
+
16
+ def gen_uuid() -> str:
17
+ return str(uuid4())
@@ -9,7 +9,6 @@
9
9
  # Updated Date: 2025.09.17 05:00:00 #
10
10
  # ================================================== #
11
11
 
12
- import gc
13
12
  import json
14
13
  import os
15
14
  import re
@@ -21,7 +20,7 @@ from typing import Optional, List, Any, Dict, Tuple
21
20
  from time import monotonic
22
21
  from io import StringIO
23
22
 
24
- from PySide6.QtCore import QTimer, QUrl
23
+ from PySide6.QtCore import QTimer, QUrl, QCoreApplication, QEventLoop, QEvent
25
24
  from PySide6.QtWebEngineCore import QWebEnginePage
26
25
 
27
26
  from pygpt_net.core.render.base import BaseRenderer
@@ -496,9 +495,10 @@ class Renderer(BaseRenderer):
496
495
 
497
496
  Soft cleanup, called after each context is done.
498
497
  """
499
- try:
500
- gc.collect()
498
+ def cleanup():
501
499
  malloc_trim_linux()
500
+ try:
501
+ QTimer.singleShot(0, cleanup)
502
502
  except Exception:
503
503
  pass
504
504
 
@@ -1300,6 +1300,12 @@ class Renderer(BaseRenderer):
1300
1300
  tab.unwrap(node)
1301
1301
  self.window.ui.nodes['output'].pop(tab.pid, None)
1302
1302
 
1303
+ try:
1304
+ QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete)
1305
+ QCoreApplication.processEvents(QEventLoop.AllEvents, 0)
1306
+ except Exception:
1307
+ pass
1308
+
1303
1309
  view = ChatWebOutput(self.window)
1304
1310
  view.set_tab(tab)
1305
1311
  view.set_meta(meta)
@@ -1310,10 +1316,6 @@ class Renderer(BaseRenderer):
1310
1316
  tab.add_ref(view)
1311
1317
  view.setVisible(True)
1312
1318
  self.window.ui.nodes['output'][tab.pid] = view
1313
- try:
1314
- gc.collect()
1315
- except Exception:
1316
- pass
1317
1319
  self.auto_cleanup_soft(meta)
1318
1320
 
1319
1321
  def get_output_node(self, meta: Optional[CtxMeta] = None) -> Optional[ChatWebOutput]:
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.6.58",
4
- "app.version": "2.6.58",
5
- "updated_at": "2025-09-22T00:00:00"
3
+ "version": "2.6.60",
4
+ "app.version": "2.6.60",
5
+ "updated_at": "2025-09-25T00:00:00"
6
6
  },
7
7
  "access.audio.event.speech": false,
8
8
  "access.audio.event.speech.disabled": [],
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.6.58",
4
- "app.version": "2.6.58",
5
- "updated_at": "2025-09-22T00:00:00"
3
+ "version": "2.6.60",
4
+ "app.version": "2.6.60",
5
+ "updated_at": "2025-09-25T00:00:00"
6
6
  },
7
7
  "items": {
8
8
  "SpeakLeash/bielik-11b-v2.3-instruct:Q4_K_M": {
@@ -75,7 +75,7 @@ action.video.transcribe = Transcribe audio...
75
75
  agent.builder.confirm.clear.msg = Do you really want to clear the graph?
76
76
  agent.builder.confirm.clear.title = Clear
77
77
  agent.builder.confirm.delete.msg = Do you really want to delete the agent?
78
- agent.builder.title = Agent Builder
78
+ agent.builder.title = Agents Builder (beta)
79
79
  agent.coder.additional.label = Additional prompt
80
80
  agent.coder.additional.prompt.desc = Additional prompt for agent (will be added to the base prompt)
81
81
  agent.coder.base.label = Base prompt
@@ -115,7 +115,7 @@ agent.option.section.worker = Worker
115
115
  agent.option.section.writer = Writer
116
116
  agent.option.tools.local = Allow local tools
117
117
  agent.option.tools.local.desc = Allow usage of local tools for this agent
118
- agent.option.tools.remote = Allowe remote tools
118
+ agent.option.tools.remote = Allow remote tools
119
119
  agent.option.tools.remote.desc = Allow usage of remote tools for this agent
120
120
  agent.planner.plan.label = Planner (initial)
121
121
  agent.planner.plan.prompt.desc = Initial plan prompt
@@ -780,7 +780,7 @@ menu.config.save = Save config
780
780
  menu.config.settings = Settings...
781
781
  menu.debug = Debug
782
782
  menu.debug.agent = Agent...
783
- menu.debug.agent_builder = Agent Builder
783
+ menu.debug.agent_builder = Agents Builder (beta)
784
784
  menu.debug.app.log = View log file (app.log)
785
785
  menu.debug.assistants = Assistants...
786
786
  menu.debug.attachments = Files / attachments...
@@ -835,7 +835,7 @@ menu.theme.style = Style...
835
835
  menu.theme.syntax = Code syntax highlight...
836
836
  menu.theme.tooltips = Show tooltips
837
837
  menu.tools = Tools
838
- menu.tools.agent.builder = Agent Builder
838
+ menu.tools.agent.builder = Agents Builder (beta)
839
839
  menu.tools.audio.transcribe = Transcribe Audio/Video Files
840
840
  menu.tools.html_canvas = HTML/JS Canvas
841
841
  menu.tools.image.viewer = Image Viewer
@@ -21,3 +21,71 @@ sandbox_docker.description = Executes all system commands within a sandbox envir
21
21
  sandbox_docker_image.description = Specifies the Docker image to use for the sandbox.
22
22
  sandbox_docker_image.label = Docker Image
23
23
  sandbox_docker.label = Sandbox (Docker Container)
24
+
25
+ # WinAPI tab/options
26
+ winapi_enabled.label = Enable WinAPI
27
+ winapi_enabled.description = Enable Windows API features on Microsoft Windows.
28
+ win_keys_per_char_delay_ms.label = Keys: per-char delay (ms)
29
+ win_keys_per_char_delay_ms.description = Delay between characters for win_keys_text.
30
+ win_keys_hold_ms.label = Keys: hold (ms)
31
+ win_keys_hold_ms.description = Hold duration for modifiers in win_keys_send.
32
+ win_keys_gap_ms.label = Keys: gap (ms)
33
+ win_keys_gap_ms.description = Gap between normal key taps in win_keys_send.
34
+ win_drag_step_delay_ms.label = Drag: step delay (ms)
35
+ win_drag_step_delay_ms.description = Delay between intermediate drag steps in win_drag.
36
+
37
+ # WinAPI commands labels/descriptions
38
+ cmd.win_list.label = Enable: List Windows
39
+ cmd.win_list.description = Lists top-level windows (HWND, title, class, PID, EXE, rect, etc.)
40
+ cmd.win_find.label = Enable: Find Windows
41
+ cmd.win_find.description = Finds windows by title/class/exe/pid.
42
+ cmd.win_children.label = Enable: List Child Windows
43
+ cmd.win_children.description = Lists child windows for a parent HWND.
44
+ cmd.win_foreground.label = Enable: Foreground Window Info
45
+ cmd.win_foreground.description = Returns information about the current foreground window.
46
+ cmd.win_rect.label = Enable: Get Window Rect
47
+ cmd.win_rect.description = Returns window rectangle (geometry).
48
+ cmd.win_get_state.label = Enable: Get Window State
49
+ cmd.win_get_state.description = Returns window metadata and flags.
50
+ cmd.win_focus.label = Enable: Focus Window
51
+ cmd.win_focus.description = Brings a selected window to the foreground.
52
+ cmd.win_move_resize.label = Enable: Move/Resize Window
53
+ cmd.win_move_resize.description = Moves and resizes a window.
54
+ cmd.win_minimize.label = Enable: Minimize Window
55
+ cmd.win_minimize.description = Minimizes a window.
56
+ cmd.win_maximize.label = Enable: Maximize Window
57
+ cmd.win_maximize.description = Maximizes a window.
58
+ cmd.win_restore.label = Enable: Restore Window
59
+ cmd.win_restore.description = Restores a window to normal state.
60
+ cmd.win_close.label = Enable: Close Window
61
+ cmd.win_close.description = Closes a window using WM_CLOSE.
62
+ cmd.win_show.label = Enable: Show Window
63
+ cmd.win_show.description = Shows a window.
64
+ cmd.win_hide.label = Enable: Hide Window
65
+ cmd.win_hide.description = Hides a window.
66
+ cmd.win_always_on_top.label = Enable: Always On Top
67
+ cmd.win_always_on_top.description = Toggles topmost flag of a window.
68
+ cmd.win_set_opacity.label = Enable: Set Opacity
69
+ cmd.win_set_opacity.description = Sets window opacity via layered window attributes.
70
+ cmd.win_screenshot.label = Enable: Window Screenshot
71
+ cmd.win_screenshot.description = Captures a window to PNG file.
72
+ cmd.win_area_screenshot.label = Enable: Area Screenshot
73
+ cmd.win_area_screenshot.description = Captures a rectangular area of the screen to PNG file.
74
+ cmd.win_clipboard_get.label = Enable: Clipboard Get
75
+ cmd.win_clipboard_get.description = Gets text from clipboard.
76
+ cmd.win_clipboard_set.label = Enable: Clipboard Set
77
+ cmd.win_clipboard_set.description = Sets text to clipboard.
78
+ cmd.win_cursor_get.label = Enable: Cursor Get
79
+ cmd.win_cursor_get.description = Gets the cursor position.
80
+ cmd.win_cursor_set.label = Enable: Cursor Set
81
+ cmd.win_cursor_set.description = Sets the cursor position.
82
+ cmd.win_keys_text.label = Enable: Type Text
83
+ cmd.win_keys_text.description = Types Unicode text into active window.
84
+ cmd.win_keys_send.label = Enable: Send Key Combos
85
+ cmd.win_keys_send.description = Sends key combinations to active window.
86
+ cmd.win_click.label = Enable: Mouse Click
87
+ cmd.win_click.description = Sends a mouse click at given coordinates.
88
+ cmd.win_drag.label = Enable: Mouse Drag
89
+ cmd.win_drag.description = Performs a mouse drag from one point to another.
90
+ cmd.win_monitors.label = Enable: List Monitors
91
+ cmd.win_monitors.description = Lists monitors/screens and their geometry.
pygpt_net/item/agent.py CHANGED
@@ -20,18 +20,21 @@ class AgentItem:
20
20
  id: Optional[object] = None
21
21
  name: Optional[object] = None
22
22
  layout: dict = field(default_factory=dict)
23
+ schema: list = field(default_factory=list)
23
24
 
24
25
  def __init__(self):
25
26
  """Custom agent item"""
26
27
  self.id = None
27
28
  self.name = None
28
29
  self.layout = {}
30
+ self.schema = []
29
31
 
30
32
  def reset(self):
31
33
  """Reset"""
32
34
  self.id = None
33
35
  self.name = None
34
36
  self.layout = {}
37
+ self.schema = {}
35
38
 
36
39
  def to_dict(self) -> dict:
37
40
  """
@@ -42,7 +45,8 @@ class AgentItem:
42
45
  return {
43
46
  "id": self.id,
44
47
  "name": self.name,
45
- "layout": self.layout
48
+ "layout": self.layout,
49
+ "schema": self.schema,
46
50
  }
47
51
 
48
52
  def dump(self) -> str: