pygpt-net 2.6.59__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.
- pygpt_net/CHANGELOG.txt +4 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/app.py +9 -5
- pygpt_net/controller/__init__.py +1 -0
- pygpt_net/controller/presets/editor.py +442 -39
- pygpt_net/core/agents/custom/__init__.py +275 -0
- pygpt_net/core/agents/custom/debug.py +64 -0
- pygpt_net/core/agents/custom/factory.py +109 -0
- pygpt_net/core/agents/custom/graph.py +71 -0
- pygpt_net/core/agents/custom/llama_index/__init__.py +10 -0
- pygpt_net/core/agents/custom/llama_index/factory.py +89 -0
- pygpt_net/core/agents/custom/llama_index/router_streamer.py +106 -0
- pygpt_net/core/agents/custom/llama_index/runner.py +529 -0
- pygpt_net/core/agents/custom/llama_index/stream.py +56 -0
- pygpt_net/core/agents/custom/llama_index/utils.py +242 -0
- pygpt_net/core/agents/custom/logging.py +50 -0
- pygpt_net/core/agents/custom/memory.py +51 -0
- pygpt_net/core/agents/custom/router.py +116 -0
- pygpt_net/core/agents/custom/router_streamer.py +187 -0
- pygpt_net/core/agents/custom/runner.py +454 -0
- pygpt_net/core/agents/custom/schema.py +125 -0
- pygpt_net/core/agents/custom/utils.py +181 -0
- pygpt_net/core/agents/provider.py +72 -7
- pygpt_net/core/agents/runner.py +7 -4
- pygpt_net/core/agents/runners/helpers.py +1 -1
- pygpt_net/core/agents/runners/llama_workflow.py +3 -0
- pygpt_net/core/agents/runners/openai_workflow.py +8 -1
- pygpt_net/{ui/widget/builder → core/node_editor}/__init__.py +2 -2
- pygpt_net/core/{builder → node_editor}/graph.py +11 -218
- pygpt_net/core/node_editor/models.py +111 -0
- pygpt_net/core/node_editor/types.py +76 -0
- pygpt_net/core/node_editor/utils.py +17 -0
- pygpt_net/core/render/web/renderer.py +10 -8
- pygpt_net/data/config/config.json +3 -3
- pygpt_net/data/config/models.json +3 -3
- pygpt_net/data/locale/locale.en.ini +4 -4
- pygpt_net/item/agent.py +5 -1
- pygpt_net/item/preset.py +19 -1
- pygpt_net/provider/agents/base.py +33 -2
- pygpt_net/provider/agents/llama_index/flow_from_schema.py +92 -0
- pygpt_net/provider/agents/openai/flow_from_schema.py +96 -0
- pygpt_net/provider/core/agent/json_file.py +11 -5
- pygpt_net/tools/agent_builder/tool.py +217 -52
- pygpt_net/tools/agent_builder/ui/dialogs.py +119 -24
- pygpt_net/tools/agent_builder/ui/list.py +37 -10
- pygpt_net/ui/dialog/preset.py +16 -1
- pygpt_net/ui/main.py +1 -1
- pygpt_net/{core/builder → ui/widget/node_editor}/__init__.py +2 -2
- pygpt_net/ui/widget/node_editor/command.py +373 -0
- pygpt_net/ui/widget/node_editor/editor.py +2038 -0
- pygpt_net/ui/widget/node_editor/item.py +492 -0
- pygpt_net/ui/widget/node_editor/node.py +1205 -0
- pygpt_net/ui/widget/node_editor/utils.py +17 -0
- pygpt_net/ui/widget/node_editor/view.py +247 -0
- {pygpt_net-2.6.59.dist-info → pygpt_net-2.6.60.dist-info}/METADATA +72 -2
- {pygpt_net-2.6.59.dist-info → pygpt_net-2.6.60.dist-info}/RECORD +59 -33
- pygpt_net/core/agents/custom.py +0 -150
- pygpt_net/ui/widget/builder/editor.py +0 -2001
- {pygpt_net-2.6.59.dist-info → pygpt_net-2.6.60.dist-info}/LICENSE +0 -0
- {pygpt_net-2.6.59.dist-info → pygpt_net-2.6.60.dist-info}/WHEEL +0 -0
- {pygpt_net-2.6.59.dist-info → pygpt_net-2.6.60.dist-info}/entry_points.txt +0 -0
|
@@ -21,6 +21,9 @@ class BaseAgent:
|
|
|
21
21
|
self.type = ""
|
|
22
22
|
self.mode = ""
|
|
23
23
|
self.name = ""
|
|
24
|
+
self.custom_id = None
|
|
25
|
+
self.custom_options = None
|
|
26
|
+
self.custom_schema = None
|
|
24
27
|
|
|
25
28
|
def get_mode(self) -> str:
|
|
26
29
|
"""
|
|
@@ -44,12 +47,39 @@ class BaseAgent:
|
|
|
44
47
|
"""
|
|
45
48
|
pass
|
|
46
49
|
|
|
50
|
+
def set_id(self, id: str):
|
|
51
|
+
"""
|
|
52
|
+
Set custom ID for the agent
|
|
53
|
+
|
|
54
|
+
:param id: Custom ID
|
|
55
|
+
"""
|
|
56
|
+
self.custom_id = id
|
|
57
|
+
|
|
58
|
+
def set_schema(self, schema: list):
|
|
59
|
+
"""
|
|
60
|
+
Set custom schema for the agent
|
|
61
|
+
|
|
62
|
+
:param schema: Custom schema
|
|
63
|
+
"""
|
|
64
|
+
self.custom_schema = schema
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def set_options(self, options: dict):
|
|
68
|
+
"""
|
|
69
|
+
Set custom options for the agent
|
|
70
|
+
|
|
71
|
+
:param options: Custom options
|
|
72
|
+
"""
|
|
73
|
+
self.custom_options = options
|
|
74
|
+
|
|
47
75
|
def get_options(self) -> dict:
|
|
48
76
|
"""
|
|
49
77
|
Return Agent options
|
|
50
78
|
|
|
51
79
|
:return: Agent options
|
|
52
80
|
"""
|
|
81
|
+
if self.custom_options is not None:
|
|
82
|
+
return self.custom_options
|
|
53
83
|
return {}
|
|
54
84
|
|
|
55
85
|
async def run(
|
|
@@ -89,9 +119,10 @@ class BaseAgent:
|
|
|
89
119
|
print("No preset provided, returning default option value")
|
|
90
120
|
return None
|
|
91
121
|
extra = preset.extra
|
|
92
|
-
|
|
122
|
+
agent_id = self.custom_id if self.custom_id is not None else self.id
|
|
123
|
+
if not isinstance(extra, dict) or agent_id not in extra:
|
|
93
124
|
return self.get_default(section, key)
|
|
94
|
-
options = extra[
|
|
125
|
+
options = extra[agent_id]
|
|
95
126
|
if section not in options:
|
|
96
127
|
return self.get_default(section, key)
|
|
97
128
|
if key not in options[section]:
|
|
@@ -0,0 +1,92 @@
|
|
|
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 23:00:00 #
|
|
10
|
+
# ================================================== #
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
from typing import Any, Dict, Optional, List, Tuple
|
|
14
|
+
|
|
15
|
+
from pygpt_net.core.agents.custom.logging import StdLogger, NullLogger
|
|
16
|
+
from pygpt_net.core.types import AGENT_MODE_WORKFLOW, AGENT_TYPE_LLAMA
|
|
17
|
+
from pygpt_net.item.model import ModelItem
|
|
18
|
+
from pygpt_net.item.preset import PresetItem
|
|
19
|
+
from pygpt_net.core.bridge import BridgeContext
|
|
20
|
+
|
|
21
|
+
from agents import TResponseInputItem
|
|
22
|
+
|
|
23
|
+
from ..base import BaseAgent
|
|
24
|
+
from pygpt_net.core.agents.custom.llama_index.runner import DynamicFlowWorkflowLI
|
|
25
|
+
from pygpt_net.core.agents.custom.llama_index.utils import make_option_getter
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class Agent(BaseAgent):
|
|
29
|
+
"""
|
|
30
|
+
Dynamic Flow (LlamaIndex 0.13) – provider that returns a workflow-like object
|
|
31
|
+
compatible with predefined LlamaWorkflow runner (run() -> handler.stream_events()).
|
|
32
|
+
"""
|
|
33
|
+
def __init__(self, *args, **kwargs):
|
|
34
|
+
super(Agent, self).__init__(*args, **kwargs)
|
|
35
|
+
self.id = "llama_custom"
|
|
36
|
+
self.type = AGENT_TYPE_LLAMA
|
|
37
|
+
self.mode = AGENT_MODE_WORKFLOW
|
|
38
|
+
self.name = "Custom"
|
|
39
|
+
|
|
40
|
+
def get_agent(self, window, kwargs: Dict[str, Any]):
|
|
41
|
+
"""
|
|
42
|
+
Build and return DynamicFlowWorkflowLI.
|
|
43
|
+
Expected kwargs from your app:
|
|
44
|
+
- schema: List[dict]
|
|
45
|
+
- llm: LlamaIndex LLM (base) – użyty gdy brak per-node modelu
|
|
46
|
+
- tools: List[BaseTool] (LI)
|
|
47
|
+
- messages: Optional[List[TResponseInputItem]] – initial, dla pierwszego agenta
|
|
48
|
+
- context: BridgeContext (preset do get_option)
|
|
49
|
+
- router_stream_mode / max_iterations / stream / logger / model (default ModelItem)
|
|
50
|
+
"""
|
|
51
|
+
schema: List[Dict[str, Any]] = kwargs.get("schema") or []
|
|
52
|
+
llm = kwargs.get("llm")
|
|
53
|
+
tools = kwargs.get("tools", []) or []
|
|
54
|
+
initial_messages: Optional[List[TResponseInputItem]] = kwargs.get("chat_history")
|
|
55
|
+
verbose = bool(kwargs.get("verbose", False))
|
|
56
|
+
|
|
57
|
+
context: BridgeContext = kwargs.get("context", BridgeContext())
|
|
58
|
+
preset: Optional[PresetItem] = context.preset
|
|
59
|
+
default_model: ModelItem = kwargs.get("model", ModelItem())
|
|
60
|
+
|
|
61
|
+
base_prompt = self.get_option(preset, "base", "prompt")
|
|
62
|
+
allow_local_tools_default = bool(self.get_option(preset, "base", "allow_local_tools"))
|
|
63
|
+
allow_remote_tools_default = bool(self.get_option(preset, "base", "allow_remote_tools"))
|
|
64
|
+
max_iterations = int(self.get_option(preset, "base", "max_iterations") or kwargs.get("max_iterations", 20))
|
|
65
|
+
router_stream_mode = self.get_option(preset, "router", "stream_mode") or kwargs.get("router_stream_mode", "realtime")
|
|
66
|
+
|
|
67
|
+
option_get = make_option_getter(self, preset)
|
|
68
|
+
stream = bool(kwargs.get("stream", False))
|
|
69
|
+
logger = StdLogger(prefix="[flow]") if verbose else NullLogger()
|
|
70
|
+
|
|
71
|
+
return DynamicFlowWorkflowLI(
|
|
72
|
+
window=window,
|
|
73
|
+
logger=logger,
|
|
74
|
+
schema=schema,
|
|
75
|
+
initial_messages=initial_messages,
|
|
76
|
+
preset=preset,
|
|
77
|
+
default_model=default_model,
|
|
78
|
+
option_get=option_get,
|
|
79
|
+
router_stream_mode=str(router_stream_mode).lower(),
|
|
80
|
+
allow_local_tools_default=allow_local_tools_default,
|
|
81
|
+
allow_remote_tools_default=allow_remote_tools_default,
|
|
82
|
+
max_iterations=max_iterations,
|
|
83
|
+
llm=llm,
|
|
84
|
+
tools=tools,
|
|
85
|
+
stream=stream,
|
|
86
|
+
base_prompt=base_prompt,
|
|
87
|
+
timeout=120,
|
|
88
|
+
verbose=True,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
async def run(self, *args, **kwargs) -> Tuple[Any, str, str]:
|
|
92
|
+
raise NotImplementedError("Use get_agent() and run it via LlamaWorkflow runner.")
|
|
@@ -0,0 +1,96 @@
|
|
|
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 23:00:00 #
|
|
10
|
+
# ================================================== #
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
from typing import Any, Dict, Tuple, Optional, List
|
|
14
|
+
|
|
15
|
+
from pygpt_net.core.types import AGENT_TYPE_OPENAI, AGENT_MODE_OPENAI
|
|
16
|
+
from pygpt_net.item.ctx import CtxItem
|
|
17
|
+
from pygpt_net.item.model import ModelItem
|
|
18
|
+
from pygpt_net.item.preset import PresetItem
|
|
19
|
+
|
|
20
|
+
from pygpt_net.core.agents.bridge import ConnectionContext
|
|
21
|
+
from pygpt_net.core.bridge import BridgeContext
|
|
22
|
+
|
|
23
|
+
from agents import TResponseInputItem
|
|
24
|
+
|
|
25
|
+
from ..base import BaseAgent
|
|
26
|
+
|
|
27
|
+
from pygpt_net.core.agents.custom.logging import NullLogger, StdLogger
|
|
28
|
+
from pygpt_net.core.agents.custom.runner import FlowOrchestrator
|
|
29
|
+
from pygpt_net.core.agents.custom.utils import make_option_getter
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class Agent(BaseAgent):
|
|
33
|
+
def __init__(self, *args, **kwargs):
|
|
34
|
+
super(Agent, self).__init__(*args, **kwargs)
|
|
35
|
+
self.id = "openai_custom"
|
|
36
|
+
self.type = AGENT_TYPE_OPENAI
|
|
37
|
+
self.mode = AGENT_MODE_OPENAI
|
|
38
|
+
self.name = "Custom"
|
|
39
|
+
|
|
40
|
+
async def run(
|
|
41
|
+
self,
|
|
42
|
+
window: Any = None,
|
|
43
|
+
agent_kwargs: Dict[str, Any] = None,
|
|
44
|
+
previous_response_id: str = None,
|
|
45
|
+
messages: List[TResponseInputItem] = None,
|
|
46
|
+
ctx: CtxItem = None,
|
|
47
|
+
stream: bool = False,
|
|
48
|
+
bridge: ConnectionContext = None,
|
|
49
|
+
use_partial_ctx: Optional[bool] = False,
|
|
50
|
+
schema: Optional[list] = None,
|
|
51
|
+
) -> Tuple[CtxItem, str, str]:
|
|
52
|
+
agent_kwargs = agent_kwargs or {}
|
|
53
|
+
messages = messages or []
|
|
54
|
+
|
|
55
|
+
context: BridgeContext = agent_kwargs.get("context", BridgeContext())
|
|
56
|
+
preset: Optional[PresetItem] = context.preset
|
|
57
|
+
model: ModelItem = agent_kwargs.get("model", ModelItem())
|
|
58
|
+
function_tools: list = agent_kwargs.get("function_tools", [])
|
|
59
|
+
|
|
60
|
+
base_prompt = self.get_option(preset, "base", "prompt")
|
|
61
|
+
allow_local_tools_default = bool(self.get_option(preset, "base", "allow_local_tools"))
|
|
62
|
+
allow_remote_tools_default = bool(self.get_option(preset, "base", "allow_remote_tools"))
|
|
63
|
+
max_iterations = int(self.get_option(preset, "base", "max_iterations") or agent_kwargs.get("max_iterations", 20))
|
|
64
|
+
trace_id = self.get_option(preset, "debug", "trace_id") or agent_kwargs.get("trace_id", None)
|
|
65
|
+
router_stream_mode = self.get_option(preset, "router", "stream_mode") or agent_kwargs.get("router_stream_mode", "realtime")
|
|
66
|
+
verbose = bool(agent_kwargs.get("verbose", False))
|
|
67
|
+
logger = StdLogger(prefix="[flow]") if verbose else NullLogger()
|
|
68
|
+
option_get = make_option_getter(self, preset)
|
|
69
|
+
|
|
70
|
+
orchestrator = FlowOrchestrator(window=window, logger=logger)
|
|
71
|
+
logger.debug(f"[schema] {schema}")
|
|
72
|
+
|
|
73
|
+
result = await orchestrator.run_flow(
|
|
74
|
+
schema=schema or [],
|
|
75
|
+
messages=messages,
|
|
76
|
+
ctx=ctx,
|
|
77
|
+
bridge=bridge,
|
|
78
|
+
agent_kwargs=agent_kwargs,
|
|
79
|
+
preset=preset,
|
|
80
|
+
model=model,
|
|
81
|
+
stream=stream,
|
|
82
|
+
use_partial_ctx=use_partial_ctx or False,
|
|
83
|
+
base_prompt=base_prompt,
|
|
84
|
+
allow_local_tools_default=allow_local_tools_default,
|
|
85
|
+
allow_remote_tools_default=allow_remote_tools_default,
|
|
86
|
+
function_tools=function_tools,
|
|
87
|
+
trace_id=trace_id,
|
|
88
|
+
max_iterations=max_iterations,
|
|
89
|
+
router_stream_mode=str(router_stream_mode).lower(),
|
|
90
|
+
option_get=option_get,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
final_output = result.final_output or ""
|
|
94
|
+
last_response_id = result.last_response_id or ""
|
|
95
|
+
|
|
96
|
+
return result.ctx, final_output, last_response_id
|
|
@@ -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.09.
|
|
9
|
+
# Updated Date: 2025.09.24 00:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import json
|
|
@@ -60,7 +60,10 @@ class JsonFileProvider(BaseProvider):
|
|
|
60
60
|
try:
|
|
61
61
|
if os.path.exists(path):
|
|
62
62
|
with open(path, 'r', encoding="utf-8") as file:
|
|
63
|
-
|
|
63
|
+
try:
|
|
64
|
+
data = json.load(file)
|
|
65
|
+
except json.JSONDecodeError:
|
|
66
|
+
data = {}
|
|
64
67
|
if data == "" or data is None:
|
|
65
68
|
return {}
|
|
66
69
|
if "layout" in data:
|
|
@@ -143,6 +146,7 @@ class JsonFileProvider(BaseProvider):
|
|
|
143
146
|
'id': item.id,
|
|
144
147
|
'name': item.name,
|
|
145
148
|
'layout': item.layout,
|
|
149
|
+
'schema': item.schema,
|
|
146
150
|
}
|
|
147
151
|
|
|
148
152
|
@staticmethod
|
|
@@ -159,6 +163,8 @@ class JsonFileProvider(BaseProvider):
|
|
|
159
163
|
item.name = data['name']
|
|
160
164
|
if "layout" in data:
|
|
161
165
|
item.layout = data['layout']
|
|
166
|
+
if "schema" in data:
|
|
167
|
+
item.schema = data['schema']
|
|
162
168
|
|
|
163
169
|
@staticmethod
|
|
164
170
|
def serialize_layout(item: BuilderLayoutItem) -> Dict[str, Any]:
|
|
@@ -169,9 +175,9 @@ class JsonFileProvider(BaseProvider):
|
|
|
169
175
|
:return: serialized item
|
|
170
176
|
"""
|
|
171
177
|
return {
|
|
172
|
-
'id': item.id,
|
|
173
|
-
'name': item.name,
|
|
174
|
-
'data': item.data,
|
|
178
|
+
'id': item.id if item else "",
|
|
179
|
+
'name': item.name if item else "",
|
|
180
|
+
'data': item.data if item else {},
|
|
175
181
|
}
|
|
176
182
|
|
|
177
183
|
@staticmethod
|