janito 1.9.0__py3-none-any.whl → 1.11.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 (106) hide show
  1. janito/__init__.py +1 -1
  2. janito/agent/api_exceptions.py +4 -0
  3. janito/agent/config.py +1 -1
  4. janito/agent/config_defaults.py +2 -26
  5. janito/agent/conversation.py +163 -122
  6. janito/agent/conversation_api.py +246 -168
  7. janito/agent/conversation_ui.py +1 -1
  8. janito/agent/{conversation_history.py → llm_conversation_history.py} +30 -1
  9. janito/agent/openai_client.py +38 -23
  10. janito/agent/openai_schema_generator.py +162 -129
  11. janito/agent/platform_discovery.py +134 -77
  12. janito/agent/profile_manager.py +5 -5
  13. janito/agent/rich_message_handler.py +80 -31
  14. janito/agent/templates/profiles/system_prompt_template_base.txt.j2 +20 -4
  15. janito/agent/test_openai_schema_generator.py +93 -0
  16. janito/agent/tool_base.py +7 -2
  17. janito/agent/tool_executor.py +54 -49
  18. janito/agent/tool_registry.py +5 -2
  19. janito/agent/tool_use_tracker.py +26 -5
  20. janito/agent/tools/__init__.py +8 -3
  21. janito/agent/tools/create_directory.py +3 -1
  22. janito/agent/tools/create_file.py +7 -1
  23. janito/agent/tools/fetch_url.py +40 -3
  24. janito/agent/tools/find_files.py +29 -14
  25. janito/agent/tools/get_file_outline/core.py +7 -8
  26. janito/agent/tools/get_file_outline/python_outline.py +139 -95
  27. janito/agent/tools/get_file_outline/search_outline.py +3 -1
  28. janito/agent/tools/get_lines.py +98 -64
  29. janito/agent/tools/move_file.py +59 -31
  30. janito/agent/tools/open_url.py +31 -0
  31. janito/agent/tools/present_choices.py +3 -1
  32. janito/agent/tools/python_command_runner.py +149 -0
  33. janito/agent/tools/python_file_runner.py +147 -0
  34. janito/agent/tools/python_stdin_runner.py +153 -0
  35. janito/agent/tools/remove_directory.py +3 -1
  36. janito/agent/tools/remove_file.py +5 -1
  37. janito/agent/tools/replace_file.py +12 -2
  38. janito/agent/tools/replace_text_in_file.py +195 -149
  39. janito/agent/tools/run_bash_command.py +30 -69
  40. janito/agent/tools/run_powershell_command.py +138 -105
  41. janito/agent/tools/search_text/__init__.py +1 -0
  42. janito/agent/tools/search_text/core.py +176 -0
  43. janito/agent/tools/search_text/match_lines.py +58 -0
  44. janito/agent/tools/search_text/pattern_utils.py +65 -0
  45. janito/agent/tools/search_text/traverse_directory.py +127 -0
  46. janito/agent/tools/validate_file_syntax/core.py +43 -30
  47. janito/agent/tools/validate_file_syntax/html_validator.py +21 -5
  48. janito/agent/tools/validate_file_syntax/markdown_validator.py +77 -34
  49. janito/agent/tools_utils/action_type.py +7 -0
  50. janito/agent/tools_utils/dir_walk_utils.py +3 -2
  51. janito/agent/tools_utils/formatting.py +47 -21
  52. janito/agent/tools_utils/gitignore_utils.py +89 -40
  53. janito/agent/tools_utils/test_gitignore_utils.py +46 -0
  54. janito/agent/tools_utils/utils.py +7 -1
  55. janito/cli/_print_config.py +63 -61
  56. janito/cli/arg_parser.py +13 -12
  57. janito/cli/cli_main.py +137 -147
  58. janito/cli/config_commands.py +112 -109
  59. janito/cli/main.py +152 -174
  60. janito/cli/one_shot.py +40 -26
  61. janito/i18n/__init__.py +1 -1
  62. janito/rich_utils.py +46 -8
  63. janito/shell/commands/__init__.py +2 -4
  64. janito/shell/commands/conversation_restart.py +3 -1
  65. janito/shell/commands/edit.py +3 -0
  66. janito/shell/commands/history_view.py +3 -3
  67. janito/shell/commands/lang.py +3 -0
  68. janito/shell/commands/livelogs.py +5 -3
  69. janito/shell/commands/prompt.py +6 -0
  70. janito/shell/commands/session.py +3 -0
  71. janito/shell/commands/session_control.py +3 -0
  72. janito/shell/commands/termweb_log.py +8 -0
  73. janito/shell/commands/tools.py +3 -0
  74. janito/shell/commands/track.py +36 -0
  75. janito/shell/commands/utility.py +13 -18
  76. janito/shell/commands/verbose.py +3 -4
  77. janito/shell/input_history.py +62 -0
  78. janito/shell/main.py +160 -181
  79. janito/shell/session/config.py +83 -75
  80. janito/shell/session/manager.py +0 -21
  81. janito/shell/ui/interactive.py +97 -75
  82. janito/termweb/static/editor.css +32 -33
  83. janito/termweb/static/editor.css.bak +140 -22
  84. janito/termweb/static/editor.html +12 -7
  85. janito/termweb/static/editor.html.bak +16 -11
  86. janito/termweb/static/editor.js +94 -40
  87. janito/termweb/static/editor.js.bak +97 -65
  88. janito/termweb/static/index.html +1 -2
  89. janito/termweb/static/index.html.bak +1 -1
  90. janito/termweb/static/termweb.css +1 -22
  91. janito/termweb/static/termweb.css.bak +6 -4
  92. janito/termweb/static/termweb.js +0 -6
  93. janito/termweb/static/termweb.js.bak +1 -2
  94. janito/tests/test_rich_utils.py +44 -0
  95. janito/web/app.py +0 -75
  96. {janito-1.9.0.dist-info → janito-1.11.0.dist-info}/METADATA +61 -42
  97. janito-1.11.0.dist-info/RECORD +163 -0
  98. {janito-1.9.0.dist-info → janito-1.11.0.dist-info}/WHEEL +1 -1
  99. janito/agent/providers.py +0 -77
  100. janito/agent/tools/run_python_command.py +0 -161
  101. janito/agent/tools/search_text.py +0 -204
  102. janito/shell/commands/sum.py +0 -49
  103. janito-1.9.0.dist-info/RECORD +0 -151
  104. {janito-1.9.0.dist-info → janito-1.11.0.dist-info}/entry_points.txt +0 -0
  105. {janito-1.9.0.dist-info → janito-1.11.0.dist-info}/licenses/LICENSE +0 -0
  106. {janito-1.9.0.dist-info → janito-1.11.0.dist-info}/top_level.txt +0 -0
@@ -1,161 +0,0 @@
1
- import subprocess
2
- import tempfile
3
- import sys
4
- import os
5
- from janito.agent.tool_base import ToolBase
6
- from janito.agent.tool_registry import register_tool
7
- from janito.i18n import tr
8
-
9
-
10
- @register_tool(name="run_python_command")
11
- class RunPythonCommandTool(ToolBase):
12
- """
13
- Tool to execute Python code in a subprocess and capture output.
14
- Args:
15
- code (str): The Python code to execute.
16
- timeout (int, optional): Timeout in seconds for the command. Defaults to 60.
17
- require_confirmation (bool, optional): If True, require user confirmation before running. Defaults to False.
18
- interactive (bool, optional): If True, warns that the command may require user interaction. Defaults to False.
19
- Returns:
20
- str: File paths and line counts for stdout and stderr, or direct output if small enough.
21
- """
22
-
23
- def run(
24
- self,
25
- code: str,
26
- timeout: int = 60,
27
- require_confirmation: bool = False,
28
- interactive: bool = False,
29
- ) -> str:
30
- if not code.strip():
31
- self.report_warning(tr("ℹ️ Empty code provided."))
32
- return tr("Warning: Empty code provided. Operation skipped.")
33
- self.report_info(tr("🐍 Running Python code: ...\n{code}\n", code=code))
34
- if interactive:
35
- self.report_warning(
36
- tr(
37
- "⚠️ Warning: This code might be interactive, require user input, and might hang."
38
- )
39
- )
40
- sys.stdout.flush()
41
- if require_confirmation:
42
- confirmed = self.confirm_action(
43
- tr("Do you want to execute this Python code?")
44
- )
45
- if not confirmed:
46
- self.report_warning(tr("⚠️ Execution cancelled by user."))
47
- return tr("Execution cancelled by user.")
48
- try:
49
- with (
50
- tempfile.NamedTemporaryFile(
51
- mode="w+",
52
- suffix=".py",
53
- prefix="run_python_",
54
- delete=False,
55
- encoding="utf-8",
56
- ) as code_file,
57
- tempfile.NamedTemporaryFile(
58
- mode="w+",
59
- prefix="run_python_stdout_",
60
- delete=False,
61
- encoding="utf-8",
62
- ) as stdout_file,
63
- tempfile.NamedTemporaryFile(
64
- mode="w+",
65
- prefix="run_python_stderr_",
66
- delete=False,
67
- encoding="utf-8",
68
- ) as stderr_file,
69
- ):
70
- code_file.write(code)
71
- code_file.flush()
72
- env = os.environ.copy()
73
- env["PYTHONIOENCODING"] = "utf-8"
74
- process = subprocess.Popen(
75
- [sys.executable, code_file.name],
76
- stdout=stdout_file,
77
- stderr=stderr_file,
78
- text=True,
79
- env=env,
80
- )
81
- try:
82
- return_code = process.wait(timeout=timeout)
83
- except subprocess.TimeoutExpired:
84
- process.kill()
85
- self.report_error(
86
- tr(" ❌ Timed out after {timeout} seconds.", timeout=timeout)
87
- )
88
- return tr(
89
- "Code timed out after {timeout} seconds.", timeout=timeout
90
- )
91
- stdout_file.flush()
92
- stderr_file.flush()
93
- with open(
94
- stdout_file.name, "r", encoding="utf-8", errors="replace"
95
- ) as out_f:
96
- out_f.seek(0)
97
- for line in out_f:
98
- self.report_stdout(line)
99
- with open(
100
- stderr_file.name, "r", encoding="utf-8", errors="replace"
101
- ) as err_f:
102
- err_f.seek(0)
103
- for line in err_f:
104
- self.report_stderr(line)
105
- with open(
106
- stdout_file.name, "r", encoding="utf-8", errors="replace"
107
- ) as out_f:
108
- stdout_lines = sum(1 for _ in out_f)
109
- with open(
110
- stderr_file.name, "r", encoding="utf-8", errors="replace"
111
- ) as err_f:
112
- stderr_lines = sum(1 for _ in err_f)
113
- self.report_success(
114
- tr(" ✅ return code {return_code}", return_code=return_code)
115
- )
116
- warning_msg = ""
117
- if interactive:
118
- warning_msg = tr(
119
- "⚠️ Warning: This code might be interactive, require user input, and might hang.\n"
120
- )
121
- with open(
122
- stdout_file.name, "r", encoding="utf-8", errors="replace"
123
- ) as out_f:
124
- stdout_content = out_f.read()
125
- with open(
126
- stderr_file.name, "r", encoding="utf-8", errors="replace"
127
- ) as err_f:
128
- stderr_content = err_f.read()
129
- max_lines = 100
130
- if stdout_lines <= max_lines and stderr_lines <= max_lines:
131
- result = warning_msg + tr(
132
- "Return code: {return_code}\n--- STDOUT ---\n{stdout_content}",
133
- return_code=return_code,
134
- stdout_content=stdout_content,
135
- )
136
- if stderr_content.strip():
137
- result += tr(
138
- "\n--- STDERR ---\n{stderr_content}",
139
- stderr_content=stderr_content,
140
- )
141
- return result
142
- else:
143
- result = warning_msg + tr(
144
- "stdout_file: {stdout_file} (lines: {stdout_lines})\n",
145
- stdout_file=stdout_file.name,
146
- stdout_lines=stdout_lines,
147
- )
148
- if stderr_lines > 0 and stderr_content.strip():
149
- result += tr(
150
- "stderr_file: {stderr_file} (lines: {stderr_lines})\n",
151
- stderr_file=stderr_file.name,
152
- stderr_lines=stderr_lines,
153
- )
154
- result += tr(
155
- "returncode: {return_code}\nUse the get_lines tool to inspect the contents of these files when needed.",
156
- return_code=return_code,
157
- )
158
- return result
159
- except Exception as e:
160
- self.report_error(tr(" ❌ Error: {error}", error=e))
161
- return tr("Error running code: {error}", error=e)
@@ -1,204 +0,0 @@
1
- from janito.agent.tool_base import ToolBase
2
- from janito.agent.tool_registry import register_tool
3
- from janito.agent.tools_utils.utils import pluralize
4
- from janito.i18n import tr
5
- import os
6
- import re
7
- from janito.agent.tools_utils.gitignore_utils import filter_ignored
8
-
9
-
10
- def is_binary_file(path, blocksize=1024):
11
- try:
12
- with open(path, "rb") as f:
13
- chunk = f.read(blocksize)
14
- if b"\0" in chunk:
15
- return True
16
- text_characters = bytearray(
17
- {7, 8, 9, 10, 12, 13, 27} | set(range(0x20, 0x100))
18
- )
19
- nontext = chunk.translate(None, text_characters)
20
- if len(nontext) / max(1, len(chunk)) > 0.3:
21
- return True
22
- except Exception:
23
- return True
24
- return False
25
-
26
-
27
- @register_tool(name="search_text")
28
- class SearchTextTool(ToolBase):
29
- """
30
- Search for a text pattern (regex or plain string) in all files within one or more directories or file paths and return matching lines. Respects .gitignore.
31
-
32
- Args:
33
- paths (str): String of one or more paths (space-separated) to search in. Each path can be a directory or a file.
34
- pattern (str): Regex pattern or plain text substring to search for in files. Must not be empty. Tries regex first, falls back to substring if regex is invalid.
35
- Note: When using regex mode, special characters (such as [, ], ., *, etc.) must be escaped if you want to match them literally (e.g., use '\\[DEBUG\\]' to match the literal string '[DEBUG]').
36
- is_regex (bool): If True, treat pattern as regex. If False, treat as plain text. Defaults to False.
37
- max_depth (int, optional): Maximum directory depth to search. If 0 (default), search is recursive with no depth limit. If >0, limits recursion to that depth. Setting max_depth=1 disables recursion (only top-level directory). Ignored for file paths.
38
- max_results (int): Maximum number of results to return. 0 means no limit (default).
39
- ignore_utf8_errors (bool): If True, ignore utf-8 decode errors. Defaults to True.
40
- Returns:
41
- str: Matching lines from files as a newline-separated string, each formatted as 'filepath:lineno: line'.
42
- If max_results is reached, appends a note to the output.
43
- """
44
-
45
- def run(
46
- self,
47
- paths: str,
48
- pattern: str,
49
- is_regex: bool = False,
50
- max_depth: int = 0,
51
- max_results: int = 0,
52
- ignore_utf8_errors: bool = True,
53
- ) -> str:
54
- if not pattern:
55
- self.report_error(
56
- tr("Error: Empty search pattern provided. Operation aborted.")
57
- )
58
- return tr("Error: Empty search pattern provided. Operation aborted.")
59
- regex = None
60
- use_regex = False
61
- if is_regex:
62
- try:
63
- regex = re.compile(pattern)
64
- use_regex = True
65
- except re.error as e:
66
- self.report_warning(tr("⚠️ Invalid regex pattern."))
67
- return tr(
68
- "Warning: Invalid regex pattern: {error}. No results.", error=e
69
- )
70
- else:
71
- try:
72
- regex = re.compile(pattern)
73
- use_regex = True
74
- except re.error:
75
- regex = None
76
- use_regex = False
77
- output = []
78
- limit_reached = False
79
- total_results = 0
80
- paths_list = paths.split()
81
- for search_path in paths_list:
82
- from janito.agent.tools_utils.utils import display_path
83
-
84
- info_str = tr(
85
- "🔍 Searching for {search_type} '{pattern}' in '{disp_path}'",
86
- search_type=("text-regex" if use_regex else "text"),
87
- pattern=pattern,
88
- disp_path=display_path(search_path),
89
- )
90
- if max_depth > 0:
91
- info_str += tr(" [max_depth={max_depth}]", max_depth=max_depth)
92
- self.report_info(info_str)
93
- dir_output = []
94
- dir_limit_reached = False
95
- if os.path.isfile(search_path):
96
- # Handle single file
97
- path = search_path
98
- if not is_binary_file(path):
99
- try:
100
- open_kwargs = {"mode": "r", "encoding": "utf-8"}
101
- if ignore_utf8_errors:
102
- open_kwargs["errors"] = "ignore"
103
- with open(path, **open_kwargs) as f:
104
- for lineno, line in enumerate(f, 1):
105
- if use_regex:
106
- if regex.search(line):
107
- dir_output.append(
108
- f"{path}:{lineno}: {line.strip()}"
109
- )
110
- else:
111
- if pattern in line:
112
- dir_output.append(
113
- f"{path}:{lineno}: {line.strip()}"
114
- )
115
- if (
116
- max_results > 0
117
- and (total_results + len(dir_output)) >= max_results
118
- ):
119
- dir_limit_reached = True
120
- break
121
- except Exception:
122
- pass
123
- output.extend(dir_output)
124
- total_results += len(dir_output)
125
- if dir_limit_reached:
126
- limit_reached = True
127
- break
128
- continue
129
- # Directory logic as before
130
- if max_depth == 1:
131
- walk_result = next(os.walk(search_path), None)
132
- if walk_result is None:
133
- walker = [(search_path, [], [])]
134
- else:
135
- _, dirs, files = walk_result
136
- dirs, files = filter_ignored(search_path, dirs, files)
137
- walker = [(search_path, dirs, files)]
138
- else:
139
- walker = os.walk(search_path)
140
- stop_search = False
141
- for root, dirs, files in walker:
142
- if stop_search:
143
- break
144
- rel_path = os.path.relpath(root, search_path)
145
- depth = 0 if rel_path == "." else rel_path.count(os.sep) + 1
146
- if max_depth == 1 and depth > 0:
147
- break
148
- if max_depth > 0 and depth > max_depth:
149
- continue
150
- dirs, files = filter_ignored(root, dirs, files)
151
- for filename in files:
152
- if stop_search:
153
- break
154
- path = os.path.join(root, filename)
155
- if is_binary_file(path):
156
- continue
157
- try:
158
- open_kwargs = {"mode": "r", "encoding": "utf-8"}
159
- if ignore_utf8_errors:
160
- open_kwargs["errors"] = "ignore"
161
- with open(path, **open_kwargs) as f:
162
- for lineno, line in enumerate(f, 1):
163
- if use_regex:
164
- if regex.search(line):
165
- dir_output.append(
166
- f"{path}:{lineno}: {line.strip()}"
167
- )
168
- else:
169
- if pattern in line:
170
- dir_output.append(
171
- f"{path}:{lineno}: {line.strip()}"
172
- )
173
- if (
174
- max_results > 0
175
- and (total_results + len(dir_output)) >= max_results
176
- ):
177
- dir_limit_reached = True
178
- stop_search = True
179
- break
180
- except Exception:
181
- continue
182
- output.extend(dir_output)
183
- total_results += len(dir_output)
184
- if dir_limit_reached:
185
- limit_reached = True
186
- break
187
- header = tr(
188
- "[search_text] Pattern: '{pattern}' | Regex: {use_regex} | Results: {count}",
189
- pattern=pattern,
190
- use_regex=use_regex,
191
- count=len(output),
192
- )
193
- result = header + "\n" + "\n".join(output)
194
- if limit_reached:
195
- result += tr("\n[Note: max_results limit reached, output truncated.]")
196
- self.report_success(
197
- tr(
198
- " ✅ {count} {line_word}{limit}",
199
- count=len(output),
200
- line_word=pluralize("line", len(output)),
201
- limit=(" (limit reached)" if limit_reached else ""),
202
- )
203
- )
204
- return result
@@ -1,49 +0,0 @@
1
- def handle_sum(console, shell_state=None, **kwargs):
2
- """
3
- Summarize the current chat history and replace it with a summary message.
4
- """
5
- agent = kwargs.get("agent")
6
- if agent is None:
7
- console.print("[bold red]Agent not provided to /sum command.[/bold red]")
8
- return
9
-
10
- history = shell_state.conversation_history.get_messages()
11
- if not history or len(history) < 2:
12
- console.print(
13
- "[bold yellow]Not enough conversation to summarize.[/bold yellow]"
14
- )
15
- return
16
-
17
- # Find the system message if present
18
- system_msg = next((m for m in history if m.get("role") == "system"), None)
19
-
20
- # Prepare summary prompt
21
- summary_prompt = {
22
- "role": "user",
23
- "content": "Summarize the following conversation in a concise paragraph for context. Only output the summary, do not include any tool calls or formatting.",
24
- }
25
- # Exclude system messages for the summary context
26
- convo_for_summary = [m for m in history if m.get("role") != "system"]
27
- summary_messages = [summary_prompt] + convo_for_summary
28
-
29
- try:
30
- summary_response = agent.chat(summary_messages, spinner=True, max_tokens=256)
31
- summary_text = (
32
- summary_response["content"]
33
- if isinstance(summary_response, dict)
34
- else str(summary_response)
35
- )
36
- except Exception as e:
37
- console.print(f"[bold red]Error during summarization: {e}[/bold red]")
38
- return
39
-
40
- # Rebuild conversation history
41
- new_history = []
42
- if system_msg:
43
- new_history.append(system_msg)
44
- new_history.append({"role": "assistant", "content": summary_text})
45
- shell_state.conversation_history.set_messages(new_history)
46
-
47
- console.print(
48
- "[bold green]Conversation summarized and history replaced with summary.[/bold green]"
49
- )
@@ -1,151 +0,0 @@
1
- janito/__init__.py,sha256=l2eVHfMNFg4kPmiXtGSDPYsmLE4H8f13ozPPxATkS5s,23
2
- janito/__main__.py,sha256=KKIoPBE9xPcb54PRYO2UOt0ti04iAwLeJlg8YY36vew,76
3
- janito/rich_utils.py,sha256=T_DxBFwv4ZYP1qpZn-vzWRB2SzH46j0M6Upqf_bf6Pc,531
4
- janito/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- janito/agent/config.py,sha256=SMpyt9k1LhLn8DimhHcaOFmyk_iexEPnOREM1tWcMow,4616
6
- janito/agent/config_defaults.py,sha256=nzlOPZ2xllzcXLdFt5hSkjVKg6hT5NVkHiGEqj8WKvg,1324
7
- janito/agent/config_utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- janito/agent/content_handler.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- janito/agent/conversation.py,sha256=Re6RrA7wlr30hq4HvYlEMHU8H8PaXfZIyvtvg-CAeck,8105
10
- janito/agent/conversation_api.py,sha256=fLs2LQg1NAajXM2Q_ikTojYlVwyhhQYvEg-s3ZpfWpI,9369
11
- janito/agent/conversation_exceptions.py,sha256=Aw7PRLb3eUfyDOGynKds5F48dgjyiOrTCEcWSprYC58,381
12
- janito/agent/conversation_history.py,sha256=hV2zzlYrbOsCaMEiu39grE1TK8MQ7Lsq5dtIb_3Y--4,1929
13
- janito/agent/conversation_tool_calls.py,sha256=wz9FFtwNXgnyJQbcLzZfHfCPkiLfItE2vJ1JqjpKucA,1553
14
- janito/agent/conversation_ui.py,sha256=y4f0IoJQoWGrFMB3yi7uIwXokuTjhFtJGK_R7zcTv3w,397
15
- janito/agent/event.py,sha256=1jcua88NT-T4jA0mGIyIF1LvqXKu2GDT8NMjlelWmCI,517
16
- janito/agent/event_dispatcher.py,sha256=eFNDfGY8o63yNLFdMe82LqfmDyGWjrAw9CpyUAcLJAM,856
17
- janito/agent/event_handler_protocol.py,sha256=uIIf9u82BWm8pha4sZxydeEwgbxDoiWVSyplBPI0knE,130
18
- janito/agent/event_system.py,sha256=QxPSQ2XeTyiWV6ejcmS8kTqTBrs7fLHRVXdhyeVHpas,608
19
- janito/agent/message_handler.py,sha256=oZJ2u0C7OewHiHwlJslT2o3RPlvY2HhPXPoRcSsBv4M,856
20
- janito/agent/message_handler_protocol.py,sha256=E8PLl9ucNvPK_xmhLEkV-vhQzfO_P_BMvzpqDvUkcVY,150
21
- janito/agent/openai_client.py,sha256=5l45zgMK3lC5k7xS83hKC6jUEyZIjgsY7VwKWmxGaDY,4996
22
- janito/agent/openai_schema_generator.py,sha256=cquQLJYBIKaiA6ErDo-JRRF2mYl0kAu3bZzL6xcFHLQ,5925
23
- janito/agent/platform_discovery.py,sha256=yp6KTvc-_u22Dr8-J4cdjVMUS8HkCf343aeSGRu2wek,2712
24
- janito/agent/profile_manager.py,sha256=B-bwo1ZhtD2DaVPAfn0bNv1_inoduZhKGd694Pfy5GM,3231
25
- janito/agent/providers.py,sha256=fiLrYHR_rqUs6mlKXv_QMbOwzSrf3GqoabBVV4JXA9U,2199
26
- janito/agent/queued_message_handler.py,sha256=sjsZneGWkqvfuJNac9QERdHasp9lWZvNcow8dul7tVU,1844
27
- janito/agent/rich_live.py,sha256=NKWU89hRakiJ-0N6FPg40bYREOxQizqicbDv9eUfsKs,927
28
- janito/agent/rich_message_handler.py,sha256=HOm6-xUq7UrrGkE7UlDGtUPXz4BS6LZJuFv2Io1qZFs,2408
29
- janito/agent/runtime_config.py,sha256=xSx0-RD-WVA9niSCEmEn2ZPLFbQfRhPwwGIa8tid_v8,901
30
- janito/agent/test_handler_protocols.py,sha256=4o1IitFDUN1fdw48oQCRizKWahahumdmEZ4URHrlmiY,1404
31
- janito/agent/tool_base.py,sha256=rf88iEX_uZ7MwkeDl4gGMtHeESg0dlFKUo2Jr_ZqDTY,1900
32
- janito/agent/tool_executor.py,sha256=FuWpE4itUxtOS6n0JflCJePrBtXjed06R7haxZVIxmE,4677
33
- janito/agent/tool_registry.py,sha256=FlZ8YEoHdk2n7t8vZ26bVbu-fi4UeSE_yu2mZq8pusU,1594
34
- janito/agent/tool_use_tracker.py,sha256=QdzDieMJvmBk60Yd5NTyob0QE-9lSVraDjROw5jz-E4,2096
35
- janito/agent/templates/profiles/system_prompt_template_base.txt.j2,sha256=Z_Nu6tsJIJ01QF7RgUP6oYZOF0Gl5xRpMpPeaRtwr7k,913
36
- janito/agent/templates/profiles/system_prompt_template_base_pt.txt.j2,sha256=FX8piXbR9XNOEKkOSMt4ieZ2wn5fzQlffeQFf8d7gIc,723
37
- janito/agent/tests/__init__.py,sha256=QuXHKEzUJ_DooaKqenv_tKuNH-HabuIVZhvW5JNaeIc,52
38
- janito/agent/tools/__init__.py,sha256=EC8IPYi3VML4kH78CujL3b-bKBJp0mG5BslL4HNqDnw,1098
39
- janito/agent/tools/ask_user.py,sha256=DL-jBU-njSjwhNSbgi23RZCrRBt5beDgZq_PG4yzbWM,3217
40
- janito/agent/tools/create_directory.py,sha256=KFI2v3H3Mq_O2wN7jrOaIXiiZg7baJPanLoCNoLVJWM,2504
41
- janito/agent/tools/create_file.py,sha256=On8vIPbbbCOTw_xL1vJ_anQbIpPisouoKuUM-i6e53k,2225
42
- janito/agent/tools/delete_text_in_file.py,sha256=WIUDPgaaPK2Dk1WzKTPdfyckcoA6p51cwAf0SMiJj8c,3494
43
- janito/agent/tools/fetch_url.py,sha256=KQI9w71N5KI6ThBeSlLqNRdLL9WCxYDdIMTwYTa9wrI,2371
44
- janito/agent/tools/find_files.py,sha256=N467bqpx3j0VDUxc3wQGlK786vRYj-sQ3tQ7yXgkqj0,4137
45
- janito/agent/tools/get_lines.py,sha256=LhH8tQexESRIuAWWkBypq0yUkW6J2njcjWlYx4M1brI,5099
46
- janito/agent/tools/move_file.py,sha256=1EYe55JT-osFTXDzeCYHtEV7-i0cjPcc7tASzcOJyjI,4336
47
- janito/agent/tools/present_choices.py,sha256=e7SpOs3RIUXL6zi6PoeFc64akTVVuiQe2yLrm0rKpNs,2327
48
- janito/agent/tools/remove_directory.py,sha256=xXVqkaseRcjXSO3FwciJaf6WKaV00fkgHb-VC1ECaW4,2409
49
- janito/agent/tools/remove_file.py,sha256=rm74sNFbP9Ikc6R5G-y2x--Cdm_Xhs037jZKR-L9Q78,2294
50
- janito/agent/tools/replace_file.py,sha256=fxnrNeHNudexYL_Ko_CzrERGGKDAoC9pTUCgUEE8QPg,2840
51
- janito/agent/tools/replace_text_in_file.py,sha256=E-efxMYKZMgrf2Gb38qRdJnd4AvfoOBguVKVZtQd_CY,9451
52
- janito/agent/tools/run_bash_command.py,sha256=4tpHwJmBekVBb75vSnT6R8vlpxp8LD_FHhzmq6TxbV0,7474
53
- janito/agent/tools/run_powershell_command.py,sha256=geqse-o2fZrc8u5Rr6fFH-9HNKL3V389GStcmUe4dXU,8230
54
- janito/agent/tools/run_python_command.py,sha256=ti7yfjvRC8ZjvOucXp7ixeKgT4pY8i10uDeAjl3_1DY,6991
55
- janito/agent/tools/search_text.py,sha256=eqvlZkdXHt5TQrSn8IDnZfgnnQF2asF9diSU2AeLuVo,9298
56
- janito/agent/tools/get_file_outline/__init__.py,sha256=OKV_BHnoD9h-vkcVoW6AHmsuDjjauHPCKNK0nVFl4sU,37
57
- janito/agent/tools/get_file_outline/core.py,sha256=crpumYww-2JXYGjWNO13sWy3rzWWlJjcUDjpdxWs4Jw,3235
58
- janito/agent/tools/get_file_outline/markdown_outline.py,sha256=bXEBg0D93tEBDNy8t-wh4i7WxsxfpQ2C3dX1_rmtj08,434
59
- janito/agent/tools/get_file_outline/python_outline.py,sha256=P_GDB3ElMZtrLc5D3pQIueIA_7MxoOiyUbdcQXClyWo,4998
60
- janito/agent/tools/get_file_outline/search_outline.py,sha256=l6yk1BJLpYRLbM2u4igvxMXeAmOXmyThT_Q-5Pj_B0o,987
61
- janito/agent/tools/validate_file_syntax/__init__.py,sha256=P53RHmas4BbHL90cMxH9m-RpMCJI8JquoJb0rpkPVVk,29
62
- janito/agent/tools/validate_file_syntax/core.py,sha256=tXcXWyQUQKOMwESOt3uSVC93FK4Qc3obJzwAQiyIS2M,3162
63
- janito/agent/tools/validate_file_syntax/css_validator.py,sha256=tRnCzNkpiYKQ_X9yvPeDPqZvc59He2T-2CbXmCs8Hjw,1371
64
- janito/agent/tools/validate_file_syntax/html_validator.py,sha256=X1sS0-ZJn1d0hlfN-sIPHjCLME_o1PIs_G_YsswNqiA,2739
65
- janito/agent/tools/validate_file_syntax/js_validator.py,sha256=oVkGxK9wBbZ3cFqwrV_aF76FDQwKPDvbXxXn1tL4We0,1018
66
- janito/agent/tools/validate_file_syntax/json_validator.py,sha256=jfft16AjPqo4opIlv36Yc1QhpwiYVlMOyfeAJuhRZ8U,170
67
- janito/agent/tools/validate_file_syntax/markdown_validator.py,sha256=CJBG9ERfXy0Liy2FtbkdnkQS1yNq1hxzMlL8UJx4T6E,2863
68
- janito/agent/tools/validate_file_syntax/ps1_validator.py,sha256=DQbsIIC3oaFkbeK7BMjZcIzy-zkPHX1JbhMMS3q_rmc,1172
69
- janito/agent/tools/validate_file_syntax/python_validator.py,sha256=SN9eNgk9Uormr_kfyan9hCZClZ1LB5guObOzbZRyo6c,150
70
- janito/agent/tools/validate_file_syntax/xml_validator.py,sha256=nDHMnrSdjAyQhbSIJZcDuqEkeiJmjvTALlKdtn_Ny0k,304
71
- janito/agent/tools/validate_file_syntax/yaml_validator.py,sha256=zDg0F-7y9WDU5ur75tBEicIreQjZ8pXjc_FYyTUuXmo,175
72
- janito/agent/tools_utils/__init__.py,sha256=tMniEJ8rcFeiztKqidRe-sCRJh02gMw_s1OjcQB1Rg4,28
73
- janito/agent/tools_utils/dir_walk_utils.py,sha256=0r86VlWt_7TL0MtKpYR_G3KTESMl5seRT0fsY61CSVo,1081
74
- janito/agent/tools_utils/formatting.py,sha256=p781lIQ1tqGMQgOlo5KyddPmurqoromrsNVdxKKJQDY,1132
75
- janito/agent/tools_utils/gitignore_utils.py,sha256=vVcUqd5XGNp3BMMAxiGTzbaDPfjemHpbIVZrKMllo4Q,1340
76
- janito/agent/tools_utils/utils.py,sha256=nVFOqaclfs18z4XB2rvr0JlwPa-RH1H-eSs8ejdXR5k,966
77
- janito/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
- janito/cli/_livereload_log_utils.py,sha256=BGhf1VT3dVR2ZhyTnZeTFg4I8Zj2tAn2UslME-ouxXA,482
79
- janito/cli/_print_config.py,sha256=C_27QdwzhqorzeJflBFK0f46zTUtqqmdYe3EBurjOOE,3574
80
- janito/cli/_termweb_log_utils.py,sha256=QpH40uxPhksrJHWqthW4cR7BhcSSYakpza_qTeFGABs,722
81
- janito/cli/_utils.py,sha256=tRAUMDWKczd81ZvKYkwpsHWSeLzQoVlOoQ-lOw9Iujw,291
82
- janito/cli/arg_parser.py,sha256=uQLDOr-m4azb1xQ9_HEXNPRR6qolx2l6jLrl30Gjcrw,8271
83
- janito/cli/cli_main.py,sha256=SCCxKC9WIBb4qNqsSsfxW3KiyO8WiDLGIZgUFFCaDck,11265
84
- janito/cli/config_commands.py,sha256=vfU7XciVMRNR5kDvn6tnCo1PLvSEXg0Y0PzLcDEFI9w,8539
85
- janito/cli/config_runner.py,sha256=Nzam25C8P55dFlT_f6IlEj2ZvFwS63AAbnkIWe3oNsg,1702
86
- janito/cli/formatting_runner.py,sha256=k0mtHoglqR8fKcebSK81iWTT_EL-gDl7eNfjlFZRY6g,287
87
- janito/cli/livereload_starter.py,sha256=JivN7PRG9_dCEEOobXETQcJ7Ro9ELczg8AUbI8LHFPI,2285
88
- janito/cli/logging_setup.py,sha256=_KLF69xqq1xLPIfkXxy0EIewO-Ef2eYoxNVjqjsC0vc,1361
89
- janito/cli/main.py,sha256=wjmvbF2DdjMs8thZQQi80RSey62PObK2BNNOqtW2Ltc,8874
90
- janito/cli/one_shot.py,sha256=Iqaj3DlcrqjUzwqqOKpKmsMIbLfNvqRvFIqHy4t7nIc,2696
91
- janito/cli/termweb_starter.py,sha256=lN_MXGr_Glr82kS983caPyCXdKmhwzcEERmpCrfgcDA,2797
92
- janito/i18n/__init__.py,sha256=7HYvwOTTf51pVm4adU79rl1FCtAjgOy6GzeShfYCdQY,970
93
- janito/i18n/messages.py,sha256=fBuwOTFoygyHPkYphm6Y0r1iE8497Z4iryVAmPhMEkg,1851
94
- janito/i18n/pt.py,sha256=52-ENCIrPW4A1tXFRT28xA8TwuUFoihs6ezJj-m3-Y4,4260
95
- janito/livereload/app.py,sha256=oJTKDN5vpix26d1MA5iQz9mPLDu4VaHisAW8wtOUEhY,666
96
- janito/shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
97
- janito/shell/commands.py,sha256=gqMKLvb6MrESPx51O28OP5I9hDZuBkRMaom3hT_ACqA,1586
98
- janito/shell/main.py,sha256=hzsoflpMRVP6CXaw5YdKeh7JGeWR_OsJ88SoKgVz5R4,12551
99
- janito/shell/commands/__init__.py,sha256=XGnXf6w_JZqpREJG3YN_UI9Zfc2uKK0Z_K9JMJ8gmfg,2002
100
- janito/shell/commands/config.py,sha256=UTNbyNOLpIqlAle_JpCiffP7h5IOk7wxih-10_ok62w,959
101
- janito/shell/commands/conversation_restart.py,sha256=IGCNO7Br9iHj1JH327B-R4Ps73g4qJOq2IvCZvJY-T0,2752
102
- janito/shell/commands/edit.py,sha256=6o7T1FM18S2bGPadE61rvO3feWxGa5dfDFqtI4BwX9w,720
103
- janito/shell/commands/history_view.py,sha256=m_-Olds5BI3gAdjZmx0i4kDBaMpLgmNBHVIIGDd6zq4,812
104
- janito/shell/commands/lang.py,sha256=cG_gX61LUgzv_Bxk-UPTTNF1JQFfcUVaYBnPovUylNw,521
105
- janito/shell/commands/livelogs.py,sha256=7lM7RRcsyisZz26Tk00_BYSkd9gvDuco_8z31xr49Ug,1753
106
- janito/shell/commands/prompt.py,sha256=HW3z_JuJT6Zc5Yx8wJHDh4n2PZphu4ONTIMabVRTFnk,1949
107
- janito/shell/commands/session.py,sha256=AHWC8eDrV5jta9Ak77FXu57qQvxEQC_8hVCICbkglRQ,1192
108
- janito/shell/commands/session_control.py,sha256=nWxrc6OEX0ih872EwSEtodYhzBNPUC7rMr-ghmDw7ns,1249
109
- janito/shell/commands/sum.py,sha256=WB89_NY34GrulqzKJchR5ovXmyJSYX7LP3sdaOgCT_E,1884
110
- janito/shell/commands/termweb_log.py,sha256=jaVDefd2Sz-xBxGPcJqvsTRIpeynmVdi8vR2rP_nwCY,3321
111
- janito/shell/commands/tools.py,sha256=_cnxXdu-xNkElcUnAv_lSrh3l9AKX5mH0E4HR1hZCU4,917
112
- janito/shell/commands/utility.py,sha256=mfxv1J-VCzL4V2pAKMxQo1Rk8ZbyTFJ1PNh9hmqRVn0,1232
113
- janito/shell/commands/verbose.py,sha256=vNtWCfpKxRY2t3Pzcz7FC1A9kZxMD26-zHSpE1JhuHc,1008
114
- janito/shell/prompt/completer.py,sha256=6gNu0DNNSbUUVgjk8Y0hWwJwk-jbN8Lm6Y4u0mRu930,755
115
- janito/shell/prompt/load_prompt.py,sha256=gHedc5TtaFBKiGgwRM_u9nVnBuLHDTSa8VPlPOtoMEA,2125
116
- janito/shell/prompt/session_setup.py,sha256=ry4TqiXYyw3JmZfGRGIpvAgNMXGeWltCwz56NoiBqSY,1531
117
- janito/shell/session/config.py,sha256=sG04S_z27wI7nXKMaVDcwDpBCuo6Cvd4uhutUQesJKo,3807
118
- janito/shell/session/history.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
119
- janito/shell/session/manager.py,sha256=E8TNBhiXHCbdNhhvzhUp4Zr_S3tdWagh1veDprwFTHY,3919
120
- janito/shell/ui/interactive.py,sha256=XhR1vEZlLG8LijsZJqZCqvRoZVqruXHny3z-911XO6Q,7669
121
- janito/termweb/app.py,sha256=co4a7cw6pC2P79dMZaNxjPJrP_B9suTGRIWTgqK5ccw,3322
122
- janito/termweb/static/editor.css,sha256=rPSbQIVBCBnLlFJOQjHBOy2wWZkdbPDt4z8dWEBB83s,2870
123
- janito/termweb/static/editor.css.bak,sha256=KPjMz7YwryaxOUmyHJNAlOv96KYtcMLj0zfYkUuc9Vs,924
124
- janito/termweb/static/editor.html,sha256=XZpNejyIyzc1JVHnLGzc7dfUZO0ID_hX__rHpach9HU,2377
125
- janito/termweb/static/editor.html.bak,sha256=X7t-EBYzv5RorkdM_kc0JerD6lXoNes4_ZIF8aFFfzs,2245
126
- janito/termweb/static/editor.js,sha256=5FdYuQiWbmn3WUmHoUqkx_FAk6MVr8NXsglWeNl0re0,8331
127
- janito/termweb/static/editor.js.bak,sha256=orBXq043dheUYwZP7HSnhkaIlR6cvGCBsoOroK-JaIg,8841
128
- janito/termweb/static/explorer.html.bak,sha256=PM1fcbaQJm545WT94mVEekUNW3jduBAHOz6rwJBR1FA,2568
129
- janito/termweb/static/favicon.ico,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
130
- janito/termweb/static/favicon.ico.bak,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
131
- janito/termweb/static/index.html,sha256=lwF9j4C0wL56rBEU3f0s3HzdSGOWxf64LbQhBUh5fxU,2934
132
- janito/termweb/static/index.html.bak,sha256=PBEA-FxIhIYOGkyGKzefn7tsk8UxDIhSNtVkqPplQbs,2933
133
- janito/termweb/static/index.html.bak.bak,sha256=dsKoC2lE0oJCGUUDTWcnIQE3s5Uoqd12WoTkWEwbH_c,6626
134
- janito/termweb/static/landing.html.bak,sha256=JGwIcATj0B8MhHXLoXg2clypqsKJwi54NtW-rRDUsMs,1403
135
- janito/termweb/static/termicon.svg,sha256=vc2Z3q-ADVK3pLzE3wnw_qpR6vDguWKEdH_pWObPjbw,229
136
- janito/termweb/static/termweb.css,sha256=9AxhC2R8CzS82NHg9bk0GD-kxKt_NeRSRFGgTyi-3zI,4870
137
- janito/termweb/static/termweb.css.bak,sha256=9AxhC2R8CzS82NHg9bk0GD-kxKt_NeRSRFGgTyi-3zI,4870
138
- janito/termweb/static/termweb.js,sha256=hVzFd4gGMPEPvJEicQsXQpePp9mTjKVB_tS29xfWPhs,7720
139
- janito/termweb/static/termweb.js.bak,sha256=G1UQJqtWMZOoPFMiSm4MRo-Pm1OqX1oMZ_Jcm4bsDq8,7721
140
- janito/termweb/static/termweb.js.bak.bak,sha256=SQeqc9YwdreCmFJ7LtCYlHOjRHi8rsoW_fZ3x5WroWQ,7692
141
- janito/termweb/static/termweb_quickopen.js,sha256=HNT85JjWAvjI5ROwukOU-oI4ZVVjCO6yg5IT115pdXI,5379
142
- janito/termweb/static/termweb_quickopen.js.bak,sha256=sk_zbEw6HJt1iZSAYlaW0qAhq0to-KcBsOKx0AZqkKA,4814
143
- janito/web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
144
- janito/web/__main__.py,sha256=5Ck6okOZmxKYkQ-ir4mxXDH7XWMNR-9szgsm0UyQLE0,734
145
- janito/web/app.py,sha256=NarccXYgeYEMvws1lQSGZtArrzJIvw94LSNR0rW9Dq4,7331
146
- janito-1.9.0.dist-info/licenses/LICENSE,sha256=sHBqv0bvtrb29H7WRR-Z603YHm9pLtJIo3nHU_9cmgE,1091
147
- janito-1.9.0.dist-info/METADATA,sha256=Cxe4t_iI7poul_W8JwJX2ErMvdWZfQat18eD2Onphtw,12640
148
- janito-1.9.0.dist-info/WHEEL,sha256=wXxTzcEDnjrTwFYjLPcsW_7_XihufBwmpiBeiXNBGEA,91
149
- janito-1.9.0.dist-info/entry_points.txt,sha256=wIo5zZxbmu4fC-ZMrsKD0T0vq7IqkOOLYhrqRGypkx4,48
150
- janito-1.9.0.dist-info/top_level.txt,sha256=m0NaVCq0-ivxbazE2-ND0EA9Hmuijj_OGkmCbnBcCig,7
151
- janito-1.9.0.dist-info/RECORD,,