janito 1.5.2__py3-none-any.whl → 1.6.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/__main__.py +0 -1
- janito/agent/config.py +11 -10
- janito/agent/config_defaults.py +3 -2
- janito/agent/conversation.py +93 -119
- janito/agent/conversation_api.py +98 -0
- janito/agent/conversation_exceptions.py +12 -0
- janito/agent/conversation_tool_calls.py +22 -0
- janito/agent/conversation_ui.py +17 -0
- janito/agent/message_handler.py +8 -9
- janito/agent/{agent.py → openai_client.py} +48 -16
- janito/agent/openai_schema_generator.py +53 -37
- janito/agent/profile_manager.py +172 -0
- janito/agent/queued_message_handler.py +13 -14
- janito/agent/rich_live.py +32 -0
- janito/agent/rich_message_handler.py +64 -0
- janito/agent/runtime_config.py +6 -1
- janito/agent/{tools/tool_base.py → tool_base.py} +15 -8
- janito/agent/tool_registry.py +118 -132
- janito/agent/tools/__init__.py +41 -2
- janito/agent/tools/ask_user.py +43 -33
- janito/agent/tools/create_directory.py +18 -16
- janito/agent/tools/create_file.py +31 -36
- janito/agent/tools/fetch_url.py +23 -19
- janito/agent/tools/find_files.py +40 -36
- janito/agent/tools/get_file_outline.py +100 -22
- janito/agent/tools/get_lines.py +40 -32
- janito/agent/tools/gitignore_utils.py +9 -6
- janito/agent/tools/move_file.py +22 -13
- janito/agent/tools/py_compile_file.py +40 -0
- janito/agent/tools/remove_directory.py +34 -24
- janito/agent/tools/remove_file.py +22 -20
- janito/agent/tools/replace_file.py +51 -0
- janito/agent/tools/replace_text_in_file.py +69 -42
- janito/agent/tools/rich_live.py +9 -2
- janito/agent/tools/run_bash_command.py +155 -107
- janito/agent/tools/run_python_command.py +139 -0
- janito/agent/tools/search_files.py +51 -34
- janito/agent/tools/tools_utils.py +4 -2
- janito/agent/tools/utils.py +6 -2
- janito/cli/_print_config.py +42 -16
- janito/cli/_utils.py +1 -0
- janito/cli/arg_parser.py +182 -29
- janito/cli/config_commands.py +54 -22
- janito/cli/logging_setup.py +9 -3
- janito/cli/main.py +11 -10
- janito/cli/runner/__init__.py +2 -0
- janito/cli/runner/cli_main.py +148 -0
- janito/cli/runner/config.py +33 -0
- janito/cli/runner/formatting.py +12 -0
- janito/cli/runner/scan.py +44 -0
- janito/cli_chat_shell/__init__.py +0 -1
- janito/cli_chat_shell/chat_loop.py +71 -92
- janito/cli_chat_shell/chat_state.py +38 -0
- janito/cli_chat_shell/chat_ui.py +43 -0
- janito/cli_chat_shell/commands/__init__.py +45 -0
- janito/cli_chat_shell/commands/config.py +22 -0
- janito/cli_chat_shell/commands/history_reset.py +29 -0
- janito/cli_chat_shell/commands/session.py +48 -0
- janito/cli_chat_shell/commands/session_control.py +12 -0
- janito/cli_chat_shell/commands/system.py +73 -0
- janito/cli_chat_shell/commands/utility.py +29 -0
- janito/cli_chat_shell/config_shell.py +39 -10
- janito/cli_chat_shell/load_prompt.py +5 -2
- janito/cli_chat_shell/session_manager.py +24 -27
- janito/cli_chat_shell/ui.py +75 -40
- janito/rich_utils.py +15 -2
- janito/web/__main__.py +10 -2
- janito/web/app.py +88 -52
- {janito-1.5.2.dist-info → janito-1.6.0.dist-info}/METADATA +76 -11
- janito-1.6.0.dist-info/RECORD +81 -0
- {janito-1.5.2.dist-info → janito-1.6.0.dist-info}/WHEEL +1 -1
- janito/agent/rich_tool_handler.py +0 -43
- janito/agent/templates/system_instructions.j2 +0 -38
- janito/agent/tool_auto_imports.py +0 -5
- janito/agent/tools/append_text_to_file.py +0 -41
- janito/agent/tools/py_compile.py +0 -39
- janito/agent/tools/python_exec.py +0 -83
- janito/cli/runner.py +0 -137
- janito/cli_chat_shell/commands.py +0 -204
- janito/render_prompt.py +0 -13
- janito-1.5.2.dist-info/RECORD +0 -66
- {janito-1.5.2.dist-info → janito-1.6.0.dist-info}/entry_points.txt +0 -0
- {janito-1.5.2.dist-info → janito-1.6.0.dist-info}/licenses/LICENSE +0 -0
- {janito-1.5.2.dist-info → janito-1.6.0.dist-info}/top_level.txt +0 -0
@@ -1,41 +0,0 @@
|
|
1
|
-
from janito.agent.tools.tool_base import ToolBase
|
2
|
-
from janito.agent.tool_registry import register_tool
|
3
|
-
|
4
|
-
@register_tool(name="append_text_to_file")
|
5
|
-
class AppendTextToFileTool(ToolBase):
|
6
|
-
"""
|
7
|
-
Append the given text to the end of a file.
|
8
|
-
"""
|
9
|
-
def call(self, file_path: str, text_to_append: str) -> str:
|
10
|
-
"""
|
11
|
-
Append the given text to the end of a file.
|
12
|
-
|
13
|
-
Append the given text to the end of a file.
|
14
|
-
|
15
|
-
Args:
|
16
|
-
file_path (str): Path to the file where text will be appended.
|
17
|
-
text_to_append (str): The text content to append to the file.
|
18
|
-
Returns:
|
19
|
-
str: Status message. Example formats:
|
20
|
-
- "Appended 3 lines to /path/to/file.txt"
|
21
|
-
- "Warning: No text provided to append. Operation skipped."
|
22
|
-
- "Error appending text: <error message>"
|
23
|
-
"""
|
24
|
-
if not text_to_append:
|
25
|
-
self.report_warning("⚠️ Warning: No text provided to append. Operation skipped.")
|
26
|
-
return "Warning: No text provided to append. Operation skipped."
|
27
|
-
disp_path = display_path(file_path)
|
28
|
-
self.report_info(f"📝 Appending to {disp_path} ({len(text_to_append)} chars)")
|
29
|
-
try:
|
30
|
-
with open(file_path, 'a', encoding='utf-8') as f:
|
31
|
-
f.write(text_to_append)
|
32
|
-
|
33
|
-
num_lines = text_to_append.count('\n') + (1 if text_to_append else 0)
|
34
|
-
self.report_success(f"✅ {num_lines} {pluralize('line', num_lines)} appended")
|
35
|
-
return f"Appended {num_lines} {pluralize('line', num_lines)} to {file_path}"
|
36
|
-
except Exception as e:
|
37
|
-
self.report_error(f"❌ Error: {e}")
|
38
|
-
return f"Error appending text: {e}"
|
39
|
-
# Use display_path for consistent path reporting
|
40
|
-
from janito.agent.tools.tools_utils import display_path
|
41
|
-
from janito.agent.tools.tools_utils import pluralize
|
janito/agent/tools/py_compile.py
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
from janito.agent.tools.tool_base import ToolBase
|
2
|
-
from janito.agent.tool_registry import register_tool
|
3
|
-
|
4
|
-
|
5
|
-
from typing import Optional
|
6
|
-
import py_compile
|
7
|
-
|
8
|
-
@register_tool(name="py_compile")
|
9
|
-
class PyCompileTool(ToolBase):
|
10
|
-
"""
|
11
|
-
Validate a Python file by compiling it with py_compile.
|
12
|
-
Useful to validate python files after changing them, specially after import changes.
|
13
|
-
"""
|
14
|
-
def call(self, file_path: str, doraise: Optional[bool] = True) -> str:
|
15
|
-
"""
|
16
|
-
Compile a Python file to check for syntax errors.
|
17
|
-
|
18
|
-
Args:
|
19
|
-
file_path (str): Path to the Python file to compile.
|
20
|
-
doraise (bool, optional): Whether to raise exceptions on compilation errors. Defaults to True.
|
21
|
-
|
22
|
-
Returns:
|
23
|
-
str: Compilation status message. Example:
|
24
|
-
- "✅ Compiled"
|
25
|
-
- "Compile error: <error message>"
|
26
|
-
- "Error: <error message>"
|
27
|
-
"""
|
28
|
-
self.report_info(f"🛠️ Compiling Python file: {file_path}")
|
29
|
-
|
30
|
-
try:
|
31
|
-
py_compile.compile(file_path, doraise=doraise)
|
32
|
-
self.report_success("✅ Compiled")
|
33
|
-
return "✅ Compiled"
|
34
|
-
except py_compile.PyCompileError as e:
|
35
|
-
self.report_error(f" [py_compile] Compile error: {e}")
|
36
|
-
return f"Compile error: {e}"
|
37
|
-
except Exception as e:
|
38
|
-
self.report_error(f" [py_compile] Error: {e}")
|
39
|
-
return f"Error: {e}"
|
@@ -1,83 +0,0 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
import multiprocessing
|
4
|
-
import io
|
5
|
-
from janito.agent.tools.tool_base import ToolBase
|
6
|
-
from janito.agent.tool_registry import register_tool
|
7
|
-
|
8
|
-
|
9
|
-
def _run_python_code(code: str, result_queue):
|
10
|
-
import contextlib
|
11
|
-
stdout = io.StringIO()
|
12
|
-
stderr = io.StringIO()
|
13
|
-
with contextlib.redirect_stdout(stdout), contextlib.redirect_stderr(stderr):
|
14
|
-
exec(code, {'__name__': '__main__'})
|
15
|
-
result_queue.put({
|
16
|
-
'stdout': stdout.getvalue(),
|
17
|
-
'stderr': stderr.getvalue(),
|
18
|
-
'returncode': 0
|
19
|
-
})
|
20
|
-
|
21
|
-
|
22
|
-
# Converted python_exec function into PythonExecTool subclass
|
23
|
-
@register_tool(name="python_exec")
|
24
|
-
class PythonExecTool(ToolBase):
|
25
|
-
"""
|
26
|
-
Execute Python code in a separate process and capture output.
|
27
|
-
Useful for exact calculations, retrieving the current date and time, or performing any Python-supported operation.
|
28
|
-
Args:
|
29
|
-
code (str): The Python code to execute.
|
30
|
-
Returns:
|
31
|
-
str: Formatted stdout, stderr, and return code.
|
32
|
-
"""
|
33
|
-
def call(self, code: str) -> str:
|
34
|
-
"""
|
35
|
-
Execute arbitrary Python code, including exact calculations, getting the current date, time, and more.
|
36
|
-
|
37
|
-
Args:
|
38
|
-
code (str): The Python code to execute.
|
39
|
-
|
40
|
-
Returns:
|
41
|
-
str: Formatted output including stdout, stderr, and return code. Example:
|
42
|
-
- "stdout:\n<output>\nstderr:\n<errors>\nreturncode: 0"
|
43
|
-
- "stdout:\n\nstderr:\nNo result returned from process.\nreturncode: -1"
|
44
|
-
"""
|
45
|
-
"""
|
46
|
-
Execute arbitrary Python code, including exact calculations, getting the current date, time, and more.
|
47
|
-
|
48
|
-
Args:
|
49
|
-
code (str): The Python code to execute.
|
50
|
-
|
51
|
-
Returns:
|
52
|
-
str: Formatted stdout, stderr, and return code.
|
53
|
-
"""
|
54
|
-
"""
|
55
|
-
Execute arbitrary Python code, including exact calculations, getting the current date, time, and more.
|
56
|
-
|
57
|
-
Args:
|
58
|
-
code (str): The Python code to execute.
|
59
|
-
|
60
|
-
Returns:
|
61
|
-
str: Formatted stdout, stderr, and return code.
|
62
|
-
"""
|
63
|
-
self.report_info("🐍 Executing Python code ...")
|
64
|
-
self.report_info(code)
|
65
|
-
|
66
|
-
result_queue = multiprocessing.Queue()
|
67
|
-
process = multiprocessing.Process(target=_run_python_code, args=(code, result_queue))
|
68
|
-
process.start()
|
69
|
-
process.join()
|
70
|
-
if not result_queue.empty():
|
71
|
-
result = result_queue.get()
|
72
|
-
else:
|
73
|
-
result = {'stdout': '', 'stderr': 'No result returned from process.', 'returncode': -1}
|
74
|
-
|
75
|
-
if result['returncode'] == 0:
|
76
|
-
|
77
|
-
self.report_success("✅ Python code executed")
|
78
|
-
else:
|
79
|
-
|
80
|
-
self.report_error(f"\u274c Python code execution failed with return code {result['returncode']}")
|
81
|
-
return f"stdout:\n{result['stdout']}\nstderr:\n{result['stderr']}\nreturncode: {result['returncode']}"
|
82
|
-
|
83
|
-
|
janito/cli/runner.py
DELETED
@@ -1,137 +0,0 @@
|
|
1
|
-
import sys
|
2
|
-
from rich.console import Console
|
3
|
-
from janito.render_prompt import render_system_prompt
|
4
|
-
from janito.agent.agent import Agent
|
5
|
-
from janito.agent.conversation import MaxRoundsExceededError, EmptyResponseError, ProviderError
|
6
|
-
from janito.agent.runtime_config import unified_config, runtime_config
|
7
|
-
from janito.agent.config import get_api_key
|
8
|
-
from janito import __version__
|
9
|
-
|
10
|
-
|
11
|
-
def format_tokens(n):
|
12
|
-
if n is None:
|
13
|
-
return "?"
|
14
|
-
try:
|
15
|
-
n = int(n)
|
16
|
-
except (TypeError, ValueError):
|
17
|
-
return str(n)
|
18
|
-
if n >= 1_000_000:
|
19
|
-
return f"{n/1_000_000:.1f}m"
|
20
|
-
if n >= 1_000:
|
21
|
-
return f"{n/1_000:.1f}k"
|
22
|
-
return str(n)
|
23
|
-
|
24
|
-
|
25
|
-
def run_cli(args):
|
26
|
-
if args.version:
|
27
|
-
print(f"janito version {__version__}")
|
28
|
-
sys.exit(0)
|
29
|
-
|
30
|
-
role = args.role or unified_config.get("role", "software engineer")
|
31
|
-
|
32
|
-
# Ensure runtime_config is updated so chat shell sees the role
|
33
|
-
if args.role:
|
34
|
-
runtime_config.set('role', args.role)
|
35
|
-
|
36
|
-
# Set runtime_config['model'] if --model is provided (highest priority, session only)
|
37
|
-
if getattr(args, 'model', None):
|
38
|
-
runtime_config.set('model', args.model)
|
39
|
-
|
40
|
-
# Set runtime_config['max_tools'] if --max-tools is provided
|
41
|
-
if getattr(args, 'max_tools', None) is not None:
|
42
|
-
runtime_config.set('max_tools', args.max_tools)
|
43
|
-
|
44
|
-
# Set trust mode if enabled
|
45
|
-
if getattr(args, 'trust', False):
|
46
|
-
runtime_config.set('trust', True)
|
47
|
-
|
48
|
-
# New logic for --system-file
|
49
|
-
system_prompt = None
|
50
|
-
if getattr(args, 'system_file', None):
|
51
|
-
with open(args.system_file, 'r', encoding='utf-8') as f:
|
52
|
-
system_prompt = f.read()
|
53
|
-
runtime_config.set('system_prompt_file', args.system_file)
|
54
|
-
|
55
|
-
else:
|
56
|
-
system_prompt = args.system or unified_config.get("system_prompt")
|
57
|
-
if args.system:
|
58
|
-
runtime_config.set('system_prompt', system_prompt)
|
59
|
-
if system_prompt is None:
|
60
|
-
# Pass full merged config (runtime overrides effective)
|
61
|
-
|
62
|
-
system_prompt = render_system_prompt(role)
|
63
|
-
|
64
|
-
if args.show_system:
|
65
|
-
api_key = get_api_key()
|
66
|
-
# Always get model from unified_config (which checks runtime_config first)
|
67
|
-
model = unified_config.get('model')
|
68
|
-
agent = Agent(api_key=api_key, model=model)
|
69
|
-
print("Model:", agent.model)
|
70
|
-
print("Parameters: {}")
|
71
|
-
import json
|
72
|
-
print("System Prompt:", system_prompt or "(default system prompt not provided)")
|
73
|
-
sys.exit(0)
|
74
|
-
|
75
|
-
api_key = get_api_key()
|
76
|
-
|
77
|
-
# Always get model from unified_config (which checks runtime_config first)
|
78
|
-
model = unified_config.get('model')
|
79
|
-
base_url = unified_config.get('base_url', 'https://openrouter.ai/api/v1')
|
80
|
-
azure_openai_api_version = unified_config.get('azure_openai_api_version', '2023-05-15')
|
81
|
-
# Handle vanilla mode
|
82
|
-
vanilla_mode = getattr(args, 'vanilla', False)
|
83
|
-
if vanilla_mode:
|
84
|
-
runtime_config.set('vanilla_mode', True)
|
85
|
-
system_prompt = None
|
86
|
-
runtime_config.set('system_prompt', None)
|
87
|
-
# Only set temperature if explicitly provided
|
88
|
-
if args.temperature is None:
|
89
|
-
runtime_config.set('temperature', None)
|
90
|
-
else:
|
91
|
-
runtime_config.set('vanilla_mode', False)
|
92
|
-
agent = Agent(api_key=api_key, model=model, system_prompt=system_prompt, verbose_tools=args.verbose_tools, base_url=base_url, azure_openai_api_version=azure_openai_api_version, use_azure_openai=unified_config.get('use_azure_openai', False))
|
93
|
-
|
94
|
-
# Save runtime max_tokens override if provided
|
95
|
-
if args.max_tokens is not None:
|
96
|
-
runtime_config.set('max_tokens', args.max_tokens)
|
97
|
-
|
98
|
-
# If no prompt is provided, enter shell loop mode
|
99
|
-
if not getattr(args, 'prompt', None):
|
100
|
-
from janito.cli_chat_shell.chat_loop import start_chat_shell
|
101
|
-
start_chat_shell(agent, continue_session=getattr(args, 'continue_session', False))
|
102
|
-
sys.exit(0)
|
103
|
-
|
104
|
-
prompt = args.prompt
|
105
|
-
|
106
|
-
console = Console()
|
107
|
-
from janito.agent.rich_tool_handler import MessageHandler
|
108
|
-
message_handler = MessageHandler()
|
109
|
-
|
110
|
-
# Removed on_content logic; use message_handler pattern only
|
111
|
-
|
112
|
-
messages = []
|
113
|
-
if agent.system_prompt:
|
114
|
-
messages.append({"role": "system", "content": agent.system_prompt})
|
115
|
-
|
116
|
-
messages.append({"role": "user", "content": prompt})
|
117
|
-
|
118
|
-
try:
|
119
|
-
try:
|
120
|
-
max_rounds = runtime_config.get('max_rounds', 50)
|
121
|
-
response = agent.chat(
|
122
|
-
messages,
|
123
|
-
message_handler=message_handler,
|
124
|
-
spinner=True,
|
125
|
-
max_rounds=max_rounds,
|
126
|
-
)
|
127
|
-
if args.verbose_response:
|
128
|
-
import json
|
129
|
-
console.print_json(json.dumps(response))
|
130
|
-
except MaxRoundsExceededError:
|
131
|
-
print("[red]Max conversation rounds exceeded.[/red]")
|
132
|
-
except ProviderError as e:
|
133
|
-
print(f"[red]Provider error:[/red] {e}")
|
134
|
-
except EmptyResponseError as e:
|
135
|
-
print(f"[red]Error:[/red] {e}")
|
136
|
-
except KeyboardInterrupt:
|
137
|
-
console.print("[yellow]Interrupted by user.[/yellow]")
|
@@ -1,204 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import sys
|
3
|
-
import json
|
4
|
-
from prompt_toolkit.history import InMemoryHistory
|
5
|
-
from janito.render_prompt import render_system_prompt
|
6
|
-
from .load_prompt import load_prompt
|
7
|
-
|
8
|
-
|
9
|
-
def handle_exit(console, **kwargs):
|
10
|
-
console.print("[bold red]Exiting chat mode.[/bold red]")
|
11
|
-
sys.exit(0)
|
12
|
-
|
13
|
-
|
14
|
-
def handle_restart(console, **kwargs):
|
15
|
-
console.print("[bold yellow]Restarting CLI...[/bold yellow]")
|
16
|
-
os.execv(sys.executable, [sys.executable, "-m", "janito"] + sys.argv[1:])
|
17
|
-
|
18
|
-
|
19
|
-
def handle_continue(console, state, **kwargs):
|
20
|
-
save_path = os.path.join('.janito', 'last_conversation.json')
|
21
|
-
if not os.path.exists(save_path):
|
22
|
-
console.print('[bold red]No saved conversation found.[/bold red]')
|
23
|
-
return
|
24
|
-
|
25
|
-
with open(save_path, 'r', encoding='utf-8') as f:
|
26
|
-
data = json.load(f)
|
27
|
-
state['messages'].clear()
|
28
|
-
state['messages'].extend(data.get('messages', []))
|
29
|
-
state['history_list'].clear()
|
30
|
-
state['history_list'].extend(data.get('prompts', []))
|
31
|
-
state['mem_history'] = InMemoryHistory()
|
32
|
-
for item in state['history_list']:
|
33
|
-
state['mem_history'].append_string(item)
|
34
|
-
state['last_usage_info'] = data.get('last_usage_info')
|
35
|
-
console.print('[bold green]Conversation restored from last session.[/bold green]')
|
36
|
-
|
37
|
-
|
38
|
-
def handle_history(console, state, *args, **kwargs):
|
39
|
-
messages = state.get('messages', [])
|
40
|
-
if not args:
|
41
|
-
# Default: last 5 messages
|
42
|
-
start = max(0, len(messages) - 5)
|
43
|
-
end = len(messages)
|
44
|
-
elif len(args) == 1:
|
45
|
-
count = int(args[0])
|
46
|
-
start = max(0, len(messages) - count)
|
47
|
-
end = len(messages)
|
48
|
-
elif len(args) >= 2:
|
49
|
-
start = int(args[0])
|
50
|
-
end = int(args[1]) + 1 # inclusive
|
51
|
-
else:
|
52
|
-
start = 0
|
53
|
-
end = len(messages)
|
54
|
-
|
55
|
-
console.print(f"[bold cyan]Showing messages {start} to {end - 1} (total {len(messages)}):[/bold cyan]")
|
56
|
-
for idx, msg in enumerate(messages[start:end], start=start):
|
57
|
-
role = msg.get('role', 'unknown')
|
58
|
-
content = msg.get('content', '')
|
59
|
-
console.print(f"[bold]{idx} [{role}]:[/bold] {content}")
|
60
|
-
|
61
|
-
|
62
|
-
def handle_help(console, **kwargs):
|
63
|
-
console.print("""
|
64
|
-
[bold green]Available commands:[/bold green]
|
65
|
-
/exit - Exit chat mode
|
66
|
-
/restart - Restart the CLI
|
67
|
-
/help - Show this help message
|
68
|
-
/continue - Restore last saved conversation
|
69
|
-
/reset - Reset conversation history
|
70
|
-
/system - Show the system prompt
|
71
|
-
/role - Change the system role
|
72
|
-
/clear - Clear the terminal screen
|
73
|
-
/multi - Provide multiline input as next message
|
74
|
-
/config - Show or set configuration (see: /config show, /config set local|global key=value)
|
75
|
-
""")
|
76
|
-
|
77
|
-
|
78
|
-
def handle_reload(console, *args, **kwargs):
|
79
|
-
"""
|
80
|
-
/reload [filename] - Reload the system prompt from the default or specified file
|
81
|
-
"""
|
82
|
-
agent = kwargs.get('agent')
|
83
|
-
state = kwargs.get('state')
|
84
|
-
filename = args[0] if args else None
|
85
|
-
try:
|
86
|
-
prompt_text = load_prompt(filename)
|
87
|
-
if hasattr(agent, 'system_prompt'):
|
88
|
-
agent.system_prompt = prompt_text
|
89
|
-
# Update the first system message in the conversation if present
|
90
|
-
messages = state.get('messages') if state else None
|
91
|
-
if messages:
|
92
|
-
for msg in messages:
|
93
|
-
if msg.get('role') == 'system':
|
94
|
-
msg['content'] = prompt_text
|
95
|
-
break
|
96
|
-
console.print(f"[bold green]System prompt reloaded from {'default file' if not filename else filename}![/bold green]")
|
97
|
-
except Exception as e:
|
98
|
-
console.print(f"[bold red]Failed to reload system prompt:[/bold red] {e}")
|
99
|
-
|
100
|
-
|
101
|
-
def handle_system(console, **kwargs):
|
102
|
-
prompt = getattr(kwargs.get('agent'), 'system_prompt', None)
|
103
|
-
if not prompt:
|
104
|
-
prompt = render_system_prompt("software engineer")
|
105
|
-
console.print(f"[bold magenta]System Prompt:[/bold magenta]\n{prompt}")
|
106
|
-
|
107
|
-
|
108
|
-
def handle_clear(console, **kwargs):
|
109
|
-
os.system('cls' if os.name == 'nt' else 'clear')
|
110
|
-
|
111
|
-
|
112
|
-
def handle_reset(console, state, **kwargs):
|
113
|
-
import os
|
114
|
-
save_path = os.path.join('.janito', 'last_conversation.json')
|
115
|
-
|
116
|
-
# Clear in-memory conversation and prompt history
|
117
|
-
state['messages'].clear()
|
118
|
-
state['history_list'].clear()
|
119
|
-
state['mem_history'] = InMemoryHistory()
|
120
|
-
state['last_usage_info'] = None
|
121
|
-
state['last_elapsed'] = None
|
122
|
-
|
123
|
-
# Delete saved conversation file if exists
|
124
|
-
if os.path.exists(save_path):
|
125
|
-
try:
|
126
|
-
os.remove(save_path)
|
127
|
-
console.print('[bold yellow]Deleted saved conversation history.[/bold yellow]')
|
128
|
-
except Exception as e:
|
129
|
-
console.print(f'[bold red]Failed to delete saved conversation:[/bold red] {e}')
|
130
|
-
else:
|
131
|
-
console.print('[bold yellow]No saved conversation to delete.[/bold yellow]')
|
132
|
-
|
133
|
-
console.print('[bold green]Conversation history has been reset.[/bold green]')
|
134
|
-
|
135
|
-
|
136
|
-
def handle_multi(console, state, **kwargs):
|
137
|
-
console.print("[bold yellow]Multiline mode activated. Provide or write your text and press Esc + Enter to submit.[/bold yellow]")
|
138
|
-
state['paste_mode'] = True
|
139
|
-
|
140
|
-
from janito.agent.runtime_config import runtime_config
|
141
|
-
from .config_shell import handle_config_shell
|
142
|
-
|
143
|
-
def handle_role(console, *args, **kwargs):
|
144
|
-
state = kwargs.get('state')
|
145
|
-
agent = kwargs.get('agent')
|
146
|
-
if not args:
|
147
|
-
console.print('[bold red]Usage: /role <new role description>[/bold red]')
|
148
|
-
return
|
149
|
-
new_role = ' '.join(args)
|
150
|
-
# Update system message in conversation
|
151
|
-
found = False
|
152
|
-
for msg in state['messages']:
|
153
|
-
if msg.get('role') == 'system':
|
154
|
-
msg['content'] = render_system_prompt(new_role)
|
155
|
-
found = True
|
156
|
-
break
|
157
|
-
if not found:
|
158
|
-
# Insert new system message at the beginning
|
159
|
-
state['messages'].insert(0, {'role': 'system', 'content': new_role})
|
160
|
-
# Update agent's system prompt attribute if exists
|
161
|
-
if hasattr(agent, 'system_prompt'):
|
162
|
-
agent.system_prompt = render_system_prompt(new_role)
|
163
|
-
# Also store the raw role string
|
164
|
-
if hasattr(agent, 'role_name'):
|
165
|
-
agent.role_name = new_role
|
166
|
-
else:
|
167
|
-
setattr(agent, 'role_name', new_role)
|
168
|
-
# Update runtime config so all lookups see the new role
|
169
|
-
runtime_config.set('role', new_role)
|
170
|
-
console.print(f"[bold green]System role updated to:[/bold green] {new_role}")
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
COMMAND_HANDLERS = {
|
175
|
-
"/history": handle_history,
|
176
|
-
"/continue": handle_continue,
|
177
|
-
"/exit": handle_exit,
|
178
|
-
"/restart": handle_restart,
|
179
|
-
|
180
|
-
"/help": handle_help,
|
181
|
-
"/multi": handle_multi,
|
182
|
-
"/system": handle_system,
|
183
|
-
}
|
184
|
-
|
185
|
-
if not runtime_config.get('vanilla_mode', False):
|
186
|
-
COMMAND_HANDLERS["/role"] = handle_role
|
187
|
-
|
188
|
-
COMMAND_HANDLERS.update({
|
189
|
-
"/clear": handle_clear,
|
190
|
-
"/reset": handle_reset,
|
191
|
-
"/config": handle_config_shell,
|
192
|
-
"/reload": handle_reload,
|
193
|
-
})
|
194
|
-
|
195
|
-
|
196
|
-
def handle_command(command, console, **kwargs):
|
197
|
-
parts = command.strip().split()
|
198
|
-
cmd = parts[0]
|
199
|
-
args = parts[1:]
|
200
|
-
handler = COMMAND_HANDLERS.get(cmd)
|
201
|
-
if handler:
|
202
|
-
return handler(console, *args, **kwargs)
|
203
|
-
console.print(f"[bold red]Invalid command: {cmd}. Type /help for a list of commands.[/bold red]")
|
204
|
-
return None
|
janito/render_prompt.py
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
import jinja2
|
2
|
-
from pathlib import Path
|
3
|
-
|
4
|
-
|
5
|
-
def render_system_prompt(role: str) -> str:
|
6
|
-
template_loader = jinja2.FileSystemLoader(searchpath=str(Path(__file__).parent / "agent" / "templates"))
|
7
|
-
env = jinja2.Environment(loader=template_loader)
|
8
|
-
template = env.get_template("system_instructions.j2")
|
9
|
-
return template.render(role=role)
|
10
|
-
|
11
|
-
if __name__ == "__main__":
|
12
|
-
prompt = render_system_prompt("software engineer")
|
13
|
-
print(prompt)
|
janito-1.5.2.dist-info/RECORD
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
janito/__init__.py,sha256=khi4ujZnKOCcOQf36wd2PHf2pb8dzIOIyoobKILMdfw,23
|
2
|
-
janito/__main__.py,sha256=CBScR30Tm-vuhIJM8o5HXKr0q-smICiwSVyuU68BP8U,78
|
3
|
-
janito/render_prompt.py,sha256=y2pqntkfC34bh5psNobW2Vv1YAI3se04-ZcFCaoWU1s,457
|
4
|
-
janito/rich_utils.py,sha256=g5D-McYEUhzhPFpZGML41sw4w75eT51gu0x7anMQjxA,1048
|
5
|
-
janito/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
|
-
janito/agent/agent.py,sha256=j0ZffOAbeRpFMfAlIllEt5EjWRNTvkVuukbcdTpY6Z0,3517
|
7
|
-
janito/agent/config.py,sha256=jmGQAvVvFKE4V2nZHUeLRLyneydQNfEnUu8TmxDLxq0,4428
|
8
|
-
janito/agent/config_defaults.py,sha256=73tmwpICsgpWEnpCasSR97g59LXKQBB5xQFut7ZepTE,438
|
9
|
-
janito/agent/config_utils.py,sha256=UmvR236wDrMc-aTy9LxVbop6YeoJaaPb1d2DBMlkSRg,254
|
10
|
-
janito/agent/content_handler.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
|
-
janito/agent/conversation.py,sha256=qwfQeM8Rv-Tl-pBVzlTIHrFyl20vgMO82W82JLYmTjk,7550
|
12
|
-
janito/agent/message_handler.py,sha256=6g-cQg-jR-93nZIku3dNLJhLL8nZtHSbMwQqmfpyBRA,673
|
13
|
-
janito/agent/openai_schema_generator.py,sha256=dE3gUPX_ZqYzuY9rWY5Ygo9imXvy-Mn1rqPsm59Tle8,4329
|
14
|
-
janito/agent/queued_message_handler.py,sha256=raz_tQLooWpWvx1qqPrl1s4F4Xx_-wyCxQPfwcDI4II,1365
|
15
|
-
janito/agent/rich_tool_handler.py,sha256=L0YGZTnkD_iISAUdP6sLdZ8fuKKQQrRlATIlmhInPQs,1906
|
16
|
-
janito/agent/runtime_config.py,sha256=ztmU0Ajd2NS7olJxhXjHPtndqIZKuWMqFXuQm-TqCUE,891
|
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
|
20
|
-
janito/agent/templates/system_instructions.j2,sha256=Y24edrqLydMTcbaZYSW8_xJMMEbTNVS3Iy4IHrBe0-Q,1885
|
21
|
-
janito/agent/tools/__init__.py,sha256=TkXRcFj1E2OHQBb2RUkGCQPsxkL519yFUYWbR1zEDG8,120
|
22
|
-
janito/agent/tools/append_text_to_file.py,sha256=sSklc9Ifo7tTKB81yRgfU7yWfeHsRBNdUQVbOYw52EE,1881
|
23
|
-
janito/agent/tools/ask_user.py,sha256=36pZLy3WPEIQyKKallbH9Bq-8ASLWb-Eza4g1VbYZ-c,2482
|
24
|
-
janito/agent/tools/create_directory.py,sha256=fFMXIqSFRx6NyRtbJvgUId-rN83mYHsAQqP-2sBjGMA,1340
|
25
|
-
janito/agent/tools/create_file.py,sha256=YQISWGBUOMFTFA_hKqanYjXNJMHK22jDSrGIxOAMWDY,2551
|
26
|
-
janito/agent/tools/fetch_url.py,sha256=RuicvHm8uQJSCPwfLv6KV9my1HCJd0ehl3yutjKyd3g,2068
|
27
|
-
janito/agent/tools/find_files.py,sha256=14iUSLPzqycuZpRkCNpS8hoa7KvGlotogMYQc4yFobo,2547
|
28
|
-
janito/agent/tools/get_file_outline.py,sha256=NwyIY2XAJr9REmeyX6Lyd6SyQiLdAiSzN4dii_iltM0,1447
|
29
|
-
janito/agent/tools/get_lines.py,sha256=Y7tHnHZB0PFylcRIXtDvmFPXdoWTeXUmVrENpBgVBdM,3364
|
30
|
-
janito/agent/tools/gitignore_utils.py,sha256=z_IYilabTD_-c14aRxuVasojOzTsg-11xJPJqudWIKA,1306
|
31
|
-
janito/agent/tools/move_file.py,sha256=x-A3g6D_tdboVhsBkA-jWYm6h6K7uCYglFoY_9agbuM,2270
|
32
|
-
janito/agent/tools/py_compile.py,sha256=WzaPRoJcNtAwtyNTg5jNRSXuKGUkbqDWGYkbJuUX-vk,1470
|
33
|
-
janito/agent/tools/python_exec.py,sha256=lbOhguPDSR3xru8XrHoB5_sT_Wx8PBiS4qxWami6LpA,2932
|
34
|
-
janito/agent/tools/remove_directory.py,sha256=fcfm9nLYiLEjbaeSHC-fCH5DqvurJZS6lh4v5brlblk,1384
|
35
|
-
janito/agent/tools/remove_file.py,sha256=qVfuAJXThA4UR7iCU5DLc_UMY81iextp0_zXTgHQYg4,1506
|
36
|
-
janito/agent/tools/replace_text_in_file.py,sha256=0w5cG_MvXcxwQI-i8hX-GedW0qnEwn-eYXYaNlv4NxA,4969
|
37
|
-
janito/agent/tools/rich_live.py,sha256=cuZ3-ZxpuHxR1TvIcp0bi9F3QM1M6Ms0XiOMd8If8gU,1161
|
38
|
-
janito/agent/tools/run_bash_command.py,sha256=1LcoNNhRHH65tCmGmdEFtpA5S4L1kmODuvBQUl7LGnA,5246
|
39
|
-
janito/agent/tools/search_files.py,sha256=5ZTGB6adWO8OafGLZHGjnhUaW5IE4IfM1BSVxzNwNeI,2710
|
40
|
-
janito/agent/tools/tool_base.py,sha256=ch08PaWMEC8hC0UmWC7fEXmRBdnsmqXn6pXhoXbGXFU,1898
|
41
|
-
janito/agent/tools/tools_utils.py,sha256=G_Ib8QamhHbBzpKDW3TeoaxGDQgjs8_Zj8TFUInl78k,354
|
42
|
-
janito/agent/tools/utils.py,sha256=cKPE9HVA1yHmKzML8Uz4YCVLNDK13MQw9ThvhC9COCI,1101
|
43
|
-
janito/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
44
|
-
janito/cli/_print_config.py,sha256=keQ0XJN2w5ZDG4SSQxMPaayE436mn8eSUSRuB57pGCI,3254
|
45
|
-
janito/cli/_utils.py,sha256=Q_OCFZmbr78qW4hSSUUhjondVc0ao7-iUHE7Ig8IP1g,289
|
46
|
-
janito/cli/arg_parser.py,sha256=CLHv2sbHxbSwnPvnDk10-cyasCvR9lPv4Yc96QoW1qA,3885
|
47
|
-
janito/cli/config_commands.py,sha256=lhlutyVM2lBbXTeZ2FXW9iWOvFG35uDr9Rjoksx3iJY,7957
|
48
|
-
janito/cli/logging_setup.py,sha256=dWQ0wFf4YuF5lxZlhpN6lis7G56LeFYUwQdh9nA5NmA,1141
|
49
|
-
janito/cli/main.py,sha256=kCdIUbM5X7pSnVsraOGJ2n_MSrt4qMeg3syWx1CV0rs,1457
|
50
|
-
janito/cli/runner.py,sha256=aQvbxzOaRQ44ZP6CutDdpms0K8inOeI1pKRyCPYPIkQ,5193
|
51
|
-
janito/cli_chat_shell/__init__.py,sha256=PDGl7xK_vgkROoXvUxGZqVQFfuL9U4TjdexpP8E2JKg,41
|
52
|
-
janito/cli_chat_shell/chat_loop.py,sha256=35BJeKLhAkdARrMUADK2qRP-Q2bQPB2P7JSUrQ8bUxY,5501
|
53
|
-
janito/cli_chat_shell/commands.py,sha256=gBdfvujRDchRl_M5HZO-eO55dmKvDi3twS8jo3qo-a4,7301
|
54
|
-
janito/cli_chat_shell/config_shell.py,sha256=vBKAJvDRaqC2uSjTFBZ2KgQJT0FoTqbCI8u1N6VoPF4,3208
|
55
|
-
janito/cli_chat_shell/load_prompt.py,sha256=B7C_IhMk3n1XBQcfOwFVDnjrj1278JL3kV4UtkeeZx8,604
|
56
|
-
janito/cli_chat_shell/session_manager.py,sha256=mdmt6mWOZOYqBiqKJ_8D2ff_31RdeJhFB_xp3g3P6B4,2164
|
57
|
-
janito/cli_chat_shell/ui.py,sha256=-HrX7aOivKUaDdZh0_FWSbHGSRPbhVyVuKyqcbvKFmQ,6071
|
58
|
-
janito/web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
59
|
-
janito/web/__main__.py,sha256=oPXNF332aCeI7aUWr7_8M57oOKugw422VrEubxFp0P4,354
|
60
|
-
janito/web/app.py,sha256=kJhrKDI7X2Ujzk_SVxctvq1loiAXHil0ckn3RQ8e3gg,6549
|
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,,
|
File without changes
|
File without changes
|
File without changes
|