janito 1.2.0__py3-none-any.whl → 1.2.1__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/agent.py +4 -0
- janito/agent/config_utils.py +9 -0
- janito/agent/conversation.py +11 -3
- janito/agent/tools/__init__.py +2 -4
- janito/agent/tools/file_ops.py +67 -0
- janito/cli/_print_config.py +11 -11
- janito/templates/system_instructions.j2 +2 -2
- janito/web/app.py +75 -18
- {janito-1.2.0.dist-info → janito-1.2.1.dist-info}/METADATA +1 -1
- {janito-1.2.0.dist-info → janito-1.2.1.dist-info}/RECORD +15 -17
- janito/agent/tools/create_directory.py +0 -19
- janito/agent/tools/create_file.py +0 -43
- janito/agent/tools/move_file.py +0 -37
- janito/agent/tools/remove_file.py +0 -19
- {janito-1.2.0.dist-info → janito-1.2.1.dist-info}/WHEEL +0 -0
- {janito-1.2.0.dist-info → janito-1.2.1.dist-info}/entry_points.txt +0 -0
- {janito-1.2.0.dist-info → janito-1.2.1.dist-info}/licenses/LICENSE +0 -0
- {janito-1.2.0.dist-info → janito-1.2.1.dist-info}/top_level.txt +0 -0
janito/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "1.2.
|
1
|
+
__version__ = "1.2.1"
|
janito/agent/agent.py
CHANGED
@@ -60,6 +60,10 @@ class Agent:
|
|
60
60
|
self.client, self.model, self.tool_handler
|
61
61
|
)
|
62
62
|
|
63
|
+
@property
|
64
|
+
def usage_history(self):
|
65
|
+
return self.conversation_handler.usage_history
|
66
|
+
|
63
67
|
def chat(self, messages, on_content=None, on_tool_progress=None, verbose_response=False, spinner=False, max_tokens=None):
|
64
68
|
import time
|
65
69
|
from janito.agent.conversation import ProviderError
|
janito/agent/conversation.py
CHANGED
@@ -16,6 +16,7 @@ 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):
|
21
22
|
if not messages:
|
@@ -95,16 +96,23 @@ class ConversationHandler:
|
|
95
96
|
|
96
97
|
# If no tool calls, return the assistant's message and usage info
|
97
98
|
if not choice.message.tool_calls:
|
99
|
+
# Store usage info in usage_history, linked to the next assistant message index
|
100
|
+
assistant_idx = len([m for m in messages if m.get('role') == 'assistant'])
|
101
|
+
self.usage_history.append({"assistant_index": assistant_idx, "usage": usage_info})
|
98
102
|
return {
|
99
|
-
|
100
|
-
|
101
|
-
|
103
|
+
"content": choice.message.content,
|
104
|
+
"usage": usage_info,
|
105
|
+
"usage_history": self.usage_history
|
106
|
+
}
|
102
107
|
|
103
108
|
tool_responses = []
|
104
109
|
for tool_call in choice.message.tool_calls:
|
105
110
|
result = self.tool_handler.handle_tool_call(tool_call, on_progress=on_tool_progress)
|
106
111
|
tool_responses.append({"tool_call_id": tool_call.id, "content": result})
|
107
112
|
|
113
|
+
# Store usage info in usage_history, linked to the next assistant message index
|
114
|
+
assistant_idx = len([m for m in messages if m.get('role') == 'assistant'])
|
115
|
+
self.usage_history.append({"assistant_index": assistant_idx, "usage": usage_info})
|
108
116
|
messages.append({"role": "assistant", "content": choice.message.content, "tool_calls": [tc.to_dict() for tc in choice.message.tool_calls]})
|
109
117
|
|
110
118
|
for tr in tool_responses:
|
janito/agent/tools/__init__.py
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
from .ask_user import ask_user
|
2
|
-
from .
|
3
|
-
from .create_file import create_file
|
4
|
-
from .remove_file import remove_file
|
2
|
+
from .file_ops import create_directory, create_file, remove_file, move_file
|
5
3
|
from .view_file import view_file
|
6
4
|
from .find_files import find_files
|
7
5
|
from .search_text import search_text
|
8
6
|
from .bash_exec import bash_exec
|
9
7
|
from .fetch_url import fetch_url
|
10
|
-
|
8
|
+
|
11
9
|
from .file_str_replace import file_str_replace
|
@@ -0,0 +1,67 @@
|
|
1
|
+
import os
|
2
|
+
import shutil
|
3
|
+
from janito.agent.tool_handler import ToolHandler
|
4
|
+
from janito.agent.tools.rich_utils import print_info, print_success, print_error, format_path
|
5
|
+
|
6
|
+
@ToolHandler.register_tool
|
7
|
+
def create_file(path: str, content: str, overwrite: bool = False) -> str:
|
8
|
+
if os.path.exists(path):
|
9
|
+
if os.path.isdir(path):
|
10
|
+
print_error("❌ Error: is a directory")
|
11
|
+
return f"❌ Cannot create file: '{path}' is an existing directory."
|
12
|
+
if not overwrite:
|
13
|
+
print_error(f"❗ Error: file '{path}' exists and overwrite is False")
|
14
|
+
return f"❗ Cannot create file: '{path}' already exists and overwrite is False."
|
15
|
+
print_info(f"📝 Creating file: '{format_path(path)}' ... ")
|
16
|
+
try:
|
17
|
+
with open(path, "w", encoding="utf-8") as f:
|
18
|
+
f.write(content)
|
19
|
+
print_success("✅ Success")
|
20
|
+
return f"✅ Successfully created the file at '{path}'."
|
21
|
+
except Exception as e:
|
22
|
+
print_error(f"❌ Error: {e}")
|
23
|
+
return f"❌ Failed to create the file at '{path}': {e}"
|
24
|
+
|
25
|
+
@ToolHandler.register_tool
|
26
|
+
def remove_file(path: str) -> str:
|
27
|
+
print_info(f"🗑️ Removing file: '{format_path(path)}' ... ")
|
28
|
+
try:
|
29
|
+
os.remove(path)
|
30
|
+
print_success("✅ Success")
|
31
|
+
return f"✅ Successfully deleted the file at '{path}'."
|
32
|
+
except Exception as e:
|
33
|
+
print_error(f"❌ Error: {e}")
|
34
|
+
return f"❌ Failed to delete the file at '{path}': {e}"
|
35
|
+
|
36
|
+
@ToolHandler.register_tool
|
37
|
+
def move_file(source_path: str, destination_path: str, overwrite: bool = False) -> str:
|
38
|
+
print_info(f"🚚 Moving '{format_path(source_path)}' to '{format_path(destination_path)}' ... ")
|
39
|
+
try:
|
40
|
+
if not os.path.exists(source_path):
|
41
|
+
print_error("❌ Error: source does not exist")
|
42
|
+
return f"❌ Source path '{source_path}' does not exist."
|
43
|
+
if os.path.exists(destination_path):
|
44
|
+
if not overwrite:
|
45
|
+
print_error("❌ Error: destination exists and overwrite is False")
|
46
|
+
return f"❌ Destination path '{destination_path}' already exists. Use overwrite=True to replace it."
|
47
|
+
if os.path.isdir(destination_path):
|
48
|
+
shutil.rmtree(destination_path)
|
49
|
+
else:
|
50
|
+
os.remove(destination_path)
|
51
|
+
shutil.move(source_path, destination_path)
|
52
|
+
print_success("✅ Success")
|
53
|
+
return f"✅ Successfully moved '{source_path}' to '{destination_path}'."
|
54
|
+
except Exception as e:
|
55
|
+
print_error(f"❌ Error: {e}")
|
56
|
+
return f"❌ Failed to move '{source_path}' to '{destination_path}': {e}"
|
57
|
+
|
58
|
+
@ToolHandler.register_tool
|
59
|
+
def create_directory(path: str) -> str:
|
60
|
+
print_info(f"📁 Creating directory: '{format_path(path)}' ... ")
|
61
|
+
try:
|
62
|
+
os.makedirs(path, exist_ok=True)
|
63
|
+
print_success("✅ Success")
|
64
|
+
return f"✅ Directory '{path}' created successfully."
|
65
|
+
except Exception as e:
|
66
|
+
print_error(f"❌ Error: {e}")
|
67
|
+
return f"❌ Error creating directory '{path}': {e}"
|
janito/cli/_print_config.py
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
import os
|
2
|
-
from
|
2
|
+
from janito.agent.tools.rich_utils import print_info, print_success, print_error, print_warning, print_magenta
|
3
3
|
from ._utils import home_shorten
|
4
4
|
|
5
5
|
def print_config_items(items, color_label=None):
|
6
6
|
if not items:
|
7
7
|
return
|
8
8
|
if color_label:
|
9
|
-
|
9
|
+
print_info(color_label)
|
10
10
|
home = os.path.expanduser("~")
|
11
11
|
for key, value in items.items():
|
12
12
|
if key == "system_prompt" and isinstance(value, str):
|
13
13
|
if value.startswith(home):
|
14
14
|
print(f"{key} = {home_shorten(value)}")
|
15
15
|
else:
|
16
|
-
|
16
|
+
print_info(f"{key} = {value}")
|
17
17
|
else:
|
18
|
-
|
19
|
-
|
18
|
+
print_info(f"{key} = {value}")
|
19
|
+
print_info("")
|
20
20
|
|
21
21
|
def print_full_config(local_config, global_config, unified_config, config_defaults, console=None):
|
22
22
|
"""
|
@@ -28,9 +28,9 @@ def print_full_config(local_config, global_config, unified_config, config_defaul
|
|
28
28
|
local_keys = set(local_config.all().keys())
|
29
29
|
global_keys = set(global_config.all().keys())
|
30
30
|
all_keys = set(config_defaults.keys()) | global_keys | local_keys
|
31
|
-
out =
|
31
|
+
out = print_info if console is None else console.print
|
32
32
|
if not (local_keys or global_keys):
|
33
|
-
|
33
|
+
print_warning("No configuration found.")
|
34
34
|
else:
|
35
35
|
for key in sorted(local_keys):
|
36
36
|
if key == "api_key":
|
@@ -57,12 +57,12 @@ def print_full_config(local_config, global_config, unified_config, config_defaul
|
|
57
57
|
shown_keys = set(local_items.keys()) | set(global_items.keys())
|
58
58
|
default_items = {k: v for k, v in config_defaults.items() if k not in shown_keys and k != 'api_key'}
|
59
59
|
if default_items:
|
60
|
-
|
60
|
+
print_magenta("[green]🟢 Defaults (not set in config files)[/green]")
|
61
61
|
from pathlib import Path
|
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
|
-
|
65
|
+
print_info(f"{key} = (default template path: {home_shorten(str(template_path))})")
|
66
66
|
else:
|
67
|
-
|
68
|
-
|
67
|
+
print_info(f"{key} = {value}")
|
68
|
+
print_info("")
|
@@ -18,7 +18,7 @@ If in doubt during editing, use the `ask_user` function to get additional inform
|
|
18
18
|
|
19
19
|
When you need to make changes to a file, consider the following:
|
20
20
|
|
21
|
-
- Use `file_str_replace` when you want to update or fix specific text fragments within a file without altering the rest of its content. It is preferred over full file replacement when:
|
21
|
+
- Use `file_str_replace` when you want to update or fix specific text fragments within a file without altering the rest of its content. It is preferred over full file replacement when:
|
22
22
|
- Only small, targeted changes are needed.
|
23
23
|
- You want to avoid the risk of accidentally overwriting unrelated content.
|
24
24
|
- The file is large, and rewriting the entire file would be inefficient.
|
@@ -34,5 +34,5 @@ After performing changes:
|
|
34
34
|
|
35
35
|
- Review the README content if there are user-exposed or public API changes.
|
36
36
|
- Use `git commit` to save the changes. Unless requested otherwise, review `git diff` when composing the commit message.
|
37
|
-
-
|
37
|
+
- Update `docs/structure.md` considering discovered, created, or modified files.
|
38
38
|
</finishing>
|
janito/web/app.py
CHANGED
@@ -8,8 +8,15 @@ from janito.render_prompt import render_system_prompt
|
|
8
8
|
import os
|
9
9
|
import threading
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
from janito.agent.runtime_config import unified_config
|
12
|
+
|
13
|
+
# Render system prompt from config
|
14
|
+
role = unified_config.get("role", "software engineer")
|
15
|
+
system_prompt_override = unified_config.get("system_prompt")
|
16
|
+
if system_prompt_override:
|
17
|
+
system_prompt = system_prompt_override
|
18
|
+
else:
|
19
|
+
system_prompt = render_system_prompt(role)
|
13
20
|
|
14
21
|
app = Flask(
|
15
22
|
__name__,
|
@@ -33,15 +40,59 @@ stream_queue = Queue()
|
|
33
40
|
# Create a QueuedToolHandler with the queue
|
34
41
|
queued_handler = QueuedToolHandler(stream_queue)
|
35
42
|
|
36
|
-
# Instantiate the Agent with
|
43
|
+
# Instantiate the Agent with config-driven parameters
|
37
44
|
agent = Agent(
|
38
|
-
api_key=
|
45
|
+
api_key=unified_config.get("api_key"),
|
46
|
+
model=unified_config.get("model"),
|
47
|
+
base_url=unified_config.get("base_url"),
|
39
48
|
tool_handler=queued_handler
|
40
49
|
)
|
41
50
|
|
42
|
-
@app.route('/
|
43
|
-
def
|
44
|
-
|
51
|
+
@app.route('/get_config')
|
52
|
+
def get_config():
|
53
|
+
# Expose full config for the web app: defaults, effective, runtime (mask api_key)
|
54
|
+
from janito.agent.runtime_config import unified_config
|
55
|
+
from janito.agent.config_defaults import CONFIG_DEFAULTS
|
56
|
+
# Start with defaults
|
57
|
+
config = dict(CONFIG_DEFAULTS)
|
58
|
+
# Overlay effective config
|
59
|
+
config.update(unified_config.effective_cfg.all())
|
60
|
+
# Overlay runtime config (highest priority)
|
61
|
+
config.update(unified_config.runtime_cfg.all())
|
62
|
+
api_key = config.get("api_key")
|
63
|
+
if api_key:
|
64
|
+
config["api_key"] = api_key[:4] + '...' + api_key[-4:] if len(api_key) > 8 else '***'
|
65
|
+
return jsonify(config)
|
66
|
+
|
67
|
+
@app.route('/set_config', methods=['POST'])
|
68
|
+
def set_config():
|
69
|
+
from janito.agent.runtime_config import runtime_config
|
70
|
+
from janito.agent.config import CONFIG_OPTIONS
|
71
|
+
from janito.agent.config_defaults import CONFIG_DEFAULTS
|
72
|
+
data = request.get_json()
|
73
|
+
key = data.get('key')
|
74
|
+
value = data.get('value')
|
75
|
+
if key not in CONFIG_OPTIONS:
|
76
|
+
return jsonify({'status': 'error', 'message': f'Invalid config key: {key}'}), 400
|
77
|
+
# Type coercion based on defaults
|
78
|
+
default = CONFIG_DEFAULTS.get(key)
|
79
|
+
if default is not None and value is not None:
|
80
|
+
try:
|
81
|
+
if isinstance(default, bool):
|
82
|
+
value = bool(value)
|
83
|
+
elif isinstance(default, int):
|
84
|
+
value = int(value)
|
85
|
+
elif isinstance(default, float):
|
86
|
+
value = float(value)
|
87
|
+
# else: leave as string or None
|
88
|
+
except Exception as e:
|
89
|
+
return jsonify({'status': 'error', 'message': f'Invalid value type for {key}: {e}'}), 400
|
90
|
+
runtime_config.set(key, value)
|
91
|
+
# Mask api_key in response
|
92
|
+
resp_value = value
|
93
|
+
if key == 'api_key' and value:
|
94
|
+
resp_value = value[:4] + '...' + value[-4:] if len(value) > 8 else '***'
|
95
|
+
return jsonify({'status': 'ok', 'key': key, 'value': resp_value})
|
45
96
|
|
46
97
|
|
47
98
|
@app.route('/favicon.ico')
|
@@ -91,19 +142,25 @@ def execute_stream():
|
|
91
142
|
conversation.append({"role": "user", "content": user_input})
|
92
143
|
|
93
144
|
def run_agent():
|
94
|
-
response = agent.chat(
|
95
|
-
conversation,
|
96
|
-
on_content=lambda data: stream_queue.put({"type": "content", "content": data.get("content")})
|
97
|
-
)
|
98
|
-
if response and 'content' in response:
|
99
|
-
conversation.append({"role": "assistant", "content": response['content']})
|
100
145
|
try:
|
101
|
-
|
102
|
-
|
103
|
-
|
146
|
+
response = agent.chat(
|
147
|
+
conversation,
|
148
|
+
on_content=lambda data: stream_queue.put({"type": "content", "content": data.get("content")})
|
149
|
+
)
|
150
|
+
if response and 'content' in response:
|
151
|
+
conversation.append({"role": "assistant", "content": response['content']})
|
152
|
+
try:
|
153
|
+
os.makedirs(os.path.dirname(conversation_file), exist_ok=True)
|
154
|
+
with open(conversation_file, 'w') as f:
|
155
|
+
json.dump(conversation, f, indent=2)
|
156
|
+
except Exception as e:
|
157
|
+
print(f"Error saving conversation: {e}")
|
104
158
|
except Exception as e:
|
105
|
-
|
106
|
-
|
159
|
+
import traceback
|
160
|
+
tb = traceback.format_exc()
|
161
|
+
stream_queue.put({"type": "error", "error": str(e), "traceback": tb})
|
162
|
+
finally:
|
163
|
+
stream_queue.put(None)
|
107
164
|
|
108
165
|
threading.Thread(target=run_agent, daemon=True).start()
|
109
166
|
|
@@ -1,31 +1,29 @@
|
|
1
|
-
janito/__init__.py,sha256=
|
1
|
+
janito/__init__.py,sha256=1y7BBR2l-3BuWrDXe70lefKZxLd53JVfWAfn4y7Mn_0,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
|
-
janito/agent/agent.py,sha256=
|
5
|
+
janito/agent/agent.py,sha256=N0Vx-0yV-12ta54FNJNPGPUERyGpCI2XcWmAzqpDzAw,3693
|
6
6
|
janito/agent/config.py,sha256=-zespUJrFb61fyJzjemont6lirnPM_FF88NUiTVI91I,3555
|
7
7
|
janito/agent/config_defaults.py,sha256=Ow-LKq88MmMTQ6LDH_u26NqJ8-db35KpcfR8FYuWGBw,363
|
8
|
-
janito/agent/
|
8
|
+
janito/agent/config_utils.py,sha256=UmvR236wDrMc-aTy9LxVbop6YeoJaaPb1d2DBMlkSRg,254
|
9
|
+
janito/agent/conversation.py,sha256=ZUMUyDpeORjH2vQ6MbJnk58XvUxRrLo0aJAQ7T0xFUA,5661
|
9
10
|
janito/agent/queued_tool_handler.py,sha256=THPymKXnpoXfN49EhW5b4hrwpWZZup73JKFDJ_U03tI,540
|
10
11
|
janito/agent/runtime_config.py,sha256=gigcKUwaXs_qSdXdC5InUTPmdXUbOA-tRUx2ZJ5zzI0,906
|
11
12
|
janito/agent/tool_handler.py,sha256=MiwGx6Wlasan6KO3-Q0UDEJjmtDavd7ITc0gVjfa47s,4536
|
12
|
-
janito/agent/tools/__init__.py,sha256=
|
13
|
+
janito/agent/tools/__init__.py,sha256=qcTByy9wtIcK7lHIcqavd1-mtU6ckuUW6PBssvCKZbc,335
|
13
14
|
janito/agent/tools/ask_user.py,sha256=MHKHyBTD4iyCM-z9_ZUbe7AMn-pz7cr6FIAB0SdESH4,1895
|
14
15
|
janito/agent/tools/bash_exec.py,sha256=1HkjvTlXunjZ7xvxqzdayG8JWtrioC0MYOfdid_6uiY,2486
|
15
|
-
janito/agent/tools/create_directory.py,sha256=qnP8bFeAYr3fnstbIIp6EOqur1o0xAVv1k21Y9LOAHs,698
|
16
|
-
janito/agent/tools/create_file.py,sha256=pauO9YYnPDeO61U2tcTHgC1VPJ7yhWQOrIHhCKuLk8E,1782
|
17
16
|
janito/agent/tools/fetch_url.py,sha256=ZPasbnPxM-lcVlpRUwviGmhiqm-MoVFA1_1K99h8I94,1926
|
17
|
+
janito/agent/tools/file_ops.py,sha256=uI5SIPC4SjBEOi8lJF2PsGfyBM3sOos5GvYXVcfg-BA,3093
|
18
18
|
janito/agent/tools/file_str_replace.py,sha256=9ooaDVEHT4WDdSbFZuz_QHkQpG9s8OtP1g99_GbechA,2012
|
19
19
|
janito/agent/tools/find_files.py,sha256=KgvnAAa7YbU59ASYcUI6XsGpxB7ouPde7E1h8e8Vf4E,1608
|
20
20
|
janito/agent/tools/gitignore_utils.py,sha256=zXiqx4HetZ7iKkV5qXyHyZ5yrrVex4G17WHBWToFo3Y,1158
|
21
|
-
janito/agent/tools/move_file.py,sha256=aIbZ0Jxt0JI8fHqW5SPkNMiFFs40s_wYXoHT8ooPHzs,1679
|
22
|
-
janito/agent/tools/remove_file.py,sha256=sWvdDIP5lrQh4rhBcQEEa1hQ6AJDCuFovsBZkirk3mU,658
|
23
21
|
janito/agent/tools/rich_live.py,sha256=cuZ3-ZxpuHxR1TvIcp0bi9F3QM1M6Ms0XiOMd8If8gU,1161
|
24
22
|
janito/agent/tools/rich_utils.py,sha256=aQMqeaq3hIpzZ5EHQBNTKS5dNsojQp9MDfJSoqOQe0k,837
|
25
23
|
janito/agent/tools/search_text.py,sha256=TdTpaomLt4oZpX_0zz9W_bXhI5vvQLu0IjA7mCRCJYU,2020
|
26
24
|
janito/agent/tools/view_file.py,sha256=i4IBpn_Waw_4sgHUOaPIYPcMNmmvzM9ECoR5O5fldfU,1535
|
27
25
|
janito/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
28
|
-
janito/cli/_print_config.py,sha256=
|
26
|
+
janito/cli/_print_config.py,sha256=76X_eA1BCr5abkRYz2yIBIK3knFllvcdBsyoh8n6aS4,3291
|
29
27
|
janito/cli/_utils.py,sha256=Q_OCFZmbr78qW4hSSUUhjondVc0ao7-iUHE7Ig8IP1g,289
|
30
28
|
janito/cli/arg_parser.py,sha256=kMQAstvPldkwYrXjuWwp6lYfuQCl1NLrridFtyI75_g,3089
|
31
29
|
janito/cli/config_commands.py,sha256=WQKHt3iIdjRiAKmi-dnOSLFybF-HSc93zYoWd2aZcTU,5694
|
@@ -39,13 +37,13 @@ janito/cli_chat_shell/config_shell.py,sha256=s59PCt_TmBPqQJ_C8nkKo4kCcW9aq3Jhpe9
|
|
39
37
|
janito/cli_chat_shell/load_prompt.py,sha256=EuUlHg317T8f5VqEMaJxFgzWBl51zC2sND0eeYr6pJ4,612
|
40
38
|
janito/cli_chat_shell/session_manager.py,sha256=Gax0pC0ediDsExLUwPEg_nD8MdSrznaHoer53zxLYuE,1966
|
41
39
|
janito/cli_chat_shell/ui.py,sha256=7O36dWaXDQ5r-GGD6a57iHSiDpN2pkdav3HxSdf6CIc,5279
|
42
|
-
janito/templates/system_instructions.j2,sha256=
|
40
|
+
janito/templates/system_instructions.j2,sha256=trK2ubyjtn_y2wxgANRAMA3bQqko06WqZHAy6XbeCQw,1817
|
43
41
|
janito/web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
44
42
|
janito/web/__main__.py,sha256=oPXNF332aCeI7aUWr7_8M57oOKugw422VrEubxFp0P4,354
|
45
|
-
janito/web/app.py,sha256=
|
46
|
-
janito-1.2.
|
47
|
-
janito-1.2.
|
48
|
-
janito-1.2.
|
49
|
-
janito-1.2.
|
50
|
-
janito-1.2.
|
51
|
-
janito-1.2.
|
43
|
+
janito/web/app.py,sha256=LCwIhgGKIeSHZB2TAWgLNGSEL_6Hvbey4J68n_DQFEQ,6639
|
44
|
+
janito-1.2.1.dist-info/licenses/LICENSE,sha256=sHBqv0bvtrb29H7WRR-Z603YHm9pLtJIo3nHU_9cmgE,1091
|
45
|
+
janito-1.2.1.dist-info/METADATA,sha256=Ksud9sFr5qGboUv-C2UBjIZlsh5k5mOZAl__l28uafk,4664
|
46
|
+
janito-1.2.1.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
47
|
+
janito-1.2.1.dist-info/entry_points.txt,sha256=wIo5zZxbmu4fC-ZMrsKD0T0vq7IqkOOLYhrqRGypkx4,48
|
48
|
+
janito-1.2.1.dist-info/top_level.txt,sha256=m0NaVCq0-ivxbazE2-ND0EA9Hmuijj_OGkmCbnBcCig,7
|
49
|
+
janito-1.2.1.dist-info/RECORD,,
|
@@ -1,19 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
from janito.agent.tool_handler import ToolHandler
|
3
|
-
from janito.agent.tools.rich_utils import print_info, print_success, print_error, format_path
|
4
|
-
|
5
|
-
@ToolHandler.register_tool
|
6
|
-
def create_directory(path: str) -> str:
|
7
|
-
"""
|
8
|
-
Create a directory at the specified path.
|
9
|
-
|
10
|
-
path: The path of the directory to create
|
11
|
-
"""
|
12
|
-
print_info(f"📁 Creating directory: '{format_path(path)}' ... ")
|
13
|
-
try:
|
14
|
-
os.makedirs(path, exist_ok=True)
|
15
|
-
print_success("✅ Success")
|
16
|
-
return f"✅ Directory '{path}' created successfully."
|
17
|
-
except Exception as e:
|
18
|
-
print_error(f"❌ Error: {e}")
|
19
|
-
return f"❌ Error creating directory '{path}': {e}"
|
@@ -1,43 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
from janito.agent.tool_handler import ToolHandler
|
3
|
-
from janito.agent.tools.rich_utils import print_info, print_success, print_error, format_path
|
4
|
-
|
5
|
-
@ToolHandler.register_tool
|
6
|
-
def create_file(path: str, content: str, overwrite: bool = False) -> str:
|
7
|
-
"""
|
8
|
-
Create a file with the specified content.
|
9
|
-
|
10
|
-
path: The path of the file to create
|
11
|
-
content: The content to write into the file
|
12
|
-
overwrite: Whether to overwrite the file if it exists (default: False)
|
13
|
-
"""
|
14
|
-
old_lines = None
|
15
|
-
if os.path.exists(path):
|
16
|
-
if os.path.isdir(path):
|
17
|
-
print_error("❌ Error: is a directory")
|
18
|
-
return f"❌ Cannot create file: '{path}' is an existing directory."
|
19
|
-
if overwrite:
|
20
|
-
try:
|
21
|
-
with open(path, "r", encoding="utf-8") as f:
|
22
|
-
old_lines = sum(1 for _ in f)
|
23
|
-
except Exception:
|
24
|
-
old_lines = 'unknown'
|
25
|
-
else:
|
26
|
-
print_error(f"❗ Error: file '{path}' exists and overwrite is False")
|
27
|
-
return f"❗ Cannot create file: '{path}' already exists and overwrite is False."
|
28
|
-
|
29
|
-
new_lines = content.count('\n') + 1 if content else 0
|
30
|
-
|
31
|
-
if old_lines is not None:
|
32
|
-
print_info(f"♻️ Replacing file: '{format_path(path)}' (line count: {old_lines} -> {new_lines}) ... ")
|
33
|
-
else:
|
34
|
-
print_info(f"📝 Creating file: '{format_path(path)}' (lines: {new_lines}) ... ")
|
35
|
-
|
36
|
-
try:
|
37
|
-
with open(path, "w", encoding="utf-8") as f:
|
38
|
-
f.write(content)
|
39
|
-
print_success("✅ Success")
|
40
|
-
return f"✅ Successfully created the file at '{path}'."
|
41
|
-
except Exception as e:
|
42
|
-
print_error(f"❌ Error: {e}")
|
43
|
-
return f"❌ Failed to create the file at '{path}': {e}"
|
janito/agent/tools/move_file.py
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
import shutil
|
2
|
-
import os
|
3
|
-
from janito.agent.tool_handler import ToolHandler
|
4
|
-
from janito.agent.tools.rich_utils import print_info, print_success, print_error, format_path
|
5
|
-
|
6
|
-
|
7
|
-
@ToolHandler.register_tool
|
8
|
-
def move_file(source_path: str, destination_path: str, overwrite: bool = False) -> str:
|
9
|
-
"""
|
10
|
-
Move a file or directory from source_path to destination_path.
|
11
|
-
|
12
|
-
source_path: The path of the file or directory to move
|
13
|
-
destination_path: The target path
|
14
|
-
overwrite: Whether to overwrite the destination if it exists (default: False)
|
15
|
-
"""
|
16
|
-
print_info(f"🚚 Moving '{format_path(source_path)}' to '{format_path(destination_path)}' ... ")
|
17
|
-
try:
|
18
|
-
if not os.path.exists(source_path):
|
19
|
-
print_error("❌ Error: source does not exist")
|
20
|
-
return f"❌ Source path '{source_path}' does not exist."
|
21
|
-
|
22
|
-
if os.path.exists(destination_path):
|
23
|
-
if not overwrite:
|
24
|
-
print_error("❌ Error: destination exists and overwrite is False")
|
25
|
-
return f"❌ Destination path '{destination_path}' already exists. Use overwrite=True to replace it."
|
26
|
-
# Remove destination if overwrite is True
|
27
|
-
if os.path.isdir(destination_path):
|
28
|
-
shutil.rmtree(destination_path)
|
29
|
-
else:
|
30
|
-
os.remove(destination_path)
|
31
|
-
|
32
|
-
shutil.move(source_path, destination_path)
|
33
|
-
print_success("✅ Success")
|
34
|
-
return f"✅ Successfully moved '{source_path}' to '{destination_path}'."
|
35
|
-
except Exception as e:
|
36
|
-
print_error(f"❌ Error: {e}")
|
37
|
-
return f"❌ Failed to move '{source_path}' to '{destination_path}': {e}"
|
@@ -1,19 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
from janito.agent.tool_handler import ToolHandler
|
3
|
-
from janito.agent.tools.rich_utils import print_info, print_success, print_error, format_path
|
4
|
-
|
5
|
-
@ToolHandler.register_tool
|
6
|
-
def remove_file(path: str) -> str:
|
7
|
-
"""
|
8
|
-
Remove a specified file.
|
9
|
-
|
10
|
-
path: The path of the file to remove
|
11
|
-
"""
|
12
|
-
print_info(f"🗑️ Removing file: '{format_path(path)}' ... ")
|
13
|
-
try:
|
14
|
-
os.remove(path)
|
15
|
-
print_success("✅ Success")
|
16
|
-
return f"✅ Successfully deleted the file at '{path}'."
|
17
|
-
except Exception as e:
|
18
|
-
print_error(f"❌ Error: {e}")
|
19
|
-
return f"❌ Failed to delete the file at '{path}': {e}"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|