janito 3.2.0__py3-none-any.whl → 3.3.0__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.
- janito/README.md +0 -3
- janito/cli/chat_mode/bindings.py +0 -26
- janito/cli/chat_mode/session.py +1 -12
- janito/cli/chat_mode/shell/commands/security/allowed_sites.py +33 -47
- janito/cli/cli_commands/list_plugins.py +8 -13
- janito/cli/core/model_guesser.py +24 -40
- janito/cli/prompt_core.py +9 -20
- janito/i18n/it.py +46 -46
- janito/llm/agent.py +16 -32
- janito/llm/driver.py +0 -8
- janito/{plugin_system → plugin_system_backup_20250825_070018}/core_loader.py +3 -76
- janito/{plugin_system → plugin_system_backup_20250825_070018}/core_loader_fixed.py +3 -79
- janito/plugins/__init__.py +21 -29
- janito/plugins/__main__.py +85 -0
- janito/plugins/base.py +57 -0
- janito/plugins/builtin.py +1 -1
- janito/plugins/core/filemanager/tools/copy_file.py +25 -1
- janito/plugins/core/filemanager/tools/create_directory.py +28 -1
- janito/plugins/core/filemanager/tools/create_file.py +27 -3
- janito/plugins/core/filemanager/tools/delete_text_in_file.py +1 -0
- janito/plugins/core/imagedisplay/plugin.py +1 -1
- janito/plugins/core_loader.py +144 -0
- janito/plugins/discovery.py +3 -3
- janito/plugins/example_plugin.py +1 -1
- janito/plugins/manager.py +1 -1
- janito/plugins_backup_20250825_070018/__init__.py +36 -0
- janito/{plugins → plugins_backup_20250825_070018}/auto_loader.py +11 -12
- janito/plugins_backup_20250825_070018/builtin.py +102 -0
- janito/plugins_backup_20250825_070018/config.py +84 -0
- janito/plugins_backup_20250825_070018/core/__init__.py +7 -0
- janito/plugins_backup_20250825_070018/core/codeanalyzer/__init__.py +43 -0
- janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/get_file_outline/__init__.py +1 -0
- janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/get_file_outline/core.py +122 -0
- janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/search_text/__init__.py +1 -0
- janito/plugins_backup_20250825_070018/core/codeanalyzer/tools/search_text/core.py +205 -0
- janito/plugins_backup_20250825_070018/core/filemanager/__init__.py +124 -0
- janito/plugins_backup_20250825_070018/core/filemanager/tools/copy_file.py +87 -0
- janito/plugins_backup_20250825_070018/core/filemanager/tools/create_directory.py +70 -0
- janito/plugins_backup_20250825_070018/core/filemanager/tools/create_file.py +87 -0
- janito/plugins_backup_20250825_070018/core/filemanager/tools/delete_text_in_file.py +135 -0
- janito/plugins_backup_20250825_070018/core/filemanager/tools/find_files.py +143 -0
- janito/plugins_backup_20250825_070018/core/filemanager/tools/move_file.py +131 -0
- janito/plugins_backup_20250825_070018/core/filemanager/tools/read_files.py +58 -0
- janito/plugins_backup_20250825_070018/core/filemanager/tools/remove_directory.py +55 -0
- janito/plugins_backup_20250825_070018/core/filemanager/tools/remove_file.py +58 -0
- janito/plugins_backup_20250825_070018/core/filemanager/tools/replace_text_in_file.py +270 -0
- janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/__init__.py +1 -0
- janito/plugins_backup_20250825_070018/core/filemanager/tools/validate_file_syntax/core.py +114 -0
- janito/plugins_backup_20250825_070018/core/filemanager/tools/view_file.py +172 -0
- janito/plugins_backup_20250825_070018/core/imagedisplay/__init__.py +14 -0
- janito/plugins_backup_20250825_070018/core/imagedisplay/plugin.py +51 -0
- janito/plugins_backup_20250825_070018/core/imagedisplay/tools/__init__.py +1 -0
- janito/plugins_backup_20250825_070018/core/imagedisplay/tools/show_image.py +83 -0
- janito/plugins_backup_20250825_070018/core/imagedisplay/tools/show_image_grid.py +84 -0
- janito/plugins_backup_20250825_070018/core/system/__init__.py +23 -0
- janito/plugins_backup_20250825_070018/core/system/tools/run_bash_command.py +183 -0
- janito/plugins_backup_20250825_070018/core/system/tools/run_powershell_command.py +218 -0
- janito/plugins_backup_20250825_070018/core_adapter.py +55 -0
- janito/plugins_backup_20250825_070018/dev/__init__.py +7 -0
- janito/plugins_backup_20250825_070018/dev/pythondev/__init__.py +37 -0
- janito/plugins_backup_20250825_070018/dev/pythondev/tools/python_code_run.py +172 -0
- janito/plugins_backup_20250825_070018/dev/pythondev/tools/python_command_run.py +171 -0
- janito/plugins_backup_20250825_070018/dev/pythondev/tools/python_file_run.py +172 -0
- janito/plugins_backup_20250825_070018/dev/visualization/__init__.py +23 -0
- janito/plugins_backup_20250825_070018/dev/visualization/tools/read_chart.py +259 -0
- janito/plugins_backup_20250825_070018/discovery.py +289 -0
- janito/{plugins → plugins_backup_20250825_070018}/discovery_core.py +9 -14
- janito/plugins_backup_20250825_070018/example_plugin.py +108 -0
- janito/plugins_backup_20250825_070018/manager.py +243 -0
- janito/{plugins → plugins_backup_20250825_070018}/tools/core_tools_plugin.py +10 -9
- janito/{plugins → plugins_backup_20250825_070018}/tools/create_file.py +2 -2
- janito/{plugins → plugins_backup_20250825_070018}/tools/delete_text_in_file.py +1 -0
- janito/plugins_backup_20250825_070018/tools/get_file_outline/java_outline.py +47 -0
- janito/plugins_backup_20250825_070018/tools/get_file_outline/markdown_outline.py +14 -0
- janito/plugins_backup_20250825_070018/tools/get_file_outline/python_outline.py +303 -0
- janito/plugins_backup_20250825_070018/tools/get_file_outline/search_outline.py +36 -0
- janito/plugins_backup_20250825_070018/tools/search_text/match_lines.py +67 -0
- janito/plugins_backup_20250825_070018/tools/search_text/pattern_utils.py +73 -0
- janito/plugins_backup_20250825_070018/tools/search_text/traverse_directory.py +145 -0
- janito/plugins_backup_20250825_070018/tools/validate_file_syntax/css_validator.py +35 -0
- janito/plugins_backup_20250825_070018/tools/validate_file_syntax/html_validator.py +100 -0
- janito/plugins_backup_20250825_070018/tools/validate_file_syntax/jinja2_validator.py +50 -0
- janito/plugins_backup_20250825_070018/tools/validate_file_syntax/js_validator.py +27 -0
- janito/plugins_backup_20250825_070018/tools/validate_file_syntax/json_validator.py +6 -0
- janito/plugins_backup_20250825_070018/tools/validate_file_syntax/markdown_validator.py +109 -0
- janito/plugins_backup_20250825_070018/tools/validate_file_syntax/ps1_validator.py +32 -0
- janito/plugins_backup_20250825_070018/tools/validate_file_syntax/python_validator.py +5 -0
- janito/plugins_backup_20250825_070018/tools/validate_file_syntax/xml_validator.py +11 -0
- janito/plugins_backup_20250825_070018/tools/validate_file_syntax/yaml_validator.py +6 -0
- janito/plugins_backup_20250825_070018/ui/__init__.py +7 -0
- janito/plugins_backup_20250825_070018/ui/userinterface/__init__.py +16 -0
- janito/plugins_backup_20250825_070018/ui/userinterface/tools/ask_user.py +110 -0
- janito/plugins_backup_20250825_070018/web/__init__.py +7 -0
- janito/plugins_backup_20250825_070018/web/webtools/__init__.py +33 -0
- janito/plugins_backup_20250825_070018/web/webtools/tools/fetch_url.py +458 -0
- janito/plugins_backup_20250825_070018/web/webtools/tools/open_html_in_browser.py +51 -0
- janito/plugins_backup_20250825_070018/web/webtools/tools/open_url.py +37 -0
- janito/providers/__init__.py +0 -1
- janito/tools/base.py +31 -1
- janito/tools/cli_initializer.py +1 -1
- janito/tools/function_adapter.py +176 -0
- janito/tools/initialize.py +1 -1
- janito/tools/loop_protection_decorator.py +117 -114
- janito/tools/tool_base.py +142 -114
- janito/tools/tools_schema.py +12 -6
- {janito-3.2.0.dist-info → janito-3.3.0.dist-info}/METADATA +1 -1
- {janito-3.2.0.dist-info → janito-3.3.0.dist-info}/RECORD +160 -95
- janito/llm/cancellation_manager.py +0 -63
- janito/llm/enter_cancellation.py +0 -107
- janito/plugins/core_adapter.py +0 -131
- janito/providers/together/__init__.py +0 -1
- janito/providers/together/model_info.py +0 -69
- janito/providers/together/provider.py +0 -108
- /janito/{plugin_system → plugin_system_backup_20250825_070018}/__init__.py +0 -0
- /janito/{plugin_system → plugin_system_backup_20250825_070018}/base.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/auto_loader_fixed.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018/core/codeanalyzer}/tools/get_file_outline/java_outline.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018/core/codeanalyzer}/tools/get_file_outline/markdown_outline.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018/core/codeanalyzer}/tools/get_file_outline/python_outline.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018/core/codeanalyzer}/tools/get_file_outline/search_outline.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018/core/codeanalyzer}/tools/search_text/match_lines.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018/core/codeanalyzer}/tools/search_text/pattern_utils.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018/core/codeanalyzer}/tools/search_text/traverse_directory.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018/core/filemanager}/tools/validate_file_syntax/css_validator.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018/core/filemanager}/tools/validate_file_syntax/html_validator.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018/core/filemanager}/tools/validate_file_syntax/jinja2_validator.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018/core/filemanager}/tools/validate_file_syntax/js_validator.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018/core/filemanager}/tools/validate_file_syntax/json_validator.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018/core/filemanager}/tools/validate_file_syntax/markdown_validator.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018/core/filemanager}/tools/validate_file_syntax/ps1_validator.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018/core/filemanager}/tools/validate_file_syntax/python_validator.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018/core/filemanager}/tools/validate_file_syntax/xml_validator.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018/core/filemanager}/tools/validate_file_syntax/yaml_validator.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/__init__.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/ask_user.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/copy_file.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/create_directory.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/decorators.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/fetch_url.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/find_files.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/get_file_outline/__init__.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/get_file_outline/core.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/move_file.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/open_html_in_browser.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/open_url.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/python_code_run.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/python_command_run.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/python_file_run.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/read_chart.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/read_files.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/remove_directory.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/remove_file.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/replace_text_in_file.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/run_bash_command.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/run_powershell_command.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/search_text/__init__.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/search_text/core.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/show_image.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/show_image_grid.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/validate_file_syntax/__init__.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/validate_file_syntax/core.py +0 -0
- /janito/{plugins → plugins_backup_20250825_070018}/tools/view_file.py +0 -0
- {janito-3.2.0.dist-info → janito-3.3.0.dist-info}/WHEEL +0 -0
- {janito-3.2.0.dist-info → janito-3.3.0.dist-info}/entry_points.txt +0 -0
- {janito-3.2.0.dist-info → janito-3.3.0.dist-info}/licenses/LICENSE +0 -0
- {janito-3.2.0.dist-info → janito-3.3.0.dist-info}/top_level.txt +0 -0
janito/README.md
CHANGED
@@ -106,9 +106,6 @@ janito --set model=kimi-k1-8k
|
|
106
106
|
|
107
107
|
## Advanced Features
|
108
108
|
|
109
|
-
### 🚀 New in v3.1.0: Enter Key Cancellation
|
110
|
-
**Chat Mode Enhancement**: Press **Enter** at any time to instantly cancel long-running requests in interactive chat mode. No more waiting for stuck requests!
|
111
|
-
|
112
109
|
### Tool Usage
|
113
110
|
|
114
111
|
Janito includes powerful built-in tools for:
|
janito/cli/chat_mode/bindings.py
CHANGED
@@ -35,30 +35,4 @@ class KeyBindingsFactory:
|
|
35
35
|
buf.text = "Do It"
|
36
36
|
buf.validate_and_handle()
|
37
37
|
|
38
|
-
@bindings.add("c-c")
|
39
|
-
def _(event):
|
40
|
-
"""Handle Ctrl+C to interrupt current request or exit chat."""
|
41
|
-
# Use global cancellation manager for robust cancellation
|
42
|
-
from janito.llm.cancellation_manager import get_cancellation_manager
|
43
|
-
|
44
|
-
cancel_manager = get_cancellation_manager()
|
45
|
-
|
46
|
-
cancelled = cancel_manager.cancel_current_request()
|
47
|
-
if cancelled:
|
48
|
-
# Provide user feedback
|
49
|
-
from rich.console import Console
|
50
|
-
|
51
|
-
console = Console()
|
52
|
-
console.print("[red]Request cancelled by Ctrl+C[/red]")
|
53
|
-
|
54
|
-
# Prevent the Ctrl+C from being processed as input
|
55
|
-
event.app.output.flush()
|
56
|
-
return
|
57
|
-
else:
|
58
|
-
# No active request to cancel, exit the chat
|
59
|
-
from rich.console import Console
|
60
|
-
console = Console()
|
61
|
-
console.print("[yellow]Goodbye![/yellow]")
|
62
|
-
event.app.exit()
|
63
|
-
|
64
38
|
return bindings
|
janito/cli/chat_mode/session.py
CHANGED
@@ -22,7 +22,6 @@ import time
|
|
22
22
|
|
23
23
|
# Shared prompt/agent factory
|
24
24
|
from janito.cli.prompt_setup import setup_agent_and_prompt_handler
|
25
|
-
from janito.llm.cancellation_manager import get_cancellation_manager
|
26
25
|
|
27
26
|
import time
|
28
27
|
|
@@ -114,10 +113,6 @@ class ChatSession:
|
|
114
113
|
|
115
114
|
# Check if multi-line mode should be enabled by default
|
116
115
|
self.multi_line_mode = getattr(args, "multi", False) if args else False
|
117
|
-
|
118
|
-
# Default to single-line mode (Enter submits) unless explicitly enabled
|
119
|
-
if not self.multi_line_mode:
|
120
|
-
self.multi_line_mode = False
|
121
116
|
|
122
117
|
def _select_profile_and_role(self, args, role):
|
123
118
|
profile, role_arg, python_profile, market_profile = self._extract_args(args)
|
@@ -288,13 +283,7 @@ class ChatSession:
|
|
288
283
|
)
|
289
284
|
)
|
290
285
|
|
291
|
-
|
292
|
-
self._prompt_handler.run_prompt(cmd_input)
|
293
|
-
finally:
|
294
|
-
# Ensure cancellation manager is cleared
|
295
|
-
cancel_manager = get_cancellation_manager()
|
296
|
-
cancel_manager.clear_current_request()
|
297
|
-
|
286
|
+
self._prompt_handler.run_prompt(cmd_input)
|
298
287
|
end_time = time.time()
|
299
288
|
elapsed = end_time - start_time
|
300
289
|
self.msg_count += 1
|
@@ -59,53 +59,39 @@ Examples:
|
|
59
59
|
command = args[0].lower()
|
60
60
|
whitelist_manager = get_url_whitelist_manager()
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
62
|
+
if command == "list":
|
63
|
+
sites = whitelist_manager.get_allowed_sites()
|
64
|
+
if sites:
|
65
|
+
print("Allowed sites:")
|
66
|
+
for site in sites:
|
67
|
+
print(f" • {site}")
|
68
|
+
else:
|
69
|
+
print("No sites are whitelisted (all sites are allowed)")
|
70
|
+
|
71
|
+
elif command == "add":
|
72
|
+
if len(args) < 2:
|
73
|
+
print("Error: Please specify a site to add")
|
74
|
+
return
|
75
|
+
site = args[1]
|
76
|
+
if whitelist_manager.add_allowed_site(site):
|
77
|
+
print(f"✅ Added '{site}' to allowed sites")
|
78
|
+
else:
|
79
|
+
print(f"ℹ️ '{site}' is already in allowed sites")
|
80
|
+
|
81
|
+
elif command == "remove":
|
82
|
+
if len(args) < 2:
|
83
|
+
print("Error: Please specify a site to remove")
|
84
|
+
return
|
85
|
+
site = args[1]
|
86
|
+
if whitelist_manager.remove_allowed_site(site):
|
87
|
+
print(f"✅ Removed '{site}' from allowed sites")
|
88
|
+
else:
|
89
|
+
print(f"ℹ️ '{site}' was not in allowed sites")
|
90
|
+
|
91
|
+
elif command == "clear":
|
92
|
+
whitelist_manager.clear_whitelist()
|
93
|
+
print("✅ Cleared all allowed sites (all sites are now allowed)")
|
94
|
+
|
72
95
|
else:
|
73
96
|
print(f"Error: Unknown command '{command}'")
|
74
97
|
print(self.get_usage())
|
75
|
-
|
76
|
-
def _handle_list(self, args, whitelist_manager):
|
77
|
-
"""Handle list command."""
|
78
|
-
sites = whitelist_manager.get_allowed_sites()
|
79
|
-
if sites:
|
80
|
-
print("Allowed sites:")
|
81
|
-
for site in sites:
|
82
|
-
print(f" • {site}")
|
83
|
-
else:
|
84
|
-
print("No sites are whitelisted (all sites are allowed)")
|
85
|
-
|
86
|
-
def _handle_add(self, args, whitelist_manager):
|
87
|
-
"""Handle add command."""
|
88
|
-
if len(args) < 2:
|
89
|
-
print("Error: Please specify a site to add")
|
90
|
-
return
|
91
|
-
site = args[1]
|
92
|
-
if whitelist_manager.add_allowed_site(site):
|
93
|
-
print(f"✅ Added '{site}' to allowed sites")
|
94
|
-
else:
|
95
|
-
print(f"ℹ️ '{site}' is already in allowed sites")
|
96
|
-
|
97
|
-
def _handle_remove(self, args, whitelist_manager):
|
98
|
-
"""Handle remove command."""
|
99
|
-
if len(args) < 2:
|
100
|
-
print("Error: Please specify a site to remove")
|
101
|
-
return
|
102
|
-
site = args[1]
|
103
|
-
if whitelist_manager.remove_allowed_site(site):
|
104
|
-
print(f"✅ Removed '{site}' from allowed sites")
|
105
|
-
else:
|
106
|
-
print(f"ℹ️ '{site}' was not in allowed sites")
|
107
|
-
|
108
|
-
def _handle_clear(self, args, whitelist_manager):
|
109
|
-
"""Handle clear command."""
|
110
|
-
whitelist_manager.clear_whitelist()
|
111
|
-
print("✅ Cleared all allowed sites (all sites are now allowed)")
|
@@ -8,11 +8,8 @@ from janito.plugins.discovery import list_available_plugins
|
|
8
8
|
import os
|
9
9
|
from janito.plugins.manager import PluginManager
|
10
10
|
from janito.plugins.builtin import BuiltinPluginRegistry
|
11
|
-
from janito.plugins.
|
12
|
-
|
13
|
-
get_loaded_core_plugins,
|
14
|
-
is_core_plugin,
|
15
|
-
)
|
11
|
+
from janito.plugins.manager import PluginManager
|
12
|
+
from janito.plugins.core_loader import get_core_plugins
|
16
13
|
from rich.console import Console
|
17
14
|
from rich.table import Table
|
18
15
|
from rich.panel import Panel
|
@@ -55,7 +52,7 @@ def _list_available_plugins():
|
|
55
52
|
console.print(table)
|
56
53
|
|
57
54
|
# Show core plugins
|
58
|
-
from janito.
|
55
|
+
from janito.plugins.core_loader import get_core_plugins
|
59
56
|
|
60
57
|
core_plugins = get_core_plugins()
|
61
58
|
core_table = Table(title="Core Plugins (Enabled by Default)")
|
@@ -98,10 +95,8 @@ def _print_external_plugins(available, builtin_plugins):
|
|
98
95
|
|
99
96
|
def _list_plugin_resources():
|
100
97
|
"""List all resources from loaded plugins using rich formatting."""
|
101
|
-
from janito.plugins.auto_loader_fixed import get_plugin_manager
|
102
|
-
|
103
98
|
console = Console()
|
104
|
-
manager =
|
99
|
+
manager = PluginManager()
|
105
100
|
all_resources = manager.list_all_resources()
|
106
101
|
|
107
102
|
if all_resources:
|
@@ -174,10 +169,8 @@ def _print_resources_by_type(resources):
|
|
174
169
|
|
175
170
|
def _list_loaded_plugins():
|
176
171
|
"""List loaded plugins using rich formatting."""
|
177
|
-
from janito.plugins.auto_loader_fixed import get_plugin_manager
|
178
|
-
|
179
172
|
console = Console()
|
180
|
-
manager =
|
173
|
+
manager = PluginManager()
|
181
174
|
loaded = manager.list_plugins()
|
182
175
|
|
183
176
|
if loaded:
|
@@ -192,7 +185,9 @@ def _list_loaded_plugins():
|
|
192
185
|
other_plugins = []
|
193
186
|
|
194
187
|
for plugin_name in loaded:
|
195
|
-
|
188
|
+
from janito.plugins.core_loader import get_core_plugins
|
189
|
+
core_plugin_list = get_core_plugins()
|
190
|
+
if plugin_name in core_plugin_list:
|
196
191
|
core_plugins.append(plugin_name)
|
197
192
|
else:
|
198
193
|
other_plugins.append(plugin_name)
|
janito/cli/core/model_guesser.py
CHANGED
@@ -21,50 +21,34 @@ def guess_provider_from_model(model_name: str) -> str:
|
|
21
21
|
model_name = model_name.lower()
|
22
22
|
|
23
23
|
# Check each provider's models
|
24
|
-
return _find_provider_for_model(model_name)
|
25
|
-
|
26
|
-
|
27
|
-
def _find_provider_for_model(model_name: str) -> str:
|
28
|
-
"""Find provider for given model name."""
|
29
24
|
for provider_name in LLMProviderRegistry.list_providers():
|
30
25
|
provider_class = LLMProviderRegistry.get(provider_name)
|
31
26
|
if not provider_class:
|
32
27
|
continue
|
33
28
|
|
34
|
-
|
35
|
-
|
29
|
+
# Get model specs for this provider
|
30
|
+
try:
|
31
|
+
if hasattr(provider_class, "MODEL_SPECS"):
|
32
|
+
model_specs = provider_class.MODEL_SPECS
|
33
|
+
for spec_model_name in model_specs.keys():
|
34
|
+
if spec_model_name.lower() == model_name:
|
35
|
+
return provider_name
|
36
|
+
|
37
|
+
# Handle special cases like moonshot
|
38
|
+
if provider_name == "moonshot":
|
39
|
+
try:
|
40
|
+
from janito.providers.moonshot.model_info import (
|
41
|
+
MOONSHOT_MODEL_SPECS,
|
42
|
+
)
|
43
|
+
|
44
|
+
for spec_model_name in MOONSHOT_MODEL_SPECS.keys():
|
45
|
+
if spec_model_name.lower() == model_name:
|
46
|
+
return "moonshot"
|
47
|
+
except ImportError:
|
48
|
+
pass
|
49
|
+
|
50
|
+
except Exception:
|
51
|
+
# Skip providers that have issues accessing model specs
|
52
|
+
continue
|
36
53
|
|
37
54
|
return None
|
38
|
-
|
39
|
-
|
40
|
-
def _check_provider_models(provider_name: str, provider_class, model_name: str) -> bool:
|
41
|
-
"""Check if provider has matching model."""
|
42
|
-
try:
|
43
|
-
if hasattr(provider_class, "MODEL_SPECS"):
|
44
|
-
model_specs = provider_class.MODEL_SPECS
|
45
|
-
for spec_model_name in model_specs.keys():
|
46
|
-
if spec_model_name.lower() == model_name:
|
47
|
-
return True
|
48
|
-
|
49
|
-
# Handle special cases like moonshot
|
50
|
-
if provider_name == "moonshot":
|
51
|
-
return _check_moonshot_models(model_name)
|
52
|
-
|
53
|
-
except Exception:
|
54
|
-
# Skip providers that have issues accessing model specs
|
55
|
-
pass
|
56
|
-
|
57
|
-
return False
|
58
|
-
|
59
|
-
|
60
|
-
def _check_moonshot_models(model_name: str) -> bool:
|
61
|
-
"""Check moonshot models specifically."""
|
62
|
-
try:
|
63
|
-
from janito.providers.moonshot.model_info import MOONSHOT_MODEL_SPECS
|
64
|
-
|
65
|
-
for spec_model_name in MOONSHOT_MODEL_SPECS.keys():
|
66
|
-
if spec_model_name.lower() == model_name:
|
67
|
-
return True
|
68
|
-
except ImportError:
|
69
|
-
pass
|
70
|
-
return False
|
janito/cli/prompt_core.py
CHANGED
@@ -207,26 +207,15 @@ class PromptHandler:
|
|
207
207
|
"""
|
208
208
|
try:
|
209
209
|
self._print_verbose_debug("Calling agent.chat()...")
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
if hasattr(self.agent, "set_latest_event"):
|
220
|
-
self.agent.set_latest_event(final_event)
|
221
|
-
self.agent.last_event = final_event
|
222
|
-
self._print_verbose_debug(f"agent.chat() returned: {final_event}")
|
223
|
-
self._print_verbose_final_event(final_event)
|
224
|
-
if on_event and final_event is not None:
|
225
|
-
on_event(final_event)
|
226
|
-
global_event_bus.publish(final_event)
|
227
|
-
finally:
|
228
|
-
cancel_manager.clear_current_request()
|
229
|
-
|
210
|
+
final_event = self.agent.chat(prompt=user_prompt)
|
211
|
+
if hasattr(self.agent, "set_latest_event"):
|
212
|
+
self.agent.set_latest_event(final_event)
|
213
|
+
self.agent.last_event = final_event
|
214
|
+
self._print_verbose_debug(f"agent.chat() returned: {final_event}")
|
215
|
+
self._print_verbose_final_event(final_event)
|
216
|
+
if on_event and final_event is not None:
|
217
|
+
on_event(final_event)
|
218
|
+
global_event_bus.publish(final_event)
|
230
219
|
except KeyboardInterrupt:
|
231
220
|
# Capture user interrupt / cancellation
|
232
221
|
self.console.print("[red]Interrupted by the user.[/red]")
|
janito/i18n/it.py
CHANGED
@@ -1,46 +1,46 @@
|
|
1
|
-
# pragma: allowlist secret
|
2
|
-
translations = {
|
3
|
-
"36107ed78ab25f6fb12ad8ce13018cd1ce6735d1": "Avvio del server web...",
|
4
|
-
"70a0d194687568a47aa617fd85036ace1e69a982": "Vuoi davvero uscire? (s/n): ",
|
5
|
-
"5c9ebcbbd7632ecb328bd52958b17158afaa32c6": "F12 = Azione Rapida (segue l'azione raccomandata)",
|
6
|
-
"fe21121e2934234b68d19b2757532117d440c1e3": "Chiave API non trovata. Si prega di configurare 'api_key' nel file di configurazione.",
|
7
|
-
"c9e3759b1756eba35b381ce2b72cd659e132b01f": "Ciao, {name}!",
|
8
|
-
"ca1fee2f55baabdc2e4b0e9529c89ee024e62079": "Nessun prompt fornito nei messaggi",
|
9
|
-
"f7449d23d0c500ae2a0b31e04f92b47a4d8ae845": "max_tokens deve essere un intero, ricevuto: {resolved_max_tokens!r}",
|
10
|
-
"70a9ed8edb6da12e208431a31aa16ba54419b26f": "Risposta non valida/malformed da OpenAI (tentativo {attempt}/{max_retries}). Riprovo tra {wait_time} secondi...",
|
11
|
-
"a873085e3b06184fb5d27e842f97b06b6190976d": "Numero massimo di tentativi per risposta non valida raggiunto. Generazione errore.",
|
12
|
-
"66a34568bbe846bb1bde3619eb4d6dfa10211104": "L'API non supporta l'uso degli strumenti.",
|
13
|
-
"09b81476b75586da4116b83f8be70d77b174cec3": "
|
14
|
-
"5717a35dd2a1533fb7e15edc8c9329cb69f3410b": "Errore server API OpenAI (tentativo {attempt}/{max_retries}): {e}. Riprovo tra {wait_time} secondi...",
|
15
|
-
"02e760ba15ed863176c1290ac8a9b923963103cd": "Errore client API OpenAI {status_code}: {e}. Nessun nuovo tentativo.",
|
16
|
-
"2e52b0bbc8f16226b70e3e20f95c9245d2bcdb47": "Errore API OpenAI (tentativo {attempt}/{max_retries}): {e}. Riprovo tra {wait_time} secondi...",
|
17
|
-
"012cc970e039fdd79c452fc676202c814ffc76ae": "Numero massimo di tentativi per errore API OpenAI raggiunto. Generazione errore.",
|
18
|
-
"d0438e45667d31e0022b2497b5901cd4300f084b": "QueuedMessageHandler.handle_message si aspetta un dizionario con 'type' e 'message', ricevuto {msg_type}: {msg!r}",
|
19
|
-
"9d3460187ffa19c7c8a4020157072b1087e1bd2f": "[QueuedMessageHandler] {msg_type}: {msg}",
|
20
|
-
"3813833343430e8afa8fce33385c5e39fb24dd60": "[QueuedMessageHandler] {msg_type}: {message}",
|
21
|
-
"0be9a22226e16a40797010d23a0f581542dca40e": "[ToolExecutor] {tool_name} chiamato con argomenti: {args}",
|
22
|
-
"42c68edcb25442f518b1af77c6a2ddc07461aae0": "[ToolExecutor] Motivo chiamata: {tool_call_reason}",
|
23
|
-
"002ff598115d84595ffeee6219cb5c03d3a1d4a6": "Domanda",
|
24
|
-
"35747d13dcd91e8e8790c7f767d5ed764f541b9e": "procedi",
|
25
|
-
"33dde3a1afbc418768a69fa53168d9b0638fe1aa": "avanti",
|
26
|
-
"eee0bbba4ff92adbeb038a77df0466d660f15716": "continua",
|
27
|
-
"edee9402d198b04ac77dcf5dc9cc3dac44573782": "prossimo",
|
28
|
-
"8fdb7e2fa84f4faf0d9b92f466df424ec47a165b": "ok",
|
29
|
-
"5f8f924671cda79b5205a6bf1b776f347c4a7a07": "Opzioni di configurazione disponibili:\n",
|
30
|
-
"cef780a309cd234750764d42697882c24168ddab": "{key:15} {desc} (predefinito: {default})",
|
31
|
-
"68c2cc7f0ceaa3e499ecb4db331feb4debbbcc23": "Modello",
|
32
|
-
"c3f104d1365744b538bfde9f4adb6a6df4b80355": "Funzione",
|
33
|
-
"99a0efc6cfd85d8ff2732a6718140f822cb90472": "Stile",
|
34
|
-
"f1702b4686278becffc88baabe6f4b7a8355532c": "Messaggi",
|
35
|
-
"c38c6c1f3a2743f8626703abb302e403d20ff81c": "Token",
|
36
|
-
"a817d7eb8e0f1dab755ab5203a082e5c3c094fce": "Prompt",
|
37
|
-
"2ff255684a2277f806fcebf3fe338ed27857f350": "Completamento",
|
38
|
-
"b25928c69902557b0ef0a628490a3a1768d7b82f": "Totale",
|
39
|
-
"76e63d65c883ed50df40ac3aeef0c2d6a1c4ad60": "Azione Rapida",
|
40
|
-
"5397e0583f14f6c88de06b1ef28f460a1fb5b0ae": "Sì",
|
41
|
-
"816c52fd2bdd94a63cd0944823a6c0aa9384c103": "No",
|
42
|
-
"c47ae15370cfe1ed2781eedc1dc2547d12d9e972": "Aiuto",
|
43
|
-
"cc3dbd47e1cf9003a55d3366b3adbcd72275e525": "Nuovo Task",
|
44
|
-
"efa5a8b84e1afe65c81ecfce28c398c48f19ddc2": "Benvenuto su Janito{version_str}! Modalità chat attiva. Digita /exit per uscire.",
|
45
|
-
"b314d6e1460f86e0f21abc5aceb7935a2a0667e8": "Benvenuto su Janito{version_str} in modalità [white on magenta]VANILLA[/white on magenta]! Strumenti, prompt di sistema e temperatura sono disattivati, a meno che non siano sovrascritti.",
|
46
|
-
}
|
1
|
+
# pragma: allowlist secret
|
2
|
+
translations = {
|
3
|
+
"36107ed78ab25f6fb12ad8ce13018cd1ce6735d1": "Avvio del server web...",
|
4
|
+
"70a0d194687568a47aa617fd85036ace1e69a982": "Vuoi davvero uscire? (s/n): ",
|
5
|
+
"5c9ebcbbd7632ecb328bd52958b17158afaa32c6": "F12 = Azione Rapida (segue l'azione raccomandata)",
|
6
|
+
"fe21121e2934234b68d19b2757532117d440c1e3": "Chiave API non trovata. Si prega di configurare 'api_key' nel file di configurazione.",
|
7
|
+
"c9e3759b1756eba35b381ce2b72cd659e132b01f": "Ciao, {name}!",
|
8
|
+
"ca1fee2f55baabdc2e4b0e9529c89ee024e62079": "Nessun prompt fornito nei messaggi",
|
9
|
+
"f7449d23d0c500ae2a0b31e04f92b47a4d8ae845": "max_tokens deve essere un intero, ricevuto: {resolved_max_tokens!r}",
|
10
|
+
"70a9ed8edb6da12e208431a31aa16ba54419b26f": "Risposta non valida/malformed da OpenAI (tentativo {attempt}/{max_retries}). Riprovo tra {wait_time} secondi...",
|
11
|
+
"a873085e3b06184fb5d27e842f97b06b6190976d": "Numero massimo di tentativi per risposta non valida raggiunto. Generazione errore.",
|
12
|
+
"66a34568bbe846bb1bde3619eb4d6dfa10211104": "L'API non supporta l'uso degli strumenti.",
|
13
|
+
"09b81476b75586da4116b83f8be70d77b174cec3": "Limite di richieste API OpenAI (429) (tentativo {attempt}/{max_retries}): {e}. Riprovo tra {wait_time} secondi...",
|
14
|
+
"5717a35dd2a1533fb7e15edc8c9329cb69f3410b": "Errore server API OpenAI (tentativo {attempt}/{max_retries}): {e}. Riprovo tra {wait_time} secondi...",
|
15
|
+
"02e760ba15ed863176c1290ac8a9b923963103cd": "Errore client API OpenAI {status_code}: {e}. Nessun nuovo tentativo.",
|
16
|
+
"2e52b0bbc8f16226b70e3e20f95c9245d2bcdb47": "Errore API OpenAI (tentativo {attempt}/{max_retries}): {e}. Riprovo tra {wait_time} secondi...",
|
17
|
+
"012cc970e039fdd79c452fc676202c814ffc76ae": "Numero massimo di tentativi per errore API OpenAI raggiunto. Generazione errore.",
|
18
|
+
"d0438e45667d31e0022b2497b5901cd4300f084b": "QueuedMessageHandler.handle_message si aspetta un dizionario con 'type' e 'message', ricevuto {msg_type}: {msg!r}",
|
19
|
+
"9d3460187ffa19c7c8a4020157072b1087e1bd2f": "[QueuedMessageHandler] {msg_type}: {msg}",
|
20
|
+
"3813833343430e8afa8fce33385c5e39fb24dd60": "[QueuedMessageHandler] {msg_type}: {message}",
|
21
|
+
"0be9a22226e16a40797010d23a0f581542dca40e": "[ToolExecutor] {tool_name} chiamato con argomenti: {args}",
|
22
|
+
"42c68edcb25442f518b1af77c6a2ddc07461aae0": "[ToolExecutor] Motivo chiamata: {tool_call_reason}",
|
23
|
+
"002ff598115d84595ffeee6219cb5c03d3a1d4a6": "Domanda",
|
24
|
+
"35747d13dcd91e8e8790c7f767d5ed764f541b9e": "procedi",
|
25
|
+
"33dde3a1afbc418768a69fa53168d9b0638fe1aa": "avanti",
|
26
|
+
"eee0bbba4ff92adbeb038a77df0466d660f15716": "continua",
|
27
|
+
"edee9402d198b04ac77dcf5dc9cc3dac44573782": "prossimo",
|
28
|
+
"8fdb7e2fa84f4faf0d9b92f466df424ec47a165b": "ok",
|
29
|
+
"5f8f924671cda79b5205a6bf1b776f347c4a7a07": "Opzioni di configurazione disponibili:\n",
|
30
|
+
"cef780a309cd234750764d42697882c24168ddab": "{key:15} {desc} (predefinito: {default})",
|
31
|
+
"68c2cc7f0ceaa3e499ecb4db331feb4debbbcc23": "Modello",
|
32
|
+
"c3f104d1365744b538bfde9f4adb6a6df4b80355": "Funzione",
|
33
|
+
"99a0efc6cfd85d8ff2732a6718140f822cb90472": "Stile",
|
34
|
+
"f1702b4686278becffc88baabe6f4b7a8355532c": "Messaggi",
|
35
|
+
"c38c6c1f3a2743f8626703abb302e403d20ff81c": "Token",
|
36
|
+
"a817d7eb8e0f1dab755ab5203a082e5c3c094fce": "Prompt",
|
37
|
+
"2ff255684a2277f806fcebf3fe338ed27857f350": "Completamento",
|
38
|
+
"b25928c69902557b0ef0a628490a3a1768d7b82f": "Totale",
|
39
|
+
"76e63d65c883ed50df40ac3aeef0c2d6a1c4ad60": "Azione Rapida",
|
40
|
+
"5397e0583f14f6c88de06b1ef28f460a1fb5b0ae": "Sì",
|
41
|
+
"816c52fd2bdd94a63cd0944823a6c0aa9384c103": "No",
|
42
|
+
"c47ae15370cfe1ed2781eedc1dc2547d12d9e972": "Aiuto",
|
43
|
+
"cc3dbd47e1cf9003a55d3366b3adbcd72275e525": "Nuovo Task",
|
44
|
+
"efa5a8b84e1afe65c81ecfce28c398c48f19ddc2": "Benvenuto su Janito{version_str}! Modalità chat attiva. Digita /exit per uscire.",
|
45
|
+
"b314d6e1460f86e0f21abc5aceb7935a2a0667e8": "Benvenuto su Janito{version_str} in modalità [white on magenta]VANILLA[/white on magenta]! Strumenti, prompt di sistema e temperatura sono disattivati, a meno che non siano sovrascritti.",
|
46
|
+
}
|
janito/llm/agent.py
CHANGED
@@ -318,39 +318,23 @@ class LLMAgent:
|
|
318
318
|
loop_count = 1
|
319
319
|
import threading
|
320
320
|
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
config, cancel_event=driver_cancel_event
|
321
|
+
cancel_event = threading.Event()
|
322
|
+
while True:
|
323
|
+
self._print_verbose_chat_loop(loop_count)
|
324
|
+
driver_input = self._prepare_driver_input(config, cancel_event=cancel_event)
|
325
|
+
self.input_queue.put(driver_input)
|
326
|
+
try:
|
327
|
+
result, added_tool_results = self._process_next_response()
|
328
|
+
except KeyboardInterrupt:
|
329
|
+
cancel_event.set()
|
330
|
+
raise
|
331
|
+
if getattr(self, "verbose_agent", False):
|
332
|
+
print(
|
333
|
+
f"[agent] [DEBUG] Returned from _process_next_response: result={result}, added_tool_results={added_tool_results}"
|
335
334
|
)
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
except KeyboardInterrupt:
|
340
|
-
cancel_manager.cancel_current_request()
|
341
|
-
raise
|
342
|
-
if getattr(self, "verbose_agent", False):
|
343
|
-
print(
|
344
|
-
f"[agent] [DEBUG] Returned from _process_next_response: result={result}, added_tool_results={added_tool_results}"
|
345
|
-
)
|
346
|
-
if self._should_exit_chat_loop(result, added_tool_results):
|
347
|
-
return result
|
348
|
-
loop_count += 1
|
349
|
-
finally:
|
350
|
-
cancel_manager.clear_current_request()
|
351
|
-
# Clean up cancellation event
|
352
|
-
if hasattr(self, "cancel_event"):
|
353
|
-
delattr(self, "cancel_event")
|
335
|
+
if self._should_exit_chat_loop(result, added_tool_results):
|
336
|
+
return result
|
337
|
+
loop_count += 1
|
354
338
|
|
355
339
|
def _clear_driver_queues(self):
|
356
340
|
if hasattr(self, "driver") and self.driver:
|
janito/llm/driver.py
CHANGED
@@ -252,11 +252,3 @@ class LLMDriver(ABC):
|
|
252
252
|
def _get_message_from_result(self, result):
|
253
253
|
"""Extract the message object from the provider result. Subclasses must implement this."""
|
254
254
|
raise NotImplementedError("Subclasses must implement _get_message_from_result.")
|
255
|
-
|
256
|
-
def cancel_current_request(self):
|
257
|
-
"""Cancel the current request being processed."""
|
258
|
-
# Use global cancellation manager to cancel the current request
|
259
|
-
from janito.llm.cancellation_manager import get_cancellation_manager
|
260
|
-
|
261
|
-
cancel_manager = get_cancellation_manager()
|
262
|
-
cancel_manager.cancel_current_request()
|
@@ -12,7 +12,8 @@ from pathlib import Path
|
|
12
12
|
from typing import Optional, List, Type
|
13
13
|
|
14
14
|
from janito.plugin_system.base import Plugin, PluginMetadata
|
15
|
-
from janito.tools.
|
15
|
+
from janito.tools.function_adapter import create_function_tool
|
16
|
+
from janito.tools.tool_base import ToolBase
|
16
17
|
|
17
18
|
|
18
19
|
class CorePlugin(Plugin):
|
@@ -37,86 +38,12 @@ class CorePlugin(Plugin):
|
|
37
38
|
def get_tools(self) -> List[Type[ToolBase]]:
|
38
39
|
return self._tool_classes
|
39
40
|
|
40
|
-
def _create_tool_class(self, func):
|
41
|
-
"""Create a ToolBase class from a function."""
|
42
|
-
resolved_tool_name = getattr(func, "tool_name", func.__name__)
|
43
|
-
|
44
|
-
# Create a proper tool class with explicit parameters and documentation
|
45
|
-
import inspect
|
46
|
-
from typing import get_type_hints
|
47
|
-
|
48
|
-
func_sig = inspect.signature(func)
|
49
|
-
type_hints = get_type_hints(func)
|
50
|
-
|
51
|
-
# Build parameter definitions for the run method
|
52
|
-
param_defs = []
|
53
|
-
param_docs = []
|
54
|
-
for name, param in func_sig.parameters.items():
|
55
|
-
type_hint = type_hints.get(name, str)
|
56
|
-
if param.default == inspect.Parameter.empty:
|
57
|
-
param_defs.append(f"{name}: {type_hint.__name__}")
|
58
|
-
else:
|
59
|
-
param_defs.append(f"{name}: {type_hint.__name__} = {repr(param.default)}")
|
60
|
-
|
61
|
-
# Add parameter documentation
|
62
|
-
param_docs.append(f" {name}: {type_hint.__name__} - Parameter {name}")
|
63
|
-
|
64
|
-
# Get function docstring or create one
|
65
|
-
func_doc = func.__doc__ or f"Execute {resolved_tool_name} tool"
|
66
|
-
|
67
|
-
# Create the tool class with proper signature and documentation
|
68
|
-
exec_globals = {
|
69
|
-
'ToolBase': ToolBase,
|
70
|
-
'ToolPermissions': ToolPermissions,
|
71
|
-
'func': func,
|
72
|
-
'inspect': inspect,
|
73
|
-
'str': str,
|
74
|
-
}
|
75
|
-
|
76
|
-
param_docs_str = '\n'.join(param_docs)
|
77
|
-
|
78
|
-
class_def = f'''
|
79
|
-
class DynamicTool(ToolBase):
|
80
|
-
"""
|
81
|
-
{func_doc}
|
82
|
-
|
83
|
-
Parameters:
|
84
|
-
{param_docs_str}
|
85
|
-
|
86
|
-
Returns:
|
87
|
-
str: Execution result
|
88
|
-
"""
|
89
|
-
tool_name = "{resolved_tool_name}"
|
90
|
-
permissions = ToolPermissions(read=True, write=True, execute=True)
|
91
|
-
|
92
|
-
def __init__(self):
|
93
|
-
super().__init__()
|
94
|
-
|
95
|
-
def run(self, {', '.join(param_defs)}) -> str:
|
96
|
-
kwargs = locals()
|
97
|
-
sig = inspect.signature(func)
|
98
|
-
|
99
|
-
# Filter kwargs to only include parameters the function accepts
|
100
|
-
filtered_kwargs = {{}}
|
101
|
-
for name, param in sig.parameters.items():
|
102
|
-
if name in kwargs and kwargs[name] is not None:
|
103
|
-
filtered_kwargs[name] = kwargs[name]
|
104
|
-
|
105
|
-
result = func(**filtered_kwargs)
|
106
|
-
return str(result) if result is not None else ""
|
107
|
-
'''
|
108
|
-
|
109
|
-
exec(class_def, exec_globals)
|
110
|
-
return exec_globals['DynamicTool']
|
111
|
-
|
112
|
-
return DynamicTool
|
113
|
-
|
114
41
|
def initialize(self):
|
115
42
|
"""Initialize by creating tool classes."""
|
116
43
|
self._tool_classes = []
|
117
44
|
for tool_func in self._tools:
|
118
45
|
if callable(tool_func):
|
119
|
-
tool_class =
|
46
|
+
tool_class = create_function_tool(tool_func)
|
120
47
|
self._tool_classes.append(tool_class)
|
121
48
|
|
122
49
|
|