janito 1.5.0__py3-none-any.whl → 1.5.2__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.5.0"
1
+ __version__ = "1.5.1"
@@ -0,0 +1,5 @@
1
+ # janito/agent/tool_auto_imports.py
2
+ # This module imports all tool modules to ensure they are registered via their decorators.
3
+ # It should be imported only where tool auto-registration is needed, to avoid circular import issues.
4
+
5
+ from janito.agent.tools import search_files, run_bash_command, replace_text_in_file, remove_file, remove_directory, py_compile, python_exec, move_file, get_lines, get_file_outline, find_files, fetch_url, create_file, create_directory, ask_user, append_text_to_file
@@ -1,92 +1,132 @@
1
- # janito/agent/tool_registry.py
2
- import json
3
- from janito.agent.tools.tool_base import ToolBase
4
-
5
- from janito.agent.openai_schema_generator import generate_openai_function_schema
6
-
7
- _tool_registry = {}
8
-
9
- def register_tool(tool=None, *, name: str = None):
10
- if tool is None:
11
- return lambda t: register_tool(t, name=name)
12
- override_name = name
13
- if not (isinstance(tool, type) and issubclass(tool, ToolBase)):
14
- raise TypeError("Tool must be a class derived from ToolBase.")
15
- instance = tool()
16
- func = instance.call
17
- default_name = tool.__name__
18
- tool_name = override_name or default_name
19
- schema = generate_openai_function_schema(func, tool_name)
20
-
21
-
22
- _tool_registry[tool_name] = {
23
- "function": func,
24
- "description": schema["description"],
25
- "parameters": schema["parameters"]
26
- }
27
- return tool
28
-
29
- def get_tool_schemas():
30
- schemas = []
31
- for name, entry in _tool_registry.items():
32
- schemas.append({
33
- "type": "function",
34
- "function": {
35
- "name": name,
36
- "description": entry["description"],
37
- "parameters": entry["parameters"]
38
- }
39
- })
40
- return schemas
41
-
42
- def handle_tool_call(tool_call, message_handler=None, verbose=False):
43
- import uuid
44
- call_id = getattr(tool_call, 'id', None) or str(uuid.uuid4())
45
- tool_entry = _tool_registry.get(tool_call.function.name)
46
- if not tool_entry:
47
- return f"Unknown tool: {tool_call.function.name}"
48
- func = tool_entry["function"]
49
- args = json.loads(tool_call.function.arguments)
50
- if verbose:
51
- print(f"[Tool Call] {tool_call.function.name} called with arguments: {args}")
52
- instance = None
53
- if hasattr(func, '__self__') and isinstance(func.__self__, ToolBase):
54
- instance = func.__self__
55
- if message_handler:
56
- instance._progress_callback = message_handler.handle_message
57
- # Emit tool_call event before calling the tool
58
- if message_handler:
59
- message_handler.handle_message({
60
- 'type': 'tool_call',
61
- 'tool': tool_call.function.name,
62
- 'args': args,
63
- 'call_id': call_id
64
- })
65
- try:
66
- result = func(**args)
67
- except Exception as e:
68
- import traceback # Kept here: only needed on error
69
- error_message = f"[Tool Error] {type(e).__name__}: {e}\n" + traceback.format_exc()
70
- if message_handler:
71
- message_handler.handle_message({'type': 'error', 'message': error_message})
72
- result = error_message
73
- # Emit tool_result event after tool execution
74
- if message_handler:
75
- message_handler.handle_message({
76
- 'type': 'tool_result',
77
- 'tool': tool_call.function.name,
78
- 'call_id': call_id,
79
- 'result': result
80
- })
81
- if verbose:
82
- preview = result
83
- if isinstance(result, str):
84
- lines = result.splitlines()
85
- if len(lines) > 10:
86
- preview = "\n".join(lines[:10]) + "\n... (truncated)"
87
- elif len(result) > 500:
88
- preview = result[:500] + "... (truncated)"
89
- print(f"[Tool Result] {tool_call.function.name} returned:\n{preview}")
90
- if instance is not None:
91
- instance._progress_callback = None
92
- return result
1
+ # janito/agent/tool_registry.py
2
+ import json
3
+ from janito.agent.tools.tool_base import ToolBase
4
+ from janito.agent.openai_schema_generator import generate_openai_function_schema
5
+
6
+ _tool_registry = {}
7
+
8
+ def register_tool(tool=None, *, name: str = None):
9
+ if tool is None:
10
+ return lambda t: register_tool(t, name=name)
11
+ override_name = name
12
+ if not (isinstance(tool, type) and issubclass(tool, ToolBase)):
13
+ raise TypeError("Tool must be a class derived from ToolBase.")
14
+ instance = tool()
15
+ func = instance.call
16
+ default_name = tool.__name__
17
+ tool_name = override_name or default_name
18
+ schema = generate_openai_function_schema(func, tool_name)
19
+ _tool_registry[tool_name] = {
20
+ "function": func,
21
+ "description": schema["description"],
22
+ "parameters": schema["parameters"]
23
+ }
24
+ return tool
25
+
26
+ def get_tool_schemas():
27
+ schemas = []
28
+ for name, entry in _tool_registry.items():
29
+ schemas.append({
30
+ "type": "function",
31
+ "function": {
32
+ "name": name,
33
+ "description": entry["description"],
34
+ "parameters": entry["parameters"]
35
+ }
36
+ })
37
+ return schemas
38
+
39
+ def handle_tool_call(tool_call, message_handler=None, verbose=False):
40
+ import uuid
41
+ call_id = getattr(tool_call, 'id', None) or str(uuid.uuid4())
42
+ tool_entry = _tool_registry.get(tool_call.function.name)
43
+ if not tool_entry:
44
+ return f"Unknown tool: {tool_call.function.name}"
45
+ func = tool_entry["function"]
46
+ args = json.loads(tool_call.function.arguments)
47
+ if verbose:
48
+ print(f"[Tool Call] {tool_call.function.name} called with arguments: {args}")
49
+ instance = None
50
+ if hasattr(func, '__self__') and isinstance(func.__self__, ToolBase):
51
+ instance = func.__self__
52
+ if message_handler:
53
+ instance._progress_callback = message_handler.handle_message
54
+ # Emit tool_call event before calling the tool
55
+ if message_handler:
56
+ message_handler.handle_message({
57
+ 'type': 'tool_call',
58
+ 'tool': tool_call.function.name,
59
+ 'call_id': call_id,
60
+ 'arguments': args,
61
+ })
62
+ try:
63
+ result = func(**args)
64
+ if message_handler:
65
+ message_handler.handle_message({
66
+ 'type': 'tool_result',
67
+ 'tool': tool_call.function.name,
68
+ 'call_id': call_id,
69
+ 'result': result,
70
+ })
71
+ return result
72
+ except Exception as e:
73
+ if message_handler:
74
+ message_handler.handle_message({
75
+ 'type': 'tool_error',
76
+ 'tool': tool_call.function.name,
77
+ 'call_id': call_id,
78
+ 'error': str(e),
79
+ })
80
+ raise
81
+
82
+ def handle_tool_call(tool_call, message_handler=None, verbose=False):
83
+ import uuid
84
+ call_id = getattr(tool_call, 'id', None) or str(uuid.uuid4())
85
+ tool_entry = _tool_registry.get(tool_call.function.name)
86
+ if not tool_entry:
87
+ return f"Unknown tool: {tool_call.function.name}"
88
+ func = tool_entry["function"]
89
+ args = json.loads(tool_call.function.arguments)
90
+ if verbose:
91
+ print(f"[Tool Call] {tool_call.function.name} called with arguments: {args}")
92
+ instance = None
93
+ if hasattr(func, '__self__') and isinstance(func.__self__, ToolBase):
94
+ instance = func.__self__
95
+ if message_handler:
96
+ instance._progress_callback = message_handler.handle_message
97
+ # Emit tool_call event before calling the tool
98
+ if message_handler:
99
+ message_handler.handle_message({
100
+ 'type': 'tool_call',
101
+ 'tool': tool_call.function.name,
102
+ 'args': args,
103
+ 'call_id': call_id
104
+ })
105
+ try:
106
+ result = func(**args)
107
+ except Exception as e:
108
+ import traceback # Kept here: only needed on error
109
+ error_message = f"[Tool Error] {type(e).__name__}: {e}\n" + traceback.format_exc()
110
+ if message_handler:
111
+ message_handler.handle_message({'type': 'error', 'message': error_message})
112
+ result = error_message
113
+ # Emit tool_result event after tool execution
114
+ if message_handler:
115
+ message_handler.handle_message({
116
+ 'type': 'tool_result',
117
+ 'tool': tool_call.function.name,
118
+ 'call_id': call_id,
119
+ 'result': result
120
+ })
121
+ if verbose:
122
+ preview = result
123
+ if isinstance(result, str):
124
+ lines = result.splitlines()
125
+ if len(lines) > 10:
126
+ preview = "\n".join(lines[:10]) + "\n... (truncated)"
127
+ elif len(result) > 500:
128
+ preview = result[:500] + "... (truncated)"
129
+ print(f"[Tool Result] {tool_call.function.name} returned:\n{preview}")
130
+ if instance is not None:
131
+ instance._progress_callback = None
132
+ return result
@@ -0,0 +1,2 @@
1
+ # This file is now unused. All tool registry logic has been consolidated into tool_registry.py.
2
+ # Kept for backward compatibility only. Do not use.
@@ -1,9 +1,2 @@
1
- import importlib
2
- import os
3
-
4
- # Dynamically import all tool modules in this directory (except __init__.py and tool_base.py)
5
- _tool_dir = os.path.dirname(__file__)
6
- for fname in os.listdir(_tool_dir):
7
- if fname.endswith('.py') and fname not in ('__init__.py', 'tool_base.py'):
8
- modname = fname[:-3]
9
- importlib.import_module(f'janito.agent.tools.{modname}')
1
+ # This file is intentionally empty.
2
+ # Tool auto-imports are handled by janito.agent.tool_auto_imports at CLI startup.
@@ -43,8 +43,14 @@ class FindFilesTool(ToolBase):
43
43
  if len(matches) >= max_results:
44
44
  break
45
45
 
46
- self.report_success(f" {len(matches)} {pluralize('file', len(matches))}")
47
- return "\n".join(matches)
46
+ warning = ""
47
+ if len(matches) >= max_results:
48
+ warning = "\n⚠️ Warning: Maximum result limit reached. Some matches may not be shown."
49
+ suffix = " (Max Reached)"
50
+ else:
51
+ suffix = ""
52
+ self.report_success(f" ✅ {len(matches)} {pluralize('file', len(matches))}{suffix}")
53
+ return "\n".join(matches) + warning
48
54
 
49
55
 
50
56
  from janito.agent.tools.tools_utils import pluralize
@@ -7,13 +7,14 @@ from janito.agent.tools.gitignore_utils import filter_ignored
7
7
  @register_tool(name="search_files")
8
8
  class SearchFilesTool(ToolBase):
9
9
  """Search for a text pattern in all files within a directory and return matching lines. Respects .gitignore."""
10
- def call(self, directories: list[str], pattern: str) -> str:
10
+ def call(self, directories: list[str], pattern: str, max_results: int=100) -> str:
11
11
  """
12
12
  Search for a text pattern in all files within one or more directories and return matching lines.
13
13
 
14
14
  Args:
15
15
  directories (list[str]): List of directories to search in.
16
16
  pattern (str): Plain text substring to search for in files. (Not a regular expression or glob pattern.)
17
+ max_results (int): Maximum number of results to return. Defaults to 100.
17
18
 
18
19
  Returns:
19
20
  str: Matching lines from files as a newline-separated string, each formatted as 'filepath:lineno: line'. Example:
@@ -35,11 +36,19 @@ class SearchFilesTool(ToolBase):
35
36
  for lineno, line in enumerate(f, 1):
36
37
  if pattern in line:
37
38
  matches.append(f"{path}:{lineno}: {line.strip()}")
39
+ if len(matches) >= max_results:
40
+ break
38
41
  except Exception:
39
42
  continue
40
43
 
41
- self.report_success(f" {len(matches)} {pluralize('line', len(matches))}")
42
- return '\n'.join(matches)
44
+ warning = ""
45
+ if len(matches) >= max_results:
46
+ warning = "\n⚠️ Warning: Maximum result limit reached. Some matches may not be shown."
47
+ suffix = " (Max Reached)"
48
+ else:
49
+ suffix = ""
50
+ self.report_success(f" ✅ {len(matches)} {pluralize('line', len(matches))}{suffix}")
51
+ return '\n'.join(matches) + warning
43
52
 
44
53
 
45
54
  from janito.agent.tools.tools_utils import pluralize
janito/cli/main.py CHANGED
@@ -1,5 +1,6 @@
1
1
  """Main CLI entry point for Janito."""
2
2
 
3
+ import janito.agent.tool_auto_imports
3
4
  from janito.cli.arg_parser import create_parser
4
5
  from janito.cli.config_commands import handle_config_commands
5
6
  from janito.cli.logging_setup import setup_verbose_logging
@@ -41,4 +41,97 @@ def print_welcome(console, version=None, continued=False):
41
41
  console.print("[yellow]To resume your previous conversation, type /continue at any time.[/yellow]")
42
42
 
43
43
 
44
+ def get_toolbar_func(messages_ref, last_usage_info_ref, last_elapsed_ref, model_name=None, role_ref=None):
45
+ def format_tokens(n):
46
+ if n is None:
47
+ return "?"
48
+ if n >= 1_000_000:
49
+ return f"{n/1_000_000:.1f}m"
50
+ if n >= 1_000:
51
+ return f"{n/1_000:.1f}k"
52
+ return str(n)
53
+
54
+ def get_toolbar():
55
+ left = f' Messages: <msg_count>{len(messages_ref())}</msg_count>'
56
+ usage = last_usage_info_ref()
57
+ last_elapsed = last_elapsed_ref()
58
+ if usage:
59
+ prompt_tokens = usage.get('prompt_tokens')
60
+ completion_tokens = usage.get('completion_tokens')
61
+ total_tokens = (prompt_tokens or 0) + (completion_tokens or 0)
62
+ speed = None
63
+ if last_elapsed and last_elapsed > 0:
64
+ speed = total_tokens / last_elapsed
65
+ left += (
66
+ f" | Tokens: In=<tokens_in>{format_tokens(prompt_tokens)}</tokens_in> / "
67
+ f"Out=<tokens_out>{format_tokens(completion_tokens)}</tokens_out> / "
68
+ f"Total=<tokens_total>{format_tokens(total_tokens)}</tokens_total>"
69
+ )
70
+ if speed is not None:
71
+ left += f", speed=<speed>{speed:.1f}</speed> tokens/sec"
72
+
73
+ from prompt_toolkit.application import get_app
74
+ width = get_app().output.get_size().columns
75
+ model_part = f" Model: <model>{model_name}</model>" if model_name else ""
76
+ role_part = ""
77
+ vanilla_mode = runtime_config.get('vanilla_mode', False)
78
+ if role_ref and not vanilla_mode:
79
+ role = role_ref()
80
+ if role:
81
+ role_part = f"Role: <b>{role}</b>"
82
+ first_line_parts = []
83
+ if model_part:
84
+ first_line_parts.append(model_part)
85
+ if role_part:
86
+ first_line_parts.append(role_part)
87
+ first_line = " | ".join(first_line_parts)
88
+ help_part = "<b>/help</b> for help | <b>F12</b>: Go ahead"
89
+ total_len = len(left) + len(help_part) + 3 # separators and spaces
90
+ if first_line:
91
+ total_len += len(first_line) + 3
92
+ if total_len < width:
93
+ padding = ' ' * (width - total_len)
94
+ second_line = f"{left}{padding} | {help_part}"
95
+ else:
96
+ second_line = f"{left} | {help_part}"
97
+ if first_line:
98
+ toolbar_text = first_line + "\n" + second_line
99
+ else:
100
+ toolbar_text = second_line
101
+ return HTML(toolbar_text)
102
+ return get_toolbar
103
+
104
+ def get_prompt_session(get_toolbar_func, mem_history):
105
+ from prompt_toolkit.key_binding import KeyBindings
106
+ style = Style.from_dict({
107
+ 'bottom-toolbar': 'bg:#333333 #ffffff',
108
+ 'b': 'bold',
109
+ 'prompt': 'bold bg:#000080 #ffffff',
110
+ 'model': 'bold bg:#005f5f #ffffff', # distinct background/foreground
111
+ 'msg_count': 'bg:#333333 #ffff00 bold',
112
+ 'tokens_in': 'ansicyan bold',
113
+ 'tokens_out': 'ansigreen bold',
114
+ 'tokens_total': 'ansiyellow bold',
115
+ 'speed': 'ansimagenta bold',
116
+ 'right': 'bg:#005f5f #ffffff',
117
+ 'input': 'bg:#000080 #ffffff',
118
+ '': 'bg:#000080 #ffffff',
119
+ })
120
+ kb = KeyBindings()
121
+ @kb.add('f12')
122
+ def _(event):
123
+ """When F12 is pressed, send 'Go ahead' as input immediately."""
124
+ buf = event.app.current_buffer
125
+ buf.text = 'Go ahead'
126
+ buf.validate_and_handle()
127
+ session = PromptSession(
128
+ multiline=False,
129
+ key_bindings=kb,
130
+ editing_mode=EditingMode.EMACS,
131
+ bottom_toolbar=get_toolbar_func,
132
+ style=style,
133
+ history=mem_history
134
+ )
135
+ return session
136
+
44
137
  # ... rest of the file remains unchanged ...
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: janito
3
- Version: 1.5.0
3
+ Version: 1.5.2
4
4
  Summary: A Natural Programming Language Agent,
5
5
  Author-email: João Pinto <joao.pinto@gmail.com>
6
6
  License: MIT
@@ -1,4 +1,4 @@
1
- janito/__init__.py,sha256=TJdX3kZk_MYc3dWRgST-ZjHyS_SdJ3N_VqRvVAVCkc4,23
1
+ janito/__init__.py,sha256=khi4ujZnKOCcOQf36wd2PHf2pb8dzIOIyoobKILMdfw,23
2
2
  janito/__main__.py,sha256=CBScR30Tm-vuhIJM8o5HXKr0q-smICiwSVyuU68BP8U,78
3
3
  janito/render_prompt.py,sha256=y2pqntkfC34bh5psNobW2Vv1YAI3se04-ZcFCaoWU1s,457
4
4
  janito/rich_utils.py,sha256=g5D-McYEUhzhPFpZGML41sw4w75eT51gu0x7anMQjxA,1048
@@ -14,15 +14,17 @@ janito/agent/openai_schema_generator.py,sha256=dE3gUPX_ZqYzuY9rWY5Ygo9imXvy-Mn1r
14
14
  janito/agent/queued_message_handler.py,sha256=raz_tQLooWpWvx1qqPrl1s4F4Xx_-wyCxQPfwcDI4II,1365
15
15
  janito/agent/rich_tool_handler.py,sha256=L0YGZTnkD_iISAUdP6sLdZ8fuKKQQrRlATIlmhInPQs,1906
16
16
  janito/agent/runtime_config.py,sha256=ztmU0Ajd2NS7olJxhXjHPtndqIZKuWMqFXuQm-TqCUE,891
17
- janito/agent/tool_registry.py,sha256=4vDVdAzm_a12M2h94h_IgYeAkIVGMwDlIRohS8SydBA,3376
17
+ janito/agent/tool_auto_imports.py,sha256=eS-iWMkAq2KIInExRtlPdLAfSIVlXeDkeXXYE-kxmFk,495
18
+ janito/agent/tool_registry.py,sha256=GAhiX3R1y-WoveSCp-qQkREaMqRryqp-o19A7O1XOPo,4852
19
+ janito/agent/tool_registry_core.py,sha256=bF7rRn3ZMpU7JXBFhYQPg2XxczhN572Xc5pbdLBPkvE,148
18
20
  janito/agent/templates/system_instructions.j2,sha256=Y24edrqLydMTcbaZYSW8_xJMMEbTNVS3Iy4IHrBe0-Q,1885
19
- janito/agent/tools/__init__.py,sha256=Vv1oWF6Ur-Tkm3p0KCz5HD7wwar9rUHtY596NGPnn2s,378
21
+ janito/agent/tools/__init__.py,sha256=TkXRcFj1E2OHQBb2RUkGCQPsxkL519yFUYWbR1zEDG8,120
20
22
  janito/agent/tools/append_text_to_file.py,sha256=sSklc9Ifo7tTKB81yRgfU7yWfeHsRBNdUQVbOYw52EE,1881
21
23
  janito/agent/tools/ask_user.py,sha256=36pZLy3WPEIQyKKallbH9Bq-8ASLWb-Eza4g1VbYZ-c,2482
22
24
  janito/agent/tools/create_directory.py,sha256=fFMXIqSFRx6NyRtbJvgUId-rN83mYHsAQqP-2sBjGMA,1340
23
25
  janito/agent/tools/create_file.py,sha256=YQISWGBUOMFTFA_hKqanYjXNJMHK22jDSrGIxOAMWDY,2551
24
26
  janito/agent/tools/fetch_url.py,sha256=RuicvHm8uQJSCPwfLv6KV9my1HCJd0ehl3yutjKyd3g,2068
25
- janito/agent/tools/find_files.py,sha256=3jQAJTOeh8eqjnajX-jIPsTJmKablHw5c_OvPfkmqZ4,2283
27
+ janito/agent/tools/find_files.py,sha256=14iUSLPzqycuZpRkCNpS8hoa7KvGlotogMYQc4yFobo,2547
26
28
  janito/agent/tools/get_file_outline.py,sha256=NwyIY2XAJr9REmeyX6Lyd6SyQiLdAiSzN4dii_iltM0,1447
27
29
  janito/agent/tools/get_lines.py,sha256=Y7tHnHZB0PFylcRIXtDvmFPXdoWTeXUmVrENpBgVBdM,3364
28
30
  janito/agent/tools/gitignore_utils.py,sha256=z_IYilabTD_-c14aRxuVasojOzTsg-11xJPJqudWIKA,1306
@@ -34,7 +36,7 @@ janito/agent/tools/remove_file.py,sha256=qVfuAJXThA4UR7iCU5DLc_UMY81iextp0_zXTgH
34
36
  janito/agent/tools/replace_text_in_file.py,sha256=0w5cG_MvXcxwQI-i8hX-GedW0qnEwn-eYXYaNlv4NxA,4969
35
37
  janito/agent/tools/rich_live.py,sha256=cuZ3-ZxpuHxR1TvIcp0bi9F3QM1M6Ms0XiOMd8If8gU,1161
36
38
  janito/agent/tools/run_bash_command.py,sha256=1LcoNNhRHH65tCmGmdEFtpA5S4L1kmODuvBQUl7LGnA,5246
37
- janito/agent/tools/search_files.py,sha256=Po6Xnngqq95WVIkQkKLkpjugom7D4E4-RnaE50jBtc8,2222
39
+ janito/agent/tools/search_files.py,sha256=5ZTGB6adWO8OafGLZHGjnhUaW5IE4IfM1BSVxzNwNeI,2710
38
40
  janito/agent/tools/tool_base.py,sha256=ch08PaWMEC8hC0UmWC7fEXmRBdnsmqXn6pXhoXbGXFU,1898
39
41
  janito/agent/tools/tools_utils.py,sha256=G_Ib8QamhHbBzpKDW3TeoaxGDQgjs8_Zj8TFUInl78k,354
40
42
  janito/agent/tools/utils.py,sha256=cKPE9HVA1yHmKzML8Uz4YCVLNDK13MQw9ThvhC9COCI,1101
@@ -44,7 +46,7 @@ janito/cli/_utils.py,sha256=Q_OCFZmbr78qW4hSSUUhjondVc0ao7-iUHE7Ig8IP1g,289
44
46
  janito/cli/arg_parser.py,sha256=CLHv2sbHxbSwnPvnDk10-cyasCvR9lPv4Yc96QoW1qA,3885
45
47
  janito/cli/config_commands.py,sha256=lhlutyVM2lBbXTeZ2FXW9iWOvFG35uDr9Rjoksx3iJY,7957
46
48
  janito/cli/logging_setup.py,sha256=dWQ0wFf4YuF5lxZlhpN6lis7G56LeFYUwQdh9nA5NmA,1141
47
- janito/cli/main.py,sha256=O483LhcDMxNqwr5PWsVNOf-ms6DRTfUKawB9MVMJIfM,1418
49
+ janito/cli/main.py,sha256=kCdIUbM5X7pSnVsraOGJ2n_MSrt4qMeg3syWx1CV0rs,1457
48
50
  janito/cli/runner.py,sha256=aQvbxzOaRQ44ZP6CutDdpms0K8inOeI1pKRyCPYPIkQ,5193
49
51
  janito/cli_chat_shell/__init__.py,sha256=PDGl7xK_vgkROoXvUxGZqVQFfuL9U4TjdexpP8E2JKg,41
50
52
  janito/cli_chat_shell/chat_loop.py,sha256=35BJeKLhAkdARrMUADK2qRP-Q2bQPB2P7JSUrQ8bUxY,5501
@@ -52,13 +54,13 @@ janito/cli_chat_shell/commands.py,sha256=gBdfvujRDchRl_M5HZO-eO55dmKvDi3twS8jo3q
52
54
  janito/cli_chat_shell/config_shell.py,sha256=vBKAJvDRaqC2uSjTFBZ2KgQJT0FoTqbCI8u1N6VoPF4,3208
53
55
  janito/cli_chat_shell/load_prompt.py,sha256=B7C_IhMk3n1XBQcfOwFVDnjrj1278JL3kV4UtkeeZx8,604
54
56
  janito/cli_chat_shell/session_manager.py,sha256=mdmt6mWOZOYqBiqKJ_8D2ff_31RdeJhFB_xp3g3P6B4,2164
55
- janito/cli_chat_shell/ui.py,sha256=sPuDhRapcdJ8MRyi1DKkaU8Vot_O29RVLqOjDZPpFaU,2354
57
+ janito/cli_chat_shell/ui.py,sha256=-HrX7aOivKUaDdZh0_FWSbHGSRPbhVyVuKyqcbvKFmQ,6071
56
58
  janito/web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
59
  janito/web/__main__.py,sha256=oPXNF332aCeI7aUWr7_8M57oOKugw422VrEubxFp0P4,354
58
60
  janito/web/app.py,sha256=kJhrKDI7X2Ujzk_SVxctvq1loiAXHil0ckn3RQ8e3gg,6549
59
- janito-1.5.0.dist-info/licenses/LICENSE,sha256=sHBqv0bvtrb29H7WRR-Z603YHm9pLtJIo3nHU_9cmgE,1091
60
- janito-1.5.0.dist-info/METADATA,sha256=gyl65Ab0HqC08D1hJ0P3_ghOG6-3aqE9josu449WOFQ,7539
61
- janito-1.5.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
62
- janito-1.5.0.dist-info/entry_points.txt,sha256=wIo5zZxbmu4fC-ZMrsKD0T0vq7IqkOOLYhrqRGypkx4,48
63
- janito-1.5.0.dist-info/top_level.txt,sha256=m0NaVCq0-ivxbazE2-ND0EA9Hmuijj_OGkmCbnBcCig,7
64
- janito-1.5.0.dist-info/RECORD,,
61
+ janito-1.5.2.dist-info/licenses/LICENSE,sha256=sHBqv0bvtrb29H7WRR-Z603YHm9pLtJIo3nHU_9cmgE,1091
62
+ janito-1.5.2.dist-info/METADATA,sha256=Oz8I9ZTvqWPvxsSbBhNKNufJT2olOf56MWEpj1CnyCQ,7539
63
+ janito-1.5.2.dist-info/WHEEL,sha256=lTU6B6eIfYoiQJTZNc-fyaR6BpL6ehTzU3xGYxn2n8k,91
64
+ janito-1.5.2.dist-info/entry_points.txt,sha256=wIo5zZxbmu4fC-ZMrsKD0T0vq7IqkOOLYhrqRGypkx4,48
65
+ janito-1.5.2.dist-info/top_level.txt,sha256=m0NaVCq0-ivxbazE2-ND0EA9Hmuijj_OGkmCbnBcCig,7
66
+ janito-1.5.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.1.0)
2
+ Generator: setuptools (78.1.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5