janito 1.9.0__py3-none-any.whl → 1.10.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- janito/__init__.py +1 -1
- janito/agent/api_exceptions.py +4 -0
- janito/agent/config.py +1 -1
- janito/agent/config_defaults.py +2 -26
- janito/agent/conversation.py +163 -122
- janito/agent/conversation_api.py +149 -159
- janito/agent/{conversation_history.py → llm_conversation_history.py} +18 -1
- janito/agent/openai_client.py +38 -23
- janito/agent/openai_schema_generator.py +162 -129
- janito/agent/platform_discovery.py +134 -77
- janito/agent/profile_manager.py +5 -5
- janito/agent/rich_message_handler.py +80 -31
- janito/agent/templates/profiles/system_prompt_template_base.txt.j2 +5 -4
- janito/agent/test_openai_schema_generator.py +93 -0
- janito/agent/tool_base.py +7 -2
- janito/agent/tool_executor.py +54 -49
- janito/agent/tool_registry.py +5 -2
- janito/agent/tool_use_tracker.py +26 -5
- janito/agent/tools/__init__.py +6 -3
- janito/agent/tools/create_directory.py +3 -1
- janito/agent/tools/create_file.py +7 -1
- janito/agent/tools/fetch_url.py +40 -3
- janito/agent/tools/find_files.py +3 -1
- janito/agent/tools/get_file_outline/core.py +6 -7
- janito/agent/tools/get_file_outline/search_outline.py +3 -1
- janito/agent/tools/get_lines.py +7 -2
- janito/agent/tools/move_file.py +3 -1
- janito/agent/tools/present_choices.py +3 -1
- janito/agent/tools/python_command_runner.py +150 -0
- janito/agent/tools/python_file_runner.py +148 -0
- janito/agent/tools/python_stdin_runner.py +154 -0
- janito/agent/tools/remove_directory.py +3 -1
- janito/agent/tools/remove_file.py +5 -1
- janito/agent/tools/replace_file.py +12 -2
- janito/agent/tools/replace_text_in_file.py +4 -2
- janito/agent/tools/run_bash_command.py +30 -69
- janito/agent/tools/run_powershell_command.py +134 -105
- janito/agent/tools/search_text.py +172 -122
- janito/agent/tools/validate_file_syntax/core.py +3 -1
- janito/agent/tools_utils/action_type.py +7 -0
- janito/agent/tools_utils/dir_walk_utils.py +3 -2
- janito/agent/tools_utils/formatting.py +47 -21
- janito/agent/tools_utils/gitignore_utils.py +66 -40
- janito/agent/tools_utils/test_gitignore_utils.py +46 -0
- janito/cli/_print_config.py +63 -61
- janito/cli/arg_parser.py +13 -12
- janito/cli/cli_main.py +137 -147
- janito/cli/main.py +152 -174
- janito/cli/one_shot.py +40 -26
- janito/i18n/__init__.py +1 -1
- janito/rich_utils.py +46 -8
- janito/shell/commands/__init__.py +2 -4
- janito/shell/commands/conversation_restart.py +3 -1
- janito/shell/commands/edit.py +3 -0
- janito/shell/commands/history_view.py +3 -3
- janito/shell/commands/lang.py +3 -0
- janito/shell/commands/livelogs.py +5 -3
- janito/shell/commands/prompt.py +6 -0
- janito/shell/commands/session.py +3 -0
- janito/shell/commands/session_control.py +3 -0
- janito/shell/commands/termweb_log.py +8 -0
- janito/shell/commands/tools.py +3 -0
- janito/shell/commands/track.py +36 -0
- janito/shell/commands/utility.py +13 -18
- janito/shell/commands/verbose.py +3 -4
- janito/shell/input_history.py +62 -0
- janito/shell/main.py +117 -181
- janito/shell/session/manager.py +0 -21
- janito/shell/ui/interactive.py +0 -2
- janito/termweb/static/editor.css +0 -4
- janito/tests/test_rich_utils.py +44 -0
- janito/web/app.py +0 -75
- {janito-1.9.0.dist-info → janito-1.10.0.dist-info}/METADATA +61 -42
- {janito-1.9.0.dist-info → janito-1.10.0.dist-info}/RECORD +78 -71
- {janito-1.9.0.dist-info → janito-1.10.0.dist-info}/WHEEL +1 -1
- janito/agent/providers.py +0 -77
- janito/agent/tools/run_python_command.py +0 -161
- janito/shell/commands/sum.py +0 -49
- {janito-1.9.0.dist-info → janito-1.10.0.dist-info}/entry_points.txt +0 -0
- {janito-1.9.0.dist-info → janito-1.10.0.dist-info}/licenses/LICENSE +0 -0
- {janito-1.9.0.dist-info → janito-1.10.0.dist-info}/top_level.txt +0 -0
janito/agent/providers.py
DELETED
@@ -1,77 +0,0 @@
|
|
1
|
-
"""Providers module: defines LLM provider interfaces and implementations."""
|
2
|
-
|
3
|
-
from abc import ABC, abstractmethod
|
4
|
-
|
5
|
-
|
6
|
-
class Provider(ABC):
|
7
|
-
"""Abstract base class for LLM providers."""
|
8
|
-
|
9
|
-
def __init__(self, config: dict):
|
10
|
-
self.config = config
|
11
|
-
|
12
|
-
@abstractmethod
|
13
|
-
def create_client(self):
|
14
|
-
"""Instantiate and return the provider-specific client."""
|
15
|
-
pass
|
16
|
-
|
17
|
-
@abstractmethod
|
18
|
-
def get_default_model(self) -> str:
|
19
|
-
"""Return the default model for this provider."""
|
20
|
-
pass
|
21
|
-
|
22
|
-
|
23
|
-
class OpenAIProvider(Provider):
|
24
|
-
def create_client(self):
|
25
|
-
from openai import OpenAI
|
26
|
-
|
27
|
-
return OpenAI(
|
28
|
-
base_url=self.config.get("base_url", "https://api.openai.com/v1"),
|
29
|
-
api_key=self.config["api_key"],
|
30
|
-
)
|
31
|
-
|
32
|
-
def get_default_model(self) -> str:
|
33
|
-
return self.config.get("default_model", "gpt-3.5-turbo")
|
34
|
-
|
35
|
-
|
36
|
-
class AzureAIProvider(Provider):
|
37
|
-
def create_client(self):
|
38
|
-
from openai import AzureOpenAI
|
39
|
-
|
40
|
-
return AzureOpenAI(
|
41
|
-
api_key=self.config["api_key"],
|
42
|
-
azure_endpoint=self.config["base_url"],
|
43
|
-
api_version=self.config.get("api_version", "2023-05-15"),
|
44
|
-
)
|
45
|
-
|
46
|
-
def get_default_model(self) -> str:
|
47
|
-
return self.config.get("default_model", "gpt-35-turbo")
|
48
|
-
|
49
|
-
|
50
|
-
class OpenrouterAIProvider(Provider):
|
51
|
-
def create_client(self):
|
52
|
-
from openai import OpenAI
|
53
|
-
|
54
|
-
return OpenAI(
|
55
|
-
base_url=self.config.get("base_url", "https://openrouter.ai/api/v1"),
|
56
|
-
api_key=self.config["api_key"],
|
57
|
-
)
|
58
|
-
|
59
|
-
def get_default_model(self) -> str:
|
60
|
-
return self.config.get("default_model", "openrouter/cognitive")
|
61
|
-
|
62
|
-
|
63
|
-
class FireworksAIProvider(Provider):
|
64
|
-
def create_client(self):
|
65
|
-
from openai import OpenAI
|
66
|
-
|
67
|
-
return OpenAI(
|
68
|
-
base_url=self.config.get(
|
69
|
-
"base_url", "https://api.fireworks.ai/inference/v1"
|
70
|
-
),
|
71
|
-
api_key=self.config["api_key"],
|
72
|
-
)
|
73
|
-
|
74
|
-
def get_default_model(self) -> str:
|
75
|
-
return self.config.get(
|
76
|
-
"default_model", "accounts/fireworks/models/firefunction-v1"
|
77
|
-
)
|
@@ -1,161 +0,0 @@
|
|
1
|
-
import subprocess
|
2
|
-
import tempfile
|
3
|
-
import sys
|
4
|
-
import os
|
5
|
-
from janito.agent.tool_base import ToolBase
|
6
|
-
from janito.agent.tool_registry import register_tool
|
7
|
-
from janito.i18n import tr
|
8
|
-
|
9
|
-
|
10
|
-
@register_tool(name="run_python_command")
|
11
|
-
class RunPythonCommandTool(ToolBase):
|
12
|
-
"""
|
13
|
-
Tool to execute Python code in a subprocess and capture output.
|
14
|
-
Args:
|
15
|
-
code (str): The Python code to execute.
|
16
|
-
timeout (int, optional): Timeout in seconds for the command. Defaults to 60.
|
17
|
-
require_confirmation (bool, optional): If True, require user confirmation before running. Defaults to False.
|
18
|
-
interactive (bool, optional): If True, warns that the command may require user interaction. Defaults to False.
|
19
|
-
Returns:
|
20
|
-
str: File paths and line counts for stdout and stderr, or direct output if small enough.
|
21
|
-
"""
|
22
|
-
|
23
|
-
def run(
|
24
|
-
self,
|
25
|
-
code: str,
|
26
|
-
timeout: int = 60,
|
27
|
-
require_confirmation: bool = False,
|
28
|
-
interactive: bool = False,
|
29
|
-
) -> str:
|
30
|
-
if not code.strip():
|
31
|
-
self.report_warning(tr("ℹ️ Empty code provided."))
|
32
|
-
return tr("Warning: Empty code provided. Operation skipped.")
|
33
|
-
self.report_info(tr("🐍 Running Python code: ...\n{code}\n", code=code))
|
34
|
-
if interactive:
|
35
|
-
self.report_warning(
|
36
|
-
tr(
|
37
|
-
"⚠️ Warning: This code might be interactive, require user input, and might hang."
|
38
|
-
)
|
39
|
-
)
|
40
|
-
sys.stdout.flush()
|
41
|
-
if require_confirmation:
|
42
|
-
confirmed = self.confirm_action(
|
43
|
-
tr("Do you want to execute this Python code?")
|
44
|
-
)
|
45
|
-
if not confirmed:
|
46
|
-
self.report_warning(tr("⚠️ Execution cancelled by user."))
|
47
|
-
return tr("Execution cancelled by user.")
|
48
|
-
try:
|
49
|
-
with (
|
50
|
-
tempfile.NamedTemporaryFile(
|
51
|
-
mode="w+",
|
52
|
-
suffix=".py",
|
53
|
-
prefix="run_python_",
|
54
|
-
delete=False,
|
55
|
-
encoding="utf-8",
|
56
|
-
) as code_file,
|
57
|
-
tempfile.NamedTemporaryFile(
|
58
|
-
mode="w+",
|
59
|
-
prefix="run_python_stdout_",
|
60
|
-
delete=False,
|
61
|
-
encoding="utf-8",
|
62
|
-
) as stdout_file,
|
63
|
-
tempfile.NamedTemporaryFile(
|
64
|
-
mode="w+",
|
65
|
-
prefix="run_python_stderr_",
|
66
|
-
delete=False,
|
67
|
-
encoding="utf-8",
|
68
|
-
) as stderr_file,
|
69
|
-
):
|
70
|
-
code_file.write(code)
|
71
|
-
code_file.flush()
|
72
|
-
env = os.environ.copy()
|
73
|
-
env["PYTHONIOENCODING"] = "utf-8"
|
74
|
-
process = subprocess.Popen(
|
75
|
-
[sys.executable, code_file.name],
|
76
|
-
stdout=stdout_file,
|
77
|
-
stderr=stderr_file,
|
78
|
-
text=True,
|
79
|
-
env=env,
|
80
|
-
)
|
81
|
-
try:
|
82
|
-
return_code = process.wait(timeout=timeout)
|
83
|
-
except subprocess.TimeoutExpired:
|
84
|
-
process.kill()
|
85
|
-
self.report_error(
|
86
|
-
tr(" ❌ Timed out after {timeout} seconds.", timeout=timeout)
|
87
|
-
)
|
88
|
-
return tr(
|
89
|
-
"Code timed out after {timeout} seconds.", timeout=timeout
|
90
|
-
)
|
91
|
-
stdout_file.flush()
|
92
|
-
stderr_file.flush()
|
93
|
-
with open(
|
94
|
-
stdout_file.name, "r", encoding="utf-8", errors="replace"
|
95
|
-
) as out_f:
|
96
|
-
out_f.seek(0)
|
97
|
-
for line in out_f:
|
98
|
-
self.report_stdout(line)
|
99
|
-
with open(
|
100
|
-
stderr_file.name, "r", encoding="utf-8", errors="replace"
|
101
|
-
) as err_f:
|
102
|
-
err_f.seek(0)
|
103
|
-
for line in err_f:
|
104
|
-
self.report_stderr(line)
|
105
|
-
with open(
|
106
|
-
stdout_file.name, "r", encoding="utf-8", errors="replace"
|
107
|
-
) as out_f:
|
108
|
-
stdout_lines = sum(1 for _ in out_f)
|
109
|
-
with open(
|
110
|
-
stderr_file.name, "r", encoding="utf-8", errors="replace"
|
111
|
-
) as err_f:
|
112
|
-
stderr_lines = sum(1 for _ in err_f)
|
113
|
-
self.report_success(
|
114
|
-
tr(" ✅ return code {return_code}", return_code=return_code)
|
115
|
-
)
|
116
|
-
warning_msg = ""
|
117
|
-
if interactive:
|
118
|
-
warning_msg = tr(
|
119
|
-
"⚠️ Warning: This code might be interactive, require user input, and might hang.\n"
|
120
|
-
)
|
121
|
-
with open(
|
122
|
-
stdout_file.name, "r", encoding="utf-8", errors="replace"
|
123
|
-
) as out_f:
|
124
|
-
stdout_content = out_f.read()
|
125
|
-
with open(
|
126
|
-
stderr_file.name, "r", encoding="utf-8", errors="replace"
|
127
|
-
) as err_f:
|
128
|
-
stderr_content = err_f.read()
|
129
|
-
max_lines = 100
|
130
|
-
if stdout_lines <= max_lines and stderr_lines <= max_lines:
|
131
|
-
result = warning_msg + tr(
|
132
|
-
"Return code: {return_code}\n--- STDOUT ---\n{stdout_content}",
|
133
|
-
return_code=return_code,
|
134
|
-
stdout_content=stdout_content,
|
135
|
-
)
|
136
|
-
if stderr_content.strip():
|
137
|
-
result += tr(
|
138
|
-
"\n--- STDERR ---\n{stderr_content}",
|
139
|
-
stderr_content=stderr_content,
|
140
|
-
)
|
141
|
-
return result
|
142
|
-
else:
|
143
|
-
result = warning_msg + tr(
|
144
|
-
"stdout_file: {stdout_file} (lines: {stdout_lines})\n",
|
145
|
-
stdout_file=stdout_file.name,
|
146
|
-
stdout_lines=stdout_lines,
|
147
|
-
)
|
148
|
-
if stderr_lines > 0 and stderr_content.strip():
|
149
|
-
result += tr(
|
150
|
-
"stderr_file: {stderr_file} (lines: {stderr_lines})\n",
|
151
|
-
stderr_file=stderr_file.name,
|
152
|
-
stderr_lines=stderr_lines,
|
153
|
-
)
|
154
|
-
result += tr(
|
155
|
-
"returncode: {return_code}\nUse the get_lines tool to inspect the contents of these files when needed.",
|
156
|
-
return_code=return_code,
|
157
|
-
)
|
158
|
-
return result
|
159
|
-
except Exception as e:
|
160
|
-
self.report_error(tr(" ❌ Error: {error}", error=e))
|
161
|
-
return tr("Error running code: {error}", error=e)
|
janito/shell/commands/sum.py
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
def handle_sum(console, shell_state=None, **kwargs):
|
2
|
-
"""
|
3
|
-
Summarize the current chat history and replace it with a summary message.
|
4
|
-
"""
|
5
|
-
agent = kwargs.get("agent")
|
6
|
-
if agent is None:
|
7
|
-
console.print("[bold red]Agent not provided to /sum command.[/bold red]")
|
8
|
-
return
|
9
|
-
|
10
|
-
history = shell_state.conversation_history.get_messages()
|
11
|
-
if not history or len(history) < 2:
|
12
|
-
console.print(
|
13
|
-
"[bold yellow]Not enough conversation to summarize.[/bold yellow]"
|
14
|
-
)
|
15
|
-
return
|
16
|
-
|
17
|
-
# Find the system message if present
|
18
|
-
system_msg = next((m for m in history if m.get("role") == "system"), None)
|
19
|
-
|
20
|
-
# Prepare summary prompt
|
21
|
-
summary_prompt = {
|
22
|
-
"role": "user",
|
23
|
-
"content": "Summarize the following conversation in a concise paragraph for context. Only output the summary, do not include any tool calls or formatting.",
|
24
|
-
}
|
25
|
-
# Exclude system messages for the summary context
|
26
|
-
convo_for_summary = [m for m in history if m.get("role") != "system"]
|
27
|
-
summary_messages = [summary_prompt] + convo_for_summary
|
28
|
-
|
29
|
-
try:
|
30
|
-
summary_response = agent.chat(summary_messages, spinner=True, max_tokens=256)
|
31
|
-
summary_text = (
|
32
|
-
summary_response["content"]
|
33
|
-
if isinstance(summary_response, dict)
|
34
|
-
else str(summary_response)
|
35
|
-
)
|
36
|
-
except Exception as e:
|
37
|
-
console.print(f"[bold red]Error during summarization: {e}[/bold red]")
|
38
|
-
return
|
39
|
-
|
40
|
-
# Rebuild conversation history
|
41
|
-
new_history = []
|
42
|
-
if system_msg:
|
43
|
-
new_history.append(system_msg)
|
44
|
-
new_history.append({"role": "assistant", "content": summary_text})
|
45
|
-
shell_state.conversation_history.set_messages(new_history)
|
46
|
-
|
47
|
-
console.print(
|
48
|
-
"[bold green]Conversation summarized and history replaced with summary.[/bold green]"
|
49
|
-
)
|
File without changes
|
File without changes
|
File without changes
|