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.
Files changed (81) hide show
  1. janito/__init__.py +1 -1
  2. janito/agent/api_exceptions.py +4 -0
  3. janito/agent/config.py +1 -1
  4. janito/agent/config_defaults.py +2 -26
  5. janito/agent/conversation.py +163 -122
  6. janito/agent/conversation_api.py +149 -159
  7. janito/agent/{conversation_history.py → llm_conversation_history.py} +18 -1
  8. janito/agent/openai_client.py +38 -23
  9. janito/agent/openai_schema_generator.py +162 -129
  10. janito/agent/platform_discovery.py +134 -77
  11. janito/agent/profile_manager.py +5 -5
  12. janito/agent/rich_message_handler.py +80 -31
  13. janito/agent/templates/profiles/system_prompt_template_base.txt.j2 +5 -4
  14. janito/agent/test_openai_schema_generator.py +93 -0
  15. janito/agent/tool_base.py +7 -2
  16. janito/agent/tool_executor.py +54 -49
  17. janito/agent/tool_registry.py +5 -2
  18. janito/agent/tool_use_tracker.py +26 -5
  19. janito/agent/tools/__init__.py +6 -3
  20. janito/agent/tools/create_directory.py +3 -1
  21. janito/agent/tools/create_file.py +7 -1
  22. janito/agent/tools/fetch_url.py +40 -3
  23. janito/agent/tools/find_files.py +3 -1
  24. janito/agent/tools/get_file_outline/core.py +6 -7
  25. janito/agent/tools/get_file_outline/search_outline.py +3 -1
  26. janito/agent/tools/get_lines.py +7 -2
  27. janito/agent/tools/move_file.py +3 -1
  28. janito/agent/tools/present_choices.py +3 -1
  29. janito/agent/tools/python_command_runner.py +150 -0
  30. janito/agent/tools/python_file_runner.py +148 -0
  31. janito/agent/tools/python_stdin_runner.py +154 -0
  32. janito/agent/tools/remove_directory.py +3 -1
  33. janito/agent/tools/remove_file.py +5 -1
  34. janito/agent/tools/replace_file.py +12 -2
  35. janito/agent/tools/replace_text_in_file.py +4 -2
  36. janito/agent/tools/run_bash_command.py +30 -69
  37. janito/agent/tools/run_powershell_command.py +134 -105
  38. janito/agent/tools/search_text.py +172 -122
  39. janito/agent/tools/validate_file_syntax/core.py +3 -1
  40. janito/agent/tools_utils/action_type.py +7 -0
  41. janito/agent/tools_utils/dir_walk_utils.py +3 -2
  42. janito/agent/tools_utils/formatting.py +47 -21
  43. janito/agent/tools_utils/gitignore_utils.py +66 -40
  44. janito/agent/tools_utils/test_gitignore_utils.py +46 -0
  45. janito/cli/_print_config.py +63 -61
  46. janito/cli/arg_parser.py +13 -12
  47. janito/cli/cli_main.py +137 -147
  48. janito/cli/main.py +152 -174
  49. janito/cli/one_shot.py +40 -26
  50. janito/i18n/__init__.py +1 -1
  51. janito/rich_utils.py +46 -8
  52. janito/shell/commands/__init__.py +2 -4
  53. janito/shell/commands/conversation_restart.py +3 -1
  54. janito/shell/commands/edit.py +3 -0
  55. janito/shell/commands/history_view.py +3 -3
  56. janito/shell/commands/lang.py +3 -0
  57. janito/shell/commands/livelogs.py +5 -3
  58. janito/shell/commands/prompt.py +6 -0
  59. janito/shell/commands/session.py +3 -0
  60. janito/shell/commands/session_control.py +3 -0
  61. janito/shell/commands/termweb_log.py +8 -0
  62. janito/shell/commands/tools.py +3 -0
  63. janito/shell/commands/track.py +36 -0
  64. janito/shell/commands/utility.py +13 -18
  65. janito/shell/commands/verbose.py +3 -4
  66. janito/shell/input_history.py +62 -0
  67. janito/shell/main.py +117 -181
  68. janito/shell/session/manager.py +0 -21
  69. janito/shell/ui/interactive.py +0 -2
  70. janito/termweb/static/editor.css +0 -4
  71. janito/tests/test_rich_utils.py +44 -0
  72. janito/web/app.py +0 -75
  73. {janito-1.9.0.dist-info → janito-1.10.0.dist-info}/METADATA +61 -42
  74. {janito-1.9.0.dist-info → janito-1.10.0.dist-info}/RECORD +78 -71
  75. {janito-1.9.0.dist-info → janito-1.10.0.dist-info}/WHEEL +1 -1
  76. janito/agent/providers.py +0 -77
  77. janito/agent/tools/run_python_command.py +0 -161
  78. janito/shell/commands/sum.py +0 -49
  79. {janito-1.9.0.dist-info → janito-1.10.0.dist-info}/entry_points.txt +0 -0
  80. {janito-1.9.0.dist-info → janito-1.10.0.dist-info}/licenses/LICENSE +0 -0
  81. {janito-1.9.0.dist-info → janito-1.10.0.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,7 @@
1
1
  import os
2
- from janito.rich_utils import print_info, print_warning, print_magenta
2
+ from janito.rich_utils import RichPrinter
3
+
4
+ _rich_printer = RichPrinter()
3
5
  from ._utils import home_shorten
4
6
 
5
7
 
@@ -7,17 +9,65 @@ def print_config_items(items, color_label=None):
7
9
  if not items:
8
10
  return
9
11
  if color_label:
10
- print_info(color_label)
12
+ _rich_printer.print_info(color_label)
11
13
  home = os.path.expanduser("~")
12
14
  for key, value in items.items():
13
15
  if key == "system_prompt_template" and isinstance(value, str):
14
16
  if value.startswith(home):
15
17
  print(f"{key} = {home_shorten(value)}")
16
18
  else:
17
- print_info(f"{key} = {value}")
19
+ _rich_printer.print_info(f"{key} = {value}")
20
+ else:
21
+ _rich_printer.print_info(f"{key} = {value}")
22
+ _rich_printer.print_info("")
23
+
24
+
25
+ def _mask_api_key(value):
26
+ if value and len(value) > 8:
27
+ return value[:4] + "..." + value[-4:]
28
+ elif value:
29
+ return "***"
30
+ return None
31
+
32
+
33
+ def _collect_config_items(config, unified_config, keys):
34
+ items = {}
35
+ for key in sorted(keys):
36
+ if key == "api_key":
37
+ value = config.get("api_key")
38
+ value = _mask_api_key(value)
18
39
  else:
19
- print_info(f"{key} = {value}")
20
- print_info("")
40
+ value = unified_config.get(key)
41
+ items[key] = value
42
+ return items
43
+
44
+
45
+ def _print_defaults(config_defaults, shown_keys):
46
+ default_items = {
47
+ k: v
48
+ for k, v in config_defaults.items()
49
+ if k not in shown_keys and k != "api_key"
50
+ }
51
+ if default_items:
52
+ _rich_printer.print_magenta(
53
+ "[green]\U0001f7e2 Defaults (not set in config files)[/green]"
54
+ )
55
+ from pathlib import Path
56
+
57
+ template_path = (
58
+ Path(__file__).parent
59
+ / "agent"
60
+ / "templates"
61
+ / "system_prompt_template_default.j2"
62
+ )
63
+ for key, value in default_items.items():
64
+ if key == "system_prompt_template" and value is None:
65
+ _rich_printer.print_info(
66
+ f"{key} = (default template path: {home_shorten(str(template_path))})"
67
+ )
68
+ else:
69
+ _rich_printer.print_info(f"{key} = {value}")
70
+ _rich_printer.print_info("")
21
71
 
22
72
 
23
73
  def print_full_config(
@@ -27,68 +77,20 @@ def print_full_config(
27
77
  Print local, global, and default config values in a unified way.
28
78
  Handles masking API keys and showing the template file for system_prompt_template if not set.
29
79
  """
30
- local_items = {}
31
- global_items = {}
32
80
  local_keys = set(local_config.all().keys())
33
81
  global_keys = set(global_config.all().keys())
34
82
  if not (local_keys or global_keys):
35
- print_warning("No configuration found.")
83
+ _rich_printer.print_warning("No configuration found.")
36
84
  else:
37
- for key in sorted(local_keys):
38
- if key == "api_key":
39
- value = local_config.get("api_key")
40
- value = (
41
- value[:4] + "..." + value[-4:]
42
- if value and len(value) > 8
43
- else ("***" if value else None)
44
- )
45
- else:
46
- value = unified_config.get(key)
47
- local_items[key] = value
48
- for key in sorted(global_keys - local_keys):
49
- if key == "api_key":
50
- value = global_config.get("api_key")
51
- value = (
52
- value[:4] + "..." + value[-4:]
53
- if value and len(value) > 8
54
- else ("***" if value else None)
55
- )
56
- else:
57
- value = unified_config.get(key)
58
- global_items[key] = value
59
- # Mask API key
60
- for cfg in (local_items, global_items):
61
- if "api_key" in cfg and cfg["api_key"]:
62
- val = cfg["api_key"]
63
- cfg["api_key"] = val[:4] + "..." + val[-4:] if len(val) > 8 else "***"
85
+ local_items = _collect_config_items(local_config, unified_config, local_keys)
86
+ global_items = _collect_config_items(
87
+ global_config, unified_config, global_keys - local_keys
88
+ )
64
89
  print_config_items(
65
- local_items, color_label="[cyan]🏠 Local Configuration[/cyan]"
90
+ local_items, color_label="[cyan]\U0001f3e0 Local Configuration[/cyan]"
66
91
  )
67
92
  print_config_items(
68
- global_items, color_label="[yellow]🌐 Global Configuration[/yellow]"
93
+ global_items, color_label="[yellow]\U0001f310 Global Configuration[/yellow]"
69
94
  )
70
- # Show defaults for unset keys
71
95
  shown_keys = set(local_items.keys()) | set(global_items.keys())
72
- default_items = {
73
- k: v
74
- for k, v in config_defaults.items()
75
- if k not in shown_keys and k != "api_key"
76
- }
77
- if default_items:
78
- print_magenta("[green]🟢 Defaults (not set in config files)[/green]")
79
- from pathlib import Path
80
-
81
- template_path = (
82
- Path(__file__).parent
83
- / "agent"
84
- / "templates"
85
- / "system_prompt_template_default.j2"
86
- )
87
- for key, value in default_items.items():
88
- if key == "system_prompt_template" and value is None:
89
- print_info(
90
- f"{key} = (default template path: {home_shorten(str(template_path))})"
91
- )
92
- else:
93
- print_info(f"{key} = {value}")
94
- print_info("")
96
+ _print_defaults(config_defaults, shown_keys)
janito/cli/arg_parser.py CHANGED
@@ -34,7 +34,7 @@ def create_parser():
34
34
  "--set-provider-config",
35
35
  nargs=3,
36
36
  metavar=("NAME", "KEY", "VALUE"),
37
- help="Set a provider config parameter (e.g., --set-provider-config openrouter.ai api_key sk-xxx).",
37
+ help="Set a provider config parameter (e.g., --set-provider-config openai api_key sk-xxx).",
38
38
  )
39
39
  parser.add_argument(
40
40
  "--lang",
@@ -52,7 +52,7 @@ def create_parser():
52
52
  "--max-tokens",
53
53
  type=int,
54
54
  default=None,
55
- help="Maximum tokens for model response (overrides config, default: 200000)",
55
+ help="Maximum tokens for model response (overrides config, default: 32000)",
56
56
  )
57
57
  parser.add_argument(
58
58
  "--max-tools",
@@ -212,6 +212,11 @@ def create_parser():
212
212
  action="store_true",
213
213
  help="Print all agent events before dispatching to the message handler (for debugging)",
214
214
  )
215
+ parser.add_argument(
216
+ "--verbose-messages",
217
+ action="store_true",
218
+ help="Print every new message added to the conversation history with a colored background.",
219
+ )
215
220
  parser.add_argument(
216
221
  "-V",
217
222
  "--vanilla",
@@ -231,16 +236,6 @@ def create_parser():
231
236
  default=None,
232
237
  help="Agent Profile name (only 'base' is supported)",
233
238
  )
234
- parser.add_argument(
235
- "--stream",
236
- action="store_true",
237
- help="Enable OpenAI streaming mode (yields tokens as they arrive)",
238
- )
239
- parser.add_argument(
240
- "--verbose-stream",
241
- action="store_true",
242
- help="Print raw chunks as they are fetched from OpenAI (for debugging)",
243
- )
244
239
  parser.add_argument(
245
240
  "--no-termweb",
246
241
  action="store_true",
@@ -263,4 +258,10 @@ def create_parser():
263
258
  action="store_true",
264
259
  help="Disable tool call reason tracking (no tools tracking)",
265
260
  )
261
+ parser.add_argument(
262
+ "--tool-user",
263
+ action="store_true",
264
+ default=False,
265
+ help="When set, tool responses will use role 'user' instead of 'tool' in the conversation history.",
266
+ )
266
267
  return parser
janito/cli/cli_main.py CHANGED
@@ -1,4 +1,5 @@
1
1
  import sys
2
+ from janito.agent.llm_conversation_history import LLMConversationHistory
2
3
  import socket
3
4
  from janito.agent.profile_manager import AgentProfileManager
4
5
  from janito.agent.runtime_config import unified_config, runtime_config
@@ -17,19 +18,11 @@ def is_port_free(port):
17
18
  return s.connect_ex(("localhost", port)) != 0
18
19
 
19
20
 
20
- def run_cli(args):
21
- if args.version:
22
- print(f"janito version {__version__}")
23
- sys.exit(0)
24
-
25
- # Set vanilla mode if -V/--vanilla is passed
21
+ def normalize_args(args):
26
22
  if getattr(args, "vanilla", False):
27
23
  runtime_config.set("vanilla_mode", True)
28
-
29
- # Set no_tools_tracking if --ntt is passed
30
24
  if getattr(args, "ntt", False):
31
25
  runtime_config.set("no_tools_tracking", True)
32
- # Normalize all verbose flags into runtime_config
33
26
  for flag in [
34
27
  "verbose_http",
35
28
  "verbose_http_raw",
@@ -37,58 +30,49 @@ def run_cli(args):
37
30
  "verbose_reason",
38
31
  "verbose_tools",
39
32
  "verbose_events",
40
- "verbose_stream",
33
+ "verbose_messages",
41
34
  ]:
42
35
  if hasattr(args, flag):
43
36
  runtime_config.set(flag, getattr(args, flag, False))
44
-
45
- role = args.role or unified_config.get("role", "software engineer")
46
- if args.role:
47
- runtime_config.set("role", args.role)
37
+ if getattr(args, "trust_tools", False):
38
+ runtime_config.set("trust_tools", True)
48
39
  if getattr(args, "model", None):
49
40
  runtime_config.set("model", args.model)
50
41
  if getattr(args, "max_tools", None) is not None:
51
42
  runtime_config.set("max_tools", args.max_tools)
52
- if getattr(args, "trust_tools", False):
53
- runtime_config.set("trust_tools", True)
54
- if not getattr(args, "prompt", None):
55
- interaction_mode = "chat"
56
- else:
57
- interaction_mode = "prompt"
58
- profile = "base"
59
- # PATCH: Pass lang from args or runtime_config to AgentProfileManager
60
- lang = getattr(args, "lang", None) or runtime_config.get("lang", "en")
61
- profile_manager = AgentProfileManager(
43
+ if getattr(args, "verbose_reason", False):
44
+ runtime_config.set("verbose_reason", True)
45
+ if getattr(args, "max_tokens", None) is not None:
46
+ runtime_config.set("max_tokens", args.max_tokens)
47
+
48
+
49
+ def setup_profile_manager(args, role, interaction_mode, profile, lang):
50
+ return AgentProfileManager(
62
51
  api_key=get_api_key(),
63
52
  model=unified_config.get("model"),
64
53
  role=role,
65
54
  profile_name=profile,
66
55
  interaction_mode=interaction_mode,
67
56
  verbose_tools=args.verbose_tools,
68
- base_url=unified_config.get("base_url", "https://openrouter.ai/api/v1"),
57
+ base_url=unified_config.get("base_url", ""),
69
58
  azure_openai_api_version=unified_config.get(
70
59
  "azure_openai_api_version", "2023-05-15"
71
60
  ),
72
61
  use_azure_openai=unified_config.get("use_azure_openai", False),
73
62
  lang=lang,
74
63
  )
75
- profile_manager.refresh_prompt()
76
- if getattr(args, "show_system", False):
77
- print(profile_manager.render_prompt())
78
- sys.exit(0)
79
- if args.max_tokens is not None:
80
- runtime_config.set("max_tokens", args.max_tokens)
81
- if getattr(args, "verbose_reason", False):
82
- runtime_config.set("verbose_reason", True)
83
64
 
84
- # --- termweb integration ---
65
+
66
+ def handle_termweb(args, interaction_mode):
85
67
  termweb_proc = None
86
68
  selected_port = None
69
+ termweb_stdout_path = None
70
+ termweb_stderr_path = None
87
71
  if (
88
72
  not getattr(args, "no_termweb", False)
89
73
  and interaction_mode == "chat"
90
74
  and not runtime_config.get("vanilla_mode", False)
91
- and not getattr(args, "input_arg", None) # Prevent termweb in one-shot mode
75
+ and not getattr(args, "input_arg", None)
92
76
  ):
93
77
  default_port = 8088
94
78
  max_port = 8100
@@ -122,54 +106,131 @@ def run_cli(args):
122
106
  termweb_proc, started, termweb_stdout_path, termweb_stderr_path = start_termweb(
123
107
  selected_port
124
108
  )
125
- # Store last running port in .janito/config.json if started
126
109
  if started:
127
110
  from janito.agent.config import local_config
128
111
 
129
112
  local_config.set("termweb_last_running_port", selected_port)
130
113
  local_config.save()
114
+ return termweb_proc, termweb_stdout_path, termweb_stderr_path
115
+
116
+
117
+ def handle_continue_session(args):
118
+ continue_session = False
119
+ session_id = None
120
+ if getattr(args, "input_arg", None) or getattr(args, "continue_session", False):
121
+ _cont = getattr(args, "continue_session", False)
122
+ if _cont:
123
+ continue_session = True
124
+ session_id = getattr(args, "input_arg", None)
125
+ if session_id is None:
126
+ import os
127
+ import glob
128
+
129
+ chat_hist_dir = (
130
+ os.path.join(os.path.expanduser("~"), ".janito", "chat_history")
131
+ if not os.path.isabs(".janito")
132
+ else os.path.join(".janito", "chat_history")
133
+ )
134
+ if not os.path.exists(chat_hist_dir):
135
+ session_id = None
136
+ else:
137
+ files = glob.glob(os.path.join(chat_hist_dir, "*.json"))
138
+ if files:
139
+ latest = max(files, key=os.path.getmtime)
140
+ session_id = os.path.splitext(os.path.basename(latest))[0]
141
+ else:
142
+ session_id = None
143
+ else:
144
+ continue_session = False
145
+ session_id = None
146
+ return continue_session, session_id
147
+
148
+
149
+ def handle_prompt_mode(args, profile_manager):
150
+ prompt = getattr(args, "input_arg", None)
151
+ from rich.console import Console
152
+ from janito.agent.rich_message_handler import RichMessageHandler
153
+
154
+ console = Console()
155
+ message_handler = RichMessageHandler()
156
+ messages = []
157
+ system_prompt_override = runtime_config.get("system_prompt_template")
158
+ if system_prompt_override:
159
+ if not runtime_config.get("vanilla_mode", False) or getattr(
160
+ args, "system", None
161
+ ):
162
+ messages.append({"role": "system", "content": system_prompt_override})
163
+ elif profile_manager.system_prompt_template and not runtime_config.get(
164
+ "vanilla_mode", False
165
+ ):
166
+ messages.append(
167
+ {"role": "system", "content": profile_manager.system_prompt_template}
168
+ )
169
+ messages.append({"role": "user", "content": prompt})
170
+ import time
171
+
172
+ info_start_time = None
173
+ if getattr(args, "info", False):
174
+ info_start_time = time.time()
175
+ try:
176
+ max_rounds = 100
177
+ result = profile_manager.agent.chat(
178
+ LLMConversationHistory(messages),
179
+ message_handler=message_handler,
180
+ spinner=True,
181
+ max_rounds=max_rounds,
182
+ tool_user=getattr(args, "tool_user", False),
183
+ )
184
+ if (
185
+ getattr(args, "info", False)
186
+ and info_start_time is not None
187
+ and result is not None
188
+ ):
189
+ usage_info = result.get("usage")
190
+ total_tokens = usage_info.get("total_tokens") if usage_info else None
191
+ prompt_tokens = usage_info.get("prompt_tokens") if usage_info else None
192
+ completion_tokens = (
193
+ usage_info.get("completion_tokens") if usage_info else None
194
+ )
195
+ elapsed = time.time() - info_start_time
196
+ console.print(
197
+ f"[bold green]Total tokens:[/] [yellow]{total_tokens}[/yellow] [bold green]| Input:[/] [cyan]{prompt_tokens}[/cyan] [bold green]| Output:[/] [magenta]{completion_tokens}[/magenta] [bold green]| Elapsed:[/] [yellow]{elapsed:.2f}s[/yellow]",
198
+ style="dim",
199
+ )
200
+ except MaxRoundsExceededError:
201
+ console.print("[red]Max conversation rounds exceeded.[/red]")
202
+ except ProviderError as e:
203
+ console.print(f"[red]Provider error:[/red] {e}")
204
+ except EmptyResponseError as e:
205
+ console.print(f"[red]Error:[/red] {e}")
206
+
131
207
 
132
- # --- End termweb integration ---
208
+ def run_cli(args):
209
+ if args.version:
210
+ print(f"janito version {__version__}")
211
+ sys.exit(0)
212
+ normalize_args(args)
213
+ role = args.role or unified_config.get("role", "software engineer")
214
+ if args.role:
215
+ runtime_config.set("role", args.role)
216
+ interaction_mode = "chat" if not getattr(args, "prompt", None) else "prompt"
217
+ profile = "base"
218
+ lang = getattr(args, "lang", None) or runtime_config.get("lang", "en")
219
+ profile_manager = setup_profile_manager(args, role, interaction_mode, profile, lang)
220
+ profile_manager.refresh_prompt()
221
+ if getattr(args, "show_system", False):
222
+ print(profile_manager.render_prompt())
223
+ sys.exit(0)
224
+ termweb_proc, termweb_stdout_path, termweb_stderr_path = handle_termweb(
225
+ args, interaction_mode
226
+ )
133
227
  try:
134
- livereload_stdout_path = None
135
- livereload_stderr_path = None
136
- continue_session = False
137
- session_id = None
228
+ continue_session, session_id = handle_continue_session(args)
138
229
  if getattr(args, "input_arg", None):
139
230
  from janito.cli.one_shot import run_oneshot_mode
140
231
 
141
232
  run_oneshot_mode(args, profile_manager, runtime_config)
142
233
  return
143
- if not getattr(args, "input_arg", None) or getattr(
144
- args, "continue_session", False
145
- ):
146
- # Determine continue_session and session_id
147
- _cont = getattr(args, "continue_session", False)
148
- if _cont:
149
- continue_session = True
150
- session_id = getattr(args, "input_arg", None)
151
- if session_id is None:
152
- # Find the most recent session id from .janito/chat_history/*.json
153
- import os
154
- import glob
155
-
156
- chat_hist_dir = (
157
- os.path.join(os.path.expanduser("~"), ".janito", "chat_history")
158
- if not os.path.isabs(".janito")
159
- else os.path.join(".janito", "chat_history")
160
- )
161
- if not os.path.exists(chat_hist_dir):
162
- session_id = None
163
- else:
164
- files = glob.glob(os.path.join(chat_hist_dir, "*.json"))
165
- if files:
166
- latest = max(files, key=os.path.getmtime)
167
- session_id = os.path.splitext(os.path.basename(latest))[0]
168
- else:
169
- session_id = None
170
- else:
171
- continue_session = False
172
- session_id = None
173
234
  import time
174
235
 
175
236
  info_start_time = None
@@ -179,18 +240,10 @@ def run_cli(args):
179
240
  profile_manager,
180
241
  continue_session=continue_session,
181
242
  session_id=session_id,
182
- termweb_stdout_path=(
183
- termweb_stdout_path if "termweb_stdout_path" in locals() else None
184
- ),
185
- termweb_stderr_path=(
186
- termweb_stderr_path if "termweb_stderr_path" in locals() else None
187
- ),
188
- livereload_stdout_path=(
189
- livereload_stdout_path if "livereload_stdout_path" in locals() else None
190
- ),
191
- livereload_stderr_path=(
192
- livereload_stderr_path if "livereload_stderr_path" in locals() else None
193
- ),
243
+ termweb_stdout_path=termweb_stdout_path,
244
+ termweb_stderr_path=termweb_stderr_path,
245
+ livereload_stdout_path=None,
246
+ livereload_stderr_path=None,
194
247
  )
195
248
  if (
196
249
  getattr(args, "info", False)
@@ -200,75 +253,12 @@ def run_cli(args):
200
253
  elapsed = time.time() - info_start_time
201
254
  from rich.console import Console
202
255
 
203
- console = Console()
204
256
  total_tokens = usage_info.get("total_tokens")
257
+ console = Console()
205
258
  console.print(
206
259
  f"[bold green]Total tokens used:[/] [yellow]{total_tokens}[/yellow] [bold green]| Elapsed time:[/] [yellow]{elapsed:.2f}s[/yellow]"
207
260
  )
208
261
  sys.exit(0)
209
- # --- Prompt mode ---
210
- prompt = getattr(args, "input_arg", None)
211
- from rich.console import Console
212
- from janito.agent.rich_message_handler import RichMessageHandler
213
-
214
- console = Console()
215
- message_handler = RichMessageHandler()
216
- messages = []
217
- system_prompt_override = runtime_config.get("system_prompt_template")
218
- if system_prompt_override:
219
- # Só adiciona system prompt se NÃO for vanilla, ou se foi explicitamente passado via --system
220
- if not runtime_config.get("vanilla_mode", False) or getattr(
221
- args, "system", None
222
- ):
223
- messages.append({"role": "system", "content": system_prompt_override})
224
- elif profile_manager.system_prompt_template and not runtime_config.get(
225
- "vanilla_mode", False
226
- ):
227
- messages.append(
228
- {"role": "system", "content": profile_manager.system_prompt_template}
229
- )
230
- messages.append({"role": "user", "content": prompt})
231
- import time
232
-
233
- info_start_time = None
234
- if getattr(args, "info", False):
235
- info_start_time = time.time()
236
- try:
237
- max_rounds = 100
238
- from janito.agent.conversation_history import ConversationHistory
239
-
240
- result = profile_manager.agent.chat(
241
- ConversationHistory(messages),
242
- message_handler=message_handler,
243
- spinner=True,
244
- max_rounds=max_rounds,
245
- stream=getattr(args, "stream", False),
246
- )
247
- if (
248
- getattr(args, "info", False)
249
- and info_start_time is not None
250
- and result is not None
251
- ):
252
- usage_info = result.get("usage")
253
- total_tokens = usage_info.get("total_tokens") if usage_info else None
254
- prompt_tokens = usage_info.get("prompt_tokens") if usage_info else None
255
- completion_tokens = (
256
- usage_info.get("completion_tokens") if usage_info else None
257
- )
258
- elapsed = time.time() - info_start_time
259
- from rich.console import Console
260
-
261
- console = Console()
262
- console.print(
263
- f"[bold green]Total tokens:[/] [yellow]{total_tokens}[/yellow] [bold green]| Input:[/] [cyan]{prompt_tokens}[/cyan] [bold green]| Output:[/] [magenta]{completion_tokens}[/magenta] [bold green]| Elapsed:[/] [yellow]{elapsed:.2f}s[/yellow]",
264
- style="dim",
265
- )
266
- except MaxRoundsExceededError:
267
- console.print("[red]Max conversation rounds exceeded.[/red]")
268
- except ProviderError as e:
269
- console.print(f"[red]Provider error:[/red] {e}")
270
- except EmptyResponseError as e:
271
- console.print(f"[red]Error:[/red] {e}")
272
262
  except KeyboardInterrupt:
273
263
  from rich.console import Console
274
264