janito 2.6.0__py3-none-any.whl → 2.7.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/__init__.py +1 -0
- janito/__main__.py +1 -0
- janito/_version.py +1 -0
- janito/agent/setup_agent.py +240 -230
- janito/agent/templates/profiles/{system_prompt_template_software_developer.txt.j2 → system_prompt_template_plain_software_developer.txt.j2} +39 -39
- janito/cli/__init__.py +1 -0
- janito/cli/chat_mode/bindings.py +1 -0
- janito/cli/chat_mode/chat_entry.py +1 -0
- janito/cli/chat_mode/prompt_style.py +1 -0
- janito/cli/chat_mode/script_runner.py +1 -0
- janito/cli/chat_mode/session.py +282 -282
- janito/cli/chat_mode/session_profile_select.py +5 -5
- janito/cli/single_shot_mode/handler.py +95 -95
- janito/drivers/driver_registry.py +27 -27
- janito/drivers/openai/driver.py +435 -435
- janito/provider_registry.py +178 -178
- janito/providers/__init__.py +1 -0
- janito/providers/anthropic/model_info.py +41 -41
- janito/providers/anthropic/provider.py +80 -80
- janito/providers/moonshotai/__init__.py +1 -0
- janito/providers/moonshotai/model_info.py +15 -0
- janito/providers/moonshotai/provider.py +82 -0
- janito/providers/openai/model_info.py +1 -0
- janito/providers/provider_static_info.py +21 -18
- janito/tools/adapters/local/__init__.py +66 -66
- janito/tools/adapters/local/move_file.py +3 -3
- janito/tools/adapters/local/read_files.py +40 -40
- {janito-2.6.0.dist-info → janito-2.7.0.dist-info}/METADATA +419 -412
- {janito-2.6.0.dist-info → janito-2.7.0.dist-info}/RECORD +33 -30
- {janito-2.6.0.dist-info → janito-2.7.0.dist-info}/WHEEL +0 -0
- {janito-2.6.0.dist-info → janito-2.7.0.dist-info}/entry_points.txt +0 -0
- {janito-2.6.0.dist-info → janito-2.7.0.dist-info}/licenses/LICENSE +0 -0
- {janito-2.6.0.dist-info → janito-2.7.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,82 @@
|
|
1
|
+
from janito.llm.provider import LLMProvider
|
2
|
+
from janito.llm.auth import LLMAuthManager
|
3
|
+
from janito.llm.driver_config import LLMDriverConfig
|
4
|
+
from janito.drivers.openai.driver import OpenAIModelDriver
|
5
|
+
from janito.tools import get_local_tools_adapter
|
6
|
+
from janito.providers.registry import LLMProviderRegistry
|
7
|
+
from .model_info import MOONSHOTAI_MODEL_SPECS
|
8
|
+
|
9
|
+
class MoonshotAIProvider(LLMProvider):
|
10
|
+
name = "moonshotai"
|
11
|
+
maintainer = "João Pinto <lamego.pinto@gmail.com>"
|
12
|
+
MODEL_SPECS = MOONSHOTAI_MODEL_SPECS
|
13
|
+
DEFAULT_MODEL = "kimi-k2-0711-preview"
|
14
|
+
|
15
|
+
def __init__(self, auth_manager: LLMAuthManager = None, config: LLMDriverConfig = None):
|
16
|
+
if not self.available:
|
17
|
+
self._tools_adapter = get_local_tools_adapter()
|
18
|
+
self._driver = None
|
19
|
+
else:
|
20
|
+
self.auth_manager = auth_manager or LLMAuthManager()
|
21
|
+
self._api_key = self.auth_manager.get_credentials(type(self).name)
|
22
|
+
self._tools_adapter = get_local_tools_adapter()
|
23
|
+
self._driver_config = config or LLMDriverConfig(model=None)
|
24
|
+
if not self._driver_config.model:
|
25
|
+
self._driver_config.model = self.DEFAULT_MODEL
|
26
|
+
if not self._driver_config.api_key:
|
27
|
+
self._driver_config.api_key = self._api_key
|
28
|
+
# Set only the correct token parameter for the model
|
29
|
+
model_name = self._driver_config.model
|
30
|
+
model_spec = self.MODEL_SPECS.get(model_name)
|
31
|
+
if hasattr(self._driver_config, "max_tokens"):
|
32
|
+
self._driver_config.max_tokens = None
|
33
|
+
if hasattr(self._driver_config, "max_completion_tokens"):
|
34
|
+
self._driver_config.max_completion_tokens = None
|
35
|
+
if model_spec:
|
36
|
+
if getattr(model_spec, "thinking_supported", False):
|
37
|
+
max_cot = getattr(model_spec, "max_cot", None)
|
38
|
+
if max_cot and max_cot != "N/A":
|
39
|
+
self._driver_config.max_completion_tokens = int(max_cot)
|
40
|
+
else:
|
41
|
+
max_response = getattr(model_spec, "max_response", None)
|
42
|
+
if max_response and max_response != "N/A":
|
43
|
+
self._driver_config.max_tokens = int(max_response)
|
44
|
+
self.fill_missing_device_info(self._driver_config)
|
45
|
+
self._driver = None
|
46
|
+
# Set MoonshotAI base_url
|
47
|
+
self._driver_config.base_url = "https://api.moonshot.ai/v1"
|
48
|
+
|
49
|
+
@property
|
50
|
+
def driver(self) -> OpenAIModelDriver:
|
51
|
+
if not self.available:
|
52
|
+
raise ImportError(f"MoonshotAIProvider unavailable: {self.unavailable_reason}")
|
53
|
+
return self._driver
|
54
|
+
|
55
|
+
@property
|
56
|
+
def available(self):
|
57
|
+
return OpenAIModelDriver.available
|
58
|
+
|
59
|
+
@property
|
60
|
+
def unavailable_reason(self):
|
61
|
+
return OpenAIModelDriver.unavailable_reason
|
62
|
+
|
63
|
+
def create_driver(self):
|
64
|
+
driver = OpenAIModelDriver(
|
65
|
+
tools_adapter=self._tools_adapter, provider_name=self.name
|
66
|
+
)
|
67
|
+
driver.config = self._driver_config
|
68
|
+
return driver
|
69
|
+
|
70
|
+
@property
|
71
|
+
def model_name(self):
|
72
|
+
return self._driver_config.model
|
73
|
+
|
74
|
+
@property
|
75
|
+
def driver_config(self):
|
76
|
+
return self._driver_config
|
77
|
+
|
78
|
+
def execute_tool(self, tool_name: str, event_bus, *args, **kwargs):
|
79
|
+
self._tools_adapter.event_bus = event_bus
|
80
|
+
return self._tools_adapter.execute_by_name(tool_name, *args, **kwargs)
|
81
|
+
|
82
|
+
LLMProviderRegistry.register(MoonshotAIProvider.name, MoonshotAIProvider)
|
@@ -1,18 +1,21 @@
|
|
1
|
-
# Provider static metadata registry for listing purposes (name, maintainer, and future fields)
|
2
|
-
STATIC_PROVIDER_METADATA = {
|
3
|
-
"openai": {
|
4
|
-
|
5
|
-
|
6
|
-
"
|
7
|
-
},
|
8
|
-
"
|
9
|
-
"maintainer": "João Pinto <lamego.pinto@gmail.com>",
|
10
|
-
},
|
11
|
-
"
|
12
|
-
"maintainer": "
|
13
|
-
},
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
1
|
+
# Provider static metadata registry for listing purposes (name, maintainer, and future fields)
|
2
|
+
STATIC_PROVIDER_METADATA = {
|
3
|
+
"openai": {},
|
4
|
+
"moonshotai": {
|
5
|
+
"maintainer": "João Pinto <lamego.pinto@gmail.com>",
|
6
|
+
"note": "MoonshotAI uses OpenAI-compatible API at https://api.moonshot.ai"
|
7
|
+
},
|
8
|
+
"google": {
|
9
|
+
"maintainer": "João Pinto <lamego.pinto@gmail.com>",
|
10
|
+
},
|
11
|
+
"azure_openai": {
|
12
|
+
"maintainer": "João Pinto <lamego.pinto@gmail.com>",
|
13
|
+
},
|
14
|
+
"anthropic": {
|
15
|
+
"maintainer": "Alberto Minetti <alberto.minetti@gmail.com>",
|
16
|
+
},
|
17
|
+
|
18
|
+
"deepseek": {
|
19
|
+
"maintainer": "João Pinto <lamego.pinto@gmail.com>",
|
20
|
+
},
|
21
|
+
}
|
@@ -1,66 +1,66 @@
|
|
1
|
-
from .adapter import LocalToolsAdapter
|
2
|
-
|
3
|
-
from .ask_user import AskUserTool
|
4
|
-
from .copy_file import CopyFileTool
|
5
|
-
from .create_directory import CreateDirectoryTool
|
6
|
-
from .create_file import CreateFileTool
|
7
|
-
from .fetch_url import FetchUrlTool
|
8
|
-
from .find_files import FindFilesTool
|
9
|
-
from .view_file import ViewFileTool
|
10
|
-
from .read_files import ReadFilesTool
|
11
|
-
from .move_file import MoveFileTool
|
12
|
-
from .open_url import OpenUrlTool
|
13
|
-
from .open_html_in_browser import OpenHtmlInBrowserTool
|
14
|
-
from .python_code_run import PythonCodeRunTool
|
15
|
-
from .python_command_run import PythonCommandRunTool
|
16
|
-
from .python_file_run import PythonFileRunTool
|
17
|
-
from .remove_directory import RemoveDirectoryTool
|
18
|
-
from .remove_file import RemoveFileTool
|
19
|
-
from .replace_text_in_file import ReplaceTextInFileTool
|
20
|
-
from .run_bash_command import RunBashCommandTool
|
21
|
-
from .run_powershell_command import RunPowershellCommandTool
|
22
|
-
from .get_file_outline.core import GetFileOutlineTool
|
23
|
-
from .get_file_outline.search_outline import SearchOutlineTool
|
24
|
-
from .search_text.core import SearchTextTool
|
25
|
-
from .validate_file_syntax.core import ValidateFileSyntaxTool
|
26
|
-
|
27
|
-
from janito.tools.tool_base import ToolPermissions
|
28
|
-
import os
|
29
|
-
from janito.tools.permissions import get_global_allowed_permissions
|
30
|
-
|
31
|
-
# Singleton tools adapter with all standard tools registered
|
32
|
-
local_tools_adapter = LocalToolsAdapter(workdir=os.getcwd())
|
33
|
-
|
34
|
-
def get_local_tools_adapter(workdir=None):
|
35
|
-
return LocalToolsAdapter(workdir=workdir or os.getcwd())
|
36
|
-
|
37
|
-
# Register tools
|
38
|
-
for tool_class in [
|
39
|
-
AskUserTool,
|
40
|
-
CopyFileTool,
|
41
|
-
CreateDirectoryTool,
|
42
|
-
CreateFileTool,
|
43
|
-
FetchUrlTool,
|
44
|
-
FindFilesTool,
|
45
|
-
ViewFileTool,
|
46
|
-
ReadFilesTool,
|
47
|
-
MoveFileTool,
|
48
|
-
OpenUrlTool,
|
49
|
-
OpenHtmlInBrowserTool,
|
50
|
-
PythonCodeRunTool,
|
51
|
-
PythonCommandRunTool,
|
52
|
-
PythonFileRunTool,
|
53
|
-
RemoveDirectoryTool,
|
54
|
-
RemoveFileTool,
|
55
|
-
ReplaceTextInFileTool,
|
56
|
-
RunBashCommandTool,
|
57
|
-
RunPowershellCommandTool,
|
58
|
-
GetFileOutlineTool,
|
59
|
-
SearchOutlineTool,
|
60
|
-
SearchTextTool,
|
61
|
-
ValidateFileSyntaxTool,
|
62
|
-
]:
|
63
|
-
local_tools_adapter.register_tool(tool_class)
|
64
|
-
|
65
|
-
# DEBUG: Print registered tools at startup
|
66
|
-
|
1
|
+
from .adapter import LocalToolsAdapter
|
2
|
+
|
3
|
+
from .ask_user import AskUserTool
|
4
|
+
from .copy_file import CopyFileTool
|
5
|
+
from .create_directory import CreateDirectoryTool
|
6
|
+
from .create_file import CreateFileTool
|
7
|
+
from .fetch_url import FetchUrlTool
|
8
|
+
from .find_files import FindFilesTool
|
9
|
+
from .view_file import ViewFileTool
|
10
|
+
from .read_files import ReadFilesTool
|
11
|
+
from .move_file import MoveFileTool
|
12
|
+
from .open_url import OpenUrlTool
|
13
|
+
from .open_html_in_browser import OpenHtmlInBrowserTool
|
14
|
+
from .python_code_run import PythonCodeRunTool
|
15
|
+
from .python_command_run import PythonCommandRunTool
|
16
|
+
from .python_file_run import PythonFileRunTool
|
17
|
+
from .remove_directory import RemoveDirectoryTool
|
18
|
+
from .remove_file import RemoveFileTool
|
19
|
+
from .replace_text_in_file import ReplaceTextInFileTool
|
20
|
+
from .run_bash_command import RunBashCommandTool
|
21
|
+
from .run_powershell_command import RunPowershellCommandTool
|
22
|
+
from .get_file_outline.core import GetFileOutlineTool
|
23
|
+
from .get_file_outline.search_outline import SearchOutlineTool
|
24
|
+
from .search_text.core import SearchTextTool
|
25
|
+
from .validate_file_syntax.core import ValidateFileSyntaxTool
|
26
|
+
|
27
|
+
from janito.tools.tool_base import ToolPermissions
|
28
|
+
import os
|
29
|
+
from janito.tools.permissions import get_global_allowed_permissions
|
30
|
+
|
31
|
+
# Singleton tools adapter with all standard tools registered
|
32
|
+
local_tools_adapter = LocalToolsAdapter(workdir=os.getcwd())
|
33
|
+
|
34
|
+
def get_local_tools_adapter(workdir=None):
|
35
|
+
return LocalToolsAdapter(workdir=workdir or os.getcwd())
|
36
|
+
|
37
|
+
# Register tools
|
38
|
+
for tool_class in [
|
39
|
+
AskUserTool,
|
40
|
+
CopyFileTool,
|
41
|
+
CreateDirectoryTool,
|
42
|
+
CreateFileTool,
|
43
|
+
FetchUrlTool,
|
44
|
+
FindFilesTool,
|
45
|
+
ViewFileTool,
|
46
|
+
ReadFilesTool,
|
47
|
+
MoveFileTool,
|
48
|
+
OpenUrlTool,
|
49
|
+
OpenHtmlInBrowserTool,
|
50
|
+
PythonCodeRunTool,
|
51
|
+
PythonCommandRunTool,
|
52
|
+
PythonFileRunTool,
|
53
|
+
RemoveDirectoryTool,
|
54
|
+
RemoveFileTool,
|
55
|
+
ReplaceTextInFileTool,
|
56
|
+
RunBashCommandTool,
|
57
|
+
RunPowershellCommandTool,
|
58
|
+
GetFileOutlineTool,
|
59
|
+
SearchOutlineTool,
|
60
|
+
SearchTextTool,
|
61
|
+
ValidateFileSyntaxTool,
|
62
|
+
]:
|
63
|
+
local_tools_adapter.register_tool(tool_class)
|
64
|
+
|
65
|
+
# DEBUG: Print registered tools at startup
|
66
|
+
|
@@ -55,7 +55,7 @@ class MoveFileTool(ToolBase):
|
|
55
55
|
disp_src=disp_src,
|
56
56
|
disp_dest=disp_dest,
|
57
57
|
),
|
58
|
-
ReportAction.
|
58
|
+
ReportAction.UPDATE,
|
59
59
|
)
|
60
60
|
shutil.move(src, dest)
|
61
61
|
self.report_success(tr("✅ Move complete."))
|
@@ -106,7 +106,7 @@ class MoveFileTool(ToolBase):
|
|
106
106
|
"❗ Destination '{disp_dest}' exists and overwrite is False.",
|
107
107
|
disp_dest=disp_dest,
|
108
108
|
),
|
109
|
-
ReportAction.
|
109
|
+
ReportAction.UPDATE,
|
110
110
|
)
|
111
111
|
return None, tr(
|
112
112
|
"❗ Destination '{disp_dest}' already exists and overwrite is False.",
|
@@ -121,7 +121,7 @@ class MoveFileTool(ToolBase):
|
|
121
121
|
except Exception as e:
|
122
122
|
self.report_error(
|
123
123
|
tr("❌ Error removing destination before move: {error}", error=e),
|
124
|
-
ReportAction.
|
124
|
+
ReportAction.UPDATE,
|
125
125
|
)
|
126
126
|
return None, tr(
|
127
127
|
"❌ Error removing destination before move: {error}", error=e
|
@@ -1,40 +1,40 @@
|
|
1
|
-
from janito.tools.tool_base import ToolBase, ToolPermissions
|
2
|
-
from janito.report_events import ReportAction
|
3
|
-
from janito.tools.adapters.local.adapter import register_local_tool
|
4
|
-
from janito.tools.tool_utils import pluralize
|
5
|
-
from janito.i18n import tr
|
6
|
-
|
7
|
-
@register_local_tool
|
8
|
-
class ReadFilesTool(ToolBase):
|
9
|
-
"""
|
10
|
-
Read all text content from multiple files.
|
11
|
-
|
12
|
-
Args:
|
13
|
-
paths (list[str]): List of file paths to read.
|
14
|
-
|
15
|
-
Returns:
|
16
|
-
str: Concatenated content of all files, each prefixed by a header with the file name. If a file cannot be read, an error message is included for that file.
|
17
|
-
"""
|
18
|
-
permissions = ToolPermissions(read=True)
|
19
|
-
tool_name = "read_files"
|
20
|
-
|
21
|
-
def run(self, paths: list[str]) -> str:
|
22
|
-
from janito.tools.tool_utils import display_path
|
23
|
-
import os
|
24
|
-
results = []
|
25
|
-
for path in paths:
|
26
|
-
disp_path = display_path(path)
|
27
|
-
self.report_action(tr("📖 Read '{disp_path}'", disp_path=disp_path), ReportAction.READ)
|
28
|
-
if not os.path.isfile(path):
|
29
|
-
self.report_warning(tr("❗ not found: {disp_path}", disp_path=disp_path))
|
30
|
-
results.append(f"--- File: {disp_path} (not found) ---\n")
|
31
|
-
continue
|
32
|
-
try:
|
33
|
-
with open(path, "r", encoding="utf-8", errors="replace") as f:
|
34
|
-
content = f.read()
|
35
|
-
results.append(f"--- File: {disp_path} ---\n{content}\n")
|
36
|
-
self.report_success(tr("✅ Read {disp_path}", disp_path=disp_path))
|
37
|
-
except Exception as e:
|
38
|
-
self.report_error(tr(" ❌ Error reading {disp_path}: {error}", disp_path=disp_path, error=e))
|
39
|
-
results.append(f"--- File: {disp_path} (error) ---\nError reading file: {e}\n")
|
40
|
-
return "\n".join(results)
|
1
|
+
from janito.tools.tool_base import ToolBase, ToolPermissions
|
2
|
+
from janito.report_events import ReportAction
|
3
|
+
from janito.tools.adapters.local.adapter import register_local_tool
|
4
|
+
from janito.tools.tool_utils import pluralize
|
5
|
+
from janito.i18n import tr
|
6
|
+
|
7
|
+
@register_local_tool
|
8
|
+
class ReadFilesTool(ToolBase):
|
9
|
+
"""
|
10
|
+
Read all text content from multiple files.
|
11
|
+
|
12
|
+
Args:
|
13
|
+
paths (list[str]): List of file paths to read.
|
14
|
+
|
15
|
+
Returns:
|
16
|
+
str: Concatenated content of all files, each prefixed by a header with the file name. If a file cannot be read, an error message is included for that file.
|
17
|
+
"""
|
18
|
+
permissions = ToolPermissions(read=True)
|
19
|
+
tool_name = "read_files"
|
20
|
+
|
21
|
+
def run(self, paths: list[str]) -> str:
|
22
|
+
from janito.tools.tool_utils import display_path
|
23
|
+
import os
|
24
|
+
results = []
|
25
|
+
for path in paths:
|
26
|
+
disp_path = display_path(path)
|
27
|
+
self.report_action(tr("📖 Read '{disp_path}'", disp_path=disp_path), ReportAction.READ)
|
28
|
+
if not os.path.isfile(path):
|
29
|
+
self.report_warning(tr("❗ not found: {disp_path}", disp_path=disp_path))
|
30
|
+
results.append(f"--- File: {disp_path} (not found) ---\n")
|
31
|
+
continue
|
32
|
+
try:
|
33
|
+
with open(path, "r", encoding="utf-8", errors="replace") as f:
|
34
|
+
content = f.read()
|
35
|
+
results.append(f"--- File: {disp_path} ---\n{content}\n")
|
36
|
+
self.report_success(tr("✅ Read {disp_path}", disp_path=disp_path))
|
37
|
+
except Exception as e:
|
38
|
+
self.report_error(tr(" ❌ Error reading {disp_path}: {error}", disp_path=disp_path, error=e))
|
39
|
+
results.append(f"--- File: {disp_path} (error) ---\nError reading file: {e}\n")
|
40
|
+
return "\n".join(results)
|