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 CHANGED
@@ -1 +1 @@
1
- __version__ = "1.0.1"
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., 'openrouter/optimus-alpha')",
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",
@@ -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": "openrouter/optimus-alpha", # Default 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
@@ -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
@@ -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({
@@ -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} = file: {home_shorten(str(template_path))}")
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("-s", "--system-prompt", type=str, default=None, help="Optional system prompt")
9
- parser.add_argument("-r", "--role", type=str, default=None, help="Role description for the system prompt")
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")
@@ -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} = file: {home_shorten(str(template_path))}")
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
- # if args.role:
38
- # runtime_config.set('role', args.role)
39
- system_prompt = args.system_prompt or unified_config.get("system_prompt")
40
- if system_prompt is None:
41
- system_prompt = render_system_prompt(role)
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
- agent = Agent(api_key=api_key, model=model, system_prompt=system_prompt, verbose_tools=args.verbose_tools, base_url=base_url)
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("[Error] Conversation exceeded maximum rounds.")
129
- sys.exit(1)
115
+ print("[red]Max conversation rounds exceeded.[/red]")
130
116
  except ProviderError as e:
131
- print(f"[Error] Provider error: {e}")
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("\n[Interrupted by user]")
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
- When using tools, please describe the purpose before calling them.
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=j9q3lYMZra0QrErNnn9E5GNXxWLOlDgeOkmX8oXa7ro,23
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=6WQbjrK-UwkG9Yb5e5ljfBIvQs3Y_Wgd3Py8FbO0RiI,3565
7
- janito/agent/config_defaults.py,sha256=cR4kFkjg6BFccE0psy4khBiKjnj60VCQhmqLvLbjcJM,373
8
- janito/agent/conversation.py,sha256=5UtWgDsRh205p0Dq8tEtqEPT0avL8KFs3xmwJomaYEk,4664
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=f3iOWi78bKn0B6twMlayedmE0OMeQ1do32yZl4DMzaE,4399
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=gsdVgG8uGHoWZHUSzgvB-FIrlvAawF0HjXtiQZAloPk,3116
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=6Y_gBJSPk7tdHKSAsi1fQdr4pnCp8dcSGFrlu7s8KiI,2498
31
- janito/cli/config_commands.py,sha256=Ovk2LszVrHcKSqXjlH-fvJYhT3axZomlh9_wpNQfSYI,5675
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=K_xpygfg4MpyLuI6hx3s1I6-leEd80w08l3F6PIO4so,5362
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=KjnmhOYU0zblBzV5Q80BCqgvKSi_rPpE3TykzzDoexk,5259
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=f-hRp0ZliGac8vg6HJiYkU0TketpFoSbUunh9TOQrtE,1795
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.1.dist-info/licenses/LICENSE,sha256=sHBqv0bvtrb29H7WRR-Z603YHm9pLtJIo3nHU_9cmgE,1091
47
- janito-1.0.1.dist-info/METADATA,sha256=NcSx21pY78wR4NzupbiIuEc0srPMn9nToBpLFbKZQjM,5103
48
- janito-1.0.1.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
49
- janito-1.0.1.dist-info/entry_points.txt,sha256=wIo5zZxbmu4fC-ZMrsKD0T0vq7IqkOOLYhrqRGypkx4,48
50
- janito-1.0.1.dist-info/top_level.txt,sha256=m0NaVCq0-ivxbazE2-ND0EA9Hmuijj_OGkmCbnBcCig,7
51
- janito-1.0.1.dist-info/RECORD,,
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,,
@@ -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