janito 1.0.1__py3-none-any.whl → 1.2.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 +1 -1
- janito/agent/config_defaults.py +1 -1
- janito/agent/conversation.py +6 -0
- janito/agent/tool_handler.py +4 -1
- janito/cli/_print_config.py +1 -1
- janito/cli/arg_parser.py +9 -2
- janito/cli/config_commands.py +1 -1
- janito/cli/runner.py +33 -50
- janito/cli_chat_shell/chat_loop.py +1 -1
- janito/templates/system_instructions.j2 +1 -1
- janito-1.2.0.dist-info/METADATA +85 -0
- {janito-1.0.1.dist-info → janito-1.2.0.dist-info}/RECORD +17 -17
- janito-1.0.1.dist-info/METADATA +0 -144
- {janito-1.0.1.dist-info → janito-1.2.0.dist-info}/WHEEL +0 -0
- {janito-1.0.1.dist-info → janito-1.2.0.dist-info}/entry_points.txt +0 -0
- {janito-1.0.1.dist-info → janito-1.2.0.dist-info}/licenses/LICENSE +0 -0
- {janito-1.0.1.dist-info → janito-1.2.0.dist-info}/top_level.txt +0 -0
janito/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "1.0
|
1
|
+
__version__ = "1.2.0"
|
janito/agent/config.py
CHANGED
@@ -59,7 +59,7 @@ class FileConfig(BaseConfig):
|
|
59
59
|
|
60
60
|
CONFIG_OPTIONS = {
|
61
61
|
"api_key": "API key for OpenAI-compatible service (required)",
|
62
|
-
"model": "Model name to use (e.g., '
|
62
|
+
"model": "Model name to use (e.g., 'openai/gpt-4.1')",
|
63
63
|
"base_url": "API base URL (OpenAI-compatible endpoint)",
|
64
64
|
"role": "Role description for the system prompt (e.g., 'software engineer')",
|
65
65
|
"system_prompt": "Override the entire system prompt text",
|
janito/agent/config_defaults.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Centralized config defaults for Janito
|
2
2
|
CONFIG_DEFAULTS = {
|
3
3
|
"api_key": None, # Must be set by user
|
4
|
-
"model": "
|
4
|
+
"model": "openai/gpt-4.1", # Default model
|
5
5
|
"base_url": "https://openrouter.ai/api/v1",
|
6
6
|
"role": "software engineer",
|
7
7
|
"system_prompt": None, # None means auto-generate from role
|
janito/agent/conversation.py
CHANGED
@@ -31,6 +31,12 @@ class ConversationHandler:
|
|
31
31
|
if resolved_max_tokens is None:
|
32
32
|
resolved_max_tokens = unified_config.get('max_tokens', 200000)
|
33
33
|
|
34
|
+
# Ensure max_tokens is always an int (handles config/CLI string values)
|
35
|
+
try:
|
36
|
+
resolved_max_tokens = int(resolved_max_tokens)
|
37
|
+
except (TypeError, ValueError):
|
38
|
+
raise ValueError(f"max_tokens must be an integer, got: {resolved_max_tokens!r}")
|
39
|
+
|
34
40
|
for _ in range(max_rounds):
|
35
41
|
if spinner:
|
36
42
|
# Calculate word count for all messages
|
janito/agent/tool_handler.py
CHANGED
@@ -45,9 +45,10 @@ class ToolHandler:
|
|
45
45
|
}
|
46
46
|
return func
|
47
47
|
|
48
|
-
def __init__(self, verbose=False):
|
48
|
+
def __init__(self, verbose=False, enable_tools=True):
|
49
49
|
self.verbose = verbose
|
50
50
|
self.tools = []
|
51
|
+
self.enable_tools = enable_tools
|
51
52
|
|
52
53
|
def register(self, func):
|
53
54
|
self.tools.append(func)
|
@@ -57,6 +58,8 @@ class ToolHandler:
|
|
57
58
|
return self.tools
|
58
59
|
|
59
60
|
def get_tool_schemas(self):
|
61
|
+
if not getattr(self, 'enable_tools', True):
|
62
|
+
return []
|
60
63
|
schemas = []
|
61
64
|
for name, entry in self._tool_registry.items():
|
62
65
|
schemas.append({
|
janito/cli/_print_config.py
CHANGED
@@ -62,7 +62,7 @@ def print_full_config(local_config, global_config, unified_config, config_defaul
|
|
62
62
|
template_path = Path(__file__).parent.parent / "templates" / "system_instructions.j2"
|
63
63
|
for key, value in default_items.items():
|
64
64
|
if key == "system_prompt" and value is None:
|
65
|
-
out(f"{key} =
|
65
|
+
out(f"{key} = (default template path: {home_shorten(str(template_path))})")
|
66
66
|
else:
|
67
67
|
out(f"{key} = {value}")
|
68
68
|
out("")
|
janito/cli/arg_parser.py
CHANGED
@@ -5,14 +5,21 @@ def create_parser():
|
|
5
5
|
parser = argparse.ArgumentParser(description="OpenRouter API call using OpenAI Python SDK")
|
6
6
|
parser.add_argument("prompt", type=str, nargs="?", help="Prompt to send to the model")
|
7
7
|
parser.add_argument("--max-tokens", type=int, default=None, help="Maximum tokens for model response (overrides config, default: 200000)")
|
8
|
-
parser.add_argument("
|
9
|
-
|
8
|
+
parser.add_argument("--model", type=str, default=None, help="Model name to use for this session (overrides config, does not persist)")
|
9
|
+
|
10
|
+
# Mutually exclusive group for system prompt options
|
11
|
+
group = parser.add_mutually_exclusive_group()
|
12
|
+
group.add_argument("-s", "--system-prompt", type=str, default=None, help="Optional system prompt as a raw string.")
|
13
|
+
group.add_argument("--system-file", type=str, default=None, help="Path to a plain text file to use as the system prompt (no template rendering, takes precedence over --system-prompt)")
|
14
|
+
|
15
|
+
parser.add_argument("-r", "--role", type=str, default=None, help="Role description for the default system prompt")
|
10
16
|
parser.add_argument("-t", "--temperature", type=float, default=None, help="Sampling temperature (e.g., 0.0 - 2.0)")
|
11
17
|
parser.add_argument("--verbose-http", action="store_true", help="Enable verbose HTTP logging")
|
12
18
|
parser.add_argument("--verbose-http-raw", action="store_true", help="Enable raw HTTP wire-level logging")
|
13
19
|
parser.add_argument("--verbose-response", action="store_true", help="Pretty print the full response object")
|
14
20
|
parser.add_argument("--show-system", action="store_true", help="Show model, parameters, system prompt, and tool definitions, then exit")
|
15
21
|
parser.add_argument("--verbose-tools", action="store_true", help="Print tool call parameters and results")
|
22
|
+
parser.add_argument("--disable-tools", action="store_true", default=False, help="Disable tool use (default: enabled)")
|
16
23
|
parser.add_argument("--set-local-config", type=str, default=None, help='Set a local config key-value pair, format "key=val"')
|
17
24
|
parser.add_argument("--set-global-config", type=str, default=None, help='Set a global config key-value pair, format "key=val"')
|
18
25
|
parser.add_argument("--show-config", action="store_true", help="Show effective configuration and exit")
|
janito/cli/config_commands.py
CHANGED
@@ -103,7 +103,7 @@ def handle_config_commands(args):
|
|
103
103
|
if key == "system_prompt" and value is None:
|
104
104
|
from pathlib import Path
|
105
105
|
template_path = Path(__file__).parent.parent / "templates" / "system_instructions.j2"
|
106
|
-
print(f"{key} =
|
106
|
+
print(f"{key} = (default template path: {home_shorten(str(template_path))})")
|
107
107
|
else:
|
108
108
|
print(f"{key} = {value}")
|
109
109
|
print()
|
janito/cli/runner.py
CHANGED
@@ -34,14 +34,31 @@ def run_cli(args):
|
|
34
34
|
# Ensure runtime_config is updated so chat shell sees the role
|
35
35
|
if args.role:
|
36
36
|
runtime_config.set('role', args.role)
|
37
|
-
|
38
|
-
#
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
|
38
|
+
# Set runtime_config['model'] if --model is provided (highest priority, session only)
|
39
|
+
if getattr(args, 'model', None):
|
40
|
+
runtime_config.set('model', args.model)
|
41
|
+
|
42
|
+
# New logic for --system-file
|
43
|
+
system_prompt = None
|
44
|
+
if getattr(args, 'system_file', None):
|
45
|
+
try:
|
46
|
+
with open(args.system_file, 'r', encoding='utf-8') as f:
|
47
|
+
system_prompt = f.read()
|
48
|
+
runtime_config.set('system_prompt_file', args.system_file)
|
49
|
+
except Exception as e:
|
50
|
+
print(f"[red]Failed to read system prompt file:[/red] {e}")
|
51
|
+
sys.exit(1)
|
52
|
+
else:
|
53
|
+
system_prompt = args.system_prompt or unified_config.get("system_prompt")
|
54
|
+
if args.system_prompt:
|
55
|
+
runtime_config.set('system_prompt', system_prompt)
|
56
|
+
if system_prompt is None:
|
57
|
+
system_prompt = render_system_prompt(role)
|
42
58
|
|
43
59
|
if args.show_system:
|
44
60
|
api_key = get_api_key()
|
61
|
+
# Always get model from unified_config (which checks runtime_config first)
|
45
62
|
model = unified_config.get('model')
|
46
63
|
agent = Agent(api_key=api_key, model=model)
|
47
64
|
print("Model:", agent.model)
|
@@ -52,37 +69,20 @@ def run_cli(args):
|
|
52
69
|
|
53
70
|
api_key = get_api_key()
|
54
71
|
|
72
|
+
# Always get model from unified_config (which checks runtime_config first)
|
55
73
|
model = unified_config.get('model')
|
56
74
|
base_url = unified_config.get('base_url', 'https://openrouter.ai/api/v1')
|
57
|
-
|
75
|
+
# Handle --enable-tools flag
|
76
|
+
from janito.agent.tool_handler import ToolHandler
|
77
|
+
tool_handler = ToolHandler(verbose=args.verbose_tools, enable_tools=not getattr(args, 'disable_tools', False))
|
78
|
+
agent = Agent(api_key=api_key, model=model, system_prompt=system_prompt, verbose_tools=args.verbose_tools, base_url=base_url, tool_handler=tool_handler)
|
58
79
|
|
59
80
|
# Save runtime max_tokens override if provided
|
60
81
|
if args.max_tokens is not None:
|
61
82
|
runtime_config.set('max_tokens', args.max_tokens)
|
62
|
-
if not args.prompt:
|
63
|
-
console = Console()
|
64
|
-
|
65
|
-
if not getattr(args, 'continue_session', False):
|
66
|
-
save_path = os.path.join('.janito', 'last_conversation.json')
|
67
|
-
if os.path.exists(save_path):
|
68
|
-
try:
|
69
|
-
with open(save_path, 'r', encoding='utf-8') as f:
|
70
|
-
data = json.load(f)
|
71
|
-
messages = data.get('messages', [])
|
72
|
-
num_messages = len(messages)
|
73
|
-
console.print(f"[bold yellow]A previous conversation with {num_messages} messages was found.[/bold yellow]")
|
74
|
-
|
75
|
-
last_usage_info = data.get('last_usage_info')
|
76
|
-
if last_usage_info:
|
77
|
-
prompt_tokens = last_usage_info.get('prompt_tokens', 0)
|
78
|
-
completion_tokens = last_usage_info.get('completion_tokens', 0)
|
79
|
-
total_tokens = prompt_tokens + completion_tokens
|
80
|
-
console.print(Rule(f"Token usage - Prompt: {format_tokens(prompt_tokens)}, Completion: {format_tokens(completion_tokens)}, Total: {format_tokens(total_tokens)}"))
|
81
|
-
|
82
|
-
console.print("You can resume it anytime by typing [bold]/continue[/bold].")
|
83
|
-
except Exception:
|
84
|
-
pass # Fail silently if file is corrupt or unreadable
|
85
83
|
|
84
|
+
# If no prompt is provided, enter shell loop mode
|
85
|
+
if not getattr(args, 'prompt', None):
|
86
86
|
from janito.cli_chat_shell.chat_loop import start_chat_shell
|
87
87
|
start_chat_shell(agent, continue_session=getattr(args, 'continue_session', False))
|
88
88
|
sys.exit(0)
|
@@ -91,14 +91,8 @@ def run_cli(args):
|
|
91
91
|
|
92
92
|
console = Console()
|
93
93
|
|
94
|
-
waiting_displayed = [True]
|
95
|
-
|
96
94
|
def on_content(data):
|
97
95
|
content = data.get("content", "")
|
98
|
-
if waiting_displayed[0]:
|
99
|
-
# Clear the waiting message
|
100
|
-
sys.stdout.flush()
|
101
|
-
waiting_displayed[0] = False
|
102
96
|
console.print(Markdown(content))
|
103
97
|
|
104
98
|
messages = []
|
@@ -117,22 +111,11 @@ def run_cli(args):
|
|
117
111
|
if args.verbose_response:
|
118
112
|
import json
|
119
113
|
console.print_json(json.dumps(response))
|
120
|
-
|
121
|
-
usage = response.get('usage')
|
122
|
-
if usage:
|
123
|
-
prompt_tokens = usage.get('prompt_tokens')
|
124
|
-
completion_tokens = usage.get('completion_tokens')
|
125
|
-
total_tokens = usage.get('total_tokens')
|
126
|
-
console.print(Rule(f"Token usage - Prompt: {format_tokens(prompt_tokens)}, Completion: {format_tokens(completion_tokens)}, Total: {format_tokens(total_tokens)}"))
|
127
114
|
except MaxRoundsExceededError:
|
128
|
-
print("[
|
129
|
-
sys.exit(1)
|
115
|
+
print("[red]Max conversation rounds exceeded.[/red]")
|
130
116
|
except ProviderError as e:
|
131
|
-
print(f"[
|
132
|
-
sys.exit(1)
|
117
|
+
print(f"[red]Provider error:[/red] {e}")
|
133
118
|
except EmptyResponseError as e:
|
134
|
-
print(f"[Error] {e}")
|
135
|
-
sys.exit(1)
|
119
|
+
print(f"[red]Error:[/red] {e}")
|
136
120
|
except KeyboardInterrupt:
|
137
|
-
print("
|
138
|
-
sys.exit(1)
|
121
|
+
console.print("[yellow]Interrupted by user.[/yellow]")
|
@@ -69,7 +69,7 @@ def start_chat_shell(agent, continue_session=False):
|
|
69
69
|
session = get_prompt_session(
|
70
70
|
get_toolbar_func(
|
71
71
|
get_messages, get_usage, get_elapsed, model_name=model_name,
|
72
|
-
role_ref=lambda: runtime_config.get('role') or effective_config.get('role')
|
72
|
+
role_ref=lambda: ("*using custom system prompt*" if (runtime_config.get('system_prompt') or runtime_config.get('system_prompt_file')) else (runtime_config.get('role') or effective_config.get('role')))
|
73
73
|
),
|
74
74
|
mem_history
|
75
75
|
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
You are a helpful {{ role }}.
|
2
2
|
|
3
|
-
|
3
|
+
You will start every response with a concise plan on how to gather additional information.
|
4
4
|
|
5
5
|
<context>
|
6
6
|
Always review `docs/structure.md` before conducting file-specific searches.
|
@@ -0,0 +1,85 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: janito
|
3
|
+
Version: 1.2.0
|
4
|
+
Summary: An agent framework with built-in tools.
|
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
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
12
|
+
Classifier: Operating System :: OS Independent
|
13
|
+
Requires-Python: >=3.8
|
14
|
+
Description-Content-Type: text/markdown
|
15
|
+
License-File: LICENSE
|
16
|
+
Requires-Dist: rich
|
17
|
+
Requires-Dist: openai
|
18
|
+
Requires-Dist: flask
|
19
|
+
Requires-Dist: pathspec
|
20
|
+
Requires-Dist: beautifulsoup4
|
21
|
+
Dynamic: license-file
|
22
|
+
|
23
|
+
# 🚀 Janito: Natural Language Code Editing Agent
|
24
|
+
|
25
|
+
## ⚡ Quick Start
|
26
|
+
|
27
|
+
Run a one-off prompt:
|
28
|
+
```bash
|
29
|
+
python -m janito "Refactor the data processing module to improve readability."
|
30
|
+
```
|
31
|
+
|
32
|
+
Or start the interactive chat shell:
|
33
|
+
```bash
|
34
|
+
python -m janito
|
35
|
+
```
|
36
|
+
|
37
|
+
Launch the web UI:
|
38
|
+
```bash
|
39
|
+
python -m janito.web
|
40
|
+
```
|
41
|
+
|
42
|
+
---
|
43
|
+
|
44
|
+
Janito is a command-line and web-based AI agent designed to **edit code and manage files** using natural language instructions.
|
45
|
+
|
46
|
+
---
|
47
|
+
|
48
|
+
## ✨ Key Features
|
49
|
+
- 📝 **Code Editing via Natural Language:** Modify, create, or delete code files simply by describing the changes.
|
50
|
+
- 📁 **File & Directory Management:** Navigate, create, move, or remove files and folders.
|
51
|
+
- 🧠 **Context-Aware:** Understands your project structure for precise edits.
|
52
|
+
- 💬 **Interactive User Prompts:** Asks for clarification when needed.
|
53
|
+
- 🧩 **Extensible Tooling:** Built-in tools for file operations, shell commands, and more.
|
54
|
+
- 🌐 **Web Interface (In Development):** Upcoming simple web UI for streaming responses and tool progress.
|
55
|
+
|
56
|
+
---
|
57
|
+
|
58
|
+
## 📦 Installation
|
59
|
+
|
60
|
+
### Requirements
|
61
|
+
- Python 3.8+
|
62
|
+
|
63
|
+
...
|
64
|
+
|
65
|
+
### Configurable Options
|
66
|
+
|
67
|
+
| Key | Description | How to set | Default |
|
68
|
+
|---------------------|---------------------------------------------------------------------------------------------|-----------------------------------------------------------------|--------------------------------------------|
|
69
|
+
| `api_key` | API key for OpenAI-compatible service | `--set-api-key`, config file | _None_ (required) |
|
70
|
+
| `model` | Model name to use | `--model` (session only), `--set-local-config model=...`, or `--set-global-config` | `openai/gpt-4.1` |
|
71
|
+
| `base_url` | API base URL (OpenAI-compatible endpoint) | `--set-local-config base_url=...` or `--set-global-config` | `https://openrouter.ai/api/v1` |
|
72
|
+
| `role` | Role description for system prompt | CLI `--role` or config | "software engineer" |
|
73
|
+
| `system_prompt` | Override the entire system prompt as a raw string. | CLI `--system-prompt` or config | _Template-generated prompt_ |
|
74
|
+
| `system_prompt_file`| Use a plain text file as the system prompt (no template rendering, takes precedence over `system_prompt`). | CLI `--system-file` | _None_ |
|
75
|
+
| `temperature` | Sampling temperature (float, e.g., 0.0 - 2.0) | CLI `--temperature` or config | 0.2 |
|
76
|
+
| `max_tokens` | Maximum tokens for model response | CLI `--max-tokens` or config | 200000 |
|
77
|
+
| `disable_tools` | Disable tool use (no tools passed to agent) | CLI `--disable-tools` | _False_ |
|
78
|
+
|
79
|
+
#### System Prompt Precedence
|
80
|
+
|
81
|
+
- If `--system-file` is provided, the file's content is used as the system prompt (no template rendering).
|
82
|
+
- Otherwise, if `--system-prompt` or the config value is set, that string is used.
|
83
|
+
- Otherwise, a default template is rendered using the current role.
|
84
|
+
|
85
|
+
...
|
@@ -1,14 +1,14 @@
|
|
1
|
-
janito/__init__.py,sha256=
|
1
|
+
janito/__init__.py,sha256=El1sbpINO-cJ2mX6y_07W6DCl7IpRhkDNz3fpZpHII0,23
|
2
2
|
janito/__main__.py,sha256=CBScR30Tm-vuhIJM8o5HXKr0q-smICiwSVyuU68BP8U,78
|
3
3
|
janito/render_prompt.py,sha256=HrMUELV4tI3PWqv6RM6teiVvnUejdehBcnHUFzit3Bo,445
|
4
4
|
janito/agent/__init__.py,sha256=CByAH5Yk-yH64zo0RU7Z3nsn_7Vmandphqk0JNlpyj8,21
|
5
5
|
janito/agent/agent.py,sha256=qGjkGajNjroz1kU-iV--0DD_2FwmwjAM1Y9Z5foxwoE,3590
|
6
|
-
janito/agent/config.py,sha256
|
7
|
-
janito/agent/config_defaults.py,sha256=
|
8
|
-
janito/agent/conversation.py,sha256=
|
6
|
+
janito/agent/config.py,sha256=-zespUJrFb61fyJzjemont6lirnPM_FF88NUiTVI91I,3555
|
7
|
+
janito/agent/config_defaults.py,sha256=Ow-LKq88MmMTQ6LDH_u26NqJ8-db35KpcfR8FYuWGBw,363
|
8
|
+
janito/agent/conversation.py,sha256=Q3sXqzKgQalr9SD8D4dJnCbe_EmklAobx_29mwYhJhE,4956
|
9
9
|
janito/agent/queued_tool_handler.py,sha256=THPymKXnpoXfN49EhW5b4hrwpWZZup73JKFDJ_U03tI,540
|
10
10
|
janito/agent/runtime_config.py,sha256=gigcKUwaXs_qSdXdC5InUTPmdXUbOA-tRUx2ZJ5zzI0,906
|
11
|
-
janito/agent/tool_handler.py,sha256=
|
11
|
+
janito/agent/tool_handler.py,sha256=MiwGx6Wlasan6KO3-Q0UDEJjmtDavd7ITc0gVjfa47s,4536
|
12
12
|
janito/agent/tools/__init__.py,sha256=7-RjFK1YXacifjSrXT4EdMXG_kyKVl7TCjrcHkklaCQ,414
|
13
13
|
janito/agent/tools/ask_user.py,sha256=MHKHyBTD4iyCM-z9_ZUbe7AMn-pz7cr6FIAB0SdESH4,1895
|
14
14
|
janito/agent/tools/bash_exec.py,sha256=1HkjvTlXunjZ7xvxqzdayG8JWtrioC0MYOfdid_6uiY,2486
|
@@ -25,27 +25,27 @@ janito/agent/tools/rich_utils.py,sha256=aQMqeaq3hIpzZ5EHQBNTKS5dNsojQp9MDfJSoqOQ
|
|
25
25
|
janito/agent/tools/search_text.py,sha256=TdTpaomLt4oZpX_0zz9W_bXhI5vvQLu0IjA7mCRCJYU,2020
|
26
26
|
janito/agent/tools/view_file.py,sha256=i4IBpn_Waw_4sgHUOaPIYPcMNmmvzM9ECoR5O5fldfU,1535
|
27
27
|
janito/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
28
|
-
janito/cli/_print_config.py,sha256=
|
28
|
+
janito/cli/_print_config.py,sha256=s6A-khfChmIQYRpYteokbXHlZ9VfIphdsnmABIYk_b4,3135
|
29
29
|
janito/cli/_utils.py,sha256=Q_OCFZmbr78qW4hSSUUhjondVc0ao7-iUHE7Ig8IP1g,289
|
30
|
-
janito/cli/arg_parser.py,sha256=
|
31
|
-
janito/cli/config_commands.py,sha256=
|
30
|
+
janito/cli/arg_parser.py,sha256=kMQAstvPldkwYrXjuWwp6lYfuQCl1NLrridFtyI75_g,3089
|
31
|
+
janito/cli/config_commands.py,sha256=WQKHt3iIdjRiAKmi-dnOSLFybF-HSc93zYoWd2aZcTU,5694
|
32
32
|
janito/cli/logging_setup.py,sha256=dWQ0wFf4YuF5lxZlhpN6lis7G56LeFYUwQdh9nA5NmA,1141
|
33
33
|
janito/cli/main.py,sha256=ONmn_lIPu8_Rd57j3YfWEx46fWj8gAkONPLdctABwy0,1333
|
34
|
-
janito/cli/runner.py,sha256=
|
34
|
+
janito/cli/runner.py,sha256=fzHdH3Vb4CoyOGDH6h74xKIOPKrUJJ3yRDlScsWJhqE,4481
|
35
35
|
janito/cli_chat_shell/__init__.py,sha256=PDGl7xK_vgkROoXvUxGZqVQFfuL9U4TjdexpP8E2JKg,41
|
36
|
-
janito/cli_chat_shell/chat_loop.py,sha256=
|
36
|
+
janito/cli_chat_shell/chat_loop.py,sha256=yPqQLEUwuzmtymmBLOwYSLd52ixRKL_C-ZK7vGYaNug,5384
|
37
37
|
janito/cli_chat_shell/commands.py,sha256=Tvhw8azybchGS1qi2yJEn3FKho-FDYOK1ZT865GYwhM,7615
|
38
38
|
janito/cli_chat_shell/config_shell.py,sha256=s59PCt_TmBPqQJ_C8nkKo4kCcW9aq3Jhpe9RlRCa0-s,3265
|
39
39
|
janito/cli_chat_shell/load_prompt.py,sha256=EuUlHg317T8f5VqEMaJxFgzWBl51zC2sND0eeYr6pJ4,612
|
40
40
|
janito/cli_chat_shell/session_manager.py,sha256=Gax0pC0ediDsExLUwPEg_nD8MdSrznaHoer53zxLYuE,1966
|
41
41
|
janito/cli_chat_shell/ui.py,sha256=7O36dWaXDQ5r-GGD6a57iHSiDpN2pkdav3HxSdf6CIc,5279
|
42
|
-
janito/templates/system_instructions.j2,sha256=
|
42
|
+
janito/templates/system_instructions.j2,sha256=JnR_nSbQrT5kfLeOwLgnvOV-x9N2msndj2HjDtEYRQw,1819
|
43
43
|
janito/web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
44
44
|
janito/web/__main__.py,sha256=oPXNF332aCeI7aUWr7_8M57oOKugw422VrEubxFp0P4,354
|
45
45
|
janito/web/app.py,sha256=bZse9S_F9hFSYRTJxoel5RjrtoAmvJ_lYkPfKRmBI1o,4125
|
46
|
-
janito-1.0.
|
47
|
-
janito-1.0.
|
48
|
-
janito-1.0.
|
49
|
-
janito-1.0.
|
50
|
-
janito-1.0.
|
51
|
-
janito-1.0.
|
46
|
+
janito-1.2.0.dist-info/licenses/LICENSE,sha256=sHBqv0bvtrb29H7WRR-Z603YHm9pLtJIo3nHU_9cmgE,1091
|
47
|
+
janito-1.2.0.dist-info/METADATA,sha256=Wyag2PcH7RCSx4YbQNFbrRrwmwOJOHg5js_se0niiNs,4664
|
48
|
+
janito-1.2.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
49
|
+
janito-1.2.0.dist-info/entry_points.txt,sha256=wIo5zZxbmu4fC-ZMrsKD0T0vq7IqkOOLYhrqRGypkx4,48
|
50
|
+
janito-1.2.0.dist-info/top_level.txt,sha256=m0NaVCq0-ivxbazE2-ND0EA9Hmuijj_OGkmCbnBcCig,7
|
51
|
+
janito-1.2.0.dist-info/RECORD,,
|
janito-1.0.1.dist-info/METADATA
DELETED
@@ -1,144 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: janito
|
3
|
-
Version: 1.0.1
|
4
|
-
Summary: An agent framework with built-in tools.
|
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
|
11
|
-
Classifier: License :: OSI Approved :: MIT License
|
12
|
-
Classifier: Operating System :: OS Independent
|
13
|
-
Requires-Python: >=3.8
|
14
|
-
Description-Content-Type: text/markdown
|
15
|
-
License-File: LICENSE
|
16
|
-
Requires-Dist: rich
|
17
|
-
Requires-Dist: openai
|
18
|
-
Requires-Dist: flask
|
19
|
-
Requires-Dist: pathspec
|
20
|
-
Dynamic: license-file
|
21
|
-
|
22
|
-
# 🚀 Janito: Natural Language Code Editing Agent
|
23
|
-
|
24
|
-
## ⚡ Quick Start
|
25
|
-
|
26
|
-
Run a one-off prompt:
|
27
|
-
```bash
|
28
|
-
python -m janito "Refactor the data processing module to improve readability."
|
29
|
-
```
|
30
|
-
|
31
|
-
Or start the interactive chat shell:
|
32
|
-
```bash
|
33
|
-
python -m janito
|
34
|
-
```
|
35
|
-
|
36
|
-
Launch the web UI:
|
37
|
-
```bash
|
38
|
-
python -m janito.web
|
39
|
-
```
|
40
|
-
|
41
|
-
---
|
42
|
-
|
43
|
-
Janito is a command-line and web-based AI agent designed to **edit code and manage files** using natural language instructions.
|
44
|
-
|
45
|
-
---
|
46
|
-
|
47
|
-
## ✨ Key Features
|
48
|
-
- 📝 **Code Editing via Natural Language:** Modify, create, or delete code files simply by describing the changes.
|
49
|
-
- 📁 **File & Directory Management:** Navigate, create, move, or remove files and folders.
|
50
|
-
- 🧠 **Context-Aware:** Understands your project structure for precise edits.
|
51
|
-
- 💬 **Interactive User Prompts:** Asks for clarification when needed.
|
52
|
-
- 🧩 **Extensible Tooling:** Built-in tools for file operations, shell commands, and more.
|
53
|
-
- 🌐 **Web Interface (In Development):** Upcoming simple web UI for streaming responses and tool progress.
|
54
|
-
|
55
|
-
---
|
56
|
-
|
57
|
-
## 📦 Installation
|
58
|
-
|
59
|
-
### Requirements
|
60
|
-
- Python 3.8+
|
61
|
-
|
62
|
-
### Install dependencies
|
63
|
-
```bash
|
64
|
-
pip install -e .
|
65
|
-
```
|
66
|
-
|
67
|
-
### Set your API key
|
68
|
-
Janito uses OpenAI-compatible APIs (default: `openrouter/optimus-alpha`). Set your API key using the CLI:
|
69
|
-
```bash
|
70
|
-
python -m janito --set-api-key your_api_key_here
|
71
|
-
```
|
72
|
-
|
73
|
-
### Obtain an API key from openrouter.io
|
74
|
-
1. Visit [https://openrouter.io/](https://openrouter.io/)
|
75
|
-
2. Sign in or create a free account.
|
76
|
-
3. Navigate to **API Keys** in your account dashboard.
|
77
|
-
4. Click **Create new key**, provide a name, and save the generated key.
|
78
|
-
5. Save it using the CLI:
|
79
|
-
```bash
|
80
|
-
python -m janito --set-api-key your_api_key_here
|
81
|
-
```
|
82
|
-
|
83
|
-
---
|
84
|
-
|
85
|
-
## ⚙️ Configuration
|
86
|
-
|
87
|
-
Janito supports multiple ways to configure API access, model, and behavior:
|
88
|
-
|
89
|
-
### API Key
|
90
|
-
|
91
|
-
- Set via CLI:
|
92
|
-
```bash
|
93
|
-
python -m janito --set-api-key your_api_key_here
|
94
|
-
```
|
95
|
-
|
96
|
-
### Configurable Options
|
97
|
-
|
98
|
-
| Key | Description | How to set | Default |
|
99
|
-
|-----------------|-----------------------------------------------------------|-----------------------------------------------------------------|--------------------------------------------|
|
100
|
-
| `api_key` | API key for OpenAI-compatible service | `--set-api-key`, config file | _None_ (required) |
|
101
|
-
| `model` | Model name to use | `--set-local-config model=...` or `--set-global-config` | `openrouter/optimus-alpha` |
|
102
|
-
| `base_url` | API base URL (OpenAI-compatible endpoint) | `--set-local-config base_url=...` or `--set-global-config` | `https://openrouter.ai/api/v1` |
|
103
|
-
| `role` | Role description for system prompt | CLI `--role` or config | "software engineer" |
|
104
|
-
| `system_prompt` | Override the entire system prompt | CLI `--system-prompt` or config | _Template-generated prompt_ |
|
105
|
-
| `temperature` | Sampling temperature (float, e.g., 0.0 - 2.0) | CLI `--temperature` or config | 0.2 |
|
106
|
-
| `max_tokens` | Maximum tokens for model response | CLI `--max-tokens` or config | 200000 |
|
107
|
-
|
108
|
-
### Config files
|
109
|
-
|
110
|
-
- **Local config:** `.janito/config.json` (project-specific)
|
111
|
-
- **Global config:** `~/.config/janito/config.json` (user-wide)
|
112
|
-
|
113
|
-
Set values via:
|
114
|
-
|
115
|
-
```bash
|
116
|
-
python -m janito --set-local-config key=value
|
117
|
-
python -m janito --set-global-config key=value
|
118
|
-
```
|
119
|
-
|
120
|
-
---
|
121
|
-
|
122
|
-
## 🚀 Build and Release
|
123
|
-
|
124
|
-
Janito provides scripts for automated build and release to PyPI:
|
125
|
-
|
126
|
-
### Bash (Linux/macOS)
|
127
|
-
|
128
|
-
```bash
|
129
|
-
./tools/release.sh
|
130
|
-
```
|
131
|
-
|
132
|
-
### PowerShell (Windows)
|
133
|
-
|
134
|
-
```powershell
|
135
|
-
./tools/release.ps1
|
136
|
-
```
|
137
|
-
|
138
|
-
These scripts will:
|
139
|
-
- Check for required tools (`hatch`, `twine`)
|
140
|
-
- Validate the version in `pyproject.toml` against PyPI and git tags
|
141
|
-
- Build the package
|
142
|
-
- Upload to PyPI
|
143
|
-
|
144
|
-
---
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|