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.
Files changed (33) hide show
  1. janito/__init__.py +1 -0
  2. janito/__main__.py +1 -0
  3. janito/_version.py +1 -0
  4. janito/agent/setup_agent.py +240 -230
  5. janito/agent/templates/profiles/{system_prompt_template_software_developer.txt.j2 → system_prompt_template_plain_software_developer.txt.j2} +39 -39
  6. janito/cli/__init__.py +1 -0
  7. janito/cli/chat_mode/bindings.py +1 -0
  8. janito/cli/chat_mode/chat_entry.py +1 -0
  9. janito/cli/chat_mode/prompt_style.py +1 -0
  10. janito/cli/chat_mode/script_runner.py +1 -0
  11. janito/cli/chat_mode/session.py +282 -282
  12. janito/cli/chat_mode/session_profile_select.py +5 -5
  13. janito/cli/single_shot_mode/handler.py +95 -95
  14. janito/drivers/driver_registry.py +27 -27
  15. janito/drivers/openai/driver.py +435 -435
  16. janito/provider_registry.py +178 -178
  17. janito/providers/__init__.py +1 -0
  18. janito/providers/anthropic/model_info.py +41 -41
  19. janito/providers/anthropic/provider.py +80 -80
  20. janito/providers/moonshotai/__init__.py +1 -0
  21. janito/providers/moonshotai/model_info.py +15 -0
  22. janito/providers/moonshotai/provider.py +82 -0
  23. janito/providers/openai/model_info.py +1 -0
  24. janito/providers/provider_static_info.py +21 -18
  25. janito/tools/adapters/local/__init__.py +66 -66
  26. janito/tools/adapters/local/move_file.py +3 -3
  27. janito/tools/adapters/local/read_files.py +40 -40
  28. {janito-2.6.0.dist-info → janito-2.7.0.dist-info}/METADATA +419 -412
  29. {janito-2.6.0.dist-info → janito-2.7.0.dist-info}/RECORD +33 -30
  30. {janito-2.6.0.dist-info → janito-2.7.0.dist-info}/WHEEL +0 -0
  31. {janito-2.6.0.dist-info → janito-2.7.0.dist-info}/entry_points.txt +0 -0
  32. {janito-2.6.0.dist-info → janito-2.7.0.dist-info}/licenses/LICENSE +0 -0
  33. {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)
@@ -123,4 +123,5 @@ MODEL_SPECS = {
123
123
  open="openai",
124
124
  driver="OpenAIModelDriver",
125
125
  ),
126
+
126
127
  }
@@ -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
- "google": {
6
- "maintainer": "João Pinto <lamego.pinto@gmail.com>",
7
- },
8
- "azure_openai": {
9
- "maintainer": "João Pinto <lamego.pinto@gmail.com>",
10
- },
11
- "anthropic": {
12
- "maintainer": "Alberto Minetti <alberto.minetti@gmail.com>",
13
- },
14
-
15
- "deepseek": {
16
- "maintainer": "João Pinto <lamego.pinto@gmail.com>",
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.CREATE,
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.MOVE,
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.MOVE,
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)