janito 2.3.0__py3-none-any.whl → 2.3.1__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 (93) hide show
  1. janito/__init__.py +6 -6
  2. janito/cli/chat_mode/shell/autocomplete.py +21 -21
  3. janito/cli/chat_mode/shell/commands/clear.py +12 -12
  4. janito/cli/chat_mode/shell/commands/multi.py +51 -51
  5. janito/cli/chat_mode/shell/input_history.py +62 -62
  6. janito/cli/cli_commands/list_models.py +35 -35
  7. janito/cli/cli_commands/list_providers.py +9 -9
  8. janito/cli/cli_commands/list_tools.py +53 -53
  9. janito/cli/cli_commands/model_selection.py +50 -50
  10. janito/cli/cli_commands/model_utils.py +95 -95
  11. janito/cli/cli_commands/set_api_key.py +19 -19
  12. janito/cli/cli_commands/show_config.py +51 -51
  13. janito/cli/cli_commands/show_system_prompt.py +62 -62
  14. janito/cli/core/__init__.py +4 -4
  15. janito/cli/core/event_logger.py +59 -59
  16. janito/cli/core/getters.py +33 -33
  17. janito/cli/core/unsetters.py +54 -54
  18. janito/cli/single_shot_mode/__init__.py +6 -6
  19. janito/config.py +5 -5
  20. janito/config_manager.py +112 -112
  21. janito/drivers/anthropic/driver.py +113 -113
  22. janito/formatting_token.py +54 -54
  23. janito/i18n/__init__.py +35 -35
  24. janito/i18n/messages.py +23 -23
  25. janito/i18n/pt.py +47 -47
  26. janito/llm/__init__.py +5 -5
  27. janito/llm/agent.py +443 -443
  28. janito/llm/auth.py +63 -63
  29. janito/llm/driver_config_builder.py +34 -34
  30. janito/llm/driver_input.py +12 -12
  31. janito/llm/message_parts.py +60 -60
  32. janito/llm/model.py +38 -38
  33. janito/llm/provider.py +196 -196
  34. janito/provider_registry.py +176 -176
  35. janito/providers/anthropic/model_info.py +22 -22
  36. janito/providers/anthropic/provider.py +2 -0
  37. janito/providers/azure_openai/model_info.py +16 -16
  38. janito/providers/azure_openai/provider.py +3 -0
  39. janito/providers/deepseek/__init__.py +1 -1
  40. janito/providers/deepseek/model_info.py +16 -16
  41. janito/providers/deepseek/provider.py +94 -91
  42. janito/providers/google/provider.py +3 -0
  43. janito/providers/mistralai/provider.py +3 -0
  44. janito/providers/openai/provider.py +4 -0
  45. janito/tools/adapters/__init__.py +1 -1
  46. janito/tools/adapters/local/ask_user.py +102 -102
  47. janito/tools/adapters/local/copy_file.py +84 -84
  48. janito/tools/adapters/local/create_directory.py +69 -69
  49. janito/tools/adapters/local/create_file.py +82 -82
  50. janito/tools/adapters/local/fetch_url.py +97 -97
  51. janito/tools/adapters/local/find_files.py +138 -138
  52. janito/tools/adapters/local/get_file_outline/__init__.py +1 -1
  53. janito/tools/adapters/local/get_file_outline/core.py +117 -117
  54. janito/tools/adapters/local/get_file_outline/java_outline.py +40 -40
  55. janito/tools/adapters/local/get_file_outline/markdown_outline.py +14 -14
  56. janito/tools/adapters/local/get_file_outline/python_outline.py +303 -303
  57. janito/tools/adapters/local/get_file_outline/python_outline_v2.py +156 -156
  58. janito/tools/adapters/local/get_file_outline/search_outline.py +33 -33
  59. janito/tools/adapters/local/python_code_run.py +166 -166
  60. janito/tools/adapters/local/python_command_run.py +164 -164
  61. janito/tools/adapters/local/python_file_run.py +163 -163
  62. janito/tools/adapters/local/run_bash_command.py +176 -176
  63. janito/tools/adapters/local/run_powershell_command.py +219 -219
  64. janito/tools/adapters/local/search_text/__init__.py +1 -1
  65. janito/tools/adapters/local/search_text/core.py +201 -201
  66. janito/tools/adapters/local/search_text/pattern_utils.py +73 -73
  67. janito/tools/adapters/local/search_text/traverse_directory.py +145 -145
  68. janito/tools/adapters/local/validate_file_syntax/__init__.py +1 -1
  69. janito/tools/adapters/local/validate_file_syntax/core.py +106 -106
  70. janito/tools/adapters/local/validate_file_syntax/css_validator.py +35 -35
  71. janito/tools/adapters/local/validate_file_syntax/html_validator.py +93 -93
  72. janito/tools/adapters/local/validate_file_syntax/js_validator.py +27 -27
  73. janito/tools/adapters/local/validate_file_syntax/json_validator.py +6 -6
  74. janito/tools/adapters/local/validate_file_syntax/markdown_validator.py +109 -109
  75. janito/tools/adapters/local/validate_file_syntax/ps1_validator.py +32 -32
  76. janito/tools/adapters/local/validate_file_syntax/python_validator.py +5 -5
  77. janito/tools/adapters/local/validate_file_syntax/xml_validator.py +11 -11
  78. janito/tools/adapters/local/validate_file_syntax/yaml_validator.py +6 -6
  79. janito/tools/adapters/local/view_file.py +167 -167
  80. janito/tools/inspect_registry.py +17 -17
  81. janito/tools/tool_base.py +105 -105
  82. janito/tools/tool_events.py +58 -58
  83. janito/tools/tool_run_exception.py +12 -12
  84. janito/tools/tool_use_tracker.py +81 -81
  85. janito/tools/tool_utils.py +45 -45
  86. janito/tools/tools_schema.py +104 -104
  87. janito/version.py +4 -4
  88. {janito-2.3.0.dist-info → janito-2.3.1.dist-info}/METADATA +390 -388
  89. {janito-2.3.0.dist-info → janito-2.3.1.dist-info}/RECORD +93 -93
  90. {janito-2.3.0.dist-info → janito-2.3.1.dist-info}/WHEEL +0 -0
  91. {janito-2.3.0.dist-info → janito-2.3.1.dist-info}/entry_points.txt +0 -0
  92. {janito-2.3.0.dist-info → janito-2.3.1.dist-info}/licenses/LICENSE +0 -0
  93. {janito-2.3.0.dist-info → janito-2.3.1.dist-info}/top_level.txt +0 -0
@@ -1,156 +1,156 @@
1
- import re
2
- from typing import List
3
-
4
-
5
- def extract_signature_and_decorators(lines, start_idx):
6
- """
7
- Extracts the signature line and leading decorators for a given function/class/method.
8
- Returns (signature:str, decorators:List[str], signature_lineno:int)
9
- """
10
- decorators = []
11
- sig_line = None
12
- sig_lineno = start_idx
13
- for i in range(start_idx - 1, -1, -1):
14
- striped = lines[i].strip()
15
- if striped.startswith("@"):
16
- decorators.insert(0, striped)
17
- sig_lineno = i
18
- elif not striped:
19
- continue
20
- else:
21
- break
22
- # Find the signature line itself
23
- for k in range(start_idx, len(lines)):
24
- striped = lines[k].strip()
25
- if striped.startswith("def ") or striped.startswith("class "):
26
- sig_line = striped
27
- sig_lineno = k
28
- break
29
- return sig_line, decorators, sig_lineno
30
-
31
-
32
- def extract_docstring(lines, start_idx, end_idx):
33
- """Extracts a docstring from lines[start_idx:end_idx] if present."""
34
- for i in range(start_idx, min(end_idx, len(lines))):
35
- line = lines[i].lstrip()
36
- if not line:
37
- continue
38
- if line.startswith('"""') or line.startswith("'''"):
39
- quote = line[:3]
40
- doc = line[3:]
41
- if doc.strip().endswith(quote):
42
- return doc.strip()[:-3].strip()
43
- docstring_lines = [doc]
44
- for j in range(i + 1, min(end_idx, len(lines))):
45
- line = lines[j]
46
- if line.strip().endswith(quote):
47
- docstring_lines.append(line.strip()[:-3])
48
- return "\n".join([d.strip() for d in docstring_lines]).strip()
49
- docstring_lines.append(line)
50
- break
51
- else:
52
- break
53
- return ""
54
-
55
-
56
- def build_outline_entry(obj, lines, outline):
57
- obj_type, name, start, end, parent, indent = obj
58
- # Determine if this is a method
59
- if obj_type == "function" and parent:
60
- outline_type = "method"
61
- elif obj_type == "function":
62
- outline_type = "function"
63
- else:
64
- outline_type = obj_type
65
- docstring = extract_docstring(lines, start, end)
66
- signature, decorators, signature_lineno = extract_signature_and_decorators(
67
- lines, start - 1
68
- )
69
- outline.append(
70
- {
71
- "type": outline_type,
72
- "name": name,
73
- "start": start,
74
- "end": end,
75
- "parent": parent,
76
- "signature": signature,
77
- "decorators": decorators,
78
- "docstring": docstring,
79
- }
80
- )
81
-
82
-
83
- def parse_python_outline_v2(lines: List[str]):
84
- class_pat = re.compile(r"^(\s*)class\s+(\w+)")
85
- func_pat = re.compile(r"^(\s*)def\s+(\w+)")
86
- assign_pat = re.compile(r"^(\s*)([A-Za-z_][A-Za-z0-9_]*)\s*=.*")
87
- main_pat = re.compile(r"^\s*if\s+__name__\s*==\s*[\'\"]__main__[\'\"]\s*:")
88
- outline = []
89
- stack = []
90
- obj_ranges = []
91
- last_top_obj = None
92
- for idx, line in enumerate(lines):
93
- class_match = class_pat.match(line)
94
- func_match = func_pat.match(line)
95
- assign_match = assign_pat.match(line)
96
- indent = len(line) - len(line.lstrip())
97
- parent = ""
98
- for s in reversed(stack):
99
- if s[0] == "class" and indent > s[2]:
100
- parent = s[1]
101
- break
102
- if class_match:
103
- obj = ("class", class_match.group(2), idx + 1, None, parent, indent)
104
- stack.append(obj)
105
- last_top_obj = obj
106
- elif func_match:
107
- obj = ("function", func_match.group(2), idx + 1, None, parent, indent)
108
- stack.append(obj)
109
- last_top_obj = obj
110
- elif assign_match and indent == 0:
111
- outline.append(
112
- {
113
- "type": "const" if assign_match.group(2).isupper() else "var",
114
- "name": assign_match.group(2),
115
- "start": idx + 1,
116
- "end": idx + 1,
117
- "parent": "",
118
- "signature": line.strip(),
119
- "decorators": [],
120
- "docstring": "",
121
- }
122
- )
123
- if line.strip().startswith("if __name__ == "):
124
- outline.append(
125
- {
126
- "type": "main",
127
- "name": "__main__",
128
- "start": idx + 1,
129
- "end": idx + 1,
130
- "parent": "",
131
- "signature": line.strip(),
132
- "decorators": [],
133
- "docstring": "",
134
- }
135
- )
136
- # Close stack objects if indent falls back
137
- while stack and indent <= stack[-1][5] and idx + 1 > stack[-1][2]:
138
- finished = stack.pop()
139
- outline_entry = finished[:2] + (
140
- finished[2],
141
- idx + 1,
142
- finished[4],
143
- finished[5],
144
- )
145
- build_outline_entry(outline_entry, lines, outline)
146
- # Close any remaining objects
147
- while stack:
148
- finished = stack.pop()
149
- outline_entry = finished[:2] + (
150
- finished[2],
151
- len(lines),
152
- finished[4],
153
- finished[5],
154
- )
155
- build_outline_entry(outline_entry, lines, outline)
156
- return outline
1
+ import re
2
+ from typing import List
3
+
4
+
5
+ def extract_signature_and_decorators(lines, start_idx):
6
+ """
7
+ Extracts the signature line and leading decorators for a given function/class/method.
8
+ Returns (signature:str, decorators:List[str], signature_lineno:int)
9
+ """
10
+ decorators = []
11
+ sig_line = None
12
+ sig_lineno = start_idx
13
+ for i in range(start_idx - 1, -1, -1):
14
+ striped = lines[i].strip()
15
+ if striped.startswith("@"):
16
+ decorators.insert(0, striped)
17
+ sig_lineno = i
18
+ elif not striped:
19
+ continue
20
+ else:
21
+ break
22
+ # Find the signature line itself
23
+ for k in range(start_idx, len(lines)):
24
+ striped = lines[k].strip()
25
+ if striped.startswith("def ") or striped.startswith("class "):
26
+ sig_line = striped
27
+ sig_lineno = k
28
+ break
29
+ return sig_line, decorators, sig_lineno
30
+
31
+
32
+ def extract_docstring(lines, start_idx, end_idx):
33
+ """Extracts a docstring from lines[start_idx:end_idx] if present."""
34
+ for i in range(start_idx, min(end_idx, len(lines))):
35
+ line = lines[i].lstrip()
36
+ if not line:
37
+ continue
38
+ if line.startswith('"""') or line.startswith("'''"):
39
+ quote = line[:3]
40
+ doc = line[3:]
41
+ if doc.strip().endswith(quote):
42
+ return doc.strip()[:-3].strip()
43
+ docstring_lines = [doc]
44
+ for j in range(i + 1, min(end_idx, len(lines))):
45
+ line = lines[j]
46
+ if line.strip().endswith(quote):
47
+ docstring_lines.append(line.strip()[:-3])
48
+ return "\n".join([d.strip() for d in docstring_lines]).strip()
49
+ docstring_lines.append(line)
50
+ break
51
+ else:
52
+ break
53
+ return ""
54
+
55
+
56
+ def build_outline_entry(obj, lines, outline):
57
+ obj_type, name, start, end, parent, indent = obj
58
+ # Determine if this is a method
59
+ if obj_type == "function" and parent:
60
+ outline_type = "method"
61
+ elif obj_type == "function":
62
+ outline_type = "function"
63
+ else:
64
+ outline_type = obj_type
65
+ docstring = extract_docstring(lines, start, end)
66
+ signature, decorators, signature_lineno = extract_signature_and_decorators(
67
+ lines, start - 1
68
+ )
69
+ outline.append(
70
+ {
71
+ "type": outline_type,
72
+ "name": name,
73
+ "start": start,
74
+ "end": end,
75
+ "parent": parent,
76
+ "signature": signature,
77
+ "decorators": decorators,
78
+ "docstring": docstring,
79
+ }
80
+ )
81
+
82
+
83
+ def parse_python_outline_v2(lines: List[str]):
84
+ class_pat = re.compile(r"^(\s*)class\s+(\w+)")
85
+ func_pat = re.compile(r"^(\s*)def\s+(\w+)")
86
+ assign_pat = re.compile(r"^(\s*)([A-Za-z_][A-Za-z0-9_]*)\s*=.*")
87
+ main_pat = re.compile(r"^\s*if\s+__name__\s*==\s*[\'\"]__main__[\'\"]\s*:")
88
+ outline = []
89
+ stack = []
90
+ obj_ranges = []
91
+ last_top_obj = None
92
+ for idx, line in enumerate(lines):
93
+ class_match = class_pat.match(line)
94
+ func_match = func_pat.match(line)
95
+ assign_match = assign_pat.match(line)
96
+ indent = len(line) - len(line.lstrip())
97
+ parent = ""
98
+ for s in reversed(stack):
99
+ if s[0] == "class" and indent > s[2]:
100
+ parent = s[1]
101
+ break
102
+ if class_match:
103
+ obj = ("class", class_match.group(2), idx + 1, None, parent, indent)
104
+ stack.append(obj)
105
+ last_top_obj = obj
106
+ elif func_match:
107
+ obj = ("function", func_match.group(2), idx + 1, None, parent, indent)
108
+ stack.append(obj)
109
+ last_top_obj = obj
110
+ elif assign_match and indent == 0:
111
+ outline.append(
112
+ {
113
+ "type": "const" if assign_match.group(2).isupper() else "var",
114
+ "name": assign_match.group(2),
115
+ "start": idx + 1,
116
+ "end": idx + 1,
117
+ "parent": "",
118
+ "signature": line.strip(),
119
+ "decorators": [],
120
+ "docstring": "",
121
+ }
122
+ )
123
+ if line.strip().startswith("if __name__ == "):
124
+ outline.append(
125
+ {
126
+ "type": "main",
127
+ "name": "__main__",
128
+ "start": idx + 1,
129
+ "end": idx + 1,
130
+ "parent": "",
131
+ "signature": line.strip(),
132
+ "decorators": [],
133
+ "docstring": "",
134
+ }
135
+ )
136
+ # Close stack objects if indent falls back
137
+ while stack and indent <= stack[-1][5] and idx + 1 > stack[-1][2]:
138
+ finished = stack.pop()
139
+ outline_entry = finished[:2] + (
140
+ finished[2],
141
+ idx + 1,
142
+ finished[4],
143
+ finished[5],
144
+ )
145
+ build_outline_entry(outline_entry, lines, outline)
146
+ # Close any remaining objects
147
+ while stack:
148
+ finished = stack.pop()
149
+ outline_entry = finished[:2] + (
150
+ finished[2],
151
+ len(lines),
152
+ finished[4],
153
+ finished[5],
154
+ )
155
+ build_outline_entry(outline_entry, lines, outline)
156
+ return outline
@@ -1,33 +1,33 @@
1
- from janito.tools.tool_base import ToolBase
2
- from janito.report_events import ReportAction
3
-
4
-
5
- class SearchOutlineTool(ToolBase):
6
- """
7
- Tool for searching outlines in files.
8
-
9
- Args:
10
- file_path (str): Path to the file for which to generate an outline.
11
- Returns:
12
- str: Outline search result or status message.
13
- """
14
-
15
- tool_name = "search_outline"
16
-
17
- def run(self, file_path: str) -> str:
18
- from janito.tools.tool_utils import display_path
19
- from janito.i18n import tr
20
-
21
- self.report_action(
22
- tr(
23
- "🔍 Searching for outline in '{disp_path}'",
24
- disp_path=display_path(file_path),
25
- ),
26
- ReportAction.READ,
27
- )
28
- # ... rest of implementation ...
29
- # Example warnings and successes:
30
- # self.report_warning(tr("No files found with supported extensions."))
31
- # self.report_warning(tr("Error reading {file_path}: {error}", file_path=file_path, error=e))
32
- # self.report_success(tr("✅ {count} {match_word} found", count=len(output), match_word=pluralize('match', len(output))))
33
- pass
1
+ from janito.tools.tool_base import ToolBase
2
+ from janito.report_events import ReportAction
3
+
4
+
5
+ class SearchOutlineTool(ToolBase):
6
+ """
7
+ Tool for searching outlines in files.
8
+
9
+ Args:
10
+ file_path (str): Path to the file for which to generate an outline.
11
+ Returns:
12
+ str: Outline search result or status message.
13
+ """
14
+
15
+ tool_name = "search_outline"
16
+
17
+ def run(self, file_path: str) -> str:
18
+ from janito.tools.tool_utils import display_path
19
+ from janito.i18n import tr
20
+
21
+ self.report_action(
22
+ tr(
23
+ "🔍 Searching for outline in '{disp_path}'",
24
+ disp_path=display_path(file_path),
25
+ ),
26
+ ReportAction.READ,
27
+ )
28
+ # ... rest of implementation ...
29
+ # Example warnings and successes:
30
+ # self.report_warning(tr("No files found with supported extensions."))
31
+ # self.report_warning(tr("Error reading {file_path}: {error}", file_path=file_path, error=e))
32
+ # self.report_success(tr("✅ {count} {match_word} found", count=len(output), match_word=pluralize('match', len(output))))
33
+ pass