janito 1.6.0__tar.gz → 1.8.0__tar.gz
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-1.8.0/MANIFEST.in +6 -0
- {janito-1.6.0 → janito-1.8.0}/PKG-INFO +73 -32
- {janito-1.6.0 → janito-1.8.0}/README.md +66 -29
- janito-1.8.0/janito/__init__.py +1 -0
- {janito-1.6.0 → janito-1.8.0}/janito/agent/config.py +3 -3
- {janito-1.6.0 → janito-1.8.0}/janito/agent/config_defaults.py +3 -2
- {janito-1.6.0 → janito-1.8.0}/janito/agent/conversation.py +73 -27
- janito-1.8.0/janito/agent/conversation_api.py +198 -0
- {janito-1.6.0 → janito-1.8.0}/janito/agent/conversation_exceptions.py +6 -0
- janito-1.8.0/janito/agent/conversation_tool_calls.py +36 -0
- janito-1.8.0/janito/agent/event.py +24 -0
- janito-1.8.0/janito/agent/event_dispatcher.py +24 -0
- janito-1.8.0/janito/agent/event_handler_protocol.py +5 -0
- janito-1.8.0/janito/agent/event_system.py +15 -0
- {janito-1.6.0 → janito-1.8.0}/janito/agent/message_handler.py +4 -1
- janito-1.8.0/janito/agent/message_handler_protocol.py +5 -0
- {janito-1.6.0 → janito-1.8.0}/janito/agent/openai_client.py +5 -6
- {janito-1.6.0 → janito-1.8.0}/janito/agent/openai_schema_generator.py +23 -4
- janito-1.8.0/janito/agent/platform_discovery.py +90 -0
- janito-1.8.0/janito/agent/profile_manager.py +96 -0
- {janito-1.6.0 → janito-1.8.0}/janito/agent/queued_message_handler.py +22 -3
- {janito-1.6.0 → janito-1.8.0}/janito/agent/rich_message_handler.py +3 -1
- janito-1.8.0/janito/agent/templates/profiles/system_prompt_template_base.txt.j2 +14 -0
- janito-1.8.0/janito/agent/templates/profiles/system_prompt_template_base_pt.txt.j2 +13 -0
- janito-1.8.0/janito/agent/test_handler_protocols.py +47 -0
- janito-1.8.0/janito/agent/tests/__init__.py +1 -0
- {janito-1.6.0 → janito-1.8.0}/janito/agent/tool_base.py +1 -1
- janito-1.8.0/janito/agent/tool_executor.py +109 -0
- janito-1.8.0/janito/agent/tool_registry.py +46 -0
- janito-1.8.0/janito/agent/tool_use_tracker.py +46 -0
- {janito-1.6.0 → janito-1.8.0}/janito/agent/tools/__init__.py +11 -8
- {janito-1.6.0 → janito-1.8.0}/janito/agent/tools/ask_user.py +26 -12
- janito-1.8.0/janito/agent/tools/create_directory.py +65 -0
- janito-1.8.0/janito/agent/tools/create_file.py +78 -0
- janito-1.8.0/janito/agent/tools/dir_walk_utils.py +16 -0
- {janito-1.6.0 → janito-1.8.0}/janito/agent/tools/fetch_url.py +10 -11
- janito-1.8.0/janito/agent/tools/find_files.py +69 -0
- janito-1.8.0/janito/agent/tools/get_lines.py +111 -0
- janito-1.8.0/janito/agent/tools/memory.py +48 -0
- janito-1.8.0/janito/agent/tools/move_file.py +108 -0
- janito-1.8.0/janito/agent/tools/outline_file/__init__.py +85 -0
- janito-1.8.0/janito/agent/tools/outline_file/formatting.py +20 -0
- janito-1.8.0/janito/agent/tools/outline_file/markdown_outline.py +14 -0
- janito-1.8.0/janito/agent/tools/outline_file/python_outline.py +71 -0
- janito-1.8.0/janito/agent/tools/present_choices.py +62 -0
- janito-1.8.0/janito/agent/tools/present_choices_test.py +18 -0
- janito-1.8.0/janito/agent/tools/remove_directory.py +55 -0
- janito-1.8.0/janito/agent/tools/remove_file.py +58 -0
- janito-1.8.0/janito/agent/tools/replace_text_in_file.py +216 -0
- janito-1.8.0/janito/agent/tools/run_bash_command.py +171 -0
- janito-1.8.0/janito/agent/tools/run_powershell_command.py +169 -0
- {janito-1.6.0 → janito-1.8.0}/janito/agent/tools/run_python_command.py +53 -29
- janito-1.8.0/janito/agent/tools/search_outline.py +17 -0
- janito-1.8.0/janito/agent/tools/search_text.py +208 -0
- janito-1.8.0/janito/agent/tools/tools_utils.py +56 -0
- janito-1.8.0/janito/agent/tools/utils.py +33 -0
- janito-1.8.0/janito/agent/tools/validate_file_syntax.py +163 -0
- {janito-1.6.0 → janito-1.8.0}/janito/cli/_print_config.py +1 -1
- {janito-1.6.0 → janito-1.8.0}/janito/cli/arg_parser.py +36 -4
- {janito-1.6.0 → janito-1.8.0}/janito/cli/config_commands.py +1 -1
- {janito-1.6.0 → janito-1.8.0}/janito/cli/logging_setup.py +7 -2
- janito-1.8.0/janito/cli/main.py +135 -0
- janito-1.8.0/janito/cli/runner/_termweb_log_utils.py +17 -0
- janito-1.8.0/janito/cli/runner/cli_main.py +180 -0
- {janito-1.6.0 → janito-1.8.0}/janito/cli/runner/config.py +6 -4
- janito-1.8.0/janito/cli/termweb_starter.py +73 -0
- {janito-1.6.0 → janito-1.8.0}/janito/cli_chat_shell/chat_loop.py +52 -13
- {janito-1.6.0 → janito-1.8.0}/janito/cli_chat_shell/chat_state.py +1 -1
- {janito-1.6.0 → janito-1.8.0}/janito/cli_chat_shell/chat_ui.py +2 -3
- {janito-1.6.0 → janito-1.8.0}/janito/cli_chat_shell/commands/__init__.py +17 -6
- janito-1.6.0/janito/cli_chat_shell/commands/history_reset.py → janito-1.8.0/janito/cli_chat_shell/commands/history_start.py +13 -5
- janito-1.8.0/janito/cli_chat_shell/commands/lang.py +16 -0
- janito-1.8.0/janito/cli_chat_shell/commands/prompt.py +42 -0
- janito-1.8.0/janito/cli_chat_shell/commands/session_control.py +47 -0
- janito-1.8.0/janito/cli_chat_shell/commands/sum.py +49 -0
- janito-1.8.0/janito/cli_chat_shell/commands/termweb_log.py +86 -0
- {janito-1.6.0 → janito-1.8.0}/janito/cli_chat_shell/commands/utility.py +5 -2
- janito-1.8.0/janito/cli_chat_shell/commands/verbose.py +29 -0
- janito-1.8.0/janito/cli_chat_shell/load_prompt.py +57 -0
- {janito-1.6.0 → janito-1.8.0}/janito/cli_chat_shell/session_manager.py +9 -1
- janito-1.8.0/janito/cli_chat_shell/shell_command_completer.py +20 -0
- janito-1.8.0/janito/cli_chat_shell/ui.py +189 -0
- janito-1.8.0/janito/i18n/__init__.py +35 -0
- janito-1.8.0/janito/i18n/messages.py +23 -0
- janito-1.8.0/janito/i18n/pt.py +46 -0
- {janito-1.6.0 → janito-1.8.0}/janito/rich_utils.py +43 -43
- janito-1.8.0/janito/termweb/app.py +95 -0
- janito-1.8.0/janito/termweb/static/editor.html +238 -0
- janito-1.8.0/janito/termweb/static/editor.html.bak +238 -0
- janito-1.8.0/janito/termweb/static/explorer.html.bak +59 -0
- janito-1.8.0/janito/termweb/static/favicon.ico +0 -0
- janito-1.8.0/janito/termweb/static/favicon.ico.bak +0 -0
- janito-1.8.0/janito/termweb/static/index.html +55 -0
- janito-1.8.0/janito/termweb/static/index.html.bak +55 -0
- janito-1.8.0/janito/termweb/static/index.html.bak.bak +175 -0
- janito-1.8.0/janito/termweb/static/landing.html.bak +36 -0
- janito-1.8.0/janito/termweb/static/termicon.svg +1 -0
- janito-1.8.0/janito/termweb/static/termweb.css +235 -0
- janito-1.8.0/janito/termweb/static/termweb.css.bak +286 -0
- janito-1.8.0/janito/termweb/static/termweb.js +187 -0
- janito-1.8.0/janito/termweb/static/termweb.js.bak +187 -0
- janito-1.8.0/janito/termweb/static/termweb.js.bak.bak +157 -0
- janito-1.8.0/janito/termweb/static/termweb_quickopen.js +135 -0
- janito-1.8.0/janito/termweb/static/termweb_quickopen.js.bak +125 -0
- janito-1.8.0/janito/web/__init__.py +0 -0
- {janito-1.6.0 → janito-1.8.0}/janito/web/app.py +10 -13
- {janito-1.6.0 → janito-1.8.0}/janito.egg-info/PKG-INFO +73 -32
- {janito-1.6.0 → janito-1.8.0}/janito.egg-info/SOURCES.txt +64 -9
- {janito-1.6.0 → janito-1.8.0}/janito.egg-info/requires.txt +5 -0
- {janito-1.6.0 → janito-1.8.0}/pyproject.toml +18 -7
- janito-1.8.0/tests/test_memory_tool.py +49 -0
- janito-1.8.0/tests/test_run_powershell_command.py +15 -0
- janito-1.8.0/tests/test_set_role.py +37 -0
- janito-1.8.0/tests/test_sum_command.py +46 -0
- {janito-1.6.0 → janito-1.8.0}/tests/test_tool_registry_docstring_formats.py +4 -4
- {janito-1.6.0 → janito-1.8.0}/tests/test_tool_registry_manual_sim.py +19 -10
- {janito-1.6.0 → janito-1.8.0}/tests/test_tool_registry_validation.py +7 -3
- janito-1.8.0/tests/test_tool_use_tracker.py +38 -0
- {janito-1.6.0 → janito-1.8.0}/tests/test_tools.py +19 -0
- janito-1.8.0/tests/test_validate_file_syntax.py +66 -0
- janito-1.8.0/tests/test_validate_file_syntax_xml_html.py +42 -0
- janito-1.8.0/tests/test_validate_markdown_syntax.py +64 -0
- janito-1.6.0/janito/__init__.py +0 -1
- janito-1.6.0/janito/agent/conversation_api.py +0 -98
- janito-1.6.0/janito/agent/conversation_tool_calls.py +0 -22
- janito-1.6.0/janito/agent/profile_manager.py +0 -172
- janito-1.6.0/janito/agent/tool_registry.py +0 -118
- janito-1.6.0/janito/agent/tool_registry_core.py +0 -2
- janito-1.6.0/janito/agent/tools/create_directory.py +0 -33
- janito-1.6.0/janito/agent/tools/create_file.py +0 -47
- janito-1.6.0/janito/agent/tools/find_files.py +0 -60
- janito-1.6.0/janito/agent/tools/get_file_outline.py +0 -117
- janito-1.6.0/janito/agent/tools/get_lines.py +0 -76
- janito-1.6.0/janito/agent/tools/move_file.py +0 -59
- janito-1.6.0/janito/agent/tools/py_compile_file.py +0 -40
- janito-1.6.0/janito/agent/tools/remove_directory.py +0 -50
- janito-1.6.0/janito/agent/tools/remove_file.py +0 -40
- janito-1.6.0/janito/agent/tools/replace_file.py +0 -51
- janito-1.6.0/janito/agent/tools/replace_text_in_file.py +0 -117
- janito-1.6.0/janito/agent/tools/run_bash_command.py +0 -155
- janito-1.6.0/janito/agent/tools/search_files.py +0 -71
- janito-1.6.0/janito/agent/tools/tools_utils.py +0 -13
- janito-1.6.0/janito/agent/tools/utils.py +0 -34
- janito-1.6.0/janito/cli/main.py +0 -41
- janito-1.6.0/janito/cli/runner/__init__.py +0 -2
- janito-1.6.0/janito/cli/runner/cli_main.py +0 -148
- janito-1.6.0/janito/cli/runner/scan.py +0 -44
- janito-1.6.0/janito/cli_chat_shell/commands/session_control.py +0 -12
- janito-1.6.0/janito/cli_chat_shell/commands/system.py +0 -73
- janito-1.6.0/janito/cli_chat_shell/load_prompt.py +0 -18
- janito-1.6.0/janito/cli_chat_shell/ui.py +0 -172
- {janito-1.6.0 → janito-1.8.0}/LICENSE +0 -0
- {janito-1.6.0 → janito-1.8.0}/janito/__main__.py +0 -0
- {janito-1.6.0 → janito-1.8.0}/janito/agent/__init__.py +0 -0
- {janito-1.6.0 → janito-1.8.0}/janito/agent/config_utils.py +0 -0
- {janito-1.6.0 → janito-1.8.0}/janito/agent/content_handler.py +0 -0
- {janito-1.6.0 → janito-1.8.0}/janito/agent/conversation_ui.py +0 -0
- {janito-1.6.0 → janito-1.8.0}/janito/agent/rich_live.py +0 -0
- {janito-1.6.0 → janito-1.8.0}/janito/agent/runtime_config.py +0 -0
- {janito-1.6.0 → janito-1.8.0}/janito/agent/tools/gitignore_utils.py +0 -0
- {janito-1.6.0 → janito-1.8.0}/janito/agent/tools/rich_live.py +0 -0
- {janito-1.6.0 → janito-1.8.0}/janito/cli/__init__.py +0 -0
- {janito-1.6.0 → janito-1.8.0}/janito/cli/_utils.py +0 -0
- {janito-1.6.0/janito/cli_chat_shell → janito-1.8.0/janito/cli/runner}/__init__.py +0 -0
- {janito-1.6.0 → janito-1.8.0}/janito/cli/runner/formatting.py +0 -0
- {janito-1.6.0/janito/web → janito-1.8.0/janito/cli_chat_shell}/__init__.py +0 -0
- {janito-1.6.0 → janito-1.8.0}/janito/cli_chat_shell/commands/config.py +0 -0
- {janito-1.6.0 → janito-1.8.0}/janito/cli_chat_shell/commands/session.py +0 -0
- {janito-1.6.0 → janito-1.8.0}/janito/cli_chat_shell/config_shell.py +0 -0
- {janito-1.6.0 → janito-1.8.0}/janito/web/__main__.py +0 -0
- {janito-1.6.0 → janito-1.8.0}/janito.egg-info/dependency_links.txt +0 -0
- {janito-1.6.0 → janito-1.8.0}/janito.egg-info/entry_points.txt +0 -0
- {janito-1.6.0 → janito-1.8.0}/janito.egg-info/top_level.txt +0 -0
- {janito-1.6.0 → janito-1.8.0}/setup.cfg +0 -0
- {janito-1.6.0 → janito-1.8.0}/tests/test_basic.py +0 -0
janito-1.8.0/MANIFEST.in
ADDED
@@ -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
|
|
@@ -1,14 +1,51 @@
|
|
1
|
-
# 🚀 Janito: Natural Language
|
1
|
+
# 🚀 Janito: Natural Language Coding Agent
|
2
2
|
|
3
|
-
**Current Version: 1.
|
4
|
-
See [CHANGELOG.md](./CHANGELOG.md)
|
3
|
+
**Current Version: 1.7.0**
|
4
|
+
See [CHANGELOG.md](./CHANGELOG.md) for details on the latest release.
|
5
5
|
|
6
6
|
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.
|
7
7
|
|
8
|
-
For a technical overview, see the [Architecture Guide](docs/
|
8
|
+
For a technical overview, see the [Architecture Guide](docs/reference/architecture.md).
|
9
|
+
|
10
|
+
## 🧪 Experimental Feature: Liteweb File Viewer
|
11
|
+
|
12
|
+
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!
|
13
|
+
|
14
|
+
### How to Use
|
15
|
+
|
16
|
+
- Start the CLI chat shell with the `--termweb` flag:
|
17
|
+
```bash
|
18
|
+
janito --termweb
|
19
|
+
```
|
20
|
+
- By default, the viewer runs at http://localhost:8088 (or the next available port up to 8100).
|
21
|
+
- To specify a port, use `--termweb-port 8090`.
|
22
|
+
- File paths in CLI output become clickable links that open the file in your browser.
|
23
|
+
|
24
|
+
**Note:** This feature is experimental. It is intended for quick file previews and review, not for editing or production use. Feedback is welcome!
|
25
|
+
|
26
|
+
### Why is this useful?
|
27
|
+
- Enables instant file previews from the CLI without a full IDE.
|
28
|
+
- Works with all Janito file tools and outputs that display file paths.
|
29
|
+
- Uses the Rich library’s link markup for clickable terminal links.
|
30
|
+
|
31
|
+
---
|
32
|
+
|
33
|
+
## 📖 Full Documentation & Overview
|
34
|
+
- For structured and in-depth guides, visit the [Janito Documentation Site](https://docs.janito.dev).
|
35
|
+
- For a high-level, user-friendly overview, see [janito.dev](https://janito.dev).
|
9
36
|
|
10
37
|
---
|
11
38
|
|
39
|
+
## Listing Available Tools
|
40
|
+
|
41
|
+
To list all registered tools on the command line, use the option:
|
42
|
+
|
43
|
+
```sh
|
44
|
+
janito --list-tools
|
45
|
+
```
|
46
|
+
|
47
|
+
This will display a colorful table with the name, description, and parameters of each available tool.
|
48
|
+
|
12
49
|
## ⚡ Quick Start
|
13
50
|
|
14
51
|
## 🖥️ Supported Human Interfaces
|
@@ -56,7 +93,7 @@ janito --web
|
|
56
93
|
- 📁 **File & Directory Management:** Navigate, create, move, or remove files and folders.
|
57
94
|
- 🧠 **Context-Aware:** Understands your project structure for precise edits.
|
58
95
|
- 💬 **Interactive User Prompts:** Asks for clarification when needed.
|
59
|
-
-
|
96
|
+
- 🛠️ **Extensible Tooling:** Built-in tools for file operations, shell commands, directory and file management, Python code execution and validation, text replacement, and more.
|
60
97
|
- 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).
|
61
98
|
- 🌐 **Web Interface (In Development):** Simple web UI for streaming responses and tool progress.
|
62
99
|
|
@@ -68,7 +105,7 @@ janito --web
|
|
68
105
|
|
69
106
|
### Contributing & Developer Guide
|
70
107
|
|
71
|
-
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
|
108
|
+
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).
|
72
109
|
|
73
110
|
|
74
111
|
|
@@ -105,12 +142,12 @@ For details on using models hosted on Azure OpenAI, see [docs/AZURE_OPENAI.md](d
|
|
105
142
|
|
106
143
|
---
|
107
144
|
|
108
|
-
##
|
145
|
+
## 🧑💻 System Prompt & Role
|
109
146
|
|
110
|
-
Janito operates using a system prompt template that defines its behavior, communication
|
147
|
+
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.
|
111
148
|
|
112
149
|
- **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`.
|
113
|
-
- **System Prompt Template:** The system prompt is rendered from a Jinja2 template (see `janito/agent/templates/
|
150
|
+
- **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.
|
114
151
|
- **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.
|
115
152
|
|
116
153
|
The default template ensures the agent:
|
@@ -119,7 +156,7 @@ The default template ensures the agent:
|
|
119
156
|
- Provides concise plans before taking action
|
120
157
|
- Documents any changes made
|
121
158
|
|
122
|
-
For more details or to customize the prompt, see the template file at `janito/agent/templates/
|
159
|
+
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).
|
123
160
|
|
124
161
|
---
|
125
162
|
|
@@ -151,18 +188,18 @@ Vanilla mode is ideal for:
|
|
151
188
|
|
152
189
|
> Note: Vanilla mode is a runtime switch and does not change the Agent API or class signatures. It is controlled via CLI/config only.
|
153
190
|
|
154
|
-
##
|
191
|
+
## 👨💻 AgentProfileManager: Profile, Role, and Prompt Management
|
155
192
|
|
156
|
-
Janito now uses a dedicated `AgentProfileManager` class to manage user profiles, roles, interaction
|
157
|
-
- Stores the current role (e.g., "software engineer") and interaction
|
158
|
-
- Renders the system prompt from the appropriate template based on interaction
|
193
|
+
Janito now uses a dedicated `AgentProfileManager` class to manage user profiles, roles, interaction profiles, and system prompt selection. This manager:
|
194
|
+
- Stores the current role (e.g., "software engineer") and interaction profile (e.g., "default", "technical").
|
195
|
+
- Renders the system prompt from the appropriate template based on interaction profile.
|
159
196
|
- Instantiates and manages the low-level LLM Agent, passing the correct prompt.
|
160
|
-
- Provides methods to update the role, interaction
|
197
|
+
- Provides methods to update the role, interaction profile, and refresh the prompt at runtime.
|
161
198
|
|
162
199
|
### Multiple System Prompt Templates
|
163
|
-
- The system prompt template is now selected based on the interaction
|
200
|
+
- The system prompt template is now selected based on the interaction profile (e.g., `default` or `technical`).
|
164
201
|
- Templates are located in `janito/agent/templates/` (see `system_prompt_template.j2` and `system_prompt_template_technical.j2`).
|
165
|
-
- You can switch interaction
|
202
|
+
- You can switch interaction profiles at runtime using the profile manager, enabling different agent behaviors for different user needs.
|
166
203
|
|
167
204
|
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.
|
168
205
|
|
@@ -170,47 +207,47 @@ See `janito/agent/profile_manager.py` for implementation details.
|
|
170
207
|
|
171
208
|
### Agent Interaction Style
|
172
209
|
|
173
|
-
You can control the agent's behavior and prompt
|
210
|
+
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.
|
174
211
|
- `default`: Concise, general-purpose agent (default)
|
175
212
|
- `technical`: Strict, workflow-oriented for technical/developer use
|
176
213
|
|
177
214
|
Set globally:
|
178
215
|
```bash
|
179
|
-
janito --set-global-config
|
216
|
+
janito --set-global-config profile=technical
|
180
217
|
```
|
181
218
|
Or per-project (in your project root):
|
182
219
|
```bash
|
183
|
-
janito --set-local-config
|
220
|
+
janito --set-local-config profile=technical
|
184
221
|
```
|
185
222
|
|
186
223
|
You can also override for a session with the CLI flag:
|
187
224
|
```bash
|
188
|
-
janito --
|
225
|
+
janito --profile technical
|
189
226
|
```
|
190
227
|
|
191
228
|
See [docs/CONFIGURATION.md](docs/CONFIGURATION.md) for full details.
|
192
229
|
|
193
|
-
##
|
230
|
+
## 🧑💻 Combinatorial Style System
|
194
231
|
|
195
|
-
Janito now supports combinatorial
|
232
|
+
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`).
|
196
233
|
|
197
|
-
- **Main
|
198
|
-
- **Feature extensions:** Optional features that override or extend the main
|
234
|
+
- **Main profile:** The base agent behavior and workflow (e.g., `default`, `technical`).
|
235
|
+
- **Feature extensions:** Optional features that override or extend the main profile (e.g., `commit_all`).
|
199
236
|
- **Syntax:** Use a hyphen to combine, e.g., `technical-commit_all`.
|
200
237
|
|
201
238
|
**How it works:**
|
202
|
-
- The main
|
239
|
+
- The main profile template is loaded first.
|
203
240
|
- Each feature extension template is layered on top, overriding or extending specific blocks in the main template.
|
204
241
|
- Feature templates must use `{% extends parent_template %}` for dynamic inheritance.
|
205
242
|
|
206
243
|
**Example usage:**
|
207
244
|
```bash
|
208
|
-
janito --
|
245
|
+
janito --profile technical-commit_all
|
209
246
|
```
|
210
247
|
|
211
|
-
This will apply the `technical`
|
248
|
+
This will apply the `technical` profile with the `commit_all` feature enabled in the agent's system prompt.
|
212
249
|
|
213
250
|
See `janito/render_prompt.py` and `janito/agent/templates/` for implementation details and to create your own feature extensions.
|
214
251
|
|
215
252
|
---
|
216
|
-
_generated by janito.dev_
|
253
|
+
_generated by janito.dev_
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "1.8.0"
|
@@ -38,7 +38,7 @@ class FileConfig(BaseConfig):
|
|
38
38
|
|
39
39
|
def load(self):
|
40
40
|
if self.path.exists():
|
41
|
-
with open(self.path, "r") as f:
|
41
|
+
with open(self.path, "r", encoding="utf-8") as f:
|
42
42
|
self._data = json.load(f)
|
43
43
|
# Remove keys with value None (null in JSON)
|
44
44
|
self._data = {k: v for k, v in self._data.items() if v is not None}
|
@@ -48,7 +48,7 @@ class FileConfig(BaseConfig):
|
|
48
48
|
|
49
49
|
def save(self):
|
50
50
|
self.path.parent.mkdir(parents=True, exist_ok=True)
|
51
|
-
with open(self.path, "w") as f:
|
51
|
+
with open(self.path, "w", encoding="utf-8") as f:
|
52
52
|
json.dump(self._data, f, indent=2)
|
53
53
|
|
54
54
|
|
@@ -64,7 +64,7 @@ CONFIG_OPTIONS = {
|
|
64
64
|
"use_azure_openai": "Whether to use Azure OpenAI client (default: False)",
|
65
65
|
# Accept template.* keys as valid config keys (for CLI validation, etc.)
|
66
66
|
"template": "Template context dictionary for Agent Profile prompt rendering (nested)",
|
67
|
-
"
|
67
|
+
"profile": "Agent Profile name (only 'base' is supported)",
|
68
68
|
# Note: template.* keys are validated dynamically, not statically here
|
69
69
|
}
|
70
70
|
|
@@ -3,10 +3,11 @@ CONFIG_DEFAULTS = {
|
|
3
3
|
"api_key": None, # Must be set by user
|
4
4
|
"model": "openai/gpt-4.1", # Default model
|
5
5
|
"base_url": "https://openrouter.ai/api/v1",
|
6
|
-
"role": "software
|
6
|
+
"role": "software developer", # Part of the Agent Profile
|
7
7
|
"system_prompt_template": None, # None means auto-generate from Agent Profile role
|
8
8
|
"temperature": 0.2,
|
9
9
|
"max_tokens": 200000,
|
10
10
|
"use_azure_openai": False,
|
11
|
-
"
|
11
|
+
"azure_openai_api_version": "2023-05-15",
|
12
|
+
"profile": "base",
|
12
13
|
}
|
@@ -8,8 +8,9 @@ from janito.agent.conversation_ui import show_spinner, print_verbose_event
|
|
8
8
|
from janito.agent.conversation_exceptions import (
|
9
9
|
MaxRoundsExceededError,
|
10
10
|
EmptyResponseError,
|
11
|
+
NoToolSupportError,
|
11
12
|
)
|
12
|
-
from janito.agent.runtime_config import unified_config
|
13
|
+
from janito.agent.runtime_config import unified_config, runtime_config
|
13
14
|
import pprint
|
14
15
|
|
15
16
|
|
@@ -19,6 +20,13 @@ class ConversationHandler:
|
|
19
20
|
self.model = model
|
20
21
|
self.usage_history = []
|
21
22
|
|
23
|
+
@staticmethod
|
24
|
+
def remove_system_prompt(messages):
|
25
|
+
"""
|
26
|
+
Return a new messages list with all system prompts removed.
|
27
|
+
"""
|
28
|
+
return [msg for msg in messages if msg.get("role") != "system"]
|
29
|
+
|
22
30
|
def handle_conversation(
|
23
31
|
self,
|
24
32
|
messages,
|
@@ -41,39 +49,75 @@ class ConversationHandler:
|
|
41
49
|
resolved_max_tokens = int(resolved_max_tokens)
|
42
50
|
except (TypeError, ValueError):
|
43
51
|
raise ValueError(
|
44
|
-
|
52
|
+
"max_tokens must be an integer, got: {resolved_max_tokens!r}".format(
|
53
|
+
resolved_max_tokens=resolved_max_tokens
|
54
|
+
)
|
45
55
|
)
|
46
56
|
|
57
|
+
# If vanilla mode is set and max_tokens was not provided, default to 8000
|
58
|
+
if runtime_config.get("vanilla_mode", False) and max_tokens is None:
|
59
|
+
resolved_max_tokens = 8000
|
60
|
+
|
47
61
|
for _ in range(max_rounds):
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
62
|
+
try:
|
63
|
+
if stream:
|
64
|
+
# Streaming mode
|
65
|
+
def get_stream():
|
66
|
+
return get_openai_stream_response(
|
67
|
+
self.client,
|
68
|
+
self.model,
|
69
|
+
messages,
|
70
|
+
resolved_max_tokens,
|
71
|
+
verbose_stream=runtime_config.get("verbose_stream", False),
|
72
|
+
message_handler=message_handler,
|
73
|
+
)
|
74
|
+
|
75
|
+
retry_api_call(get_stream)
|
76
|
+
return None
|
77
|
+
else:
|
78
|
+
# Non-streaming mode
|
79
|
+
def api_call():
|
80
|
+
return get_openai_response(
|
81
|
+
self.client, self.model, messages, resolved_max_tokens
|
82
|
+
)
|
83
|
+
|
84
|
+
if spinner:
|
85
|
+
response = show_spinner(
|
86
|
+
"Waiting for AI response...", retry_api_call, api_call
|
87
|
+
)
|
88
|
+
else:
|
89
|
+
response = retry_api_call(api_call)
|
90
|
+
print("[DEBUG] OpenAI API raw response:", repr(response))
|
91
|
+
except NoToolSupportError:
|
92
|
+
print(
|
93
|
+
"⚠️ Endpoint does not support tool use. Proceeding in vanilla mode (tools disabled)."
|
94
|
+
)
|
95
|
+
runtime_config.set("vanilla_mode", True)
|
96
|
+
if max_tokens is None:
|
97
|
+
runtime_config.set("max_tokens", 8000)
|
98
|
+
resolved_max_tokens = 8000
|
59
99
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
def api_call():
|
100
|
+
# Remove system prompt for vanilla mode if needed (call this externally when appropriate)
|
101
|
+
# messages = ConversationHandler.remove_system_prompt(messages)
|
102
|
+
# Retry once with tools disabled
|
103
|
+
def api_call_vanilla():
|
65
104
|
return get_openai_response(
|
66
105
|
self.client, self.model, messages, resolved_max_tokens
|
67
106
|
)
|
68
107
|
|
69
108
|
if spinner:
|
70
109
|
response = show_spinner(
|
71
|
-
"Waiting for AI response...",
|
110
|
+
"Waiting for AI response (tools disabled)...",
|
111
|
+
retry_api_call,
|
112
|
+
api_call_vanilla,
|
72
113
|
)
|
73
114
|
else:
|
74
|
-
response = retry_api_call(
|
75
|
-
|
76
|
-
|
115
|
+
response = retry_api_call(api_call_vanilla)
|
116
|
+
print(
|
117
|
+
"[DEBUG] OpenAI API raw response (tools disabled):",
|
118
|
+
repr(response),
|
119
|
+
)
|
120
|
+
if runtime_config.get("verbose_response", False):
|
77
121
|
pprint.pprint(response)
|
78
122
|
if response is None or not getattr(response, "choices", None):
|
79
123
|
raise EmptyResponseError(
|
@@ -83,6 +127,8 @@ class ConversationHandler:
|
|
83
127
|
usage = getattr(response, "usage", None)
|
84
128
|
usage_info = (
|
85
129
|
{
|
130
|
+
# DEBUG: Show usage extraction
|
131
|
+
"_debug_raw_usage": getattr(response, "usage", None),
|
86
132
|
"prompt_tokens": getattr(usage, "prompt_tokens", None),
|
87
133
|
"completion_tokens": getattr(usage, "completion_tokens", None),
|
88
134
|
"total_tokens": getattr(usage, "total_tokens", None),
|
@@ -91,7 +137,7 @@ class ConversationHandler:
|
|
91
137
|
else None
|
92
138
|
)
|
93
139
|
event = {"type": "content", "message": choice.message.content}
|
94
|
-
if verbose_events:
|
140
|
+
if runtime_config.get("verbose_events", False):
|
95
141
|
print_verbose_event(event)
|
96
142
|
if message_handler is not None and choice.message.content:
|
97
143
|
message_handler.handle_message(event)
|
@@ -118,12 +164,12 @@ class ConversationHandler:
|
|
118
164
|
"tool_calls": [tc.to_dict() for tc in choice.message.tool_calls],
|
119
165
|
}
|
120
166
|
)
|
121
|
-
for
|
167
|
+
for tool_response in tool_responses:
|
122
168
|
messages.append(
|
123
169
|
{
|
124
170
|
"role": "tool",
|
125
|
-
"tool_call_id":
|
126
|
-
"content":
|
171
|
+
"tool_call_id": tool_response["tool_call_id"],
|
172
|
+
"content": tool_response["content"],
|
127
173
|
}
|
128
174
|
)
|
129
|
-
raise MaxRoundsExceededError("Max conversation rounds exceeded")
|
175
|
+
raise MaxRoundsExceededError(f"Max conversation rounds exceeded ({max_rounds})")
|