janito 1.6.0__py3-none-any.whl → 1.8.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 -1
- janito/agent/config.py +3 -3
- janito/agent/config_defaults.py +3 -2
- janito/agent/conversation.py +73 -27
- janito/agent/conversation_api.py +104 -4
- janito/agent/conversation_exceptions.py +6 -0
- janito/agent/conversation_tool_calls.py +17 -3
- janito/agent/event.py +24 -0
- janito/agent/event_dispatcher.py +24 -0
- janito/agent/event_handler_protocol.py +5 -0
- janito/agent/event_system.py +15 -0
- janito/agent/message_handler.py +4 -1
- janito/agent/message_handler_protocol.py +5 -0
- janito/agent/openai_client.py +5 -6
- janito/agent/openai_schema_generator.py +23 -4
- janito/agent/platform_discovery.py +90 -0
- janito/agent/profile_manager.py +34 -110
- janito/agent/queued_message_handler.py +22 -3
- janito/agent/rich_message_handler.py +3 -1
- janito/agent/templates/profiles/system_prompt_template_base.txt.j2 +14 -0
- janito/agent/templates/profiles/system_prompt_template_base_pt.txt.j2 +13 -0
- janito/agent/test_handler_protocols.py +47 -0
- janito/agent/tests/__init__.py +1 -0
- janito/agent/tool_base.py +1 -1
- janito/agent/tool_executor.py +109 -0
- janito/agent/tool_registry.py +3 -75
- janito/agent/tool_use_tracker.py +46 -0
- janito/agent/tools/__init__.py +11 -8
- janito/agent/tools/ask_user.py +26 -12
- janito/agent/tools/create_directory.py +50 -18
- janito/agent/tools/create_file.py +60 -29
- janito/agent/tools/dir_walk_utils.py +16 -0
- janito/agent/tools/fetch_url.py +10 -11
- janito/agent/tools/find_files.py +49 -40
- janito/agent/tools/get_lines.py +60 -25
- janito/agent/tools/memory.py +48 -0
- janito/agent/tools/move_file.py +72 -23
- janito/agent/tools/outline_file/__init__.py +85 -0
- janito/agent/tools/outline_file/formatting.py +20 -0
- janito/agent/tools/outline_file/markdown_outline.py +14 -0
- janito/agent/tools/outline_file/python_outline.py +71 -0
- janito/agent/tools/present_choices.py +62 -0
- janito/agent/tools/present_choices_test.py +18 -0
- janito/agent/tools/remove_directory.py +31 -26
- janito/agent/tools/remove_file.py +31 -13
- janito/agent/tools/replace_text_in_file.py +135 -36
- janito/agent/tools/run_bash_command.py +113 -97
- janito/agent/tools/run_powershell_command.py +169 -0
- janito/agent/tools/run_python_command.py +53 -29
- janito/agent/tools/search_outline.py +17 -0
- janito/agent/tools/search_text.py +208 -0
- janito/agent/tools/tools_utils.py +47 -4
- janito/agent/tools/utils.py +14 -15
- janito/agent/tools/validate_file_syntax.py +163 -0
- janito/cli/_print_config.py +1 -1
- janito/cli/arg_parser.py +36 -4
- janito/cli/config_commands.py +1 -1
- janito/cli/logging_setup.py +7 -2
- janito/cli/main.py +97 -3
- janito/cli/runner/__init__.py +0 -2
- janito/cli/runner/_termweb_log_utils.py +17 -0
- janito/cli/runner/cli_main.py +121 -89
- janito/cli/runner/config.py +6 -4
- janito/cli/termweb_starter.py +73 -0
- janito/cli_chat_shell/chat_loop.py +52 -13
- janito/cli_chat_shell/chat_state.py +1 -1
- janito/cli_chat_shell/chat_ui.py +2 -3
- janito/cli_chat_shell/commands/__init__.py +17 -6
- janito/cli_chat_shell/commands/{history_reset.py → history_start.py} +13 -5
- janito/cli_chat_shell/commands/lang.py +16 -0
- janito/cli_chat_shell/commands/prompt.py +42 -0
- janito/cli_chat_shell/commands/session_control.py +36 -1
- janito/cli_chat_shell/commands/sum.py +49 -0
- janito/cli_chat_shell/commands/termweb_log.py +86 -0
- janito/cli_chat_shell/commands/utility.py +5 -2
- janito/cli_chat_shell/commands/verbose.py +29 -0
- janito/cli_chat_shell/load_prompt.py +47 -8
- janito/cli_chat_shell/session_manager.py +9 -1
- janito/cli_chat_shell/shell_command_completer.py +20 -0
- janito/cli_chat_shell/ui.py +110 -93
- janito/i18n/__init__.py +35 -0
- janito/i18n/messages.py +23 -0
- janito/i18n/pt.py +46 -0
- janito/rich_utils.py +43 -43
- janito/termweb/app.py +95 -0
- janito/termweb/static/editor.html +238 -0
- janito/termweb/static/editor.html.bak +238 -0
- janito/termweb/static/explorer.html.bak +59 -0
- janito/termweb/static/favicon.ico +0 -0
- janito/termweb/static/favicon.ico.bak +0 -0
- janito/termweb/static/index.html +55 -0
- janito/termweb/static/index.html.bak +55 -0
- janito/termweb/static/index.html.bak.bak +175 -0
- janito/termweb/static/landing.html.bak +36 -0
- janito/termweb/static/termicon.svg +1 -0
- janito/termweb/static/termweb.css +235 -0
- janito/termweb/static/termweb.css.bak +286 -0
- janito/termweb/static/termweb.js +187 -0
- janito/termweb/static/termweb.js.bak +187 -0
- janito/termweb/static/termweb.js.bak.bak +157 -0
- janito/termweb/static/termweb_quickopen.js +135 -0
- janito/termweb/static/termweb_quickopen.js.bak +125 -0
- janito/web/app.py +10 -13
- {janito-1.6.0.dist-info → janito-1.8.0.dist-info}/METADATA +73 -32
- janito-1.8.0.dist-info/RECORD +127 -0
- {janito-1.6.0.dist-info → janito-1.8.0.dist-info}/WHEEL +1 -1
- janito/agent/tool_registry_core.py +0 -2
- janito/agent/tools/get_file_outline.py +0 -117
- janito/agent/tools/py_compile_file.py +0 -40
- janito/agent/tools/replace_file.py +0 -51
- janito/agent/tools/search_files.py +0 -71
- janito/cli/runner/scan.py +0 -44
- janito/cli_chat_shell/commands/system.py +0 -73
- janito-1.6.0.dist-info/RECORD +0 -81
- {janito-1.6.0.dist-info → janito-1.8.0.dist-info}/entry_points.txt +0 -0
- {janito-1.6.0.dist-info → janito-1.8.0.dist-info}/licenses/LICENSE +0 -0
- {janito-1.6.0.dist-info → janito-1.8.0.dist-info}/top_level.txt +0 -0
@@ -1,10 +1,10 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: janito
|
3
|
-
Version: 1.
|
4
|
-
Summary:
|
3
|
+
Version: 1.8.0
|
4
|
+
Summary: Natural Language Coding Agent,
|
5
5
|
Author-email: João Pinto <joao.pinto@gmail.com>
|
6
|
-
License: MIT
|
7
|
-
Project-URL: homepage, https://
|
6
|
+
License-Expression: MIT
|
7
|
+
Project-URL: homepage, https://janito.dev
|
8
8
|
Project-URL: repository, https://github.com/joaompinto/janito
|
9
9
|
Keywords: agent,framework,tools,automation
|
10
10
|
Classifier: Programming Language :: Python :: 3.10
|
@@ -21,19 +21,60 @@ Requires-Dist: pathspec
|
|
21
21
|
Requires-Dist: prompt_toolkit
|
22
22
|
Requires-Dist: requests
|
23
23
|
Requires-Dist: rich
|
24
|
+
Requires-Dist: toml
|
25
|
+
Provides-Extra: docs
|
26
|
+
Requires-Dist: mkdocs>=1.5.3; extra == "docs"
|
27
|
+
Requires-Dist: mkdocs-material>=9.4.8; extra == "docs"
|
24
28
|
Dynamic: license-file
|
25
29
|
|
26
|
-
# 🚀 Janito: Natural Language
|
30
|
+
# 🚀 Janito: Natural Language Coding Agent
|
27
31
|
|
28
|
-
**Current Version: 1.
|
29
|
-
See [CHANGELOG.md](./CHANGELOG.md)
|
32
|
+
**Current Version: 1.7.0**
|
33
|
+
See [CHANGELOG.md](./CHANGELOG.md) for details on the latest release.
|
30
34
|
|
31
35
|
Janito is an AI-powered assistant for the command line and web that interprets natural language system_prompt_template to edit code, manage files, and analyze projects using patterns and tools designed by experienced software engineers. It prioritizes transparency, interactive clarification, and precise, reviewable changes.
|
32
36
|
|
33
|
-
For a technical overview, see the [Architecture Guide](docs/
|
37
|
+
For a technical overview, see the [Architecture Guide](docs/reference/architecture.md).
|
38
|
+
|
39
|
+
## 🧪 Experimental Feature: Liteweb File Viewer
|
40
|
+
|
41
|
+
Janito now includes an experimental lightweight web file viewer for use with the CLI chat shell. This feature allows you to click on file paths in the terminal (when using a Rich-compatible terminal) and instantly preview file contents in your browser—no full IDE required!
|
42
|
+
|
43
|
+
### How to Use
|
44
|
+
|
45
|
+
- Start the CLI chat shell with the `--termweb` flag:
|
46
|
+
```bash
|
47
|
+
janito --termweb
|
48
|
+
```
|
49
|
+
- By default, the viewer runs at http://localhost:8088 (or the next available port up to 8100).
|
50
|
+
- To specify a port, use `--termweb-port 8090`.
|
51
|
+
- File paths in CLI output become clickable links that open the file in your browser.
|
52
|
+
|
53
|
+
**Note:** This feature is experimental. It is intended for quick file previews and review, not for editing or production use. Feedback is welcome!
|
54
|
+
|
55
|
+
### Why is this useful?
|
56
|
+
- Enables instant file previews from the CLI without a full IDE.
|
57
|
+
- Works with all Janito file tools and outputs that display file paths.
|
58
|
+
- Uses the Rich library’s link markup for clickable terminal links.
|
59
|
+
|
60
|
+
---
|
61
|
+
|
62
|
+
## 📖 Full Documentation & Overview
|
63
|
+
- For structured and in-depth guides, visit the [Janito Documentation Site](https://docs.janito.dev).
|
64
|
+
- For a high-level, user-friendly overview, see [janito.dev](https://janito.dev).
|
34
65
|
|
35
66
|
---
|
36
67
|
|
68
|
+
## Listing Available Tools
|
69
|
+
|
70
|
+
To list all registered tools on the command line, use the option:
|
71
|
+
|
72
|
+
```sh
|
73
|
+
janito --list-tools
|
74
|
+
```
|
75
|
+
|
76
|
+
This will display a colorful table with the name, description, and parameters of each available tool.
|
77
|
+
|
37
78
|
## ⚡ Quick Start
|
38
79
|
|
39
80
|
## 🖥️ Supported Human Interfaces
|
@@ -81,7 +122,7 @@ janito --web
|
|
81
122
|
- 📁 **File & Directory Management:** Navigate, create, move, or remove files and folders.
|
82
123
|
- 🧠 **Context-Aware:** Understands your project structure for precise edits.
|
83
124
|
- 💬 **Interactive User Prompts:** Asks for clarification when needed.
|
84
|
-
-
|
125
|
+
- 🛠️ **Extensible Tooling:** Built-in tools for file operations, shell commands, directory and file management, Python code execution and validation, text replacement, and more.
|
85
126
|
- See [janito/agent/tools/README.md](janito/agent/tools/README.md) for the full list of built-in tools and their usage details. For the message handler model, see [docs/MESSAGE_HANDLER_MODEL.md](docs/MESSAGE_HANDLER_MODEL.md).
|
86
127
|
- 🌐 **Web Interface (In Development):** Simple web UI for streaming responses and tool progress.
|
87
128
|
|
@@ -93,7 +134,7 @@ janito --web
|
|
93
134
|
|
94
135
|
### Contributing & Developer Guide
|
95
136
|
|
96
|
-
If you want to extend Janito or add new tools, see the [Developer Guide](docs/README_DEV.md) for system_prompt_template, tool registration requirements, and code
|
137
|
+
If you want to extend Janito or add new tools, see the [Developer Guide](docs/README_DEV.md) for system_prompt_template, tool registration requirements, and code profile guidelines. For the full list of built-in tools and their usage, see the [Tools Reference](janito/agent/tools/README.md).
|
97
138
|
|
98
139
|
|
99
140
|
|
@@ -130,12 +171,12 @@ For details on using models hosted on Azure OpenAI, see [docs/AZURE_OPENAI.md](d
|
|
130
171
|
|
131
172
|
---
|
132
173
|
|
133
|
-
##
|
174
|
+
## 🧑💻 System Prompt & Role
|
134
175
|
|
135
|
-
Janito operates using a system prompt template that defines its behavior, communication
|
176
|
+
Janito operates using a system prompt template that defines its behavior, communication profile, and capabilities. By default, Janito assumes the role of a "software engineer"—this means its responses and actions are tailored to the expectations and best practices of professional software engineering.
|
136
177
|
|
137
178
|
- **Role:** You can customize the agent's role (e.g., "data scientist", "DevOps engineer") using the `--role` flag or config. The default is `software engineer`.
|
138
|
-
- **System Prompt Template:** The system prompt is rendered from a Jinja2 template (see `janito/agent/templates/
|
179
|
+
- **System Prompt Template:** The system prompt is rendered from a Jinja2 template (see `janito/agent/templates/prompt_prompt_template.j2`). This template governs how the agent interprets system_prompt_template, interacts with files, and communicates with users.
|
139
180
|
- **Customization & Precedence:** Advanced users can override the system prompt with the `--system` flag (raw string), or point to a custom file using `--system-file`. The precedence is: `--system-file` > `--system`/config > default template.
|
140
181
|
|
141
182
|
The default template ensures the agent:
|
@@ -144,7 +185,7 @@ The default template ensures the agent:
|
|
144
185
|
- Provides concise plans before taking action
|
145
186
|
- Documents any changes made
|
146
187
|
|
147
|
-
For more details or to customize the prompt, see the template file at `janito/agent/templates/
|
188
|
+
For more details or to customize the prompt, see the template file at `janito/agent/templates/prompt_prompt_template.j2` and the architecture overview in [docs/reference/architecture.md](docs/reference/architecture.md).
|
148
189
|
|
149
190
|
---
|
150
191
|
|
@@ -176,18 +217,18 @@ Vanilla mode is ideal for:
|
|
176
217
|
|
177
218
|
> Note: Vanilla mode is a runtime switch and does not change the Agent API or class signatures. It is controlled via CLI/config only.
|
178
219
|
|
179
|
-
##
|
220
|
+
## 👨💻 AgentProfileManager: Profile, Role, and Prompt Management
|
180
221
|
|
181
|
-
Janito now uses a dedicated `AgentProfileManager` class to manage user profiles, roles, interaction
|
182
|
-
- Stores the current role (e.g., "software engineer") and interaction
|
183
|
-
- Renders the system prompt from the appropriate template based on interaction
|
222
|
+
Janito now uses a dedicated `AgentProfileManager` class to manage user profiles, roles, interaction profiles, and system prompt selection. This manager:
|
223
|
+
- Stores the current role (e.g., "software engineer") and interaction profile (e.g., "default", "technical").
|
224
|
+
- Renders the system prompt from the appropriate template based on interaction profile.
|
184
225
|
- Instantiates and manages the low-level LLM Agent, passing the correct prompt.
|
185
|
-
- Provides methods to update the role, interaction
|
226
|
+
- Provides methods to update the role, interaction profile, and refresh the prompt at runtime.
|
186
227
|
|
187
228
|
### Multiple System Prompt Templates
|
188
|
-
- The system prompt template is now selected based on the interaction
|
229
|
+
- The system prompt template is now selected based on the interaction profile (e.g., `default` or `technical`).
|
189
230
|
- Templates are located in `janito/agent/templates/` (see `system_prompt_template.j2` and `system_prompt_template_technical.j2`).
|
190
|
-
- You can switch interaction
|
231
|
+
- You can switch interaction profiles at runtime using the profile manager, enabling different agent behaviors for different user needs.
|
191
232
|
|
192
233
|
This separation ensures that the LLM Agent remains focused on language model interaction and tool execution, while all profile, role, and prompt logic is managed at a higher level.
|
193
234
|
|
@@ -195,45 +236,45 @@ See `janito/agent/profile_manager.py` for implementation details.
|
|
195
236
|
|
196
237
|
### Agent Interaction Style
|
197
238
|
|
198
|
-
You can control the agent's behavior and prompt
|
239
|
+
You can control the agent's behavior and prompt profile globally or per-project using the `profile` config key. See [Prompt Profiles Guide](docs/guides/prompt_profiles.md) for all available styles and combinations.
|
199
240
|
- `default`: Concise, general-purpose agent (default)
|
200
241
|
- `technical`: Strict, workflow-oriented for technical/developer use
|
201
242
|
|
202
243
|
Set globally:
|
203
244
|
```bash
|
204
|
-
janito --set-global-config
|
245
|
+
janito --set-global-config profile=technical
|
205
246
|
```
|
206
247
|
Or per-project (in your project root):
|
207
248
|
```bash
|
208
|
-
janito --set-local-config
|
249
|
+
janito --set-local-config profile=technical
|
209
250
|
```
|
210
251
|
|
211
252
|
You can also override for a session with the CLI flag:
|
212
253
|
```bash
|
213
|
-
janito --
|
254
|
+
janito --profile technical
|
214
255
|
```
|
215
256
|
|
216
257
|
See [docs/CONFIGURATION.md](docs/CONFIGURATION.md) for full details.
|
217
258
|
|
218
|
-
##
|
259
|
+
## 🧑💻 Combinatorial Style System
|
219
260
|
|
220
|
-
Janito now supports combinatorial
|
261
|
+
Janito now supports combinatorial profiles for system prompts, allowing you to combine a main profile (such as `default` or `technical`) with one or more feature extensions (such as `commit_all`).
|
221
262
|
|
222
|
-
- **Main
|
223
|
-
- **Feature extensions:** Optional features that override or extend the main
|
263
|
+
- **Main profile:** The base agent behavior and workflow (e.g., `default`, `technical`).
|
264
|
+
- **Feature extensions:** Optional features that override or extend the main profile (e.g., `commit_all`).
|
224
265
|
- **Syntax:** Use a hyphen to combine, e.g., `technical-commit_all`.
|
225
266
|
|
226
267
|
**How it works:**
|
227
|
-
- The main
|
268
|
+
- The main profile template is loaded first.
|
228
269
|
- Each feature extension template is layered on top, overriding or extending specific blocks in the main template.
|
229
270
|
- Feature templates must use `{% extends parent_template %}` for dynamic inheritance.
|
230
271
|
|
231
272
|
**Example usage:**
|
232
273
|
```bash
|
233
|
-
janito --
|
274
|
+
janito --profile technical-commit_all
|
234
275
|
```
|
235
276
|
|
236
|
-
This will apply the `technical`
|
277
|
+
This will apply the `technical` profile with the `commit_all` feature enabled in the agent's system prompt.
|
237
278
|
|
238
279
|
See `janito/render_prompt.py` and `janito/agent/templates/` for implementation details and to create your own feature extensions.
|
239
280
|
|
@@ -0,0 +1,127 @@
|
|
1
|
+
janito/__init__.py,sha256=TEX5rBxpQQMGbHlz1RNwQDTVirV3Dy0Px6DtRIL00_0,23
|
2
|
+
janito/__main__.py,sha256=KKIoPBE9xPcb54PRYO2UOt0ti04iAwLeJlg8YY36vew,76
|
3
|
+
janito/rich_utils.py,sha256=FZEwrRnd_G9dnhBpUus5c40dDs-XDr0tTnIoctZAEME,1128
|
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=mSS_NHNH8FrZOoX61ED8LktfOEUYT84Rfek0Oaue3MA,517
|
7
|
+
janito/agent/config_utils.py,sha256=UmvR236wDrMc-aTy9LxVbop6YeoJaaPb1d2DBMlkSRg,254
|
8
|
+
janito/agent/content_handler.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
|
+
janito/agent/conversation.py,sha256=8i6pm1gsOiE2y__nzBjt7LaigRRrqTtHkx3-SwyX_UE,7326
|
10
|
+
janito/agent/conversation_api.py,sha256=q6ZqbHdyo5vkHmXeu51Yfqf6cEjELUUAazew_IxGrHg,8200
|
11
|
+
janito/agent/conversation_exceptions.py,sha256=Aw7PRLb3eUfyDOGynKds5F48dgjyiOrTCEcWSprYC58,381
|
12
|
+
janito/agent/conversation_tool_calls.py,sha256=CJateY04z27ZHMorb5I4DpaeqFnjhX25uBjg1Foxpb0,1459
|
13
|
+
janito/agent/conversation_ui.py,sha256=y4f0IoJQoWGrFMB3yi7uIwXokuTjhFtJGK_R7zcTv3w,397
|
14
|
+
janito/agent/event.py,sha256=1jcua88NT-T4jA0mGIyIF1LvqXKu2GDT8NMjlelWmCI,517
|
15
|
+
janito/agent/event_dispatcher.py,sha256=eFNDfGY8o63yNLFdMe82LqfmDyGWjrAw9CpyUAcLJAM,856
|
16
|
+
janito/agent/event_handler_protocol.py,sha256=uIIf9u82BWm8pha4sZxydeEwgbxDoiWVSyplBPI0knE,130
|
17
|
+
janito/agent/event_system.py,sha256=QxPSQ2XeTyiWV6ejcmS8kTqTBrs7fLHRVXdhyeVHpas,608
|
18
|
+
janito/agent/message_handler.py,sha256=oZJ2u0C7OewHiHwlJslT2o3RPlvY2HhPXPoRcSsBv4M,856
|
19
|
+
janito/agent/message_handler_protocol.py,sha256=E8PLl9ucNvPK_xmhLEkV-vhQzfO_P_BMvzpqDvUkcVY,150
|
20
|
+
janito/agent/openai_client.py,sha256=oPbDFQoYzzD7XWw9E_4C_eqERc3Y5DkWyUcYRl7L8cs,4638
|
21
|
+
janito/agent/openai_schema_generator.py,sha256=WIE2kQYB0bPe_0IV3vA6OJHoW-uJr5ezHENNkmbH8bg,5762
|
22
|
+
janito/agent/platform_discovery.py,sha256=yp6KTvc-_u22Dr8-J4cdjVMUS8HkCf343aeSGRu2wek,2712
|
23
|
+
janito/agent/profile_manager.py,sha256=B-bwo1ZhtD2DaVPAfn0bNv1_inoduZhKGd694Pfy5GM,3231
|
24
|
+
janito/agent/queued_message_handler.py,sha256=sjsZneGWkqvfuJNac9QERdHasp9lWZvNcow8dul7tVU,1844
|
25
|
+
janito/agent/rich_live.py,sha256=NKWU89hRakiJ-0N6FPg40bYREOxQizqicbDv9eUfsKs,927
|
26
|
+
janito/agent/rich_message_handler.py,sha256=cSeTvdgHAPoSDddd5kFQNG2RnGj9kYMfuq6nzhtyJuE,2401
|
27
|
+
janito/agent/runtime_config.py,sha256=xSx0-RD-WVA9niSCEmEn2ZPLFbQfRhPwwGIa8tid_v8,901
|
28
|
+
janito/agent/test_handler_protocols.py,sha256=4o1IitFDUN1fdw48oQCRizKWahahumdmEZ4URHrlmiY,1404
|
29
|
+
janito/agent/tool_base.py,sha256=rf88iEX_uZ7MwkeDl4gGMtHeESg0dlFKUo2Jr_ZqDTY,1900
|
30
|
+
janito/agent/tool_executor.py,sha256=ltYdegI2-xpFZXVqclh3-Dv-yJEv3vIIuxZjirJovfI,4246
|
31
|
+
janito/agent/tool_registry.py,sha256=FlZ8YEoHdk2n7t8vZ26bVbu-fi4UeSE_yu2mZq8pusU,1594
|
32
|
+
janito/agent/tool_use_tracker.py,sha256=WJ1Pi5VlzDLrh-iDL3hNTC9IBfqr2QRPaz3n9w32q3o,1546
|
33
|
+
janito/agent/templates/profiles/system_prompt_template_base.txt.j2,sha256=-cSdepK7LC-d7iCFOreRnA5aYiaFuUvfrOSMWfz0_4s,676
|
34
|
+
janito/agent/templates/profiles/system_prompt_template_base_pt.txt.j2,sha256=FX8piXbR9XNOEKkOSMt4ieZ2wn5fzQlffeQFf8d7gIc,723
|
35
|
+
janito/agent/tests/__init__.py,sha256=QuXHKEzUJ_DooaKqenv_tKuNH-HabuIVZhvW5JNaeIc,52
|
36
|
+
janito/agent/tools/__init__.py,sha256=ulJfUtzEJFp8iPkpF6wSkNjSwqOZzePPuTY4WuFvIWE,1063
|
37
|
+
janito/agent/tools/ask_user.py,sha256=DL-jBU-njSjwhNSbgi23RZCrRBt5beDgZq_PG4yzbWM,3217
|
38
|
+
janito/agent/tools/create_directory.py,sha256=KQKt4o9pRu3ruDO9hDOxkcpzuyqxUqKlez5YFudKuXw,2481
|
39
|
+
janito/agent/tools/create_file.py,sha256=cmPhLIl_MozLIQZM38yQHC1a5R_jjFh8ZeqlFuWnETQ,3524
|
40
|
+
janito/agent/tools/dir_walk_utils.py,sha256=aE2UjCmmpJckcBKujq-1dGUGLWu7ryyAA7EzIbXPVtw,656
|
41
|
+
janito/agent/tools/fetch_url.py,sha256=ZJJXk-6avQUX7ezT982LuwrnU0R0Lryo1g1M6_fs3V8,2131
|
42
|
+
janito/agent/tools/find_files.py,sha256=n8k1US3_T23uZzXVD5Zx2t_wre1uiLnqUzQMEpGLzh4,3156
|
43
|
+
janito/agent/tools/get_lines.py,sha256=rYl9E6w3WKDrO3nhxLofWgYrLjncfD2R6dwUwuF-M6o,5148
|
44
|
+
janito/agent/tools/gitignore_utils.py,sha256=fDLyRZmCu6Hqhp1BEN8hs7oG0FtA-1SM9TGDz4g0lbw,1470
|
45
|
+
janito/agent/tools/memory.py,sha256=vvFGGTHJkh_SuLIrd1yzrEyGg_jfytVrKNhUhvUpYyA,1745
|
46
|
+
janito/agent/tools/move_file.py,sha256=rkiw4sSlhn9DmUcKadg9oMVvjl2jPqNRn-qXSe1zBt0,4339
|
47
|
+
janito/agent/tools/present_choices.py,sha256=e7SpOs3RIUXL6zi6PoeFc64akTVVuiQe2yLrm0rKpNs,2327
|
48
|
+
janito/agent/tools/present_choices_test.py,sha256=YYFki84vV1FT4MKnBgiwamjZyxUb2g5RDFQKmFF8Vdc,625
|
49
|
+
janito/agent/tools/remove_directory.py,sha256=aDNhXkUGHQU8bXIoIXjytYhODQFysjUerApBOOOa-1Y,2409
|
50
|
+
janito/agent/tools/remove_file.py,sha256=B5HOFCDhB8AgHgcgzMz_0y10yzPV7BSDrMwVYuMg1i4,2336
|
51
|
+
janito/agent/tools/replace_text_in_file.py,sha256=AZGPf4pjgAGqKlvvNdnbVTKZZkOgvyFEokg-5yPYE-w,9435
|
52
|
+
janito/agent/tools/rich_live.py,sha256=KpAN-dF0h9LZnYvSK-UKR_sbDnnDw0jUxY3cj_EW_wQ,1215
|
53
|
+
janito/agent/tools/run_bash_command.py,sha256=zJ08AC7oRMOTaRs34IVsGw3DuFM_KFicSkxWo6y86dU,7556
|
54
|
+
janito/agent/tools/run_powershell_command.py,sha256=Vgy4eghQ_x0AFvzj7n_-scOCzsATBpUAfa9SnIfUSjc,7863
|
55
|
+
janito/agent/tools/run_python_command.py,sha256=3cI7Vb63Aeogb0zp5AKqwNF4CysrDSMVXCaBGpeqdqs,7041
|
56
|
+
janito/agent/tools/search_outline.py,sha256=ubSvovxCRszrmSZ3NTgrbqadJ_lEAO8ohq910iyd7zw,698
|
57
|
+
janito/agent/tools/search_text.py,sha256=eYk70KW24syvdPtFku1-_dpdcM2vgmcu-B37XlcMJ1U,9240
|
58
|
+
janito/agent/tools/tools_utils.py,sha256=NNKRfzFpqUR7gS4RKmigO7PM9WAw_M6mkQH1c4rHKDg,2090
|
59
|
+
janito/agent/tools/utils.py,sha256=igD1FBUFCmzSxt8WQRbLEYqXngupXrhfdzquYaWv4ng,932
|
60
|
+
janito/agent/tools/validate_file_syntax.py,sha256=ngxkb85YwDbraiJXiWwPCA3wTZJTv_KgBu8uv0KuBHY,7558
|
61
|
+
janito/agent/tools/outline_file/__init__.py,sha256=Y3UK2zE8UnZyM9mOIKHMr38_8x1BhtYWWsg4luRmOVQ,3315
|
62
|
+
janito/agent/tools/outline_file/formatting.py,sha256=AB44kMT6LRVW2fNqX2u2Re7B1Dy3qqObfQHRhcDd9Ow,913
|
63
|
+
janito/agent/tools/outline_file/markdown_outline.py,sha256=bXEBg0D93tEBDNy8t-wh4i7WxsxfpQ2C3dX1_rmtj08,434
|
64
|
+
janito/agent/tools/outline_file/python_outline.py,sha256=8Y6UYRSSrFmhndwGUTQacVIvFZvPVu8B91oqZhia4q8,2571
|
65
|
+
janito/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
66
|
+
janito/cli/_print_config.py,sha256=C_27QdwzhqorzeJflBFK0f46zTUtqqmdYe3EBurjOOE,3574
|
67
|
+
janito/cli/_utils.py,sha256=tRAUMDWKczd81ZvKYkwpsHWSeLzQoVlOoQ-lOw9Iujw,291
|
68
|
+
janito/cli/arg_parser.py,sha256=fnR9hKmQn_aIZz4hT8kr7tq31KDjkkFW-boNsrcPau8,6873
|
69
|
+
janito/cli/config_commands.py,sha256=vfU7XciVMRNR5kDvn6tnCo1PLvSEXg0Y0PzLcDEFI9w,8539
|
70
|
+
janito/cli/logging_setup.py,sha256=_KLF69xqq1xLPIfkXxy0EIewO-Ef2eYoxNVjqjsC0vc,1361
|
71
|
+
janito/cli/main.py,sha256=Njsvs-x22p4WumR0Z4lpG3KwRz18hoSQBdiGAW9Tces,5312
|
72
|
+
janito/cli/termweb_starter.py,sha256=Ky9qJPQ8nY3TOeDHmq-IZvWNZa4m68IVeCZqNTQ9RFY,2795
|
73
|
+
janito/cli/runner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
74
|
+
janito/cli/runner/_termweb_log_utils.py,sha256=QpH40uxPhksrJHWqthW4cR7BhcSSYakpza_qTeFGABs,722
|
75
|
+
janito/cli/runner/cli_main.py,sha256=Y74v_F39XCCkrv0aAJTXXNZQfdBjoISZYGkefrZNJf8,6880
|
76
|
+
janito/cli/runner/config.py,sha256=Nzam25C8P55dFlT_f6IlEj2ZvFwS63AAbnkIWe3oNsg,1702
|
77
|
+
janito/cli/runner/formatting.py,sha256=k0mtHoglqR8fKcebSK81iWTT_EL-gDl7eNfjlFZRY6g,287
|
78
|
+
janito/cli_chat_shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
79
|
+
janito/cli_chat_shell/chat_loop.py,sha256=DNuM2VM6FOjcY-2017HCiGeX6hO_9f0iBqlrTO-FpXo,5832
|
80
|
+
janito/cli_chat_shell/chat_state.py,sha256=Gf8gyh60SYdD_G5rSwJTKto96UHVaPrQlkRcceoN8yU,1221
|
81
|
+
janito/cli_chat_shell/chat_ui.py,sha256=3cw2Mu4u0T60malPy-SXFA3vW0MtGMCQcHAZYO-Irfw,1272
|
82
|
+
janito/cli_chat_shell/config_shell.py,sha256=sG04S_z27wI7nXKMaVDcwDpBCuo6Cvd4uhutUQesJKo,3807
|
83
|
+
janito/cli_chat_shell/load_prompt.py,sha256=gHedc5TtaFBKiGgwRM_u9nVnBuLHDTSa8VPlPOtoMEA,2125
|
84
|
+
janito/cli_chat_shell/session_manager.py,sha256=J3K5fzObwjIDSUfyKOdr8Db2jcoFGf1M4nmtYhQXpq4,2365
|
85
|
+
janito/cli_chat_shell/shell_command_completer.py,sha256=bEpfHlMqmGlTeV2wzl0xSungEl1_2eo488qxx5_ia1w,764
|
86
|
+
janito/cli_chat_shell/ui.py,sha256=6wqKFSJyILPLnzwoAVpkqFc95Mh8HkLr9DN3Sl6mC-k,7213
|
87
|
+
janito/cli_chat_shell/commands/__init__.py,sha256=3rpT6fFPP50qEePRQNOIQmmuU0U7bKRK9DnHZ0pNkNU,1777
|
88
|
+
janito/cli_chat_shell/commands/config.py,sha256=JTQwIuSBunxDwvGsU_Cu78GkQNYCtDFTPZ7HOxNOZCY,945
|
89
|
+
janito/cli_chat_shell/commands/history_start.py,sha256=JUwxaKatqMWWn0yCC5S2YDVVTfAQCpJG6oPBuW4nYWo,1139
|
90
|
+
janito/cli_chat_shell/commands/lang.py,sha256=cG_gX61LUgzv_Bxk-UPTTNF1JQFfcUVaYBnPovUylNw,521
|
91
|
+
janito/cli_chat_shell/commands/prompt.py,sha256=YVW1uHfYVPPNvcGoQeHWOwyfpGhCAgSmv670xjRnLs4,1713
|
92
|
+
janito/cli_chat_shell/commands/session.py,sha256=64H9UYB-LRSWzMar_C7iNM06MqrKmpRm_Dk9XXIMCiM,1739
|
93
|
+
janito/cli_chat_shell/commands/session_control.py,sha256=m4SolmEi7RMHe4WZiUlHQfTIzS0KDT_PYqvnetEm4fs,1398
|
94
|
+
janito/cli_chat_shell/commands/sum.py,sha256=S_46ubHUnGoLNwL5_0VeDmA5YYo99aX8baZuBdU1gZ8,1829
|
95
|
+
janito/cli_chat_shell/commands/termweb_log.py,sha256=6hU2K-cZUHCC1-l7bBMjyB6illSX_eB28opdGa9dz6g,3219
|
96
|
+
janito/cli_chat_shell/commands/utility.py,sha256=PdCkb4UpvyE5jr5o_zZpgfiCXzH4ma_3FjAl2_y0qsU,1145
|
97
|
+
janito/cli_chat_shell/commands/verbose.py,sha256=woN1-suIGBnoxTzkoZomOrK6KEl64mDPc0bgO3ToBOI,997
|
98
|
+
janito/i18n/__init__.py,sha256=7HYvwOTTf51pVm4adU79rl1FCtAjgOy6GzeShfYCdQY,970
|
99
|
+
janito/i18n/messages.py,sha256=fBuwOTFoygyHPkYphm6Y0r1iE8497Z4iryVAmPhMEkg,1851
|
100
|
+
janito/i18n/pt.py,sha256=52-ENCIrPW4A1tXFRT28xA8TwuUFoihs6ezJj-m3-Y4,4260
|
101
|
+
janito/termweb/app.py,sha256=TO_oWHGqrud4Fhf4DcExc40hCHzyO3P99pZm4oA5INM,3374
|
102
|
+
janito/termweb/static/editor.html,sha256=T5IeILW4yFIm5ZbNTqUJjqDldv7ACIdHF8AsZdv7T9M,8859
|
103
|
+
janito/termweb/static/editor.html.bak,sha256=rFm5Y_-Rh_03Hs19gzfVu3IBmljIsuPduen2gDKQEyg,8862
|
104
|
+
janito/termweb/static/explorer.html.bak,sha256=PM1fcbaQJm545WT94mVEekUNW3jduBAHOz6rwJBR1FA,2568
|
105
|
+
janito/termweb/static/favicon.ico,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
106
|
+
janito/termweb/static/favicon.ico.bak,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
107
|
+
janito/termweb/static/index.html,sha256=MCCF7ncTEBsE-c829jy3UnkVsIKmnfm0vt3s54cmwcQ,3124
|
108
|
+
janito/termweb/static/index.html.bak,sha256=SB6bQFktnZpJzMeo1CzlC82XkYpLcpLnjv1uMS-11FQ,3123
|
109
|
+
janito/termweb/static/index.html.bak.bak,sha256=dsKoC2lE0oJCGUUDTWcnIQE3s5Uoqd12WoTkWEwbH_c,6626
|
110
|
+
janito/termweb/static/landing.html.bak,sha256=JGwIcATj0B8MhHXLoXg2clypqsKJwi54NtW-rRDUsMs,1403
|
111
|
+
janito/termweb/static/termicon.svg,sha256=vc2Z3q-ADVK3pLzE3wnw_qpR6vDguWKEdH_pWObPjbw,229
|
112
|
+
janito/termweb/static/termweb.css,sha256=9AxhC2R8CzS82NHg9bk0GD-kxKt_NeRSRFGgTyi-3zI,4870
|
113
|
+
janito/termweb/static/termweb.css.bak,sha256=PICa5u6RgaXDg47EGOEn1Yt63k7Wm8mW1vc3zSUU-hs,6004
|
114
|
+
janito/termweb/static/termweb.js,sha256=SgXq3FWGl4ltUeQeamT6YRQJ7RFdy9EPaD6iSvq1uSs,9093
|
115
|
+
janito/termweb/static/termweb.js.bak,sha256=Y62Uew5kb3I6Fs5hZBcREArymigU7NHHrKdoaswqjyc,9131
|
116
|
+
janito/termweb/static/termweb.js.bak.bak,sha256=SQeqc9YwdreCmFJ7LtCYlHOjRHi8rsoW_fZ3x5WroWQ,7692
|
117
|
+
janito/termweb/static/termweb_quickopen.js,sha256=HNT85JjWAvjI5ROwukOU-oI4ZVVjCO6yg5IT115pdXI,5379
|
118
|
+
janito/termweb/static/termweb_quickopen.js.bak,sha256=sk_zbEw6HJt1iZSAYlaW0qAhq0to-KcBsOKx0AZqkKA,4814
|
119
|
+
janito/web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
120
|
+
janito/web/__main__.py,sha256=5Ck6okOZmxKYkQ-ir4mxXDH7XWMNR-9szgsm0UyQLE0,734
|
121
|
+
janito/web/app.py,sha256=NarccXYgeYEMvws1lQSGZtArrzJIvw94LSNR0rW9Dq4,7331
|
122
|
+
janito-1.8.0.dist-info/licenses/LICENSE,sha256=sHBqv0bvtrb29H7WRR-Z603YHm9pLtJIo3nHU_9cmgE,1091
|
123
|
+
janito-1.8.0.dist-info/METADATA,sha256=3F51ULeTzBgxUVFZs5cemk1bX1ZFUfRfzpFr6V0WTK8,12479
|
124
|
+
janito-1.8.0.dist-info/WHEEL,sha256=ck4Vq1_RXyvS4Jt6SI0Vz6fyVs4GWg7AINwpsaGEgPE,91
|
125
|
+
janito-1.8.0.dist-info/entry_points.txt,sha256=wIo5zZxbmu4fC-ZMrsKD0T0vq7IqkOOLYhrqRGypkx4,48
|
126
|
+
janito-1.8.0.dist-info/top_level.txt,sha256=m0NaVCq0-ivxbazE2-ND0EA9Hmuijj_OGkmCbnBcCig,7
|
127
|
+
janito-1.8.0.dist-info/RECORD,,
|
@@ -1,117 +0,0 @@
|
|
1
|
-
from janito.agent.tool_base import ToolBase
|
2
|
-
from janito.agent.tool_registry import register_tool
|
3
|
-
import os
|
4
|
-
import re
|
5
|
-
from typing import List
|
6
|
-
|
7
|
-
|
8
|
-
@register_tool(name="get_file_outline")
|
9
|
-
class GetFileOutlineTool(ToolBase):
|
10
|
-
"""
|
11
|
-
Get an outline of a file's structure.
|
12
|
-
|
13
|
-
Note:
|
14
|
-
The outline extraction for Python files is based on regular expression (regex) pattern matching for class and function definitions.
|
15
|
-
This approach may not capture all edge cases or non-standard code structures. For complex files, further examination or more advanced parsing may be required.
|
16
|
-
|
17
|
-
Args:
|
18
|
-
file_path (str): Path to the file.
|
19
|
-
Returns:
|
20
|
-
str: Outline of the file's structure, starting with a summary line. Example:
|
21
|
-
- "Outline: 5 items (python)\n| Type | Name | Start | End | Parent |\n|---------|-------------|-------|-----|----------|\n| class | MyClass | 1 | 20 | |\n| method | my_method | 3 | 10 | MyClass |\n| function| my_func | 22 | 30 | |\n..."
|
22
|
-
- "Outline: 100 lines (default)\nFile has 100 lines."
|
23
|
-
- "Error reading file: <error message>"
|
24
|
-
"""
|
25
|
-
|
26
|
-
def call(self, file_path: str) -> str:
|
27
|
-
from janito.agent.tools.tools_utils import display_path
|
28
|
-
|
29
|
-
disp_path = display_path(file_path)
|
30
|
-
self.report_info(f"📄 Getting outline for: {disp_path}")
|
31
|
-
|
32
|
-
try:
|
33
|
-
ext = os.path.splitext(file_path)[1].lower()
|
34
|
-
with open(file_path, "r", encoding="utf-8", errors="replace") as f:
|
35
|
-
lines = f.readlines()
|
36
|
-
if ext == ".py":
|
37
|
-
outline_items = self._parse_python_outline(lines)
|
38
|
-
outline_type = "python"
|
39
|
-
table = self._format_outline_table(outline_items)
|
40
|
-
self.report_success(f"✅ {len(outline_items)} items ({outline_type})")
|
41
|
-
return f"Outline: {len(outline_items)} items ({outline_type})\n" + table
|
42
|
-
else:
|
43
|
-
outline_type = "default"
|
44
|
-
self.report_success(f"✅ {len(lines)} lines ({outline_type})")
|
45
|
-
return f"Outline: {len(lines)} lines ({outline_type})\nFile has {len(lines)} lines."
|
46
|
-
except Exception as e:
|
47
|
-
self.report_error(f"❌ Error reading file: {e}")
|
48
|
-
return f"Error reading file: {e}"
|
49
|
-
|
50
|
-
def _parse_python_outline(self, lines: List[str]):
|
51
|
-
# Regex for class, function, and method definitions
|
52
|
-
class_pat = re.compile(r"^(\s*)class\s+(\w+)")
|
53
|
-
func_pat = re.compile(r"^(\s*)def\s+(\w+)")
|
54
|
-
outline = []
|
55
|
-
stack = [] # (name, type, indent, start, parent)
|
56
|
-
for idx, line in enumerate(lines):
|
57
|
-
class_match = class_pat.match(line)
|
58
|
-
func_match = func_pat.match(line)
|
59
|
-
indent = len(line) - len(line.lstrip())
|
60
|
-
if class_match:
|
61
|
-
name = class_match.group(2)
|
62
|
-
parent = stack[-1][1] if stack and stack[-1][0] == "class" else ""
|
63
|
-
stack.append(("class", name, indent, idx + 1, parent))
|
64
|
-
elif func_match:
|
65
|
-
name = func_match.group(2)
|
66
|
-
parent = (
|
67
|
-
stack[-1][1]
|
68
|
-
if stack
|
69
|
-
and stack[-1][0] in ("class", "function")
|
70
|
-
and indent > stack[-1][2]
|
71
|
-
else ""
|
72
|
-
)
|
73
|
-
stack.append(("function", name, indent, idx + 1, parent))
|
74
|
-
# Pop stack if indentation decreases
|
75
|
-
while stack and indent < stack[-1][2]:
|
76
|
-
popped = stack.pop()
|
77
|
-
outline.append(
|
78
|
-
{
|
79
|
-
"type": (
|
80
|
-
popped[0]
|
81
|
-
if popped[0] != "function" or popped[3] == 1
|
82
|
-
else ("method" if popped[4] else "function")
|
83
|
-
),
|
84
|
-
"name": popped[1],
|
85
|
-
# Add end line for popped item
|
86
|
-
"start": popped[3],
|
87
|
-
"end": idx,
|
88
|
-
"parent": popped[4],
|
89
|
-
}
|
90
|
-
)
|
91
|
-
# Pop any remaining items in the stack at EOF
|
92
|
-
for popped in stack:
|
93
|
-
outline.append(
|
94
|
-
{
|
95
|
-
"type": (
|
96
|
-
popped[0]
|
97
|
-
if popped[0] != "function" or popped[3] == 1
|
98
|
-
else ("method" if popped[4] else "function")
|
99
|
-
),
|
100
|
-
"name": popped[1],
|
101
|
-
"start": popped[3],
|
102
|
-
"end": len(lines),
|
103
|
-
"parent": popped[4],
|
104
|
-
}
|
105
|
-
)
|
106
|
-
return outline
|
107
|
-
|
108
|
-
def _format_outline_table(self, outline_items):
|
109
|
-
if not outline_items:
|
110
|
-
return "No classes or functions found."
|
111
|
-
header = "| Type | Name | Start | End | Parent |\n|---------|-------------|-------|-----|----------|"
|
112
|
-
rows = []
|
113
|
-
for item in outline_items:
|
114
|
-
rows.append(
|
115
|
-
f"| {item['type']:<7} | {item['name']:<11} | {item['start']:<5} | {item['end']:<3} | {item['parent']:<8} |"
|
116
|
-
)
|
117
|
-
return header + "\n" + "\n".join(rows)
|
@@ -1,40 +0,0 @@
|
|
1
|
-
from janito.agent.tool_base import ToolBase
|
2
|
-
from janito.agent.tool_registry import register_tool
|
3
|
-
|
4
|
-
from typing import Optional
|
5
|
-
import py_compile
|
6
|
-
|
7
|
-
|
8
|
-
@register_tool(name="py_compile_file")
|
9
|
-
class PyCompileFileTool(ToolBase):
|
10
|
-
"""
|
11
|
-
Validate a Python file by compiling it with py_compile.
|
12
|
-
Useful to validate python files after changing them, especially after import changes.
|
13
|
-
|
14
|
-
Args:
|
15
|
-
file_path (str): Path to the Python file to compile.
|
16
|
-
doraise (bool, optional): Whether to raise exceptions on compilation errors. Defaults to True.
|
17
|
-
Returns:
|
18
|
-
str: Compilation status message. Example:
|
19
|
-
- "✅ Compiled"
|
20
|
-
- "Compile error: <error message>"
|
21
|
-
- "Error: <error message>"
|
22
|
-
"""
|
23
|
-
|
24
|
-
def call(self, file_path: str, doraise: Optional[bool] = True) -> str:
|
25
|
-
self.report_info(f"🛠️ Compiling Python file: {file_path}")
|
26
|
-
|
27
|
-
if not (file_path.endswith(".py") or file_path.endswith(".pyw")):
|
28
|
-
msg = f"Error: {file_path} is not a Python (.py/.pyw) file."
|
29
|
-
self.report_error(f" [py_compile_file] {msg}")
|
30
|
-
return msg
|
31
|
-
try:
|
32
|
-
py_compile.compile(file_path, doraise=doraise)
|
33
|
-
self.report_success(" ✅ Compiled")
|
34
|
-
return "✅ Compiled"
|
35
|
-
except py_compile.PyCompileError as e:
|
36
|
-
self.report_error(f" [py_compile_file] Compile error: {e}")
|
37
|
-
return f"Compile error: {e}"
|
38
|
-
except Exception as e:
|
39
|
-
self.report_error(f" [py_compile_file] Error: {e}")
|
40
|
-
return f"Error: {e}"
|
@@ -1,51 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import shutil
|
3
|
-
from janito.agent.tool_registry import register_tool
|
4
|
-
from janito.agent.tools.utils import expand_path, display_path
|
5
|
-
from janito.agent.tool_base import ToolBase
|
6
|
-
|
7
|
-
|
8
|
-
@register_tool(name="replace_file")
|
9
|
-
class ReplaceFileTool(ToolBase):
|
10
|
-
"""
|
11
|
-
Overwrite (replace) a file with the given content. Creates the file if it does not exist.
|
12
|
-
|
13
|
-
Args:
|
14
|
-
path (str): Path to the file to overwrite or create.
|
15
|
-
content (str): Content to write to the file.
|
16
|
-
backup (bool, optional): If True, create a backup (.bak) before replacing if the file exists. Recommend using backup=True only in the first call to avoid redundant backups. Defaults to False.
|
17
|
-
Returns:
|
18
|
-
str: Status message indicating the result. Example:
|
19
|
-
- "\u2705 Successfully replaced the file at ..."
|
20
|
-
- "\u2705 Successfully created the file at ..."
|
21
|
-
"""
|
22
|
-
|
23
|
-
def call(self, path: str, content: str, backup: bool = False) -> str:
|
24
|
-
original_path = path
|
25
|
-
path = expand_path(path)
|
26
|
-
disp_path = display_path(original_path, path)
|
27
|
-
updating = os.path.exists(path) and not os.path.isdir(path)
|
28
|
-
if os.path.exists(path) and os.path.isdir(path):
|
29
|
-
self.report_error("\u274c Error: is a directory")
|
30
|
-
return (
|
31
|
-
f"\u274c Cannot replace file: '{disp_path}' is an existing directory."
|
32
|
-
)
|
33
|
-
# Ensure parent directories exist
|
34
|
-
dir_name = os.path.dirname(path)
|
35
|
-
if dir_name:
|
36
|
-
os.makedirs(dir_name, exist_ok=True)
|
37
|
-
if backup and os.path.exists(path) and not os.path.isdir(path):
|
38
|
-
shutil.copy2(path, path + ".bak")
|
39
|
-
with open(path, "w", encoding="utf-8", errors="replace") as f:
|
40
|
-
f.write(content)
|
41
|
-
new_lines = content.count("\n") + 1 if content else 0
|
42
|
-
if updating:
|
43
|
-
self.report_success(
|
44
|
-
f"\u2705 Successfully replaced the file at '{disp_path}' ({new_lines} lines)."
|
45
|
-
)
|
46
|
-
return f"\u2705 Successfully replaced the file at '{disp_path}' ({new_lines} lines)."
|
47
|
-
else:
|
48
|
-
self.report_success(
|
49
|
-
f"\u2705 Successfully created the file at '{disp_path}' ({new_lines} lines)."
|
50
|
-
)
|
51
|
-
return f"\u2705 Successfully created the file at '{disp_path}' ({new_lines} lines)."
|
@@ -1,71 +0,0 @@
|
|
1
|
-
from janito.agent.tool_base import ToolBase
|
2
|
-
from janito.agent.tool_registry import register_tool
|
3
|
-
from janito.agent.tools.tools_utils import pluralize
|
4
|
-
|
5
|
-
import os
|
6
|
-
from janito.agent.tools.gitignore_utils import filter_ignored
|
7
|
-
|
8
|
-
|
9
|
-
@register_tool(name="search_files")
|
10
|
-
class SearchFilesTool(ToolBase):
|
11
|
-
"""
|
12
|
-
Search for a text pattern in all files within a directory and return matching lines. Respects .gitignore.
|
13
|
-
|
14
|
-
Args:
|
15
|
-
directories (list[str]): List of directories to search in.
|
16
|
-
pattern (str): Plain text substring to search for in files. (Not a regular expression or glob pattern.)
|
17
|
-
recursive (bool): Whether to search recursively in subdirectories. Defaults to True.
|
18
|
-
max_depth (int, optional): Maximum directory depth to search (0 = only top-level). If None, unlimited. Defaults to None.
|
19
|
-
Returns:
|
20
|
-
str: Matching lines from files as a newline-separated string, each formatted as 'filepath:lineno: line'. Example:
|
21
|
-
- "/path/to/file.py:10: def my_function():"
|
22
|
-
- "Warning: Empty search pattern provided. Operation skipped."
|
23
|
-
"""
|
24
|
-
|
25
|
-
def call(
|
26
|
-
self,
|
27
|
-
directories: list[str],
|
28
|
-
pattern: str,
|
29
|
-
recursive: bool = True,
|
30
|
-
max_depth: int = None,
|
31
|
-
) -> str:
|
32
|
-
if not pattern:
|
33
|
-
self.report_warning(
|
34
|
-
"⚠️ Warning: Empty search pattern provided. Operation skipped."
|
35
|
-
)
|
36
|
-
return "Warning: Empty search pattern provided. Operation skipped."
|
37
|
-
output = []
|
38
|
-
for directory in directories:
|
39
|
-
info_str = f"🔎 Searching for text '{pattern}' in '{directory}'"
|
40
|
-
if recursive is False:
|
41
|
-
info_str += f" (recursive={recursive})"
|
42
|
-
self.report_info(info_str)
|
43
|
-
if recursive:
|
44
|
-
walker = os.walk(directory)
|
45
|
-
else:
|
46
|
-
# Only the top directory, not recursive
|
47
|
-
dirs, files = filter_ignored(
|
48
|
-
directory, *os.walk(directory).__next__()[1:]
|
49
|
-
)
|
50
|
-
walker = [(directory, dirs, files)]
|
51
|
-
for root, dirs, files in walker:
|
52
|
-
# Calculate depth
|
53
|
-
rel_path = os.path.relpath(root, directory)
|
54
|
-
depth = 0 if rel_path == "." else rel_path.count(os.sep) + 1
|
55
|
-
if max_depth is not None and depth > max_depth:
|
56
|
-
dirs[:] = []
|
57
|
-
continue
|
58
|
-
if not recursive and depth > 0:
|
59
|
-
break
|
60
|
-
dirs, files = filter_ignored(root, dirs, files)
|
61
|
-
for filename in files:
|
62
|
-
path = os.path.join(root, filename)
|
63
|
-
try:
|
64
|
-
with open(path, "r", encoding="utf-8", errors="ignore") as f:
|
65
|
-
for lineno, line in enumerate(f, 1):
|
66
|
-
if pattern in line:
|
67
|
-
output.append(f"{path}:{lineno}: {line.strip()}")
|
68
|
-
except Exception:
|
69
|
-
continue
|
70
|
-
self.report_success(f" ✅ {len(output)} {pluralize('line', len(output))} found")
|
71
|
-
return "\n".join(output)
|