pygpt-net 2.6.8__py3-none-any.whl → 2.6.10__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 +12 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/app.py +4 -0
- pygpt_net/controller/ctx/common.py +9 -3
- pygpt_net/controller/ctx/ctx.py +19 -17
- pygpt_net/controller/kernel/kernel.py +1 -2
- pygpt_net/core/agents/runner.py +19 -0
- pygpt_net/core/agents/tools.py +93 -52
- pygpt_net/core/render/web/body.py +11 -33
- pygpt_net/core/render/web/renderer.py +52 -79
- pygpt_net/data/config/config.json +4 -3
- pygpt_net/data/config/models.json +3 -3
- pygpt_net/data/config/presets/agent_openai_supervisor.json +54 -0
- pygpt_net/data/config/presets/agent_supervisor.json +52 -0
- pygpt_net/data/config/settings.json +14 -0
- pygpt_net/data/locale/locale.de.ini +2 -0
- pygpt_net/data/locale/locale.en.ini +2 -0
- pygpt_net/data/locale/locale.es.ini +2 -0
- pygpt_net/data/locale/locale.fr.ini +2 -0
- pygpt_net/data/locale/locale.it.ini +2 -0
- pygpt_net/data/locale/locale.pl.ini +3 -1
- pygpt_net/data/locale/locale.uk.ini +2 -0
- pygpt_net/data/locale/locale.zh.ini +2 -0
- pygpt_net/plugin/google/config.py +306 -1
- pygpt_net/plugin/google/plugin.py +22 -0
- pygpt_net/plugin/google/worker.py +579 -3
- pygpt_net/provider/agents/llama_index/supervisor_workflow.py +116 -0
- pygpt_net/provider/agents/llama_index/workflow/supervisor.py +303 -0
- pygpt_net/provider/agents/openai/supervisor.py +361 -0
- pygpt_net/provider/core/config/patch.py +11 -0
- pygpt_net/provider/core/preset/patch.py +18 -0
- pygpt_net/ui/main.py +1 -1
- pygpt_net/ui/widget/lists/context.py +10 -1
- pygpt_net/ui/widget/textarea/web.py +47 -4
- {pygpt_net-2.6.8.dist-info → pygpt_net-2.6.10.dist-info}/METADATA +93 -29
- {pygpt_net-2.6.8.dist-info → pygpt_net-2.6.10.dist-info}/RECORD +39 -34
- {pygpt_net-2.6.8.dist-info → pygpt_net-2.6.10.dist-info}/LICENSE +0 -0
- {pygpt_net-2.6.8.dist-info → pygpt_net-2.6.10.dist-info}/WHEEL +0 -0
- {pygpt_net-2.6.8.dist-info → pygpt_net-2.6.10.dist-info}/entry_points.txt +0 -0
pygpt_net/CHANGELOG.txt
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
2.6.10 (2025-08-17)
|
|
2
|
+
|
|
3
|
+
- Enhanced the handling of the context list.
|
|
4
|
+
- Integrated RAG into OpenAI Agents.
|
|
5
|
+
- Enhanced RAG management in Agents.
|
|
6
|
+
- Added an option: Config -> Agents -> General -> Auto-retrieve additional context from RAG.
|
|
7
|
+
- Included Google Docs, Maps, and Colab in the Google plugin.
|
|
8
|
+
|
|
9
|
+
2.6.9 (2025-08-17)
|
|
10
|
+
|
|
11
|
+
- Added two new agents for LlamaIndex and OpenAI: Supervisor and Worker (beta).
|
|
12
|
+
|
|
1
13
|
2.6.8 (2025-08-16)
|
|
2
14
|
|
|
3
15
|
- Fixed: updated paragraph color on theme switch.
|
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.17 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.10"
|
|
17
|
+
__build__ = "2025-08-17"
|
|
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
|
@@ -88,6 +88,7 @@ from pygpt_net.provider.agents.llama_index.openai_workflow import OpenAIAgent as
|
|
|
88
88
|
# from pygpt_net.provider.agents.llama_index.legacy.react import ReactAgent
|
|
89
89
|
from pygpt_net.provider.agents.llama_index.react_workflow import ReactWorkflowAgent
|
|
90
90
|
from pygpt_net.provider.agents.llama_index.codeact_workflow import CodeActAgent
|
|
91
|
+
from pygpt_net.provider.agents.llama_index.supervisor_workflow import SupervisorAgent as LlamaSupervisorAgent
|
|
91
92
|
from pygpt_net.provider.agents.openai.agent import Agent as OpenAIAgentsBase
|
|
92
93
|
from pygpt_net.provider.agents.openai.agent_with_experts import Agent as OpenAIAgentsExperts
|
|
93
94
|
from pygpt_net.provider.agents.openai.agent_with_experts_feedback import Agent as OpenAIAgentsExpertsFeedback
|
|
@@ -96,6 +97,7 @@ from pygpt_net.provider.agents.openai.bot_researcher import Agent as OpenAIAgent
|
|
|
96
97
|
from pygpt_net.provider.agents.openai.agent_planner import Agent as OpenAIAgentPlanner
|
|
97
98
|
from pygpt_net.provider.agents.openai.evolve import Agent as OpenAIAgentsEvolve
|
|
98
99
|
from pygpt_net.provider.agents.openai.agent_b2b import Agent as OpenAIAgentsB2B
|
|
100
|
+
from pygpt_net.provider.agents.openai.supervisor import Agent as OpenAIAgentSupervisor
|
|
99
101
|
|
|
100
102
|
# LLM wrapper providers (langchain, llama-index, embeddings)
|
|
101
103
|
from pygpt_net.provider.llms.anthropic import AnthropicLLM
|
|
@@ -445,6 +447,7 @@ def run(**kwargs):
|
|
|
445
447
|
# launcher.add_agent(ReactAgent()) # llama-index
|
|
446
448
|
launcher.add_agent(ReactWorkflowAgent()) # llama-index
|
|
447
449
|
launcher.add_agent(CodeActAgent()) # llama-index
|
|
450
|
+
launcher.add_agent(LlamaSupervisorAgent()) # llama-index
|
|
448
451
|
launcher.add_agent(OpenAIAgentsBase()) # openai-agents
|
|
449
452
|
launcher.add_agent(OpenAIAgentsExperts()) # openai-agents
|
|
450
453
|
launcher.add_agent(OpenAIAgentFeedback()) # openai-agents
|
|
@@ -453,6 +456,7 @@ def run(**kwargs):
|
|
|
453
456
|
launcher.add_agent(OpenAIAgentsExpertsFeedback()) # openai-agents
|
|
454
457
|
launcher.add_agent(OpenAIAgentsEvolve()) # openai-agents
|
|
455
458
|
launcher.add_agent(OpenAIAgentsB2B()) # openai-agents
|
|
459
|
+
launcher.add_agent(OpenAIAgentSupervisor()) # openai-agents
|
|
456
460
|
|
|
457
461
|
# register custom agents
|
|
458
462
|
agents = kwargs.get('agents', None)
|
|
@@ -31,7 +31,8 @@ class Common:
|
|
|
31
31
|
self.summarizer = Summarizer(window)
|
|
32
32
|
|
|
33
33
|
def _update_ctx_no_scroll(self):
|
|
34
|
-
|
|
34
|
+
"""Update ctx list without scroll"""
|
|
35
|
+
self.window.controller.ctx.update_and_restore()
|
|
35
36
|
|
|
36
37
|
def update_label_by_current(self):
|
|
37
38
|
"""Update ctx label from current ctx"""
|
|
@@ -83,7 +84,7 @@ class Common:
|
|
|
83
84
|
if new_id is not None:
|
|
84
85
|
self.window.core.attachments.context.duplicate(meta_id, new_id)
|
|
85
86
|
self.window.update_status(f"Context duplicated, new ctx id: {new_id}")
|
|
86
|
-
QTimer.singleShot(
|
|
87
|
+
QTimer.singleShot(10, self._update_ctx_no_scroll)
|
|
87
88
|
|
|
88
89
|
def dismiss_rename(self):
|
|
89
90
|
"""Dismiss rename dialog"""
|
|
@@ -97,7 +98,12 @@ class Common:
|
|
|
97
98
|
"""
|
|
98
99
|
data_id = meta.id if meta else None
|
|
99
100
|
title = meta.name if meta else None
|
|
100
|
-
self.window.controller.ui.tabs.focus_by_type(
|
|
101
|
+
self.window.controller.ui.tabs.focus_by_type(
|
|
102
|
+
Tab.TAB_CHAT,
|
|
103
|
+
data_id=data_id,
|
|
104
|
+
title=title,
|
|
105
|
+
meta=meta
|
|
106
|
+
)
|
|
101
107
|
|
|
102
108
|
def restore_display_filter(self):
|
|
103
109
|
"""Restore display filter"""
|
pygpt_net/controller/ctx/ctx.py
CHANGED
|
@@ -334,17 +334,20 @@ class Ctx:
|
|
|
334
334
|
if id is not None:
|
|
335
335
|
self.select(id)
|
|
336
336
|
|
|
337
|
-
def update_list(self, reload: bool = False):
|
|
337
|
+
def update_list(self, reload: bool = False, restore_scroll: bool = False):
|
|
338
338
|
"""
|
|
339
339
|
Reload current ctx list
|
|
340
340
|
|
|
341
341
|
:param reload: reload ctx list items
|
|
342
|
+
:param restore_scroll: restore scroll position
|
|
342
343
|
"""
|
|
343
344
|
self.window.ui.contexts.ctx_list.update(
|
|
344
345
|
'ctx.list',
|
|
345
346
|
self.window.core.ctx.get_meta(reload),
|
|
346
347
|
expand=False,
|
|
347
348
|
)
|
|
349
|
+
if restore_scroll:
|
|
350
|
+
self.window.ui.nodes['ctx.list'].restore_scroll_position()
|
|
348
351
|
|
|
349
352
|
def refresh(self, restore_model: bool = True):
|
|
350
353
|
"""
|
|
@@ -520,7 +523,7 @@ class Ctx:
|
|
|
520
523
|
self.window.core.ctx.clear_current()
|
|
521
524
|
event = RenderEvent(RenderEvent.CLEAR_OUTPUT)
|
|
522
525
|
self.window.dispatch(event)
|
|
523
|
-
self.
|
|
526
|
+
self.update_and_restore()
|
|
524
527
|
|
|
525
528
|
self.window.controller.ui.tabs.update_title_current("...")
|
|
526
529
|
|
|
@@ -653,8 +656,7 @@ class Ctx:
|
|
|
653
656
|
if meta is not None:
|
|
654
657
|
meta.important = value
|
|
655
658
|
self.window.core.ctx.save(id)
|
|
656
|
-
self.
|
|
657
|
-
self.select_by_current()
|
|
659
|
+
self.update_and_restore()
|
|
658
660
|
|
|
659
661
|
def is_important(self, idx: int) -> bool:
|
|
660
662
|
"""
|
|
@@ -686,9 +688,15 @@ class Ctx:
|
|
|
686
688
|
self.window.core.ctx.save(id)
|
|
687
689
|
QTimer.singleShot(
|
|
688
690
|
10,
|
|
689
|
-
lambda: self.
|
|
691
|
+
lambda: self.update_and_restore()
|
|
690
692
|
)
|
|
691
693
|
|
|
694
|
+
def update_and_restore(self):
|
|
695
|
+
"""Update ctx and restore scroll position"""
|
|
696
|
+
self.window.ui.nodes['ctx.list'].store_scroll_position()
|
|
697
|
+
self.update()
|
|
698
|
+
self.window.ui.nodes['ctx.list'].restore_scroll_position()
|
|
699
|
+
|
|
692
700
|
def update_name(
|
|
693
701
|
self,
|
|
694
702
|
id: int,
|
|
@@ -713,7 +721,7 @@ class Ctx:
|
|
|
713
721
|
self.window.ui.dialog['rename'].close()
|
|
714
722
|
|
|
715
723
|
if refresh:
|
|
716
|
-
self.
|
|
724
|
+
self.update_and_restore()
|
|
717
725
|
else:
|
|
718
726
|
self.update(reload=True, all=False, no_scroll=True)
|
|
719
727
|
|
|
@@ -964,7 +972,7 @@ class Ctx:
|
|
|
964
972
|
if update:
|
|
965
973
|
QTimer.singleShot(
|
|
966
974
|
10,
|
|
967
|
-
lambda: self.
|
|
975
|
+
lambda: self.update_and_restore()
|
|
968
976
|
)
|
|
969
977
|
|
|
970
978
|
def remove_from_group(self, meta_id):
|
|
@@ -977,7 +985,7 @@ class Ctx:
|
|
|
977
985
|
self.group_id = None
|
|
978
986
|
QTimer.singleShot(
|
|
979
987
|
10,
|
|
980
|
-
lambda: self.
|
|
988
|
+
lambda: self.update_and_restore()
|
|
981
989
|
)
|
|
982
990
|
|
|
983
991
|
def new_group(
|
|
@@ -1063,13 +1071,7 @@ class Ctx:
|
|
|
1063
1071
|
self.window.core.ctx.update_group(group)
|
|
1064
1072
|
if close:
|
|
1065
1073
|
self.window.ui.dialog['rename'].close()
|
|
1066
|
-
self.
|
|
1067
|
-
reload=True,
|
|
1068
|
-
all=False,
|
|
1069
|
-
select=False,
|
|
1070
|
-
no_scroll=True
|
|
1071
|
-
)
|
|
1072
|
-
self.select_group(id)
|
|
1074
|
+
self.update_and_restore()
|
|
1073
1075
|
|
|
1074
1076
|
def get_group_name(self, id: int) -> str:
|
|
1075
1077
|
"""
|
|
@@ -1119,7 +1121,7 @@ class Ctx:
|
|
|
1119
1121
|
self.window.core.ctx.remove_group(group, all=False)
|
|
1120
1122
|
if self.group_id == id:
|
|
1121
1123
|
self.group_id = None
|
|
1122
|
-
self.
|
|
1124
|
+
self.update_and_restore()
|
|
1123
1125
|
|
|
1124
1126
|
def delete_group_all(
|
|
1125
1127
|
self,
|
|
@@ -1144,7 +1146,7 @@ class Ctx:
|
|
|
1144
1146
|
self.window.core.ctx.remove_group(group, all=True)
|
|
1145
1147
|
if self.group_id == id:
|
|
1146
1148
|
self.group_id = None
|
|
1147
|
-
self.
|
|
1149
|
+
self.update_and_restore()
|
|
1148
1150
|
|
|
1149
1151
|
def reload(self):
|
|
1150
1152
|
"""Reload ctx"""
|
|
@@ -31,7 +31,7 @@ from .reply import Reply
|
|
|
31
31
|
from .stack import Stack
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
class Kernel
|
|
34
|
+
class Kernel:
|
|
35
35
|
|
|
36
36
|
STATE_IDLE = "idle"
|
|
37
37
|
STATE_BUSY = "busy"
|
|
@@ -81,7 +81,6 @@ class Kernel(QObject):
|
|
|
81
81
|
|
|
82
82
|
:param window: The window context to which the kernel will be bound.
|
|
83
83
|
"""
|
|
84
|
-
super(Kernel, self).__init__(window)
|
|
85
84
|
self.window = window
|
|
86
85
|
self.replies = Reply(window)
|
|
87
86
|
self.stack = Stack(window)
|
pygpt_net/core/agents/runner.py
CHANGED
|
@@ -105,6 +105,25 @@ class Runner:
|
|
|
105
105
|
self.window.core.agents.tools.context = context
|
|
106
106
|
self.window.core.agents.tools.agent_idx = vector_store_idx
|
|
107
107
|
|
|
108
|
+
# --- ADDITIONAL CONTEXT ---
|
|
109
|
+
# append additional context from RAG if available
|
|
110
|
+
if vector_store_idx and self.window.core.config.get("agent.idx.auto_retrieve", True):
|
|
111
|
+
ad_context = self.window.core.idx.chat.query_retrieval(
|
|
112
|
+
query=prompt,
|
|
113
|
+
idx=vector_store_idx,
|
|
114
|
+
model=context.model,
|
|
115
|
+
)
|
|
116
|
+
if ad_context:
|
|
117
|
+
to_append = ""
|
|
118
|
+
if ctx.hidden_input is None:
|
|
119
|
+
ctx.hidden_input = ""
|
|
120
|
+
if not ctx.hidden_input: # may be not empty (appended before from attachments)
|
|
121
|
+
to_append = "ADDITIONAL CONTEXT:"
|
|
122
|
+
ctx.hidden_input += to_append
|
|
123
|
+
to_append += "\n" + ad_context
|
|
124
|
+
ctx.hidden_input += to_append
|
|
125
|
+
prompt += "\n\n" + to_append
|
|
126
|
+
|
|
108
127
|
tools = self.window.core.agents.tools.prepare(context, extra, force=True)
|
|
109
128
|
function_tools = self.window.core.agents.tools.get_function_tools(ctx, extra, force=True)
|
|
110
129
|
plugin_tools = self.window.core.agents.tools.get_plugin_tools(context, extra, force=True)
|
pygpt_net/core/agents/tools.py
CHANGED
|
@@ -25,6 +25,13 @@ from pygpt_net.item.ctx import CtxItem
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
class Tools:
|
|
28
|
+
|
|
29
|
+
QUERY_ENGINE_TOOL_NAME = "rag_get_context"
|
|
30
|
+
QUERY_ENGINE_TOOL_DESCRIPTION = "Get additional context for provided question. Use this whenever you need additional context to provide an answer. "
|
|
31
|
+
QUERY_ENGINE_TOOL_SPEC = ("**"+QUERY_ENGINE_TOOL_NAME+"**: "
|
|
32
|
+
+ QUERY_ENGINE_TOOL_DESCRIPTION +
|
|
33
|
+
"available params: {'query': {'type': 'string', 'description': 'query string'}}, required: [query]")
|
|
34
|
+
|
|
28
35
|
def __init__(self, window=None):
|
|
29
36
|
"""
|
|
30
37
|
Agent tools
|
|
@@ -62,6 +69,32 @@ class Tools:
|
|
|
62
69
|
plugin_functions = self.get_plugin_functions(context.ctx, verbose=verbose, force=force)
|
|
63
70
|
tools.extend(plugin_functions)
|
|
64
71
|
|
|
72
|
+
# add query engine tool if idx is provided
|
|
73
|
+
query_engine_tools = self.get_retriever_tool(
|
|
74
|
+
context=context,
|
|
75
|
+
extra=extra,
|
|
76
|
+
verbose=verbose,
|
|
77
|
+
)
|
|
78
|
+
if query_engine_tools:
|
|
79
|
+
tools.extend(query_engine_tools)
|
|
80
|
+
return tools
|
|
81
|
+
|
|
82
|
+
def get_retriever_tool(
|
|
83
|
+
self,
|
|
84
|
+
context: BridgeContext,
|
|
85
|
+
extra: Dict[str, Any],
|
|
86
|
+
verbose: bool = False
|
|
87
|
+
) -> List[BaseTool]:
|
|
88
|
+
"""
|
|
89
|
+
Prepare tools for agent
|
|
90
|
+
|
|
91
|
+
:param context: BridgeContext
|
|
92
|
+
:param extra: extra data
|
|
93
|
+
:param verbose: verbose mode
|
|
94
|
+
:return: list of tools
|
|
95
|
+
"""
|
|
96
|
+
tool = None
|
|
97
|
+
|
|
65
98
|
# add query engine tool if idx is provided
|
|
66
99
|
idx = extra.get("agent_idx", None)
|
|
67
100
|
if idx is not None and idx != "_":
|
|
@@ -69,19 +102,51 @@ class Tools:
|
|
|
69
102
|
index = self.window.core.idx.storage.get(idx, llm, embed_model) # get index
|
|
70
103
|
if index is not None:
|
|
71
104
|
query_engine = index.as_query_engine(similarity_top_k=3)
|
|
72
|
-
|
|
105
|
+
tool = [
|
|
73
106
|
QueryEngineTool(
|
|
74
107
|
query_engine=query_engine,
|
|
75
108
|
metadata=ToolMetadata(
|
|
76
|
-
name=
|
|
77
|
-
description=
|
|
78
|
-
"Provides additional context and access to the indexed documents."
|
|
79
|
-
),
|
|
109
|
+
name=self.QUERY_ENGINE_TOOL_NAME,
|
|
110
|
+
description=self.QUERY_ENGINE_TOOL_DESCRIPTION,
|
|
80
111
|
),
|
|
81
112
|
),
|
|
82
113
|
]
|
|
83
|
-
|
|
84
|
-
|
|
114
|
+
return tool
|
|
115
|
+
|
|
116
|
+
def get_openai_retriever_tool(
|
|
117
|
+
self,
|
|
118
|
+
idx: str,
|
|
119
|
+
verbose: bool = False
|
|
120
|
+
) -> OpenAIFunctionTool:
|
|
121
|
+
"""
|
|
122
|
+
Prepare OpenAI retriever tool for agent
|
|
123
|
+
|
|
124
|
+
:param idx: index name
|
|
125
|
+
:param verbose: verbose mode
|
|
126
|
+
:return: OpenAIFunctionTool instance
|
|
127
|
+
"""
|
|
128
|
+
async def run_function(run_ctx: RunContextWrapper[Any], args: str) -> str:
|
|
129
|
+
name = run_ctx.tool_name
|
|
130
|
+
print("[Plugin] Tool call: " + name + " with args: " + str(args))
|
|
131
|
+
cmd = {
|
|
132
|
+
"cmd": name,
|
|
133
|
+
"params": json.loads(args) # args should be a JSON string
|
|
134
|
+
}
|
|
135
|
+
return self.tool_exec(name, cmd["params"])
|
|
136
|
+
|
|
137
|
+
schema = {"type": "object", "properties": {
|
|
138
|
+
"query": {
|
|
139
|
+
"type": "string",
|
|
140
|
+
"description": "The query string to search in the index."
|
|
141
|
+
}
|
|
142
|
+
}, "additionalProperties": False}
|
|
143
|
+
description = self.QUERY_ENGINE_TOOL_DESCRIPTION + f" Index: {idx}"
|
|
144
|
+
return OpenAIFunctionTool(
|
|
145
|
+
name=self.QUERY_ENGINE_TOOL_NAME,
|
|
146
|
+
description=description,
|
|
147
|
+
params_json_schema=schema,
|
|
148
|
+
on_invoke_tool=run_function,
|
|
149
|
+
)
|
|
85
150
|
|
|
86
151
|
def get_plugin_functions(
|
|
87
152
|
self,
|
|
@@ -204,6 +269,11 @@ class Tools:
|
|
|
204
269
|
tools.append(tool)
|
|
205
270
|
except Exception as e:
|
|
206
271
|
print(e)
|
|
272
|
+
|
|
273
|
+
# append query engine tool if idx is provided
|
|
274
|
+
if self.agent_idx is not None and self.agent_idx != "_":
|
|
275
|
+
tools.append(self.get_openai_retriever_tool(self.agent_idx))
|
|
276
|
+
|
|
207
277
|
return tools
|
|
208
278
|
|
|
209
279
|
def get_plugin_tools(
|
|
@@ -230,7 +300,6 @@ class Tools:
|
|
|
230
300
|
continue # skip blacklisted commands
|
|
231
301
|
|
|
232
302
|
description = item['desc']
|
|
233
|
-
schema = json.loads(item['params']) # from JSON to dict
|
|
234
303
|
|
|
235
304
|
def make_func(name, description):
|
|
236
305
|
def func(**kwargs):
|
|
@@ -255,9 +324,17 @@ class Tools:
|
|
|
255
324
|
print(e)
|
|
256
325
|
|
|
257
326
|
# add query engine tool if idx is provided
|
|
258
|
-
if self.agent_idx is not None and self.agent_idx
|
|
259
|
-
|
|
260
|
-
|
|
327
|
+
if self.agent_idx is not None and self.agent_idx != "_":
|
|
328
|
+
extra = {
|
|
329
|
+
"agent_idx": self.agent_idx, # agent index for query engine tool
|
|
330
|
+
}
|
|
331
|
+
query_engine_tools = self.get_retriever_tool(
|
|
332
|
+
context=context,
|
|
333
|
+
extra=extra,
|
|
334
|
+
verbose=verbose,
|
|
335
|
+
)
|
|
336
|
+
if query_engine_tools:
|
|
337
|
+
tools["query_engine"] = query_engine_tools[0] # add query engine tool
|
|
261
338
|
return tools
|
|
262
339
|
|
|
263
340
|
|
|
@@ -281,9 +358,7 @@ class Tools:
|
|
|
281
358
|
|
|
282
359
|
# add query engine tool spec if idx is provided
|
|
283
360
|
if self.agent_idx is not None and self.agent_idx != "_":
|
|
284
|
-
specs.append(
|
|
285
|
-
"Provides additional context and access to the indexed documents, "
|
|
286
|
-
"available params: {'query': {'type': 'string', 'description': 'query string'}}, required: [query]")
|
|
361
|
+
specs.append(self.QUERY_ENGINE_TOOL_SPEC)
|
|
287
362
|
|
|
288
363
|
for func in functions:
|
|
289
364
|
try:
|
|
@@ -292,8 +367,9 @@ class Tools:
|
|
|
292
367
|
continue # skip blacklisted commands
|
|
293
368
|
description = func['desc']
|
|
294
369
|
schema = json.loads(func['params']) # from JSON to dict
|
|
295
|
-
|
|
296
|
-
|
|
370
|
+
specs.append(
|
|
371
|
+
f"**{name}**: {description}, available params: {schema.get('properties', {})}, required: {schema.get('required', [])}\n"
|
|
372
|
+
)
|
|
297
373
|
except Exception as e:
|
|
298
374
|
print(e)
|
|
299
375
|
return specs
|
|
@@ -308,7 +384,7 @@ class Tools:
|
|
|
308
384
|
"""
|
|
309
385
|
print("[Plugin] Tool call: " + cmd + " " + str(params))
|
|
310
386
|
# special case for query engine tool
|
|
311
|
-
if cmd ==
|
|
387
|
+
if cmd == self.QUERY_ENGINE_TOOL_NAME:
|
|
312
388
|
if "query" not in params:
|
|
313
389
|
return "Query parameter is required for query_engine tool."
|
|
314
390
|
if self.context is None:
|
|
@@ -340,41 +416,6 @@ class Tools:
|
|
|
340
416
|
)
|
|
341
417
|
return response
|
|
342
418
|
|
|
343
|
-
def get_retriever_tool(
|
|
344
|
-
self,
|
|
345
|
-
context: BridgeContext,
|
|
346
|
-
extra: Dict[str, Any],
|
|
347
|
-
verbose: bool = False
|
|
348
|
-
) -> List[BaseTool]:
|
|
349
|
-
"""
|
|
350
|
-
Prepare tools for agent
|
|
351
|
-
|
|
352
|
-
:param context: BridgeContext
|
|
353
|
-
:param extra: extra data
|
|
354
|
-
:param verbose: verbose mode
|
|
355
|
-
:return: list of tools
|
|
356
|
-
"""
|
|
357
|
-
tool = None
|
|
358
|
-
# add query engine tool if idx is provided
|
|
359
|
-
idx = extra.get("agent_idx", None)
|
|
360
|
-
if idx is not None and idx != "_":
|
|
361
|
-
llm, embed_model = self.window.core.idx.llm.get_service_context(model=context.model)
|
|
362
|
-
index = self.window.core.idx.storage.get(idx, llm, embed_model) # get index
|
|
363
|
-
if index is not None:
|
|
364
|
-
query_engine = index.as_query_engine(similarity_top_k=3)
|
|
365
|
-
tool = [
|
|
366
|
-
QueryEngineTool(
|
|
367
|
-
query_engine=query_engine,
|
|
368
|
-
metadata=ToolMetadata(
|
|
369
|
-
name="query_engine",
|
|
370
|
-
description=(
|
|
371
|
-
"Provides additional context and access to the indexed documents."
|
|
372
|
-
),
|
|
373
|
-
),
|
|
374
|
-
),
|
|
375
|
-
]
|
|
376
|
-
return tool
|
|
377
|
-
|
|
378
419
|
def export_sources(
|
|
379
420
|
self,
|
|
380
421
|
response: AgentChatResponse
|
|
@@ -985,9 +985,9 @@ class Body:
|
|
|
985
985
|
syntax_style = self.window.core.config.get("render.code_syntax") or "default"
|
|
986
986
|
|
|
987
987
|
theme_css = self.window.controller.theme.markdown.get_web_css().replace('%fonts%', fonts_path)
|
|
988
|
-
parts = [self._SPINNER, theme_css
|
|
989
|
-
|
|
990
|
-
|
|
988
|
+
parts = [self._SPINNER, theme_css,
|
|
989
|
+
"pre { color: #fff; }" if syntax_style in self._syntax_dark else "pre { color: #000; }",
|
|
990
|
+
self.highlight.get_style_defs()]
|
|
991
991
|
return "\n".join(parts)
|
|
992
992
|
|
|
993
993
|
def prepare_action_icons(self, ctx: CtxItem) -> str:
|
|
@@ -1014,32 +1014,19 @@ class Body:
|
|
|
1014
1014
|
if ctx.output:
|
|
1015
1015
|
cid = ctx.id
|
|
1016
1016
|
t = trans
|
|
1017
|
-
|
|
1018
1017
|
icons.append(
|
|
1019
|
-
f'<a href="extra-audio-read:{cid}" class="action-icon" data-id="{cid}" role="button">'
|
|
1020
|
-
f'<span class="cmd">{self.get_icon("volume", t("ctx.extra.audio"), ctx)}</span></a>'
|
|
1021
|
-
)
|
|
1018
|
+
f'<a href="extra-audio-read:{cid}" class="action-icon" data-id="{cid}" role="button"><span class="cmd">{self.get_icon("volume", t("ctx.extra.audio"), ctx)}</span></a>')
|
|
1022
1019
|
icons.append(
|
|
1023
|
-
f'<a href="extra-copy:{cid}" class="action-icon" data-id="{cid}" role="button">'
|
|
1024
|
-
f'<span class="cmd">{self.get_icon("copy", t("ctx.extra.copy"), ctx)}</span></a>'
|
|
1025
|
-
)
|
|
1020
|
+
f'<a href="extra-copy:{cid}" class="action-icon" data-id="{cid}" role="button"><span class="cmd">{self.get_icon("copy", t("ctx.extra.copy"), ctx)}</span></a>')
|
|
1026
1021
|
icons.append(
|
|
1027
|
-
f'<a href="extra-replay:{cid}" class="action-icon" data-id="{cid}" role="button">'
|
|
1028
|
-
f'<span class="cmd">{self.get_icon("reload", t("ctx.extra.reply"), ctx)}</span></a>'
|
|
1029
|
-
)
|
|
1022
|
+
f'<a href="extra-replay:{cid}" class="action-icon" data-id="{cid}" role="button"><span class="cmd">{self.get_icon("reload", t("ctx.extra.reply"), ctx)}</span></a>')
|
|
1030
1023
|
icons.append(
|
|
1031
|
-
f'<a href="extra-edit:{cid}" class="action-icon edit-icon" data-id="{cid}" role="button">'
|
|
1032
|
-
f'<span class="cmd">{self.get_icon("edit", t("ctx.extra.edit"), ctx)}</span></a>'
|
|
1033
|
-
)
|
|
1024
|
+
f'<a href="extra-edit:{cid}" class="action-icon edit-icon" data-id="{cid}" role="button"><span class="cmd">{self.get_icon("edit", t("ctx.extra.edit"), ctx)}</span></a>')
|
|
1034
1025
|
icons.append(
|
|
1035
|
-
f'<a href="extra-delete:{cid}" class="action-icon edit-icon" data-id="{cid}" role="button">'
|
|
1036
|
-
f'<span class="cmd">{self.get_icon("delete", t("ctx.extra.delete"), ctx)}</span></a>'
|
|
1037
|
-
)
|
|
1026
|
+
f'<a href="extra-delete:{cid}" class="action-icon edit-icon" data-id="{cid}" role="button"><span class="cmd">{self.get_icon("delete", t("ctx.extra.delete"), ctx)}</span></a>')
|
|
1038
1027
|
if not self.window.core.ctx.is_first_item(cid):
|
|
1039
1028
|
icons.append(
|
|
1040
|
-
f'<a href="extra-join:{cid}" class="action-icon edit-icon" data-id="{cid}" role="button">'
|
|
1041
|
-
f'<span class="cmd">{self.get_icon("playlist_add", t("ctx.extra.join"), ctx)}</span></a>'
|
|
1042
|
-
)
|
|
1029
|
+
f'<a href="extra-join:{cid}" class="action-icon edit-icon" data-id="{cid}" role="button"><span class="cmd">{self.get_icon("playlist_add", t("ctx.extra.join"), ctx)}</span></a>')
|
|
1043
1030
|
return icons
|
|
1044
1031
|
|
|
1045
1032
|
def get_icon(
|
|
@@ -1058,9 +1045,7 @@ class Body:
|
|
|
1058
1045
|
"""
|
|
1059
1046
|
app_path = self.window.core.config.get_app_path()
|
|
1060
1047
|
icon_path = os.path.join(app_path, "data", "icons", f"{icon}.svg")
|
|
1061
|
-
return
|
|
1062
|
-
f'<img src="file://{icon_path}" class="action-img" title="{title}" alt="{title}" data-id="{item.id}">'
|
|
1063
|
-
)
|
|
1048
|
+
return f'<img src="file://{icon_path}" class="action-img" title="{title}" alt="{title}" data-id="{item.id}">'
|
|
1064
1049
|
|
|
1065
1050
|
def get_image_html(
|
|
1066
1051
|
self,
|
|
@@ -1078,14 +1063,7 @@ class Body:
|
|
|
1078
1063
|
"""
|
|
1079
1064
|
url, path = self.window.core.filesystem.extract_local_url(url)
|
|
1080
1065
|
basename = os.path.basename(path)
|
|
1081
|
-
return
|
|
1082
|
-
f'<div class="extra-src-img-box" title="{url}">'
|
|
1083
|
-
f'<div class="img-outer"><div class="img-wrapper">'
|
|
1084
|
-
f'<a href="{url}"><img src="{path}" class="image"></a>'
|
|
1085
|
-
f'</div>'
|
|
1086
|
-
f'<a href="{url}" class="title">{basename}</a>'
|
|
1087
|
-
f'</div></div><br/>'
|
|
1088
|
-
)
|
|
1066
|
+
return f'<div class="extra-src-img-box" title="{url}"><div class="img-outer"><div class="img-wrapper"><a href="{url}"><img src="{path}" class="image"></a></div><a href="{url}" class="title">{basename}</a></div></div><br/>'
|
|
1089
1067
|
|
|
1090
1068
|
def get_url_html(
|
|
1091
1069
|
self,
|