janito 1.14.3__py3-none-any.whl → 2.0.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 (282) hide show
  1. janito/__init__.py +6 -1
  2. janito/__main__.py +1 -1
  3. janito/agent/setup_agent.py +139 -0
  4. janito/agent/templates/profiles/{system_prompt_template_base.txt.j2 → system_prompt_template_main.txt.j2} +1 -1
  5. janito/cli/__init__.py +9 -0
  6. janito/cli/chat_mode/bindings.py +37 -0
  7. janito/cli/chat_mode/chat_entry.py +23 -0
  8. janito/cli/chat_mode/prompt_style.py +19 -0
  9. janito/cli/chat_mode/session.py +272 -0
  10. janito/{shell/prompt/completer.py → cli/chat_mode/shell/autocomplete.py} +7 -6
  11. janito/cli/chat_mode/shell/commands/__init__.py +55 -0
  12. janito/cli/chat_mode/shell/commands/base.py +9 -0
  13. janito/cli/chat_mode/shell/commands/clear.py +12 -0
  14. janito/{shell → cli/chat_mode/shell}/commands/conversation_restart.py +34 -30
  15. janito/cli/chat_mode/shell/commands/edit.py +25 -0
  16. janito/cli/chat_mode/shell/commands/help.py +16 -0
  17. janito/cli/chat_mode/shell/commands/history_view.py +93 -0
  18. janito/cli/chat_mode/shell/commands/lang.py +25 -0
  19. janito/cli/chat_mode/shell/commands/last.py +137 -0
  20. janito/cli/chat_mode/shell/commands/livelogs.py +49 -0
  21. janito/cli/chat_mode/shell/commands/multi.py +51 -0
  22. janito/cli/chat_mode/shell/commands/prompt.py +64 -0
  23. janito/cli/chat_mode/shell/commands/role.py +36 -0
  24. janito/cli/chat_mode/shell/commands/session.py +40 -0
  25. janito/{shell → cli/chat_mode/shell}/commands/session_control.py +2 -2
  26. janito/cli/chat_mode/shell/commands/termweb_log.py +92 -0
  27. janito/cli/chat_mode/shell/commands/tools.py +32 -0
  28. janito/{shell → cli/chat_mode/shell}/commands/utility.py +4 -7
  29. janito/{shell → cli/chat_mode/shell}/commands/verbose.py +5 -5
  30. janito/cli/chat_mode/shell/session/__init__.py +1 -0
  31. janito/{shell → cli/chat_mode/shell}/session/manager.py +9 -1
  32. janito/cli/chat_mode/toolbar.py +90 -0
  33. janito/cli/cli_commands/list_models.py +35 -0
  34. janito/cli/cli_commands/list_providers.py +9 -0
  35. janito/cli/cli_commands/list_tools.py +53 -0
  36. janito/cli/cli_commands/model_selection.py +50 -0
  37. janito/cli/cli_commands/model_utils.py +84 -0
  38. janito/cli/cli_commands/set_api_key.py +19 -0
  39. janito/cli/cli_commands/show_config.py +51 -0
  40. janito/cli/cli_commands/show_system_prompt.py +62 -0
  41. janito/cli/config.py +28 -0
  42. janito/cli/console.py +3 -0
  43. janito/cli/core/__init__.py +4 -0
  44. janito/cli/core/event_logger.py +59 -0
  45. janito/cli/core/getters.py +31 -0
  46. janito/cli/core/runner.py +141 -0
  47. janito/cli/core/setters.py +174 -0
  48. janito/cli/core/unsetters.py +54 -0
  49. janito/cli/main.py +8 -196
  50. janito/cli/main_cli.py +312 -0
  51. janito/cli/prompt_core.py +230 -0
  52. janito/cli/prompt_handler.py +6 -0
  53. janito/cli/rich_terminal_reporter.py +101 -0
  54. janito/cli/single_shot_mode/__init__.py +6 -0
  55. janito/cli/single_shot_mode/handler.py +137 -0
  56. janito/cli/termweb_starter.py +73 -24
  57. janito/cli/utils.py +25 -0
  58. janito/cli/verbose_output.py +196 -0
  59. janito/config.py +5 -0
  60. janito/config_manager.py +110 -0
  61. janito/conversation_history.py +30 -0
  62. janito/{agent/tools_utils/dir_walk_utils.py → dir_walk_utils.py} +3 -2
  63. janito/driver_events.py +98 -0
  64. janito/drivers/anthropic/driver.py +113 -0
  65. janito/drivers/azure_openai/driver.py +36 -0
  66. janito/drivers/driver_registry.py +33 -0
  67. janito/drivers/google_genai/driver.py +54 -0
  68. janito/drivers/google_genai/schema_generator.py +67 -0
  69. janito/drivers/mistralai/driver.py +41 -0
  70. janito/drivers/openai/driver.py +334 -0
  71. janito/event_bus/__init__.py +2 -0
  72. janito/event_bus/bus.py +68 -0
  73. janito/event_bus/event.py +15 -0
  74. janito/event_bus/handler.py +31 -0
  75. janito/event_bus/queue_bus.py +57 -0
  76. janito/exceptions.py +23 -0
  77. janito/formatting_token.py +54 -0
  78. janito/i18n/pt.py +1 -0
  79. janito/llm/__init__.py +5 -0
  80. janito/llm/agent.py +443 -0
  81. janito/llm/auth.py +62 -0
  82. janito/llm/driver.py +239 -0
  83. janito/llm/driver_config.py +34 -0
  84. janito/llm/driver_config_builder.py +34 -0
  85. janito/llm/driver_input.py +12 -0
  86. janito/llm/message_parts.py +60 -0
  87. janito/llm/model.py +38 -0
  88. janito/llm/provider.py +187 -0
  89. janito/perf_singleton.py +3 -0
  90. janito/performance_collector.py +167 -0
  91. janito/provider_config.py +98 -0
  92. janito/provider_registry.py +152 -0
  93. janito/providers/__init__.py +7 -0
  94. janito/providers/anthropic/model_info.py +22 -0
  95. janito/providers/anthropic/provider.py +65 -0
  96. janito/providers/azure_openai/model_info.py +15 -0
  97. janito/providers/azure_openai/provider.py +72 -0
  98. janito/providers/deepseek/__init__.py +1 -0
  99. janito/providers/deepseek/model_info.py +16 -0
  100. janito/providers/deepseek/provider.py +91 -0
  101. janito/providers/google/__init__.py +1 -0
  102. janito/providers/google/model_info.py +40 -0
  103. janito/providers/google/provider.py +69 -0
  104. janito/providers/mistralai/model_info.py +37 -0
  105. janito/providers/mistralai/provider.py +69 -0
  106. janito/providers/openai/__init__.py +1 -0
  107. janito/providers/openai/model_info.py +137 -0
  108. janito/providers/openai/provider.py +107 -0
  109. janito/providers/openai/schema_generator.py +63 -0
  110. janito/providers/provider_static_info.py +21 -0
  111. janito/providers/registry.py +26 -0
  112. janito/report_events.py +38 -0
  113. janito/termweb/app.py +1 -1
  114. janito/tools/__init__.py +16 -0
  115. janito/tools/adapters/__init__.py +1 -0
  116. janito/tools/adapters/local/__init__.py +54 -0
  117. janito/tools/adapters/local/adapter.py +92 -0
  118. janito/{agent/tools → tools/adapters/local}/ask_user.py +30 -13
  119. janito/tools/adapters/local/copy_file.py +84 -0
  120. janito/{agent/tools → tools/adapters/local}/create_directory.py +11 -10
  121. janito/tools/adapters/local/create_file.py +82 -0
  122. janito/tools/adapters/local/delete_text_in_file.py +136 -0
  123. janito/{agent/tools → tools/adapters/local}/fetch_url.py +18 -19
  124. janito/tools/adapters/local/find_files.py +140 -0
  125. janito/tools/adapters/local/get_file_outline/core.py +151 -0
  126. janito/{agent/tools → tools/adapters/local}/get_file_outline/python_outline.py +125 -0
  127. janito/tools/adapters/local/get_file_outline/python_outline_v2.py +156 -0
  128. janito/{agent/tools → tools/adapters/local}/get_file_outline/search_outline.py +12 -7
  129. janito/{agent/tools → tools/adapters/local}/move_file.py +13 -9
  130. janito/{agent/tools → tools/adapters/local}/open_url.py +7 -5
  131. janito/tools/adapters/local/python_code_run.py +165 -0
  132. janito/tools/adapters/local/python_command_run.py +163 -0
  133. janito/tools/adapters/local/python_file_run.py +162 -0
  134. janito/{agent/tools → tools/adapters/local}/remove_directory.py +15 -9
  135. janito/{agent/tools → tools/adapters/local}/remove_file.py +17 -14
  136. janito/{agent/tools → tools/adapters/local}/replace_text_in_file.py +27 -22
  137. janito/tools/adapters/local/run_bash_command.py +176 -0
  138. janito/tools/adapters/local/run_powershell_command.py +219 -0
  139. janito/{agent/tools → tools/adapters/local}/search_text/core.py +32 -12
  140. janito/{agent/tools → tools/adapters/local}/search_text/match_lines.py +13 -4
  141. janito/{agent/tools → tools/adapters/local}/search_text/pattern_utils.py +12 -4
  142. janito/{agent/tools → tools/adapters/local}/search_text/traverse_directory.py +15 -2
  143. janito/{agent/tools → tools/adapters/local}/validate_file_syntax/core.py +12 -11
  144. janito/{agent/tools → tools/adapters/local}/validate_file_syntax/css_validator.py +1 -1
  145. janito/{agent/tools → tools/adapters/local}/validate_file_syntax/html_validator.py +1 -1
  146. janito/{agent/tools → tools/adapters/local}/validate_file_syntax/js_validator.py +1 -1
  147. janito/{agent/tools → tools/adapters/local}/validate_file_syntax/json_validator.py +1 -1
  148. janito/{agent/tools → tools/adapters/local}/validate_file_syntax/markdown_validator.py +1 -1
  149. janito/{agent/tools → tools/adapters/local}/validate_file_syntax/ps1_validator.py +1 -1
  150. janito/{agent/tools → tools/adapters/local}/validate_file_syntax/python_validator.py +1 -1
  151. janito/{agent/tools → tools/adapters/local}/validate_file_syntax/xml_validator.py +1 -1
  152. janito/{agent/tools → tools/adapters/local}/validate_file_syntax/yaml_validator.py +1 -1
  153. janito/{agent/tools/get_lines.py → tools/adapters/local/view_file.py} +45 -27
  154. janito/tools/inspect_registry.py +17 -0
  155. janito/tools/tool_base.py +105 -0
  156. janito/tools/tool_events.py +58 -0
  157. janito/tools/tool_run_exception.py +12 -0
  158. janito/{agent → tools}/tool_use_tracker.py +2 -4
  159. janito/{agent/tools_utils/utils.py → tools/tool_utils.py} +18 -9
  160. janito/tools/tools_adapter.py +207 -0
  161. janito/tools/tools_schema.py +104 -0
  162. janito/utils.py +11 -0
  163. janito/version.py +4 -0
  164. janito-2.0.0.dist-info/METADATA +232 -0
  165. janito-2.0.0.dist-info/RECORD +180 -0
  166. janito/agent/__init__.py +0 -0
  167. janito/agent/api_exceptions.py +0 -4
  168. janito/agent/config.py +0 -147
  169. janito/agent/config_defaults.py +0 -12
  170. janito/agent/config_utils.py +0 -0
  171. janito/agent/content_handler.py +0 -0
  172. janito/agent/conversation.py +0 -238
  173. janito/agent/conversation_api.py +0 -306
  174. janito/agent/conversation_exceptions.py +0 -18
  175. janito/agent/conversation_tool_calls.py +0 -39
  176. janito/agent/conversation_ui.py +0 -17
  177. janito/agent/event.py +0 -24
  178. janito/agent/event_dispatcher.py +0 -24
  179. janito/agent/event_handler_protocol.py +0 -5
  180. janito/agent/event_system.py +0 -15
  181. janito/agent/llm_conversation_history.py +0 -82
  182. janito/agent/message_handler.py +0 -20
  183. janito/agent/message_handler_protocol.py +0 -5
  184. janito/agent/openai_client.py +0 -149
  185. janito/agent/openai_schema_generator.py +0 -187
  186. janito/agent/profile_manager.py +0 -96
  187. janito/agent/queued_message_handler.py +0 -50
  188. janito/agent/rich_live.py +0 -32
  189. janito/agent/rich_message_handler.py +0 -115
  190. janito/agent/runtime_config.py +0 -36
  191. janito/agent/test_handler_protocols.py +0 -47
  192. janito/agent/test_openai_schema_generator.py +0 -93
  193. janito/agent/tests/__init__.py +0 -1
  194. janito/agent/tool_base.py +0 -63
  195. janito/agent/tool_executor.py +0 -122
  196. janito/agent/tool_registry.py +0 -49
  197. janito/agent/tools/__init__.py +0 -47
  198. janito/agent/tools/create_file.py +0 -59
  199. janito/agent/tools/delete_text_in_file.py +0 -97
  200. janito/agent/tools/find_files.py +0 -106
  201. janito/agent/tools/get_file_outline/core.py +0 -81
  202. janito/agent/tools/present_choices.py +0 -64
  203. janito/agent/tools/python_command_runner.py +0 -201
  204. janito/agent/tools/python_file_runner.py +0 -199
  205. janito/agent/tools/python_stdin_runner.py +0 -208
  206. janito/agent/tools/replace_file.py +0 -72
  207. janito/agent/tools/run_bash_command.py +0 -218
  208. janito/agent/tools/run_powershell_command.py +0 -251
  209. janito/agent/tools_utils/__init__.py +0 -1
  210. janito/agent/tools_utils/action_type.py +0 -7
  211. janito/agent/tools_utils/test_gitignore_utils.py +0 -46
  212. janito/cli/_livereload_log_utils.py +0 -13
  213. janito/cli/_print_config.py +0 -96
  214. janito/cli/_termweb_log_utils.py +0 -17
  215. janito/cli/_utils.py +0 -9
  216. janito/cli/arg_parser.py +0 -272
  217. janito/cli/cli_main.py +0 -281
  218. janito/cli/config_commands.py +0 -211
  219. janito/cli/config_runner.py +0 -35
  220. janito/cli/formatting_runner.py +0 -12
  221. janito/cli/livereload_starter.py +0 -60
  222. janito/cli/logging_setup.py +0 -38
  223. janito/cli/one_shot.py +0 -80
  224. janito/livereload/app.py +0 -25
  225. janito/rich_utils.py +0 -59
  226. janito/shell/__init__.py +0 -0
  227. janito/shell/commands/__init__.py +0 -61
  228. janito/shell/commands/config.py +0 -22
  229. janito/shell/commands/edit.py +0 -24
  230. janito/shell/commands/history_view.py +0 -18
  231. janito/shell/commands/lang.py +0 -19
  232. janito/shell/commands/livelogs.py +0 -42
  233. janito/shell/commands/prompt.py +0 -62
  234. janito/shell/commands/termweb_log.py +0 -94
  235. janito/shell/commands/tools.py +0 -26
  236. janito/shell/commands/track.py +0 -36
  237. janito/shell/main.py +0 -326
  238. janito/shell/prompt/load_prompt.py +0 -57
  239. janito/shell/prompt/session_setup.py +0 -57
  240. janito/shell/session/config.py +0 -109
  241. janito/shell/session/history.py +0 -0
  242. janito/shell/ui/interactive.py +0 -226
  243. janito/termweb/static/editor.css +0 -158
  244. janito/termweb/static/editor.css.bak +0 -145
  245. janito/termweb/static/editor.html +0 -46
  246. janito/termweb/static/editor.html.bak +0 -46
  247. janito/termweb/static/editor.js +0 -265
  248. janito/termweb/static/editor.js.bak +0 -259
  249. janito/termweb/static/explorer.html.bak +0 -59
  250. janito/termweb/static/favicon.ico +0 -0
  251. janito/termweb/static/favicon.ico.bak +0 -0
  252. janito/termweb/static/index.html +0 -53
  253. janito/termweb/static/index.html.bak +0 -54
  254. janito/termweb/static/index.html.bak.bak +0 -175
  255. janito/termweb/static/landing.html.bak +0 -36
  256. janito/termweb/static/termicon.svg +0 -1
  257. janito/termweb/static/termweb.css +0 -214
  258. janito/termweb/static/termweb.css.bak +0 -237
  259. janito/termweb/static/termweb.js +0 -162
  260. janito/termweb/static/termweb.js.bak +0 -168
  261. janito/termweb/static/termweb.js.bak.bak +0 -157
  262. janito/termweb/static/termweb_quickopen.js +0 -135
  263. janito/termweb/static/termweb_quickopen.js.bak +0 -125
  264. janito/tests/test_rich_utils.py +0 -44
  265. janito/web/__init__.py +0 -0
  266. janito/web/__main__.py +0 -25
  267. janito/web/app.py +0 -145
  268. janito-1.14.3.dist-info/METADATA +0 -313
  269. janito-1.14.3.dist-info/RECORD +0 -162
  270. janito-1.14.3.dist-info/licenses/LICENSE +0 -21
  271. /janito/{shell → cli/chat_mode/shell}/input_history.py +0 -0
  272. /janito/{shell/commands/session.py → cli/chat_mode/shell/session/history.py} +0 -0
  273. /janito/{agent/tools_utils/formatting.py → formatting.py} +0 -0
  274. /janito/{agent/tools_utils/gitignore_utils.py → gitignore_utils.py} +0 -0
  275. /janito/{agent/platform_discovery.py → platform_discovery.py} +0 -0
  276. /janito/{agent/tools → tools/adapters/local}/get_file_outline/__init__.py +0 -0
  277. /janito/{agent/tools → tools/adapters/local}/get_file_outline/markdown_outline.py +0 -0
  278. /janito/{agent/tools → tools/adapters/local}/search_text/__init__.py +0 -0
  279. /janito/{agent/tools → tools/adapters/local}/validate_file_syntax/__init__.py +0 -0
  280. {janito-1.14.3.dist-info → janito-2.0.0.dist-info}/WHEEL +0 -0
  281. {janito-1.14.3.dist-info → janito-2.0.0.dist-info}/entry_points.txt +0 -0
  282. {janito-1.14.3.dist-info → janito-2.0.0.dist-info}/top_level.txt +0 -0
@@ -1,10 +1,14 @@
1
1
  import os
2
+ from janito.cli.chat_mode.shell.session.manager import reset_session_id
3
+ from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
4
+ from janito.cli.console import shared_console
2
5
 
3
- from janito.shell.session.manager import reset_session_id
4
6
 
5
-
6
- def handle_restart(console, shell_state=None, **kwargs):
7
- from janito.shell.session.manager import load_last_conversation, save_conversation
7
+ def handle_restart(shell_state=None):
8
+ from janito.cli.chat_mode.shell.session.manager import (
9
+ load_last_conversation,
10
+ save_conversation,
11
+ )
8
12
 
9
13
  reset_session_id()
10
14
  save_path = os.path.join(".janito", "last_conversation.json")
@@ -23,52 +27,52 @@ def handle_restart(console, shell_state=None, **kwargs):
23
27
  # Save to permanent chat history (let save_conversation pick session file)
24
28
  save_conversation(messages, prompts, usage)
25
29
  except Exception as e:
26
- console.print(
30
+ shared_console.print(
27
31
  f"[bold red]Failed to update previous conversation history:[/bold red] {e}"
28
32
  )
29
33
 
30
34
  # Clear the terminal screen
31
- console.clear()
35
+ shared_console.clear()
32
36
 
33
- # Reset conversation history using its clear method
34
- shell_state.conversation_history.clear()
37
+ # Reset conversation history using the agent's method
38
+ if hasattr(shell_state, "agent") and shell_state.agent:
39
+ shell_state.agent.reset_conversation_history()
35
40
 
36
41
  # Reset tool use tracker
37
42
  try:
38
- from janito.agent.tool_use_tracker import ToolUseTracker
43
+ from janito.tools.tool_use_tracker import ToolUseTracker
39
44
 
40
45
  ToolUseTracker.instance().clear_history()
41
46
  except Exception as e:
42
- console.print(
47
+ shared_console.print(
43
48
  f"[bold yellow]Warning: Failed to reset tool use tracker:[/bold yellow] {e}"
44
49
  )
45
- # Set system prompt from agent template if available
46
- if (
47
- hasattr(shell_state, "profile_manager")
48
- and shell_state.profile_manager
49
- and hasattr(shell_state.profile_manager, "agent")
50
- and shell_state.profile_manager.agent
51
- and getattr(shell_state.profile_manager.agent, "system_prompt_template", None)
52
- and not any(
53
- m.get("role") == "system"
54
- for m in shell_state.conversation_history.get_messages()
55
- )
56
- ):
57
- shell_state.conversation_history.set_system_message(
58
- shell_state.profile_manager.agent.system_prompt_template
59
- )
60
50
 
61
51
  # Reset token usage info in-place so all references (including status bar) are updated
62
52
  for k in ("prompt_tokens", "completion_tokens", "total_tokens"):
63
- if k in shell_state.last_usage_info:
64
- shell_state.last_usage_info[k] = 0
65
- else:
66
- shell_state.last_usage_info[k] = 0
53
+ shell_state.last_usage_info[k] = 0
67
54
  shell_state.last_elapsed = None
68
55
 
69
- console.print(
56
+ # Reset the performance collector's last usage (so toolbar immediately reflects cleared stats)
57
+ try:
58
+ from janito.perf_singleton import performance_collector
59
+
60
+ performance_collector.reset_last_request_usage()
61
+ except Exception as e:
62
+ shared_console.print(
63
+ f"[bold yellow]Warning: Failed to reset PerformanceCollector token info:[/bold yellow] {e}"
64
+ )
65
+
66
+ shared_console.print(
70
67
  "[bold green]Conversation history has been started (context reset).[/bold green]"
71
68
  )
72
69
 
73
70
 
74
71
  handle_restart.help_text = "Start a new conversation (reset context)"
72
+
73
+
74
+ class RestartShellHandler(ShellCmdHandler):
75
+ help_text = "Start a new conversation (reset context)"
76
+
77
+ def run(self):
78
+ handle_restart(self.shell_state)
@@ -0,0 +1,25 @@
1
+ import os
2
+ import webbrowser
3
+ from janito.cli.console import shared_console
4
+ from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
5
+
6
+
7
+ class EditShellHandler(ShellCmdHandler):
8
+ help_text = "Open a file in the browser-based editor"
9
+
10
+ def run(self):
11
+ filename = self.after_cmd_line.strip()
12
+ if not filename:
13
+ shared_console.print("[red]Usage: /edit <filename>[/red]")
14
+ return
15
+ if not os.path.isfile(filename):
16
+ shared_console.print(f"[red]File not found:[/red] {filename}")
17
+ return
18
+ from janito.cli.config import get_termweb_port
19
+
20
+ port = get_termweb_port()
21
+ url = f"http://localhost:{port}/?path={filename}"
22
+ shared_console.print(
23
+ f"[green]Opening in browser:[/green] [underline blue]{url}[/underline blue]"
24
+ )
25
+ webbrowser.open(url)
@@ -0,0 +1,16 @@
1
+ from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
2
+ from janito.cli.console import shared_console
3
+
4
+
5
+ class HelpShellHandler(ShellCmdHandler):
6
+ help_text = "Show this help message"
7
+
8
+ def run(self):
9
+ from . import (
10
+ COMMAND_HANDLERS,
11
+ ) # Import moved inside method to avoid circular import
12
+
13
+ shared_console.print("[bold magenta]Available commands:[/bold magenta]")
14
+ for cmd, handler_cls in sorted(COMMAND_HANDLERS.items()):
15
+ help_text = getattr(handler_cls, "help_text", "")
16
+ shared_console.print(f"[cyan]{cmd}[/cyan]: {help_text}")
@@ -0,0 +1,93 @@
1
+ from janito.cli.console import shared_console
2
+ from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
3
+ import json
4
+
5
+ TRIM_LENGTH = 200 # Max chars to show for args or outputs before trimming
6
+
7
+
8
+ def trim_value(val, trim_length=TRIM_LENGTH):
9
+ s = (
10
+ json.dumps(val, ensure_ascii=False)
11
+ if isinstance(val, (dict, list))
12
+ else str(val)
13
+ )
14
+ if len(s) > trim_length:
15
+ return s[:trim_length] + "... [trimmed]"
16
+ return s
17
+
18
+
19
+ class ViewShellHandler(ShellCmdHandler):
20
+ help_text = "Print the current LLM conversation history"
21
+
22
+ def run(self):
23
+ if not hasattr(self.shell_state, "agent") or self.shell_state.agent is None:
24
+ shared_console.print("[red]No agent found in shell state.[/red]")
25
+ return
26
+ conversation_history = self.shell_state.agent.conversation_history
27
+ messages = conversation_history.get_history()
28
+ if not messages:
29
+ shared_console.print("[yellow]Conversation history is empty.[/yellow]")
30
+ return
31
+ for i, msg in enumerate(messages, 1):
32
+ self._print_message(i, msg)
33
+
34
+ def _print_message(self, i, msg):
35
+ role = msg.get("role", "?")
36
+ content = msg.get("content", "")
37
+ metadata = msg.get("metadata")
38
+ is_tool_result = (
39
+ role == "function"
40
+ and isinstance(metadata, dict)
41
+ and metadata.get("is_tool_result")
42
+ )
43
+ is_tool_call = (
44
+ role == "tool_call"
45
+ or (
46
+ isinstance(metadata, dict)
47
+ and (
48
+ metadata.get("type") == "tool_call" or metadata.get("is_tool_call")
49
+ )
50
+ )
51
+ ) and not is_tool_result
52
+ if is_tool_call:
53
+ self._print_tool_call(i, metadata, content)
54
+ elif is_tool_result:
55
+ self._print_tool_result(i, content)
56
+ else:
57
+ self._print_regular_message(i, role, content, metadata)
58
+
59
+ def _print_tool_call(self, i, metadata, content):
60
+ func_name = None
61
+ args = None
62
+ if isinstance(metadata, dict):
63
+ tool_call = metadata.get("tool_call")
64
+ if tool_call and isinstance(tool_call, dict):
65
+ func_name = (
66
+ tool_call.get("function") or tool_call.get("name") or "<unknown>"
67
+ )
68
+ args = tool_call.get("arguments") or tool_call.get("args") or {}
69
+ else:
70
+ func_name = metadata.get("name") or "<unknown>"
71
+ args = metadata.get("arguments") or metadata.get("args") or content
72
+ else:
73
+ func_name = "<unknown>"
74
+ args = content
75
+ trimmed_args = trim_value(args)
76
+ shared_console.print(
77
+ f"[bold]{i}. TOOL_CALL:[/bold] {func_name}({trimmed_args})"
78
+ )
79
+
80
+ def _print_tool_result(self, i, content):
81
+ trimmed_output = trim_value(content)
82
+ if "\n" in trimmed_output:
83
+ shared_console.print(f"[bold]{i}. TOOL_RESULT:[/bold]")
84
+ for line in trimmed_output.splitlines():
85
+ shared_console.print(line)
86
+ else:
87
+ shared_console.print(f"[bold]{i}. TOOL_RESULT:[/bold] {trimmed_output}")
88
+
89
+ def _print_regular_message(self, i, role, content, metadata):
90
+ trimmed_content = trim_value(content)
91
+ shared_console.print(f"[bold]{i}. {role}:[/bold] {trimmed_content}")
92
+ if metadata:
93
+ shared_console.print(f" [cyan]metadata:[/cyan] {metadata}")
@@ -0,0 +1,25 @@
1
+ from janito.cli.config import config
2
+ import janito.i18n as i18n
3
+
4
+
5
+ from janito.cli.config import config
6
+ import janito.i18n as i18n
7
+ from janito.cli.console import shared_console
8
+ from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
9
+
10
+
11
+ class LangShellHandler(ShellCmdHandler):
12
+ help_text = "Change the interface language (e.g., /lang en)"
13
+
14
+ def run(self):
15
+ lang_code = self.after_cmd_line.strip()
16
+ if not lang_code:
17
+ shared_console.print(
18
+ "[bold yellow]Uso: /lang [código_idioma] (ex: pt, en, es)[/bold yellow]"
19
+ )
20
+ return
21
+ config.runtime_set("lang", lang_code)
22
+ i18n.set_locale(lang_code)
23
+ shared_console.print(
24
+ f"[bold green]Idioma alterado para:[/bold green] [cyan]{lang_code}[/cyan]"
25
+ )
@@ -0,0 +1,137 @@
1
+ from janito.performance_collector import PerformanceCollector
2
+ from rich.tree import Tree
3
+ from rich.console import Console
4
+ from rich import print as rprint
5
+ import datetime
6
+
7
+ # TODO: Replace this with your actual collector instance retrieval
8
+ # For example, if you have a global or singleton:
9
+ # from janito.app_context import performance_collector as collector
10
+ from janito.perf_singleton import performance_collector as collector
11
+ from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
12
+ from janito.cli.console import shared_console
13
+
14
+
15
+ def _event_timestamp(event):
16
+ if hasattr(event, "timestamp"):
17
+ try:
18
+ ts = float(getattr(event, "timestamp", 0))
19
+ return f" [dim]{datetime.datetime.fromtimestamp(ts)}[/dim]"
20
+ except Exception:
21
+ return ""
22
+ return ""
23
+
24
+
25
+ def _event_tool_name(event):
26
+ return (
27
+ f" [cyan]{getattr(event, 'tool_name', '')}[/cyan]"
28
+ if hasattr(event, "tool_name")
29
+ else ""
30
+ )
31
+
32
+
33
+ def _event_params(event):
34
+ return (
35
+ f" Params: {getattr(event, 'params', '')}" if hasattr(event, "params") else ""
36
+ )
37
+
38
+
39
+ def _event_result(event):
40
+ return (
41
+ f" Result: {getattr(event, 'result', '')}" if hasattr(event, "result") else ""
42
+ )
43
+
44
+
45
+ def _event_error(event):
46
+ return (
47
+ f" [red]Error: {getattr(event, 'error')}[/red]"
48
+ if hasattr(event, "error") and getattr(event, "error", None)
49
+ else ""
50
+ )
51
+
52
+
53
+ def _event_message(event):
54
+ return (
55
+ f" [yellow]Message: {getattr(event, 'message')}[/yellow]"
56
+ if hasattr(event, "message")
57
+ else ""
58
+ )
59
+
60
+
61
+ def _event_subtype(event):
62
+ return (
63
+ f" [magenta]Subtype: {getattr(event, 'subtype')}[/magenta]"
64
+ if hasattr(event, "subtype")
65
+ else ""
66
+ )
67
+
68
+
69
+ def _event_status(event):
70
+ return (
71
+ f" [blue]Status: {getattr(event, 'status')}[/blue]"
72
+ if hasattr(event, "status")
73
+ else ""
74
+ )
75
+
76
+
77
+ def _event_duration(event):
78
+ return (
79
+ f" [green]Duration: {getattr(event, 'duration')}[/green]"
80
+ if hasattr(event, "duration")
81
+ else ""
82
+ )
83
+
84
+
85
+ def format_event(event_tuple, parent_tree=None):
86
+ event_type, event = event_tuple
87
+ desc = f"[bold]{event_type}[/bold]"
88
+ # Modular logic for each possible component
89
+ desc += _event_timestamp(event)
90
+ desc += _event_tool_name(event)
91
+ desc += _event_params(event)
92
+ desc += _event_result(event)
93
+ desc += _event_error(event)
94
+ desc += _event_message(event)
95
+ desc += _event_subtype(event)
96
+ desc += _event_status(event)
97
+ desc += _event_duration(event)
98
+ if parent_tree is not None:
99
+ node = parent_tree.add(desc)
100
+ else:
101
+ node = Tree(desc)
102
+ return node
103
+
104
+
105
+ def drill_down_last_generation():
106
+ events = collector.get_all_events()
107
+ # Find the last RequestStarted
108
+ last_gen_start = None
109
+ for i in range(len(events) - 1, -1, -1):
110
+ if events[i][0] == "RequestStarted":
111
+ last_gen_start = i
112
+ break
113
+ if last_gen_start is None:
114
+ rprint("[red]No generations found.[/red]")
115
+ return
116
+ # Find the next GenerationFinished after last_gen_start
117
+ for j in range(last_gen_start + 1, len(events)):
118
+ if events[j][0] == "GenerationFinished":
119
+ last_gen_end = j
120
+ break
121
+ else:
122
+ last_gen_end = len(events) - 1
123
+ gen_events = events[last_gen_start : last_gen_end + 1]
124
+ tree = Tree("[bold green]Last Generation Details[/bold green]")
125
+ for evt in gen_events:
126
+ format_event(evt, tree)
127
+ console = Console()
128
+ console.print(tree)
129
+
130
+
131
+ class LastShellHandler(ShellCmdHandler):
132
+ help_text = (
133
+ "Show details of the last generation, with drill-down of tool executions."
134
+ )
135
+
136
+ def run(self):
137
+ drill_down_last_generation()
@@ -0,0 +1,49 @@
1
+ from janito.cli.console import shared_console
2
+ from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
3
+
4
+
5
+ class LivelogsShellHandler(ShellCmdHandler):
6
+ help_text = "Show the last lines of livereload logs. Usage: /livelogs [lines]"
7
+
8
+ def run(self):
9
+ lines_arg = self.after_cmd_line.strip()
10
+ lines = 20
11
+ if lines_arg and lines_arg.isdigit():
12
+ lines = int(lines_arg)
13
+ stdout_path = self.shell_state.termweb_stdout_path if self.shell_state else None
14
+ stderr_path = (
15
+ self.shell_state.livereload_stderr_path if self.shell_state else None
16
+ )
17
+ if not stdout_path and not stderr_path:
18
+ shared_console.print(
19
+ "[yellow][livereload] No livereload log files found for this session.[/yellow]"
20
+ )
21
+ return
22
+ stdout_lines = []
23
+ stderr_lines = []
24
+ if stdout_path:
25
+ try:
26
+ with open(stdout_path, encoding="utf-8") as f:
27
+ stdout_lines = f.readlines()[-lines:]
28
+ if stdout_lines:
29
+ shared_console.print(
30
+ f"[yellow][livereload][stdout] Tail of {stdout_path}:\n"
31
+ + "".join(stdout_lines)
32
+ )
33
+ except Exception as e:
34
+ shared_console.print(f"[red][livereload][stdout] Error: {e}[/red]")
35
+ if stderr_path:
36
+ try:
37
+ with open(stderr_path, encoding="utf-8") as f:
38
+ stderr_lines = f.readlines()[-lines:]
39
+ if stderr_lines:
40
+ shared_console.print(
41
+ f"[red][livereload][stderr] Tail of {stderr_path}:\n"
42
+ + "".join(stderr_lines)
43
+ )
44
+ except Exception as e:
45
+ shared_console.print(f"[red][livereload][stderr] Error: {e}[/red]")
46
+ if (not stdout_path or not stdout_lines) and (
47
+ not stderr_path or not stderr_lines
48
+ ):
49
+ shared_console.print("[livereload] No output or errors captured in logs.")
@@ -0,0 +1,51 @@
1
+ from prompt_toolkit.shortcuts import prompt
2
+ from prompt_toolkit.application.current import get_app
3
+ from prompt_toolkit.document import Document
4
+ from prompt_toolkit.key_binding import KeyBindings
5
+ from janito.cli.console import shared_console
6
+ from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
7
+
8
+
9
+ class MultiShellHandler(ShellCmdHandler):
10
+ help_text = "Prompt for multi-line input and display the result. Usage: /multi"
11
+
12
+ def run(self):
13
+ shared_console.print(
14
+ "[bold blue]Entering multi-line input mode. Press Esc+Enter or Ctrl+D to submit, Ctrl+C to cancel.[/bold blue]"
15
+ )
16
+ # Prompt for multi-line input
17
+ bindings = KeyBindings()
18
+ submitted = {"value": None}
19
+
20
+ @bindings.add("escape", "enter")
21
+ def _(event):
22
+ buffer = event.app.current_buffer
23
+ submitted["value"] = buffer.text
24
+ event.app.exit(result=buffer.text)
25
+
26
+ # Support Ctrl+D
27
+ @bindings.add("c-d")
28
+ def _(event):
29
+ buffer = event.app.current_buffer
30
+ submitted["value"] = buffer.text
31
+ event.app.exit(result=buffer.text)
32
+
33
+ try:
34
+ user_input = prompt(
35
+ "Multi-line > ",
36
+ multiline=True,
37
+ key_bindings=bindings,
38
+ )
39
+ except (EOFError, KeyboardInterrupt):
40
+ shared_console.print("[red]Multi-line input cancelled.[/red]")
41
+ return
42
+
43
+ # Save input to history if available
44
+ user_input_history = getattr(self.shell_state, "user_input_history", None)
45
+ if user_input_history is not None:
46
+ user_input_history.append(user_input)
47
+ # Store input for main chat loop to consume as if just entered by the user
48
+ self.shell_state.injected_input = user_input
49
+ shared_console.print(
50
+ "[green]Multi-line input will be sent as your next chat prompt.[/green]"
51
+ )
@@ -0,0 +1,64 @@
1
+ from janito.cli.config import config
2
+ from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
3
+ from janito.cli.console import shared_console
4
+
5
+
6
+ class PromptShellHandler(ShellCmdHandler):
7
+ help_text = "Show the system prompt"
8
+
9
+ def run(self):
10
+ agent = getattr(self.shell_state, "agent", None)
11
+ if agent and hasattr(agent, "get_system_prompt"):
12
+ prompt = agent.get_system_prompt()
13
+ shared_console.print(
14
+ f"[bold magenta]System Prompt:[/bold magenta]\n{prompt}"
15
+ )
16
+ else:
17
+ shared_console.print(
18
+ "[bold red]No LLM agent available to fetch the system prompt.[/bold red]"
19
+ )
20
+
21
+
22
+ class RoleShellHandler(ShellCmdHandler):
23
+ help_text = "Change the system role"
24
+
25
+ def run(self):
26
+ new_role = self.after_cmd_line.strip()
27
+ if not new_role:
28
+ agent = getattr(self.shell_state, "agent", None)
29
+ if agent and hasattr(agent, "template_vars"):
30
+ current_role = agent.template_vars.get("role", None)
31
+ else:
32
+ current_role = None
33
+ if not current_role:
34
+ current_role = "<not set>"
35
+ shared_console.print(
36
+ f"[bold green]Current system role:[/bold green] {current_role}"
37
+ )
38
+ return
39
+
40
+ agent = getattr(self.shell_state, "agent", None)
41
+ if agent and hasattr(agent, "set_template_var"):
42
+ agent.set_template_var("role", new_role)
43
+ # Refresh the system prompt with the new role if possible
44
+ if (
45
+ hasattr(agent, "set_system_using_template")
46
+ and hasattr(agent, "_system_prompt_template_file")
47
+ and agent._system_prompt_template_file
48
+ ):
49
+ agent.set_system_using_template(
50
+ agent._system_prompt_template_file, **agent.template_vars
51
+ )
52
+ shared_console.print(
53
+ f"[bold green]System role updated to:[/bold green] {new_role}"
54
+ )
55
+
56
+
57
+ class ProfileShellHandler(ShellCmdHandler):
58
+ help_text = (
59
+ "Show the current and available Agent Profile (only 'base' is supported)"
60
+ )
61
+
62
+ def run(self):
63
+ shared_console.print("[bold green]Current profile:[/bold green] base")
64
+ shared_console.print("[bold yellow]Available profiles:[/bold yellow]\n- base")
@@ -0,0 +1,36 @@
1
+ from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
2
+
3
+
4
+ class RoleCommandShellHandler(ShellCmdHandler):
5
+ """Set or display the current role."""
6
+
7
+ def __init__(self, shell_state, handler):
8
+ super().__init__(shell_state, handler)
9
+ self.name = "role"
10
+ self.description = "Set or display the current role"
11
+ self.usage = "role [new_role]"
12
+
13
+ def execute(self, args):
14
+ if not args:
15
+ # Display current role
16
+ current_role = self.handler.agent.template_vars.get("role", "default")
17
+ return f"Current role: {current_role}"
18
+ else:
19
+ # Set new role
20
+ new_role = " ".join(args)
21
+ self.handler.agent.template_vars["role"] = new_role
22
+ # Refresh the system prompt with the new role if possible
23
+ if (
24
+ hasattr(self.handler.agent, "set_system_using_template")
25
+ and hasattr(self.handler.agent, "_system_prompt_template_file")
26
+ and self.handler.agent._system_prompt_template_file
27
+ ):
28
+ self.handler.agent.set_system_using_template(
29
+ self.handler.agent._system_prompt_template_file,
30
+ **self.handler.agent.template_vars,
31
+ )
32
+ return f"Role set to: {new_role}"
33
+
34
+ def get_completions(self, document, complete_event):
35
+ # No completions for this command
36
+ return []
@@ -0,0 +1,40 @@
1
+ from janito.cli.console import shared_console
2
+
3
+ from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
4
+ from janito.cli.console import shared_console
5
+
6
+
7
+ class HistoryShellHandler(ShellCmdHandler):
8
+ help_text = "Show input history for this session"
9
+
10
+ def run(self):
11
+ if self.shell_state and hasattr(self.shell_state, "mem_history"):
12
+ input_history = list(self.shell_state.mem_history.get_strings())
13
+ else:
14
+ input_history = []
15
+ args = self.after_cmd_line.strip().split()
16
+ if not args:
17
+ start = max(0, len(input_history) - 5)
18
+ end = len(input_history)
19
+ elif len(args) == 1:
20
+ count = int(args[0])
21
+ start = max(0, len(input_history) - count)
22
+ end = len(input_history)
23
+ elif len(args) >= 2:
24
+ start = int(args[0])
25
+ end = int(args[1]) + 1
26
+ else:
27
+ start = 0
28
+ end = len(input_history)
29
+ shared_console.print(
30
+ f"[bold cyan]Showing input history {start} to {end - 1} (total {len(input_history)}):[/bold cyan]"
31
+ )
32
+ for idx, line in enumerate(input_history[start:end], start=start):
33
+ shared_console.print(f"{idx}: {line}")
34
+ if isinstance(line, dict):
35
+ role = line.get("role", "unknown")
36
+ content = line.get("content", "")
37
+ else:
38
+ role = "user"
39
+ content = line
40
+ shared_console.print(f"[bold]{idx} [{role}]:[/bold] {content}")
@@ -6,7 +6,7 @@ import subprocess
6
6
  def restart_cli():
7
7
  # Clean up prompt_toolkit session if active
8
8
  try:
9
- from janito.shell import main
9
+ from janito.cli.chat_mode import chat_mode as main
10
10
 
11
11
  session = getattr(main, "active_prompt_session", None)
12
12
  if session is not None and hasattr(session, "app"):
@@ -37,7 +37,7 @@ def restart_cli():
37
37
  os.execv(sys.executable, [sys.executable, "-m", "janito"] + sys.argv[1:])
38
38
 
39
39
 
40
- def handle_exit(console, **kwargs):
40
+ def handle_exit(**kwargs):
41
41
  console.print("[bold red]Exiting chat mode.[/bold red]")
42
42
  sys.exit(0)
43
43