pygpt-net 2.6.3__py3-none-any.whl → 2.6.6__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 +14 -0
- pygpt_net/__init__.py +2 -2
- pygpt_net/app.py +6 -1
- pygpt_net/config.py +55 -65
- pygpt_net/controller/__init__.py +5 -2
- pygpt_net/controller/chat/chat.py +38 -35
- pygpt_net/controller/chat/render.py +144 -217
- pygpt_net/controller/chat/stream.py +52 -25
- pygpt_net/controller/config/config.py +39 -42
- pygpt_net/controller/config/field/checkbox.py +16 -12
- pygpt_net/controller/config/field/checkbox_list.py +36 -31
- pygpt_net/controller/config/field/cmd.py +51 -57
- pygpt_net/controller/config/field/combo.py +33 -16
- pygpt_net/controller/config/field/dictionary.py +48 -55
- pygpt_net/controller/config/field/input.py +50 -32
- pygpt_net/controller/config/field/slider.py +40 -45
- pygpt_net/controller/config/field/textarea.py +20 -6
- pygpt_net/controller/config/placeholder.py +110 -231
- pygpt_net/controller/ctx/common.py +48 -49
- pygpt_net/controller/ctx/ctx.py +24 -4
- pygpt_net/controller/lang/mapping.py +57 -95
- pygpt_net/controller/lang/plugins.py +64 -55
- pygpt_net/controller/lang/settings.py +39 -38
- pygpt_net/controller/layout/layout.py +11 -2
- pygpt_net/controller/plugins/plugins.py +19 -1
- pygpt_net/controller/settings/profile.py +16 -4
- pygpt_net/controller/ui/mode.py +107 -125
- pygpt_net/core/bridge/bridge.py +5 -5
- pygpt_net/core/command/command.py +149 -219
- pygpt_net/core/ctx/ctx.py +94 -146
- pygpt_net/core/debug/debug.py +48 -58
- pygpt_net/core/models/models.py +74 -112
- pygpt_net/core/modes/modes.py +13 -21
- pygpt_net/core/plugins/plugins.py +154 -177
- pygpt_net/core/presets/presets.py +103 -176
- pygpt_net/core/render/web/body.py +50 -39
- pygpt_net/core/render/web/renderer.py +154 -251
- pygpt_net/core/text/utils.py +28 -44
- pygpt_net/core/tokens/tokens.py +104 -203
- pygpt_net/data/config/config.json +3 -3
- pygpt_net/data/config/models.json +3 -3
- pygpt_net/item/ctx.py +141 -139
- pygpt_net/plugin/agent/plugin.py +2 -1
- pygpt_net/plugin/audio_output/plugin.py +5 -2
- pygpt_net/plugin/base/plugin.py +77 -93
- pygpt_net/plugin/bitbucket/plugin.py +3 -2
- pygpt_net/plugin/cmd_code_interpreter/plugin.py +3 -2
- pygpt_net/plugin/cmd_custom/plugin.py +3 -2
- pygpt_net/plugin/cmd_files/plugin.py +3 -2
- pygpt_net/plugin/cmd_history/plugin.py +3 -2
- pygpt_net/plugin/cmd_mouse_control/plugin.py +5 -2
- pygpt_net/plugin/cmd_serial/plugin.py +3 -2
- pygpt_net/plugin/cmd_system/plugin.py +3 -6
- pygpt_net/plugin/cmd_web/plugin.py +3 -2
- pygpt_net/plugin/experts/plugin.py +2 -2
- pygpt_net/plugin/facebook/plugin.py +3 -4
- pygpt_net/plugin/github/plugin.py +4 -2
- pygpt_net/plugin/google/plugin.py +3 -3
- pygpt_net/plugin/idx_llama_index/plugin.py +3 -2
- pygpt_net/plugin/mailer/plugin.py +3 -5
- pygpt_net/plugin/openai_vision/plugin.py +3 -2
- pygpt_net/plugin/real_time/plugin.py +52 -60
- pygpt_net/plugin/slack/plugin.py +3 -4
- pygpt_net/plugin/telegram/plugin.py +3 -4
- pygpt_net/plugin/twitter/plugin.py +3 -4
- pygpt_net/tools/code_interpreter/tool.py +0 -1
- pygpt_net/tools/translator/tool.py +1 -1
- pygpt_net/ui/layout/ctx/ctx_list.py +10 -6
- pygpt_net/ui/main.py +46 -30
- pygpt_net/ui/tray.py +61 -60
- pygpt_net/ui/widget/lists/context.py +2 -2
- pygpt_net/ui/widget/textarea/web.py +161 -48
- pygpt_net/utils.py +8 -1
- {pygpt_net-2.6.3.dist-info → pygpt_net-2.6.6.dist-info}/METADATA +16 -2
- {pygpt_net-2.6.3.dist-info → pygpt_net-2.6.6.dist-info}/RECORD +78 -78
- {pygpt_net-2.6.3.dist-info → pygpt_net-2.6.6.dist-info}/LICENSE +0 -0
- {pygpt_net-2.6.3.dist-info → pygpt_net-2.6.6.dist-info}/WHEEL +0 -0
- {pygpt_net-2.6.3.dist-info → pygpt_net-2.6.6.dist-info}/entry_points.txt +0 -0
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
7
|
# MIT License #
|
|
8
8
|
# Created By : Marcin Szczygliński #
|
|
9
|
-
# Updated Date: 2025.
|
|
9
|
+
# Updated Date: 2025.08.15 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import copy
|
|
@@ -28,6 +28,8 @@ from pygpt_net.item.model import ModelItem
|
|
|
28
28
|
|
|
29
29
|
class Command:
|
|
30
30
|
DESC_LIMIT = 1024
|
|
31
|
+
_RE_CMD_PRESENCE = re.compile(r'<tool>\s*{.*}\s*</tool>', re.DOTALL)
|
|
32
|
+
_RE_TOOL_BLOCKS = re.compile(r'<tool>(.*?)</tool>', re.DOTALL)
|
|
31
33
|
|
|
32
34
|
def __init__(self, window=None):
|
|
33
35
|
"""
|
|
@@ -52,14 +54,15 @@ class Command:
|
|
|
52
54
|
:return: prompt with appended syntax
|
|
53
55
|
"""
|
|
54
56
|
prompt = data['prompt']
|
|
55
|
-
|
|
57
|
+
core = self.window.core
|
|
58
|
+
cmd_prompt = core.prompt.get('cmd')
|
|
56
59
|
extra = ""
|
|
57
60
|
schema = self.extract_syntax(data['cmd'])
|
|
58
61
|
if schema:
|
|
59
|
-
if
|
|
60
|
-
extra =
|
|
62
|
+
if core.config.get('mode') == MODE_ASSISTANT:
|
|
63
|
+
extra = core.prompt.get('cmd.extra.assistants')
|
|
61
64
|
else:
|
|
62
|
-
extra =
|
|
65
|
+
extra = core.prompt.get('cmd.extra')
|
|
63
66
|
if prompt.strip() != "":
|
|
64
67
|
prompt += "\n\n"
|
|
65
68
|
prompt += cmd_prompt.strip().replace("{extra}", extra).replace("{schema}", schema)
|
|
@@ -75,49 +78,39 @@ class Command:
|
|
|
75
78
|
:param cmds: commands list
|
|
76
79
|
:return: JSON string with commands usage syntax
|
|
77
80
|
"""
|
|
78
|
-
data = {}
|
|
79
|
-
|
|
80
|
-
self.window.core.ctx.current_cmd = copy.deepcopy(cmds) # for debug purposes
|
|
81
|
+
data: Dict[str, Any] = {}
|
|
82
|
+
self.window.core.ctx.current_cmd = copy.deepcopy(cmds)
|
|
81
83
|
|
|
82
84
|
for cmd in cmds:
|
|
83
85
|
if "cmd" in cmd and "instruction" in cmd:
|
|
84
86
|
cmd_name = cmd["cmd"]
|
|
85
|
-
|
|
86
|
-
"help": cmd["instruction"],
|
|
87
|
-
}
|
|
87
|
+
data_cmd = {"help": cmd["instruction"]}
|
|
88
88
|
if "params" in cmd and len(cmd["params"]) > 0:
|
|
89
|
-
|
|
89
|
+
params_out: Dict[str, Any] = {}
|
|
90
90
|
for param in cmd["params"]:
|
|
91
91
|
try:
|
|
92
|
-
if isinstance(param, dict):
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
and data[cmd_name]["params"][key]["type"] == "str"):
|
|
108
|
-
del data[cmd_name]["params"][key]["type"]
|
|
109
|
-
|
|
110
|
-
# remove description and move to help
|
|
111
|
-
if "description" in data[cmd_name]["params"][key]:
|
|
112
|
-
data[cmd_name]["params"][key]["help"] = data[cmd_name]["params"][key][
|
|
113
|
-
"description"]
|
|
114
|
-
del data[cmd_name]["params"][key]["description"]
|
|
115
|
-
|
|
116
|
-
except Exception as e:
|
|
92
|
+
if isinstance(param, dict) and "name" in param:
|
|
93
|
+
key = param["name"]
|
|
94
|
+
p = dict(param)
|
|
95
|
+
p.pop("name", None)
|
|
96
|
+
if "required" in p:
|
|
97
|
+
if p["required"] is False:
|
|
98
|
+
p["optional"] = True
|
|
99
|
+
p.pop("required", None)
|
|
100
|
+
if p.get("type") == "str":
|
|
101
|
+
p.pop("type", None)
|
|
102
|
+
if "description" in p:
|
|
103
|
+
p["help"] = p["description"]
|
|
104
|
+
p.pop("description", None)
|
|
105
|
+
params_out[key] = p
|
|
106
|
+
except Exception:
|
|
117
107
|
pass
|
|
108
|
+
if params_out:
|
|
109
|
+
data_cmd["params"] = params_out
|
|
110
|
+
data[cmd_name] = data_cmd
|
|
118
111
|
|
|
119
|
-
self.window.core.ctx.current_cmd_schema = data
|
|
120
|
-
return json.dumps(data)
|
|
112
|
+
self.window.core.ctx.current_cmd_schema = data
|
|
113
|
+
return json.dumps(data)
|
|
121
114
|
|
|
122
115
|
def has_cmds(self, text: str) -> bool:
|
|
123
116
|
"""
|
|
@@ -128,8 +121,7 @@ class Command:
|
|
|
128
121
|
"""
|
|
129
122
|
if text is None:
|
|
130
123
|
return False
|
|
131
|
-
|
|
132
|
-
return bool(re.search(regex_cmd, text))
|
|
124
|
+
return bool(self._RE_CMD_PRESENCE.search(text))
|
|
133
125
|
|
|
134
126
|
def extract_cmds(self, text: str) -> List[Dict[str, Any]]:
|
|
135
127
|
"""
|
|
@@ -138,15 +130,14 @@ class Command:
|
|
|
138
130
|
:param text: text to extract commands from
|
|
139
131
|
:return: list of commands (dict)
|
|
140
132
|
"""
|
|
141
|
-
cmds = []
|
|
133
|
+
cmds: List[Dict[str, Any]] = []
|
|
142
134
|
try:
|
|
143
|
-
chunks =
|
|
135
|
+
chunks = self._RE_TOOL_BLOCKS.findall(text)
|
|
144
136
|
for chunk in chunks:
|
|
145
|
-
cmd = self.extract_cmd(chunk)
|
|
137
|
+
cmd = self.extract_cmd(chunk)
|
|
146
138
|
if cmd is not None:
|
|
147
|
-
cmds.append(cmd)
|
|
148
|
-
except Exception
|
|
149
|
-
# do nothing
|
|
139
|
+
cmds.append(cmd)
|
|
140
|
+
except Exception:
|
|
150
141
|
pass
|
|
151
142
|
return cmds
|
|
152
143
|
|
|
@@ -161,11 +152,7 @@ class Command:
|
|
|
161
152
|
chunk = chunk.strip()
|
|
162
153
|
if chunk and chunk.startswith('{') and chunk.endswith('}'):
|
|
163
154
|
try:
|
|
164
|
-
# syntax1: {"read_file": {"path": ["my_cars.txt"]}}
|
|
165
|
-
# syntax2: {"cmd": "read_file", "params": {"path": ["my_cars.txt"]}}
|
|
166
155
|
cmd = json.loads(chunk)
|
|
167
|
-
|
|
168
|
-
# if the first key is not "cmd", then try to convert from incorrect syntax into "cmd" syntax:
|
|
169
156
|
if "cmd" not in cmd:
|
|
170
157
|
if len(cmd) == 1:
|
|
171
158
|
for key in cmd:
|
|
@@ -179,8 +166,7 @@ class Command:
|
|
|
179
166
|
"cmd": key,
|
|
180
167
|
"params": cmd[key]
|
|
181
168
|
}
|
|
182
|
-
except json.JSONDecodeError
|
|
183
|
-
# do nothing
|
|
169
|
+
except json.JSONDecodeError:
|
|
184
170
|
pass
|
|
185
171
|
return cmd
|
|
186
172
|
|
|
@@ -194,11 +180,7 @@ class Command:
|
|
|
194
180
|
:param cmds: commands list
|
|
195
181
|
:return parsed commands
|
|
196
182
|
"""
|
|
197
|
-
|
|
198
|
-
for cmd in cmds:
|
|
199
|
-
if 'cmd' in cmd:
|
|
200
|
-
commands.append(cmd)
|
|
201
|
-
return commands
|
|
183
|
+
return [cmd for cmd in cmds if 'cmd' in cmd]
|
|
202
184
|
|
|
203
185
|
def unpack_tool_calls(
|
|
204
186
|
self,
|
|
@@ -290,11 +272,9 @@ class Command:
|
|
|
290
272
|
ctx.tool_calls = tmp_calls
|
|
291
273
|
|
|
292
274
|
if append_output:
|
|
293
|
-
# append tool calls to context output
|
|
294
275
|
ctx.extra["tool_calls"] = ctx.tool_calls
|
|
295
276
|
ctx.extra["tool_output"] = []
|
|
296
277
|
|
|
297
|
-
|
|
298
278
|
def unpack_tool_calls_from_llama(
|
|
299
279
|
self,
|
|
300
280
|
tool_calls: List
|
|
@@ -348,10 +328,7 @@ class Command:
|
|
|
348
328
|
:param tool_calls: tool calls
|
|
349
329
|
:return: commands
|
|
350
330
|
"""
|
|
351
|
-
|
|
352
|
-
for tool_call in tool_calls:
|
|
353
|
-
cmds.append(self.tool_call_to_cmd(tool_call))
|
|
354
|
-
return cmds
|
|
331
|
+
return [self.tool_call_to_cmd(tool_call) for tool_call in tool_calls]
|
|
355
332
|
|
|
356
333
|
def pack_cmds(
|
|
357
334
|
self,
|
|
@@ -363,10 +340,10 @@ class Command:
|
|
|
363
340
|
:param cmds: commands
|
|
364
341
|
:return: packed commands string
|
|
365
342
|
"""
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
343
|
+
return "".join(
|
|
344
|
+
"<tool>" + json.dumps(cmd, separators=(',', ':')) + "</tool>"
|
|
345
|
+
for cmd in cmds
|
|
346
|
+
)
|
|
370
347
|
|
|
371
348
|
def append_tool_calls(self, ctx: CtxItem):
|
|
372
349
|
"""
|
|
@@ -374,8 +351,7 @@ class Command:
|
|
|
374
351
|
|
|
375
352
|
:param ctx: context item
|
|
376
353
|
"""
|
|
377
|
-
|
|
378
|
-
cmds_str = self.pack_cmds(cmds)
|
|
354
|
+
cmds_str = self.pack_cmds(self.tool_calls_to_cmds(ctx.tool_calls))
|
|
379
355
|
if ctx.output is None:
|
|
380
356
|
ctx.output = ""
|
|
381
357
|
ctx.output += cmds_str
|
|
@@ -387,32 +363,22 @@ class Command:
|
|
|
387
363
|
:param ctx: context item
|
|
388
364
|
:return: list of tool calls outputs
|
|
389
365
|
"""
|
|
390
|
-
|
|
391
|
-
idx_outputs = {}
|
|
392
|
-
for tool_call in ctx.tool_calls:
|
|
393
|
-
call_id = tool_call["id"]
|
|
394
|
-
idx_outputs[call_id] = ""
|
|
366
|
+
idx_outputs = {tool_call["id"]: "" for tool_call in ctx.tool_calls}
|
|
395
367
|
try:
|
|
396
|
-
responses = json.loads(ctx.input)
|
|
368
|
+
responses = json.loads(ctx.input)
|
|
369
|
+
last_by_name: Dict[str, Any] = {}
|
|
370
|
+
for response in responses:
|
|
371
|
+
req = response.get("request")
|
|
372
|
+
if isinstance(req, dict) and "cmd" in req:
|
|
373
|
+
last_by_name[req["cmd"]] = response.get("result")
|
|
397
374
|
for tool_call in ctx.tool_calls:
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
if "cmd" in response["request"]:
|
|
402
|
-
func_name = response["request"]["cmd"]
|
|
403
|
-
if tool_call["function"]["name"] == func_name:
|
|
404
|
-
idx_outputs[call_id] = response["result"]
|
|
405
|
-
|
|
375
|
+
name = tool_call["function"]["name"]
|
|
376
|
+
if name in last_by_name:
|
|
377
|
+
idx_outputs[tool_call["id"]] = last_by_name[name]
|
|
406
378
|
except Exception as e:
|
|
407
379
|
self.window.core.debug.log(e)
|
|
408
380
|
|
|
409
|
-
for
|
|
410
|
-
data = {
|
|
411
|
-
"tool_call_id": id,
|
|
412
|
-
"output": idx_outputs[id],
|
|
413
|
-
}
|
|
414
|
-
outputs.append(data)
|
|
415
|
-
|
|
381
|
+
outputs = [{"tool_call_id": id_, "output": out} for id_, out in idx_outputs.items()]
|
|
416
382
|
if not isinstance(ctx.extra, dict):
|
|
417
383
|
ctx.extra = {}
|
|
418
384
|
ctx.extra["tool_calls_outputs"] = outputs
|
|
@@ -436,7 +402,7 @@ class Command:
|
|
|
436
402
|
func = self.as_native_functions(all=False, parent_id=parent_id)
|
|
437
403
|
if func_user is None:
|
|
438
404
|
func_user = []
|
|
439
|
-
return func + func_user
|
|
405
|
+
return func + func_user
|
|
440
406
|
|
|
441
407
|
def as_native_functions(
|
|
442
408
|
self,
|
|
@@ -488,14 +454,14 @@ class Command:
|
|
|
488
454
|
event = Event(Event.CMD_SYNTAX_INLINE, data)
|
|
489
455
|
self.window.dispatch(event)
|
|
490
456
|
|
|
491
|
-
cmds = copy.deepcopy(data['cmd'])
|
|
492
|
-
func_plugins = self.cmds_to_functions(cmds)
|
|
457
|
+
cmds = copy.deepcopy(data['cmd'])
|
|
458
|
+
func_plugins = self.cmds_to_functions(cmds)
|
|
493
459
|
if self.window.controller.agent.legacy.enabled():
|
|
494
|
-
func_agent = self.cmds_to_functions(self.window.controller.agent.legacy.get_functions())
|
|
460
|
+
func_agent = self.cmds_to_functions(self.window.controller.agent.legacy.get_functions())
|
|
495
461
|
if (self.window.controller.agent.experts.enabled()
|
|
496
462
|
or self.window.controller.agent.legacy.enabled(check_inline=False)):
|
|
497
|
-
if parent_id is None:
|
|
498
|
-
func_experts = self.cmds_to_functions(self.window.core.experts.get_functions())
|
|
463
|
+
if parent_id is None:
|
|
464
|
+
func_experts = self.cmds_to_functions(self.window.core.experts.get_functions())
|
|
499
465
|
return func_plugins + func_agent + func_experts
|
|
500
466
|
|
|
501
467
|
def cmds_to_functions(
|
|
@@ -509,17 +475,18 @@ class Command:
|
|
|
509
475
|
:return: functions list
|
|
510
476
|
"""
|
|
511
477
|
functions = []
|
|
478
|
+
limit = self.DESC_LIMIT
|
|
512
479
|
for cmd in cmds:
|
|
513
480
|
if "cmd" in cmd and "instruction" in cmd:
|
|
514
481
|
cmd_name = cmd["cmd"]
|
|
515
482
|
desc = cmd["instruction"]
|
|
516
|
-
if len(desc) >
|
|
517
|
-
desc = desc[:
|
|
483
|
+
if len(desc) > limit:
|
|
484
|
+
desc = desc[:limit]
|
|
518
485
|
functions.append(
|
|
519
486
|
{
|
|
520
487
|
"name": cmd_name,
|
|
521
488
|
"desc": desc,
|
|
522
|
-
"params": json.dumps(self.extract_params(cmd),
|
|
489
|
+
"params": json.dumps(self.extract_params(cmd), separators=(',', ':')),
|
|
523
490
|
}
|
|
524
491
|
)
|
|
525
492
|
return functions
|
|
@@ -541,84 +508,67 @@ class Command:
|
|
|
541
508
|
"required": [],
|
|
542
509
|
"additionalProperties": False,
|
|
543
510
|
}
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
if
|
|
511
|
+
params_list = cmd.get("params") or []
|
|
512
|
+
if params_list:
|
|
513
|
+
for param in params_list:
|
|
514
|
+
if isinstance(param, dict) and param.get("required"):
|
|
548
515
|
required.append(param["name"])
|
|
549
516
|
|
|
550
|
-
if
|
|
517
|
+
if required:
|
|
551
518
|
params["required"] = required
|
|
552
519
|
|
|
553
|
-
|
|
554
|
-
|
|
520
|
+
type_map = {
|
|
521
|
+
"str": "string",
|
|
522
|
+
"enum": "string",
|
|
523
|
+
"text": "string",
|
|
524
|
+
"int": "integer",
|
|
525
|
+
"bool": "boolean",
|
|
526
|
+
"dict": "object",
|
|
527
|
+
"list": "array",
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
limit = self.DESC_LIMIT
|
|
531
|
+
for param in params_list:
|
|
555
532
|
try:
|
|
556
|
-
if isinstance(param, dict):
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
if values:
|
|
597
|
-
params["properties"][key]["enum"] = values
|
|
598
|
-
|
|
599
|
-
# remove defaults and append to description
|
|
600
|
-
if "default" in param:
|
|
601
|
-
params["properties"][key]["description"] += ", default: " + str(
|
|
602
|
-
param["default"]) + ")"
|
|
603
|
-
|
|
604
|
-
# convert internal types to supported by JSON schema
|
|
605
|
-
if params["properties"][key]["type"] == "str":
|
|
606
|
-
params["properties"][key]["type"] = "string"
|
|
607
|
-
elif params["properties"][key]["type"] == "enum":
|
|
608
|
-
params["properties"][key]["type"] = "string"
|
|
609
|
-
elif params["properties"][key]["type"] == "text":
|
|
610
|
-
params["properties"][key]["type"] = "string"
|
|
611
|
-
elif params["properties"][key]["type"] == "int":
|
|
612
|
-
params["properties"][key]["type"] = "integer"
|
|
613
|
-
elif params["properties"][key]["type"] == "bool":
|
|
614
|
-
params["properties"][key]["type"] = "boolean"
|
|
615
|
-
elif params["properties"][key]["type"] == "dict":
|
|
616
|
-
params["properties"][key]["type"] = "object"
|
|
617
|
-
elif params["properties"][key]["type"] == "list":
|
|
618
|
-
params["properties"][key]["type"] = "array"
|
|
619
|
-
params["properties"][key]["items"] = {
|
|
620
|
-
"type": "string"
|
|
621
|
-
}
|
|
533
|
+
if isinstance(param, dict) and "name" in param:
|
|
534
|
+
key = param["name"]
|
|
535
|
+
prop: Dict[str, Any] = {}
|
|
536
|
+
prop["type"] = param.get("type", "string")
|
|
537
|
+
prop["description"] = ""
|
|
538
|
+
if "type" in param and param["type"] in type_map:
|
|
539
|
+
prop["type"] = type_map[param["type"]]
|
|
540
|
+
if "description" in param:
|
|
541
|
+
desc = param["description"]
|
|
542
|
+
if len(desc) > limit:
|
|
543
|
+
desc = desc[:limit]
|
|
544
|
+
prop["description"] = desc
|
|
545
|
+
if "enum" in param:
|
|
546
|
+
prop["description"] += ", enum: " + json.dumps(param["enum"]) + ")"
|
|
547
|
+
values = []
|
|
548
|
+
enum_block = param["enum"].get(key) if isinstance(param["enum"], dict) else None
|
|
549
|
+
if isinstance(enum_block, dict):
|
|
550
|
+
values = list(enum_block.keys())
|
|
551
|
+
sub_values = []
|
|
552
|
+
for k in enum_block:
|
|
553
|
+
if isinstance(enum_block[k], dict):
|
|
554
|
+
for v in list(enum_block[k].keys()):
|
|
555
|
+
if v not in sub_values:
|
|
556
|
+
sub_values.append(v)
|
|
557
|
+
elif isinstance(enum_block[k], list):
|
|
558
|
+
for v in enum_block[k]:
|
|
559
|
+
if v not in sub_values:
|
|
560
|
+
sub_values.append(v)
|
|
561
|
+
if sub_values:
|
|
562
|
+
values = sub_values
|
|
563
|
+
elif isinstance(enum_block, list):
|
|
564
|
+
values = enum_block
|
|
565
|
+
if values:
|
|
566
|
+
prop["enum"] = values
|
|
567
|
+
if "default" in param:
|
|
568
|
+
prop["description"] += ", default: " + str(param["default"]) + ")"
|
|
569
|
+
if prop["type"] == "array":
|
|
570
|
+
prop["items"] = {"type": "string"}
|
|
571
|
+
params["properties"][key] = prop
|
|
622
572
|
except Exception as e:
|
|
623
573
|
print(e)
|
|
624
574
|
pass
|
|
@@ -638,12 +588,10 @@ class Command:
|
|
|
638
588
|
]
|
|
639
589
|
mode = self.window.core.config.get('mode')
|
|
640
590
|
|
|
641
|
-
# force disabled for specific modes
|
|
642
591
|
if mode in disabled_modes:
|
|
643
592
|
return False
|
|
644
593
|
|
|
645
594
|
if not force:
|
|
646
|
-
# check model
|
|
647
595
|
model = self.window.core.config.get('model')
|
|
648
596
|
if model:
|
|
649
597
|
model_data = self.window.core.models.get(model)
|
|
@@ -651,13 +599,11 @@ class Command:
|
|
|
651
599
|
if not self.window.core.models.is_tool_call_allowed(mode, model_data):
|
|
652
600
|
return False
|
|
653
601
|
|
|
654
|
-
# agents and experts
|
|
655
602
|
if self.window.controller.agent.legacy.enabled():
|
|
656
603
|
return self.window.core.config.get('agent.func_call.native', False)
|
|
657
604
|
if self.window.controller.agent.experts.enabled():
|
|
658
605
|
return self.window.core.config.get('experts.func_call.native', False)
|
|
659
606
|
|
|
660
|
-
# otherwise check config
|
|
661
607
|
return self.window.core.config.get('func_call.native', False)
|
|
662
608
|
|
|
663
609
|
def is_cmd(self, inline: bool = True) -> bool:
|
|
@@ -667,15 +613,10 @@ class Command:
|
|
|
667
613
|
:param inline: check if inline plugin is enabled
|
|
668
614
|
:return: True if command is enabled
|
|
669
615
|
"""
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
# check if cmd inline plugin is enabled
|
|
675
|
-
if inline and self.window.controller.plugins.is_type_enabled("cmd.inline"):
|
|
676
|
-
return True
|
|
677
|
-
|
|
678
|
-
return False
|
|
616
|
+
return bool(
|
|
617
|
+
self.window.core.config.get('cmd')
|
|
618
|
+
or (inline and self.window.controller.plugins.is_type_enabled("cmd.inline"))
|
|
619
|
+
)
|
|
679
620
|
|
|
680
621
|
def is_enabled(self, cmd: str) -> bool:
|
|
681
622
|
"""
|
|
@@ -684,38 +625,27 @@ class Command:
|
|
|
684
625
|
:param cmd: command
|
|
685
626
|
:return: True if command is enabled
|
|
686
627
|
"""
|
|
687
|
-
enabled_cmds =
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
}
|
|
709
|
-
event = Event(Event.CMD_SYNTAX_INLINE, data)
|
|
710
|
-
self.window.dispatch(event)
|
|
711
|
-
if (event.data and "cmd" in event.data
|
|
712
|
-
and isinstance(event.data["cmd"], list)):
|
|
713
|
-
for item in event.data["cmd"]:
|
|
714
|
-
if "cmd" in item:
|
|
715
|
-
enabled_cmds.append(item["cmd"])
|
|
716
|
-
if cmd in enabled_cmds:
|
|
717
|
-
return True
|
|
718
|
-
return False
|
|
628
|
+
enabled_cmds = set()
|
|
629
|
+
|
|
630
|
+
def collect(event_type):
|
|
631
|
+
data = {
|
|
632
|
+
'prompt': "",
|
|
633
|
+
'silent': True,
|
|
634
|
+
'force': True,
|
|
635
|
+
'syntax': [],
|
|
636
|
+
'cmd': [],
|
|
637
|
+
}
|
|
638
|
+
event = Event(event_type, data)
|
|
639
|
+
self.window.dispatch(event)
|
|
640
|
+
if event.data and "cmd" in event.data and isinstance(event.data["cmd"], list):
|
|
641
|
+
for item in event.data["cmd"]:
|
|
642
|
+
if "cmd" in item:
|
|
643
|
+
enabled_cmds.add(item["cmd"])
|
|
644
|
+
|
|
645
|
+
collect(Event.CMD_SYNTAX)
|
|
646
|
+
collect(Event.CMD_SYNTAX_INLINE)
|
|
647
|
+
|
|
648
|
+
return cmd in enabled_cmds
|
|
719
649
|
|
|
720
650
|
def is_model_supports_tools(
|
|
721
651
|
self,
|
|
@@ -743,4 +673,4 @@ class Command:
|
|
|
743
673
|
if (model.get_provider() == "ollama"
|
|
744
674
|
and model.id.startswith(disabled_model)):
|
|
745
675
|
return False
|
|
746
|
-
return True
|
|
676
|
+
return True
|