janito 1.2.0__tar.gz → 1.3.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.3.0/PKG-INFO +142 -0
- janito-1.3.0/README.md +117 -0
- janito-1.3.0/janito/__init__.py +1 -0
- {janito-1.2.0 → janito-1.3.0}/janito/agent/agent.py +27 -10
- {janito-1.2.0 → janito-1.3.0}/janito/agent/config.py +37 -9
- janito-1.3.0/janito/agent/config_utils.py +9 -0
- {janito-1.2.0 → janito-1.3.0}/janito/agent/conversation.py +19 -3
- {janito-1.2.0 → janito-1.3.0}/janito/agent/runtime_config.py +1 -0
- janito-1.3.0/janito/agent/tool_handler.py +229 -0
- janito-1.3.0/janito/agent/tools/__init__.py +12 -0
- {janito-1.2.0 → janito-1.3.0}/janito/agent/tools/ask_user.py +2 -1
- janito-1.3.0/janito/agent/tools/fetch_url.py +40 -0
- janito-1.3.0/janito/agent/tools/file_ops.py +72 -0
- janito-1.3.0/janito/agent/tools/find_files.py +58 -0
- janito-1.3.0/janito/agent/tools/get_lines.py +58 -0
- janito-1.3.0/janito/agent/tools/py_compile.py +26 -0
- janito-1.3.0/janito/agent/tools/python_exec.py +47 -0
- janito-1.3.0/janito/agent/tools/remove_directory.py +38 -0
- janito-1.3.0/janito/agent/tools/replace_text_in_file.py +67 -0
- janito-1.3.0/janito/agent/tools/run_bash_command.py +134 -0
- janito-1.3.0/janito/agent/tools/search_files.py +52 -0
- {janito-1.2.0 → janito-1.3.0}/janito/cli/_print_config.py +12 -12
- {janito-1.2.0 → janito-1.3.0}/janito/cli/arg_parser.py +6 -1
- {janito-1.2.0 → janito-1.3.0}/janito/cli/config_commands.py +56 -8
- {janito-1.2.0 → janito-1.3.0}/janito/cli/runner.py +21 -9
- {janito-1.2.0 → janito-1.3.0}/janito/cli_chat_shell/chat_loop.py +5 -3
- {janito-1.2.0 → janito-1.3.0}/janito/cli_chat_shell/commands.py +34 -37
- {janito-1.2.0 → janito-1.3.0}/janito/cli_chat_shell/config_shell.py +1 -1
- {janito-1.2.0 → janito-1.3.0}/janito/cli_chat_shell/load_prompt.py +1 -1
- {janito-1.2.0 → janito-1.3.0}/janito/cli_chat_shell/session_manager.py +11 -15
- {janito-1.2.0 → janito-1.3.0}/janito/cli_chat_shell/ui.py +17 -8
- {janito-1.2.0 → janito-1.3.0}/janito/render_prompt.py +3 -1
- janito-1.3.0/janito/web/app.py +189 -0
- janito-1.3.0/janito.egg-info/PKG-INFO +142 -0
- {janito-1.2.0 → janito-1.3.0}/janito.egg-info/SOURCES.txt +9 -9
- {janito-1.2.0 → janito-1.3.0}/janito.egg-info/requires.txt +6 -3
- {janito-1.2.0 → janito-1.3.0}/pyproject.toml +10 -7
- janito-1.2.0/PKG-INFO +0 -85
- janito-1.2.0/README.md +0 -63
- janito-1.2.0/janito/__init__.py +0 -1
- janito-1.2.0/janito/agent/tool_handler.py +0 -127
- janito-1.2.0/janito/agent/tools/__init__.py +0 -11
- janito-1.2.0/janito/agent/tools/bash_exec.py +0 -58
- janito-1.2.0/janito/agent/tools/create_directory.py +0 -19
- janito-1.2.0/janito/agent/tools/create_file.py +0 -43
- janito-1.2.0/janito/agent/tools/fetch_url.py +0 -48
- janito-1.2.0/janito/agent/tools/file_str_replace.py +0 -48
- janito-1.2.0/janito/agent/tools/find_files.py +0 -37
- janito-1.2.0/janito/agent/tools/move_file.py +0 -37
- janito-1.2.0/janito/agent/tools/remove_file.py +0 -19
- janito-1.2.0/janito/agent/tools/search_text.py +0 -41
- janito-1.2.0/janito/agent/tools/view_file.py +0 -34
- janito-1.2.0/janito/templates/system_instructions.j2 +0 -38
- janito-1.2.0/janito/web/app.py +0 -132
- janito-1.2.0/janito.egg-info/PKG-INFO +0 -85
- {janito-1.2.0 → janito-1.3.0}/LICENSE +0 -0
- {janito-1.2.0 → janito-1.3.0}/janito/__main__.py +0 -0
- {janito-1.2.0 → janito-1.3.0}/janito/agent/__init__.py +0 -0
- {janito-1.2.0 → janito-1.3.0}/janito/agent/config_defaults.py +0 -0
- {janito-1.2.0 → janito-1.3.0}/janito/agent/queued_tool_handler.py +0 -0
- {janito-1.2.0 → janito-1.3.0}/janito/agent/tools/gitignore_utils.py +0 -0
- {janito-1.2.0 → janito-1.3.0}/janito/agent/tools/rich_live.py +0 -0
- {janito-1.2.0 → janito-1.3.0}/janito/agent/tools/rich_utils.py +0 -0
- {janito-1.2.0 → janito-1.3.0}/janito/cli/__init__.py +0 -0
- {janito-1.2.0 → janito-1.3.0}/janito/cli/_utils.py +0 -0
- {janito-1.2.0 → janito-1.3.0}/janito/cli/logging_setup.py +0 -0
- {janito-1.2.0 → janito-1.3.0}/janito/cli/main.py +0 -0
- {janito-1.2.0 → janito-1.3.0}/janito/cli_chat_shell/__init__.py +0 -0
- {janito-1.2.0 → janito-1.3.0}/janito/web/__init__.py +0 -0
- {janito-1.2.0 → janito-1.3.0}/janito/web/__main__.py +0 -0
- {janito-1.2.0 → janito-1.3.0}/janito.egg-info/dependency_links.txt +0 -0
- {janito-1.2.0 → janito-1.3.0}/janito.egg-info/entry_points.txt +0 -0
- {janito-1.2.0 → janito-1.3.0}/janito.egg-info/top_level.txt +0 -0
- {janito-1.2.0 → janito-1.3.0}/setup.cfg +0 -0
janito-1.3.0/PKG-INFO
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: janito
|
3
|
+
Version: 1.3.0
|
4
|
+
Summary: A Natural Programming Language Agent,
|
5
|
+
Author-email: João Pinto <joao.pinto@gmail.com>
|
6
|
+
License: MIT
|
7
|
+
Project-URL: homepage, https://github.com/joaompinto/janito
|
8
|
+
Project-URL: repository, https://github.com/joaompinto/janito
|
9
|
+
Keywords: agent,framework,tools,automation
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
12
|
+
Classifier: Operating System :: OS Independent
|
13
|
+
Requires-Python: >=3.10
|
14
|
+
Description-Content-Type: text/markdown
|
15
|
+
License-File: LICENSE
|
16
|
+
Requires-Dist: beautifulsoup4
|
17
|
+
Requires-Dist: flask
|
18
|
+
Requires-Dist: jinja2
|
19
|
+
Requires-Dist: openai
|
20
|
+
Requires-Dist: pathspec
|
21
|
+
Requires-Dist: prompt_toolkit
|
22
|
+
Requires-Dist: requests
|
23
|
+
Requires-Dist: rich
|
24
|
+
Dynamic: license-file
|
25
|
+
|
26
|
+
# 🚀 Janito: Agent
|
27
|
+
|
28
|
+
Janito is an AI-powered assistant for the command line and web that interprets natural language instructions 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.
|
29
|
+
|
30
|
+
---
|
31
|
+
|
32
|
+
## ⚡ Quick Start
|
33
|
+
|
34
|
+
Run a one-off prompt:
|
35
|
+
```bash
|
36
|
+
python -m janito "Refactor the data processing module to improve readability."
|
37
|
+
```
|
38
|
+
|
39
|
+
Or start the interactive chat shell:
|
40
|
+
```bash
|
41
|
+
python -m janito
|
42
|
+
```
|
43
|
+
|
44
|
+
Launch the web UI:
|
45
|
+
```bash
|
46
|
+
python -m janito.web
|
47
|
+
```
|
48
|
+
|
49
|
+
---
|
50
|
+
|
51
|
+
## ✨ Key Features
|
52
|
+
- 📝 **Code Editing via Natural Language:** Modify, create, or delete code files simply by describing the changes.
|
53
|
+
- 📁 **File & Directory Management:** Navigate, create, move, or remove files and folders.
|
54
|
+
- 🧠 **Context-Aware:** Understands your project structure for precise edits.
|
55
|
+
- 💬 **Interactive User Prompts:** Asks for clarification when needed.
|
56
|
+
- 🧩 **Extensible Tooling:** Built-in tools for file operations, shell commands, directory listing, Python file validation, text replacement, code execution, and more. Recent tools include:
|
57
|
+
- `find_files`: Search for files matching a pattern in directories.
|
58
|
+
- `get_lines`: Retrieve specific lines from files for efficient context.
|
59
|
+
- `py_compile_file`: Validate Python files for syntax correctness.
|
60
|
+
- `replace_text_in_file`: Replace exact text fragments in files.
|
61
|
+
- `search_files`: Search for text patterns across files.
|
62
|
+
- `python_exec`: Execute Python code and capture output.
|
63
|
+
- And more, see `janito/agent/tools/` for the full list.
|
64
|
+
- 🌐 **Web Interface (In Development):** Upcoming simple web UI for streaming responses and tool progress.
|
65
|
+
|
66
|
+
---
|
67
|
+
|
68
|
+
|
69
|
+
## 📦 Installation
|
70
|
+
|
71
|
+
### Requirements
|
72
|
+
- Python 3.10+
|
73
|
+
|
74
|
+
...
|
75
|
+
|
76
|
+
### Configuration & CLI Options
|
77
|
+
|
78
|
+
Below are the supported configuration parameters and CLI flags. Some options can be set via config files, CLI flags, or both. Use `python -m janito --help` for a full list, or `python -m janito --help-config` to see all config keys and their descriptions.
|
79
|
+
|
80
|
+
| Key / Flag | Description | How to set | Default |
|
81
|
+
|---------------------------|---------------------------------------------------------------------------------------------|-----------------------------------------------------------------|--------------------------------------------|
|
82
|
+
| `api_key` | API key for OpenAI-compatible service | `--set-api-key`, config file | _None_ (required) |
|
83
|
+
| `model` | Model name to use for this session | `--model` (session only), `--set-local-config model=...`, or `--set-global-config` | `openai/gpt-4.1` |
|
84
|
+
| `base_url` | API base URL (OpenAI-compatible endpoint) | `--set-local-config base_url=...` or `--set-global-config` | `https://openrouter.ai/api/v1` |
|
85
|
+
| `role` | Role description for the system prompt | `--role` or config | "software engineer" |
|
86
|
+
| `system_prompt` | Override the entire system prompt as a raw string | `--system-prompt` or config | _Default prompt_ |
|
87
|
+
| `system_file` | Use a plain text file as the system prompt (takes precedence over `system_prompt`) | `--system-file` (CLI only) | _None_ |
|
88
|
+
| `temperature` | Sampling temperature (float, e.g., 0.0 - 2.0) | `--temperature` or config | 0.2 |
|
89
|
+
| `max_tokens` | Maximum tokens for model response | `--max-tokens` or config | 200000 |
|
90
|
+
| `max_rounds` | Maximum number of agent rounds per prompt/session | `--max-rounds` or config | 50 |
|
91
|
+
| `max_tools` | Maximum number of tool calls allowed within a chat session | `--max-tools` or config | _None_ (unlimited) |
|
92
|
+
| `no_tools` | Disable tool use (no tools passed to agent) | `-n`, `--no-tools` (CLI only) | False |
|
93
|
+
| `trust` | Trust mode: suppresses run_bash_command output, only shows output file locations | `--trust` (CLI only) | False |
|
94
|
+
| `template` / `template.*` | Template context dictionary for prompt rendering (nested or flat keys) | Config only | _None_ |
|
95
|
+
|
96
|
+
Other config-related CLI flags:
|
97
|
+
|
98
|
+
- `--set-local-config key=val` Set a local config value
|
99
|
+
- `--set-global-config key=val` Set a global config value
|
100
|
+
- `--run-config key=val` Set a runtime (in-memory only) config value (can be repeated)
|
101
|
+
- `--show-config` Show effective configuration and exit
|
102
|
+
- `--config-reset-local` Remove the local config file
|
103
|
+
- `--config-reset-global` Remove the global config file
|
104
|
+
- `--set-api-key KEY` Set and save the API key globally
|
105
|
+
- `--help-config` Show all configuration options and exit
|
106
|
+
|
107
|
+
Session & shell options:
|
108
|
+
|
109
|
+
- `--continue-session` Continue from the last saved conversation
|
110
|
+
- `--web` Launch the Janito web server instead of CLI
|
111
|
+
|
112
|
+
Verbose/debugging flags:
|
113
|
+
|
114
|
+
- `--verbose-http` Enable verbose HTTP logging
|
115
|
+
- `--verbose-http-raw` Enable raw HTTP wire-level logging
|
116
|
+
- `--verbose-response` Pretty print the full response object
|
117
|
+
- `--verbose-tools` Print tool call parameters and results
|
118
|
+
- `--show-system` Show model, parameters, system prompt, and tool definitions, then exit
|
119
|
+
- `--version` Show program's version number and exit
|
120
|
+
|
121
|
+
|
122
|
+
|
123
|
+
---
|
124
|
+
|
125
|
+
## 🧩 System Prompt & Role
|
126
|
+
|
127
|
+
Janito operates using a system prompt template that defines its behavior, communication style, 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.
|
128
|
+
|
129
|
+
- **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`.
|
130
|
+
- **System Prompt Template:** The system prompt is rendered from a Jinja2 template (see `janito/agent/templates/system_instructions.j2` (now located directly under the agent directory)). This template governs how the agent interprets instructions, interacts with files, and communicates with users.
|
131
|
+
- **Customization:** Advanced users can override the system prompt with the `--system-prompt` flag (raw string), or point to a custom file using `--system-file`.
|
132
|
+
|
133
|
+
The default template ensures the agent:
|
134
|
+
- Prioritizes safe, reviewable, and minimal changes
|
135
|
+
- Asks for clarification when instructions are ambiguous
|
136
|
+
- Provides concise plans before taking action
|
137
|
+
- Documents any changes made
|
138
|
+
|
139
|
+
For more details or to customize the prompt, see the template file at `janito/agent/templates/system_instructions.j2`.
|
140
|
+
|
141
|
+
---
|
142
|
+
|
janito-1.3.0/README.md
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
# 🚀 Janito: Agent
|
2
|
+
|
3
|
+
Janito is an AI-powered assistant for the command line and web that interprets natural language instructions 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.
|
4
|
+
|
5
|
+
---
|
6
|
+
|
7
|
+
## ⚡ Quick Start
|
8
|
+
|
9
|
+
Run a one-off prompt:
|
10
|
+
```bash
|
11
|
+
python -m janito "Refactor the data processing module to improve readability."
|
12
|
+
```
|
13
|
+
|
14
|
+
Or start the interactive chat shell:
|
15
|
+
```bash
|
16
|
+
python -m janito
|
17
|
+
```
|
18
|
+
|
19
|
+
Launch the web UI:
|
20
|
+
```bash
|
21
|
+
python -m janito.web
|
22
|
+
```
|
23
|
+
|
24
|
+
---
|
25
|
+
|
26
|
+
## ✨ Key Features
|
27
|
+
- 📝 **Code Editing via Natural Language:** Modify, create, or delete code files simply by describing the changes.
|
28
|
+
- 📁 **File & Directory Management:** Navigate, create, move, or remove files and folders.
|
29
|
+
- 🧠 **Context-Aware:** Understands your project structure for precise edits.
|
30
|
+
- 💬 **Interactive User Prompts:** Asks for clarification when needed.
|
31
|
+
- 🧩 **Extensible Tooling:** Built-in tools for file operations, shell commands, directory listing, Python file validation, text replacement, code execution, and more. Recent tools include:
|
32
|
+
- `find_files`: Search for files matching a pattern in directories.
|
33
|
+
- `get_lines`: Retrieve specific lines from files for efficient context.
|
34
|
+
- `py_compile_file`: Validate Python files for syntax correctness.
|
35
|
+
- `replace_text_in_file`: Replace exact text fragments in files.
|
36
|
+
- `search_files`: Search for text patterns across files.
|
37
|
+
- `python_exec`: Execute Python code and capture output.
|
38
|
+
- And more, see `janito/agent/tools/` for the full list.
|
39
|
+
- 🌐 **Web Interface (In Development):** Upcoming simple web UI for streaming responses and tool progress.
|
40
|
+
|
41
|
+
---
|
42
|
+
|
43
|
+
|
44
|
+
## 📦 Installation
|
45
|
+
|
46
|
+
### Requirements
|
47
|
+
- Python 3.10+
|
48
|
+
|
49
|
+
...
|
50
|
+
|
51
|
+
### Configuration & CLI Options
|
52
|
+
|
53
|
+
Below are the supported configuration parameters and CLI flags. Some options can be set via config files, CLI flags, or both. Use `python -m janito --help` for a full list, or `python -m janito --help-config` to see all config keys and their descriptions.
|
54
|
+
|
55
|
+
| Key / Flag | Description | How to set | Default |
|
56
|
+
|---------------------------|---------------------------------------------------------------------------------------------|-----------------------------------------------------------------|--------------------------------------------|
|
57
|
+
| `api_key` | API key for OpenAI-compatible service | `--set-api-key`, config file | _None_ (required) |
|
58
|
+
| `model` | Model name to use for this session | `--model` (session only), `--set-local-config model=...`, or `--set-global-config` | `openai/gpt-4.1` |
|
59
|
+
| `base_url` | API base URL (OpenAI-compatible endpoint) | `--set-local-config base_url=...` or `--set-global-config` | `https://openrouter.ai/api/v1` |
|
60
|
+
| `role` | Role description for the system prompt | `--role` or config | "software engineer" |
|
61
|
+
| `system_prompt` | Override the entire system prompt as a raw string | `--system-prompt` or config | _Default prompt_ |
|
62
|
+
| `system_file` | Use a plain text file as the system prompt (takes precedence over `system_prompt`) | `--system-file` (CLI only) | _None_ |
|
63
|
+
| `temperature` | Sampling temperature (float, e.g., 0.0 - 2.0) | `--temperature` or config | 0.2 |
|
64
|
+
| `max_tokens` | Maximum tokens for model response | `--max-tokens` or config | 200000 |
|
65
|
+
| `max_rounds` | Maximum number of agent rounds per prompt/session | `--max-rounds` or config | 50 |
|
66
|
+
| `max_tools` | Maximum number of tool calls allowed within a chat session | `--max-tools` or config | _None_ (unlimited) |
|
67
|
+
| `no_tools` | Disable tool use (no tools passed to agent) | `-n`, `--no-tools` (CLI only) | False |
|
68
|
+
| `trust` | Trust mode: suppresses run_bash_command output, only shows output file locations | `--trust` (CLI only) | False |
|
69
|
+
| `template` / `template.*` | Template context dictionary for prompt rendering (nested or flat keys) | Config only | _None_ |
|
70
|
+
|
71
|
+
Other config-related CLI flags:
|
72
|
+
|
73
|
+
- `--set-local-config key=val` Set a local config value
|
74
|
+
- `--set-global-config key=val` Set a global config value
|
75
|
+
- `--run-config key=val` Set a runtime (in-memory only) config value (can be repeated)
|
76
|
+
- `--show-config` Show effective configuration and exit
|
77
|
+
- `--config-reset-local` Remove the local config file
|
78
|
+
- `--config-reset-global` Remove the global config file
|
79
|
+
- `--set-api-key KEY` Set and save the API key globally
|
80
|
+
- `--help-config` Show all configuration options and exit
|
81
|
+
|
82
|
+
Session & shell options:
|
83
|
+
|
84
|
+
- `--continue-session` Continue from the last saved conversation
|
85
|
+
- `--web` Launch the Janito web server instead of CLI
|
86
|
+
|
87
|
+
Verbose/debugging flags:
|
88
|
+
|
89
|
+
- `--verbose-http` Enable verbose HTTP logging
|
90
|
+
- `--verbose-http-raw` Enable raw HTTP wire-level logging
|
91
|
+
- `--verbose-response` Pretty print the full response object
|
92
|
+
- `--verbose-tools` Print tool call parameters and results
|
93
|
+
- `--show-system` Show model, parameters, system prompt, and tool definitions, then exit
|
94
|
+
- `--version` Show program's version number and exit
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
---
|
99
|
+
|
100
|
+
## 🧩 System Prompt & Role
|
101
|
+
|
102
|
+
Janito operates using a system prompt template that defines its behavior, communication style, 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.
|
103
|
+
|
104
|
+
- **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`.
|
105
|
+
- **System Prompt Template:** The system prompt is rendered from a Jinja2 template (see `janito/agent/templates/system_instructions.j2` (now located directly under the agent directory)). This template governs how the agent interprets instructions, interacts with files, and communicates with users.
|
106
|
+
- **Customization:** Advanced users can override the system prompt with the `--system-prompt` flag (raw string), or point to a custom file using `--system-file`.
|
107
|
+
|
108
|
+
The default template ensures the agent:
|
109
|
+
- Prioritizes safe, reviewable, and minimal changes
|
110
|
+
- Asks for clarification when instructions are ambiguous
|
111
|
+
- Provides concise plans before taking action
|
112
|
+
- Documents any changes made
|
113
|
+
|
114
|
+
For more details or to customize the prompt, see the template file at `janito/agent/templates/system_instructions.j2`.
|
115
|
+
|
116
|
+
---
|
117
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "1.3.0"
|
@@ -7,7 +7,7 @@ from janito.agent.conversation import ConversationHandler
|
|
7
7
|
from janito.agent.tool_handler import ToolHandler
|
8
8
|
|
9
9
|
class Agent:
|
10
|
-
"""
|
10
|
+
"""Agent capable of handling conversations and tool calls."""
|
11
11
|
|
12
12
|
REFERER = "www.janito.dev"
|
13
13
|
TITLE = "Janito"
|
@@ -19,10 +19,22 @@ class Agent:
|
|
19
19
|
system_prompt: str | None = None,
|
20
20
|
verbose_tools: bool = False,
|
21
21
|
tool_handler = None,
|
22
|
-
base_url: str = "https://openrouter.ai/api/v1"
|
22
|
+
base_url: str = "https://openrouter.ai/api/v1",
|
23
|
+
azure_openai_api_version: str = "2023-05-15",
|
24
|
+
use_azure_openai: bool = False
|
23
25
|
):
|
24
26
|
"""
|
25
|
-
Initialize
|
27
|
+
Initialize Agent,
|
28
|
+
|
29
|
+
Args:
|
30
|
+
api_key: API key for OpenAI-compatible service.
|
31
|
+
model: Model name to use.
|
32
|
+
system_prompt: Optional system prompt override.
|
33
|
+
verbose_tools: Enable verbose tool call logging.
|
34
|
+
tool_handler: Optional custom ToolHandler instance.
|
35
|
+
base_url: API base URL.
|
36
|
+
azure_openai_api_version: Azure OpenAI API version (default: "2023-05-15").
|
37
|
+
use_azure_openai: Whether to use Azure OpenAI client (default: False).
|
26
38
|
|
27
39
|
Args:
|
28
40
|
api_key: API key for OpenAI-compatible service.
|
@@ -35,12 +47,12 @@ class Agent:
|
|
35
47
|
self.api_key = api_key
|
36
48
|
self.model = model
|
37
49
|
self.system_prompt = system_prompt
|
38
|
-
if
|
50
|
+
if use_azure_openai:
|
39
51
|
from openai import AzureOpenAI
|
40
52
|
self.client = AzureOpenAI(
|
41
53
|
api_key=api_key,
|
42
|
-
azure_endpoint=
|
43
|
-
api_version=
|
54
|
+
azure_endpoint=base_url,
|
55
|
+
api_version=azure_openai_api_version,
|
44
56
|
)
|
45
57
|
else:
|
46
58
|
self.client = OpenAI(
|
@@ -60,7 +72,11 @@ class Agent:
|
|
60
72
|
self.client, self.model, self.tool_handler
|
61
73
|
)
|
62
74
|
|
63
|
-
|
75
|
+
@property
|
76
|
+
def usage_history(self):
|
77
|
+
return self.conversation_handler.usage_history
|
78
|
+
|
79
|
+
def chat(self, messages, on_content=None, on_tool_progress=None, verbose_response=False, spinner=False, max_tokens=None, max_rounds=50):
|
64
80
|
import time
|
65
81
|
from janito.agent.conversation import ProviderError
|
66
82
|
|
@@ -69,11 +85,12 @@ class Agent:
|
|
69
85
|
try:
|
70
86
|
return self.conversation_handler.handle_conversation(
|
71
87
|
messages,
|
72
|
-
|
88
|
+
max_rounds=max_rounds,
|
73
89
|
on_content=on_content,
|
74
90
|
on_tool_progress=on_tool_progress,
|
75
91
|
verbose_response=verbose_response,
|
76
|
-
spinner=spinner
|
92
|
+
spinner=spinner,
|
93
|
+
max_tokens=max_tokens
|
77
94
|
)
|
78
95
|
except ProviderError as e:
|
79
96
|
error_data = getattr(e, 'error_data', {}) or {}
|
@@ -92,5 +109,5 @@ class Agent:
|
|
92
109
|
else:
|
93
110
|
print("Max retries reached. Raising error.")
|
94
111
|
raise
|
95
|
-
|
112
|
+
|
96
113
|
raise
|
@@ -40,14 +40,12 @@ class FileConfig(BaseConfig):
|
|
40
40
|
|
41
41
|
def load(self):
|
42
42
|
if self.path.exists():
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
print(f"Warning: Failed to load config file {self.path}: {e}")
|
50
|
-
self._data = {}
|
43
|
+
with open(self.path, 'r') as f:
|
44
|
+
self._data = json.load(f)
|
45
|
+
# Remove keys with value None (null in JSON)
|
46
|
+
self._data = {k: v for k, v in self._data.items() if v is not None}
|
47
|
+
|
48
|
+
|
51
49
|
else:
|
52
50
|
self._data = {}
|
53
51
|
|
@@ -57,6 +55,7 @@ class FileConfig(BaseConfig):
|
|
57
55
|
json.dump(self._data, f, indent=2)
|
58
56
|
|
59
57
|
|
58
|
+
|
60
59
|
CONFIG_OPTIONS = {
|
61
60
|
"api_key": "API key for OpenAI-compatible service (required)",
|
62
61
|
"model": "Model name to use (e.g., 'openai/gpt-4.1')",
|
@@ -64,9 +63,38 @@ CONFIG_OPTIONS = {
|
|
64
63
|
"role": "Role description for the system prompt (e.g., 'software engineer')",
|
65
64
|
"system_prompt": "Override the entire system prompt text",
|
66
65
|
"temperature": "Sampling temperature (float, e.g., 0.0 - 2.0)",
|
67
|
-
"max_tokens": "Maximum tokens for model response (int)"
|
66
|
+
"max_tokens": "Maximum tokens for model response (int)",
|
67
|
+
# Accept template.* keys as valid config keys (for CLI validation, etc.)
|
68
|
+
"template": "Template context dictionary for prompt rendering (nested)",
|
69
|
+
# Note: template.* keys are validated dynamically, not statically here
|
68
70
|
}
|
69
71
|
|
72
|
+
class BaseConfig:
|
73
|
+
def __init__(self):
|
74
|
+
self._data = {}
|
75
|
+
|
76
|
+
def get(self, key, default=None):
|
77
|
+
return self._data.get(key, default)
|
78
|
+
|
79
|
+
def set(self, key, value):
|
80
|
+
self._data[key] = value
|
81
|
+
|
82
|
+
def all(self):
|
83
|
+
return self._data
|
84
|
+
|
85
|
+
|
86
|
+
"""
|
87
|
+
Returns a dictionary suitable for passing as Jinja2 template variables.
|
88
|
+
Merges the nested 'template' dict (if present) and all flat 'template.*' keys.
|
89
|
+
Flat keys override nested dict keys if there is a conflict.
|
90
|
+
"""
|
91
|
+
template_vars = dict(self._data.get("template", {}))
|
92
|
+
for k, v in self._data.items():
|
93
|
+
if k.startswith("template.") and k != "template":
|
94
|
+
template_vars[k[9:]] = v
|
95
|
+
return template_vars
|
96
|
+
|
97
|
+
|
70
98
|
# Import defaults for reference
|
71
99
|
from .config_defaults import CONFIG_DEFAULTS
|
72
100
|
|
@@ -16,8 +16,12 @@ class ConversationHandler:
|
|
16
16
|
self.client = client
|
17
17
|
self.model = model
|
18
18
|
self.tool_handler = tool_handler
|
19
|
+
self.usage_history = []
|
19
20
|
|
20
21
|
def handle_conversation(self, messages, max_rounds=50, on_content=None, on_tool_progress=None, verbose_response=False, spinner=False, max_tokens=None):
|
22
|
+
from janito.agent.runtime_config import runtime_config
|
23
|
+
max_tools = runtime_config.get('max_tools', None)
|
24
|
+
tool_calls_made = 0
|
21
25
|
if not messages:
|
22
26
|
raise ValueError("No prompt provided in messages")
|
23
27
|
|
@@ -95,16 +99,28 @@ class ConversationHandler:
|
|
95
99
|
|
96
100
|
# If no tool calls, return the assistant's message and usage info
|
97
101
|
if not choice.message.tool_calls:
|
102
|
+
# Store usage info in usage_history, linked to the next assistant message index
|
103
|
+
assistant_idx = len([m for m in messages if m.get('role') == 'assistant'])
|
104
|
+
self.usage_history.append({"assistant_index": assistant_idx, "usage": usage_info})
|
98
105
|
return {
|
99
|
-
|
100
|
-
|
101
|
-
|
106
|
+
"content": choice.message.content,
|
107
|
+
"usage": usage_info,
|
108
|
+
"usage_history": self.usage_history
|
109
|
+
}
|
102
110
|
|
111
|
+
from janito.agent.runtime_config import runtime_config
|
103
112
|
tool_responses = []
|
113
|
+
# Sequential tool execution (default, only mode)
|
104
114
|
for tool_call in choice.message.tool_calls:
|
115
|
+
if max_tools is not None and tool_calls_made >= max_tools:
|
116
|
+
raise MaxRoundsExceededError(f"Maximum number of tool calls ({max_tools}) reached in this chat session.")
|
105
117
|
result = self.tool_handler.handle_tool_call(tool_call, on_progress=on_tool_progress)
|
106
118
|
tool_responses.append({"tool_call_id": tool_call.id, "content": result})
|
119
|
+
tool_calls_made += 1
|
107
120
|
|
121
|
+
# Store usage info in usage_history, linked to the next assistant message index
|
122
|
+
assistant_idx = len([m for m in messages if m.get('role') == 'assistant'])
|
123
|
+
self.usage_history.append({"assistant_index": assistant_idx, "usage": usage_info})
|
108
124
|
messages.append({"role": "assistant", "content": choice.message.content, "tool_calls": [tc.to_dict() for tc in choice.message.tool_calls]})
|
109
125
|
|
110
126
|
for tr in tool_responses:
|