janito 2.1.0__tar.gz → 2.2.0__tar.gz

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 (196) hide show
  1. janito-2.2.0/LICENSE +21 -0
  2. {janito-2.1.0 → janito-2.2.0}/PKG-INFO +21 -2
  3. {janito-2.1.0 → janito-2.2.0}/janito/__init__.py +1 -1
  4. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/commands/__init__.py +0 -2
  5. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/input_history.py +2 -2
  6. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/toolbar.py +2 -1
  7. {janito-2.1.0 → janito-2.2.0}/janito/cli/config.py +1 -2
  8. {janito-2.1.0 → janito-2.2.0}/janito/cli/core/runner.py +148 -141
  9. {janito-2.1.0 → janito-2.2.0}/janito/cli/main_cli.py +8 -0
  10. janito-2.2.0/janito/drivers/azure_openai/driver.py +55 -0
  11. {janito-2.1.0 → janito-2.2.0}/janito/llm/provider.py +9 -0
  12. {janito-2.1.0 → janito-2.2.0}/janito/provider_registry.py +158 -152
  13. {janito-2.1.0 → janito-2.2.0}/janito/providers/azure_openai/provider.py +20 -0
  14. {janito-2.1.0 → janito-2.2.0}/janito/providers/deepseek/model_info.py +2 -2
  15. {janito-2.1.0 → janito-2.2.0}/janito/providers/deepseek/provider.py +1 -1
  16. {janito-2.1.0 → janito-2.2.0}/janito/providers/openai/model_info.py +0 -11
  17. {janito-2.1.0 → janito-2.2.0}/janito/providers/openai/provider.py +1 -1
  18. {janito-2.1.0 → janito-2.2.0}/janito/providers/registry.py +26 -26
  19. {janito-2.1.0 → janito-2.2.0}/janito/tools/__init__.py +6 -2
  20. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/__init__.py +62 -57
  21. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/adapter.py +5 -1
  22. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/ask_user.py +2 -15
  23. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/find_files.py +0 -2
  24. janito-2.2.0/janito/tools/adapters/local/get_file_outline/core.py +117 -0
  25. janito-2.2.0/janito/tools/adapters/local/get_file_outline/java_outline.py +40 -0
  26. janito-2.2.0/janito/tools/adapters/local/open_html_in_browser.py +38 -0
  27. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/open_url.py +3 -2
  28. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/python_code_run.py +1 -0
  29. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/python_command_run.py +1 -0
  30. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/python_file_run.py +1 -0
  31. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/remove_file.py +5 -5
  32. {janito-2.1.0 → janito-2.2.0}/janito/version.py +1 -1
  33. {janito-2.1.0 → janito-2.2.0}/janito.egg-info/PKG-INFO +21 -2
  34. {janito-2.1.0 → janito-2.2.0}/janito.egg-info/SOURCES.txt +9 -2
  35. janito-2.2.0/janito.egg-info/requires.txt +18 -0
  36. {janito-2.1.0 → janito-2.2.0}/pyproject.toml +9 -2
  37. janito-2.2.0/requirements-dev.txt +9 -0
  38. janito-2.2.0/requirements.txt +10 -0
  39. janito-2.2.0/tests/test_cli_list_models.py +26 -0
  40. janito-2.2.0/tests/test_cli_list_providers.py +22 -0
  41. janito-2.2.0/tests/test_cli_version.py +11 -0
  42. janito-2.1.0/janito/cli/chat_mode/shell/commands/last.py +0 -137
  43. janito-2.1.0/janito/drivers/azure_openai/driver.py +0 -36
  44. janito-2.1.0/janito/tools/adapters/local/get_file_outline/core.py +0 -151
  45. janito-2.1.0/janito/tools/adapters/local/open_html_in_browser.py +0 -43
  46. {janito-2.1.0 → janito-2.2.0}/README.md +0 -0
  47. {janito-2.1.0 → janito-2.2.0}/janito/__main__.py +0 -0
  48. {janito-2.1.0 → janito-2.2.0}/janito/agent/setup_agent.py +0 -0
  49. {janito-2.1.0 → janito-2.2.0}/janito/agent/templates/profiles/system_prompt_template_base_pt.txt.j2 +0 -0
  50. {janito-2.1.0 → janito-2.2.0}/janito/agent/templates/profiles/system_prompt_template_main.txt.j2 +0 -0
  51. {janito-2.1.0 → janito-2.2.0}/janito/cli/__init__.py +0 -0
  52. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/bindings.py +0 -0
  53. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/chat_entry.py +0 -0
  54. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/prompt_style.py +0 -0
  55. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/session.py +0 -0
  56. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/autocomplete.py +0 -0
  57. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/commands/base.py +0 -0
  58. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/commands/clear.py +0 -0
  59. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/commands/conversation_restart.py +0 -0
  60. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/commands/edit.py +0 -0
  61. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/commands/help.py +0 -0
  62. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/commands/history_view.py +0 -0
  63. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/commands/lang.py +0 -0
  64. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/commands/livelogs.py +0 -0
  65. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/commands/multi.py +0 -0
  66. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/commands/prompt.py +0 -0
  67. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/commands/role.py +0 -0
  68. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/commands/session.py +0 -0
  69. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/commands/session_control.py +0 -0
  70. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/commands/termweb_log.py +0 -0
  71. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/commands/tools.py +0 -0
  72. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/commands/utility.py +0 -0
  73. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/commands/verbose.py +0 -0
  74. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/session/__init__.py +0 -0
  75. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/session/history.py +0 -0
  76. {janito-2.1.0 → janito-2.2.0}/janito/cli/chat_mode/shell/session/manager.py +0 -0
  77. {janito-2.1.0 → janito-2.2.0}/janito/cli/cli_commands/list_models.py +0 -0
  78. {janito-2.1.0 → janito-2.2.0}/janito/cli/cli_commands/list_providers.py +0 -0
  79. {janito-2.1.0 → janito-2.2.0}/janito/cli/cli_commands/list_tools.py +0 -0
  80. {janito-2.1.0 → janito-2.2.0}/janito/cli/cli_commands/model_selection.py +0 -0
  81. {janito-2.1.0 → janito-2.2.0}/janito/cli/cli_commands/model_utils.py +0 -0
  82. {janito-2.1.0 → janito-2.2.0}/janito/cli/cli_commands/set_api_key.py +0 -0
  83. {janito-2.1.0 → janito-2.2.0}/janito/cli/cli_commands/show_config.py +0 -0
  84. {janito-2.1.0 → janito-2.2.0}/janito/cli/cli_commands/show_system_prompt.py +0 -0
  85. {janito-2.1.0 → janito-2.2.0}/janito/cli/console.py +0 -0
  86. {janito-2.1.0 → janito-2.2.0}/janito/cli/core/__init__.py +0 -0
  87. {janito-2.1.0 → janito-2.2.0}/janito/cli/core/event_logger.py +0 -0
  88. {janito-2.1.0 → janito-2.2.0}/janito/cli/core/getters.py +0 -0
  89. {janito-2.1.0 → janito-2.2.0}/janito/cli/core/setters.py +0 -0
  90. {janito-2.1.0 → janito-2.2.0}/janito/cli/core/unsetters.py +0 -0
  91. {janito-2.1.0 → janito-2.2.0}/janito/cli/main.py +0 -0
  92. {janito-2.1.0 → janito-2.2.0}/janito/cli/prompt_core.py +0 -0
  93. {janito-2.1.0 → janito-2.2.0}/janito/cli/prompt_handler.py +0 -0
  94. {janito-2.1.0 → janito-2.2.0}/janito/cli/rich_terminal_reporter.py +0 -0
  95. {janito-2.1.0 → janito-2.2.0}/janito/cli/single_shot_mode/__init__.py +0 -0
  96. {janito-2.1.0 → janito-2.2.0}/janito/cli/single_shot_mode/handler.py +0 -0
  97. {janito-2.1.0 → janito-2.2.0}/janito/cli/termweb_starter.py +0 -0
  98. {janito-2.1.0 → janito-2.2.0}/janito/cli/utils.py +0 -0
  99. {janito-2.1.0 → janito-2.2.0}/janito/cli/verbose_output.py +0 -0
  100. {janito-2.1.0 → janito-2.2.0}/janito/config.py +0 -0
  101. {janito-2.1.0 → janito-2.2.0}/janito/config_manager.py +0 -0
  102. {janito-2.1.0 → janito-2.2.0}/janito/conversation_history.py +0 -0
  103. {janito-2.1.0 → janito-2.2.0}/janito/dir_walk_utils.py +0 -0
  104. {janito-2.1.0 → janito-2.2.0}/janito/driver_events.py +0 -0
  105. {janito-2.1.0 → janito-2.2.0}/janito/drivers/anthropic/driver.py +0 -0
  106. {janito-2.1.0 → janito-2.2.0}/janito/drivers/driver_registry.py +0 -0
  107. {janito-2.1.0 → janito-2.2.0}/janito/drivers/google_genai/driver.py +0 -0
  108. {janito-2.1.0 → janito-2.2.0}/janito/drivers/google_genai/schema_generator.py +0 -0
  109. {janito-2.1.0 → janito-2.2.0}/janito/drivers/mistralai/driver.py +0 -0
  110. {janito-2.1.0 → janito-2.2.0}/janito/drivers/openai/driver.py +0 -0
  111. {janito-2.1.0 → janito-2.2.0}/janito/event_bus/__init__.py +0 -0
  112. {janito-2.1.0 → janito-2.2.0}/janito/event_bus/bus.py +0 -0
  113. {janito-2.1.0 → janito-2.2.0}/janito/event_bus/event.py +0 -0
  114. {janito-2.1.0 → janito-2.2.0}/janito/event_bus/handler.py +0 -0
  115. {janito-2.1.0 → janito-2.2.0}/janito/event_bus/queue_bus.py +0 -0
  116. {janito-2.1.0 → janito-2.2.0}/janito/exceptions.py +0 -0
  117. {janito-2.1.0 → janito-2.2.0}/janito/formatting.py +0 -0
  118. {janito-2.1.0 → janito-2.2.0}/janito/formatting_token.py +0 -0
  119. {janito-2.1.0 → janito-2.2.0}/janito/gitignore_utils.py +0 -0
  120. {janito-2.1.0 → janito-2.2.0}/janito/i18n/__init__.py +0 -0
  121. {janito-2.1.0 → janito-2.2.0}/janito/i18n/messages.py +0 -0
  122. {janito-2.1.0 → janito-2.2.0}/janito/i18n/pt.py +0 -0
  123. {janito-2.1.0 → janito-2.2.0}/janito/llm/__init__.py +0 -0
  124. {janito-2.1.0 → janito-2.2.0}/janito/llm/agent.py +0 -0
  125. {janito-2.1.0 → janito-2.2.0}/janito/llm/auth.py +0 -0
  126. {janito-2.1.0 → janito-2.2.0}/janito/llm/driver.py +0 -0
  127. {janito-2.1.0 → janito-2.2.0}/janito/llm/driver_config.py +0 -0
  128. {janito-2.1.0 → janito-2.2.0}/janito/llm/driver_config_builder.py +0 -0
  129. {janito-2.1.0 → janito-2.2.0}/janito/llm/driver_input.py +0 -0
  130. {janito-2.1.0 → janito-2.2.0}/janito/llm/message_parts.py +0 -0
  131. {janito-2.1.0 → janito-2.2.0}/janito/llm/model.py +0 -0
  132. {janito-2.1.0 → janito-2.2.0}/janito/perf_singleton.py +0 -0
  133. {janito-2.1.0 → janito-2.2.0}/janito/performance_collector.py +0 -0
  134. {janito-2.1.0 → janito-2.2.0}/janito/platform_discovery.py +0 -0
  135. {janito-2.1.0 → janito-2.2.0}/janito/provider_config.py +0 -0
  136. {janito-2.1.0 → janito-2.2.0}/janito/providers/__init__.py +0 -0
  137. {janito-2.1.0 → janito-2.2.0}/janito/providers/anthropic/model_info.py +0 -0
  138. {janito-2.1.0 → janito-2.2.0}/janito/providers/anthropic/provider.py +0 -0
  139. {janito-2.1.0 → janito-2.2.0}/janito/providers/azure_openai/model_info.py +0 -0
  140. {janito-2.1.0 → janito-2.2.0}/janito/providers/deepseek/__init__.py +0 -0
  141. {janito-2.1.0 → janito-2.2.0}/janito/providers/google/__init__.py +0 -0
  142. {janito-2.1.0 → janito-2.2.0}/janito/providers/google/model_info.py +0 -0
  143. {janito-2.1.0 → janito-2.2.0}/janito/providers/google/provider.py +0 -0
  144. {janito-2.1.0 → janito-2.2.0}/janito/providers/mistralai/model_info.py +0 -0
  145. {janito-2.1.0 → janito-2.2.0}/janito/providers/mistralai/provider.py +0 -0
  146. {janito-2.1.0 → janito-2.2.0}/janito/providers/openai/__init__.py +0 -0
  147. {janito-2.1.0 → janito-2.2.0}/janito/providers/openai/schema_generator.py +0 -0
  148. {janito-2.1.0 → janito-2.2.0}/janito/providers/provider_static_info.py +0 -0
  149. {janito-2.1.0 → janito-2.2.0}/janito/report_events.py +0 -0
  150. {janito-2.1.0 → janito-2.2.0}/janito/termweb/app.py +0 -0
  151. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/__init__.py +0 -0
  152. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/copy_file.py +0 -0
  153. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/create_directory.py +0 -0
  154. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/create_file.py +0 -0
  155. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/delete_text_in_file.py +0 -0
  156. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/fetch_url.py +0 -0
  157. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/get_file_outline/__init__.py +0 -0
  158. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/get_file_outline/markdown_outline.py +0 -0
  159. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/get_file_outline/python_outline.py +0 -0
  160. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/get_file_outline/python_outline_v2.py +0 -0
  161. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/get_file_outline/search_outline.py +0 -0
  162. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/move_file.py +0 -0
  163. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/remove_directory.py +0 -0
  164. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/replace_text_in_file.py +0 -0
  165. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/run_bash_command.py +0 -0
  166. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/run_powershell_command.py +0 -0
  167. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/search_text/__init__.py +0 -0
  168. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/search_text/core.py +0 -0
  169. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/search_text/match_lines.py +0 -0
  170. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/search_text/pattern_utils.py +0 -0
  171. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/search_text/traverse_directory.py +0 -0
  172. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/validate_file_syntax/__init__.py +0 -0
  173. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/validate_file_syntax/core.py +0 -0
  174. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/validate_file_syntax/css_validator.py +0 -0
  175. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/validate_file_syntax/html_validator.py +0 -0
  176. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/validate_file_syntax/js_validator.py +0 -0
  177. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/validate_file_syntax/json_validator.py +0 -0
  178. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/validate_file_syntax/markdown_validator.py +0 -0
  179. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/validate_file_syntax/ps1_validator.py +0 -0
  180. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/validate_file_syntax/python_validator.py +0 -0
  181. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/validate_file_syntax/xml_validator.py +0 -0
  182. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/validate_file_syntax/yaml_validator.py +0 -0
  183. {janito-2.1.0 → janito-2.2.0}/janito/tools/adapters/local/view_file.py +0 -0
  184. {janito-2.1.0 → janito-2.2.0}/janito/tools/inspect_registry.py +0 -0
  185. {janito-2.1.0 → janito-2.2.0}/janito/tools/tool_base.py +0 -0
  186. {janito-2.1.0 → janito-2.2.0}/janito/tools/tool_events.py +0 -0
  187. {janito-2.1.0 → janito-2.2.0}/janito/tools/tool_run_exception.py +0 -0
  188. {janito-2.1.0 → janito-2.2.0}/janito/tools/tool_use_tracker.py +0 -0
  189. {janito-2.1.0 → janito-2.2.0}/janito/tools/tool_utils.py +0 -0
  190. {janito-2.1.0 → janito-2.2.0}/janito/tools/tools_adapter.py +0 -0
  191. {janito-2.1.0 → janito-2.2.0}/janito/tools/tools_schema.py +0 -0
  192. {janito-2.1.0 → janito-2.2.0}/janito/utils.py +0 -0
  193. {janito-2.1.0 → janito-2.2.0}/janito.egg-info/dependency_links.txt +0 -0
  194. {janito-2.1.0 → janito-2.2.0}/janito.egg-info/entry_points.txt +0 -0
  195. {janito-2.1.0 → janito-2.2.0}/janito.egg-info/top_level.txt +0 -0
  196. {janito-2.1.0 → janito-2.2.0}/setup.cfg +0 -0
janito-2.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) [year] [fullname]
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,11 +1,30 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: janito
3
- Version: 2.1.0
3
+ Version: 2.2.0
4
4
  Summary: A new Python package called janito.
5
- Author-email: Your Name <your.email@example.com>
5
+ Author-email: João Pinto <lamego.pinto@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/janito-dev/janito
7
7
  Requires-Python: >=3.7
8
8
  Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: attrs==25.3.0
11
+ Requires-Dist: rich==14.0.0
12
+ Requires-Dist: pathspec==0.12.1
13
+ Requires-Dist: setuptools>=61.0
14
+ Requires-Dist: pyyaml>=6.0
15
+ Requires-Dist: jinja2>=3.0.0
16
+ Requires-Dist: prompt_toolkit>=3.0.51
17
+ Requires-Dist: lxml>=5.4.0
18
+ Requires-Dist: requests>=2.32.4
19
+ Requires-Dist: bs4>=0.0.2
20
+ Provides-Extra: dev
21
+ Requires-Dist: pytest; extra == "dev"
22
+ Requires-Dist: pre-commit; extra == "dev"
23
+ Requires-Dist: ruff==0.11.9; extra == "dev"
24
+ Requires-Dist: detect-secrets==1.4.0; extra == "dev"
25
+ Requires-Dist: codespell==2.4.1; extra == "dev"
26
+ Requires-Dist: black; extra == "dev"
27
+ Dynamic: license-file
9
28
 
10
29
  # Janito
11
30
 
@@ -3,4 +3,4 @@ janito: A Python package for managing and interacting with Large Language Model
3
3
  Provides a CLI for credential management and an extensible driver system for LLMs.
4
4
  """
5
5
 
6
- __version__ = "2.1.0"
6
+ __version__ = "2.2.0"
@@ -3,7 +3,6 @@ from .edit import EditShellHandler
3
3
  from .history_view import ViewShellHandler
4
4
  from .lang import LangShellHandler
5
5
  from .livelogs import LivelogsShellHandler
6
- from .last import LastShellHandler
7
6
  from .prompt import PromptShellHandler, RoleShellHandler, ProfileShellHandler
8
7
  from .multi import MultiShellHandler
9
8
  from .role import RoleCommandShellHandler
@@ -25,7 +24,6 @@ COMMAND_HANDLERS = {
25
24
  "/view": ViewShellHandler,
26
25
  "/lang": LangShellHandler,
27
26
  "/livelogs": LivelogsShellHandler,
28
- "/last": LastShellHandler,
29
27
  "/prompt": PromptShellHandler,
30
28
  "/role": RoleShellHandler,
31
29
  "/profile": ProfileShellHandler,
@@ -7,7 +7,7 @@ from typing import List, Any, Dict
7
7
  class UserInputHistory:
8
8
  """
9
9
  Handles loading, saving, and appending of user input history for the shell.
10
- Each day's history is stored in a line-delimited JSON file (.json.log) under .janito/input_history/.
10
+ Each day's history is stored in a line-delimited JSONL file (.jsonl) under .janito/input_history/.
11
11
  Each line is a JSON dict, e.g., {"input": ..., "ts": ...}
12
12
  """
13
13
 
@@ -17,7 +17,7 @@ class UserInputHistory:
17
17
 
18
18
  def _get_today_file(self):
19
19
  today_str = datetime.now().strftime("%y%m%d")
20
- return os.path.join(self.history_dir, f"{today_str}.json.log")
20
+ return os.path.join(self.history_dir, f"{today_str}.jsonl")
21
21
 
22
22
  def load(self) -> List[Dict[str, Any]]:
23
23
  """Load today's input history as a list of dicts."""
@@ -22,7 +22,8 @@ def assemble_first_line(provider_name, model_name, role, agent=None):
22
22
 
23
23
  def assemble_bindings_line(width):
24
24
  return (
25
- f" <key-label>F1</key-label>: Restart conversation | "
25
+ f" <key-label>CTRL-C</key-label>: Interrupt Request/Exit Shell | "
26
+ f"<key-label>F1</key-label>: Restart conversation | "
26
27
  f"<b>/help</b>: Help | "
27
28
  f"<key-label>F12</key-label>: Do It "
28
29
  )
@@ -3,12 +3,11 @@ from janito.config import config
3
3
  CONFIG_OPTIONS = {
4
4
  "api_key": "API key for OpenAI-compatible service (required)", # pragma: allowlist secret
5
5
  "trust": "Trust mode: suppress all console output (bool, default: False)",
6
- "model": "Model name to use (e.g., 'gpt-4.1', 'gpt-4o', 'gpt-4-turbo', 'o3-mini', 'o4-mini', 'o4-mini-high')",
6
+ "model": "Model name to use (e.g., 'gpt-4.1', 'gpt-4o', 'gpt-4-turbo', 'o3-mini', 'o4-mini')",
7
7
  "base_url": "API base URL (OpenAI-compatible endpoint)",
8
8
  "role": "Role description for the Agent Profile (e.g., 'software engineer')",
9
9
  "temperature": "Sampling temperature (float, e.g., 0.0 - 2.0)",
10
10
  "max_tokens": "Maximum tokens for model response (int)",
11
- "use_azure_openai": "Whether to use Azure OpenAI client (default: False)",
12
11
  "template": "Template context dictionary for Agent Profile prompt rendering (nested)",
13
12
  "profile": "Agent Profile name (only 'base' is supported)",
14
13
  }
@@ -1,141 +1,148 @@
1
- """Handles LLM driver config preparation and execution modes."""
2
-
3
- from janito.llm.driver_config import LLMDriverConfig
4
- from janito.provider_config import get_config_provider
5
- from janito.cli.verbose_output import print_verbose_info
6
-
7
-
8
- def _choose_provider(args):
9
- provider = getattr(args, "provider", None)
10
- if provider is None:
11
- provider = get_config_provider()
12
- if provider and getattr(args, "verbose", False):
13
- print_verbose_info(
14
- "Default provider", provider, style="magenta", align_content=True
15
- )
16
- elif provider is None:
17
- print(
18
- "Error: No provider selected and no provider found in config. Please set a provider using '-p PROVIDER', '--set provider=name', or configure a provider."
19
- )
20
- return None
21
- return provider
22
-
23
-
24
- def _populate_driver_config_data(args, modifiers, provider, model):
25
- from janito.provider_config import get_effective_setting
26
-
27
- CONFIG_LOOKUP_KEYS = ("max_tokens", "base_url")
28
- driver_config_data = {"model": model}
29
- if getattr(args, "verbose_api", None) is not None:
30
- driver_config_data["verbose_api"] = args.verbose_api
31
- for field in LLMDriverConfig.__dataclass_fields__:
32
- if field in CONFIG_LOOKUP_KEYS:
33
- if field in modifiers and modifiers[field] is not None:
34
- driver_config_data[field] = modifiers[field]
35
- else:
36
- value = get_effective_setting(provider, model, field)
37
- if value is not None:
38
- driver_config_data[field] = value
39
- elif field in modifiers and field != "model":
40
- driver_config_data[field] = modifiers[field]
41
- return driver_config_data
42
-
43
-
44
- def prepare_llm_driver_config(args, modifiers):
45
- """Prepare the LLMDriverConfig instance based on CLI *args* and *modifiers*.
46
-
47
- This helper additionally validates that the chosen ``--model`` (or the
48
- resolved model coming from config precedence) is actually available for the
49
- selected provider. If the combination is invalid an error is printed and
50
- ``None`` is returned for the config so that the caller can abort execution
51
- gracefully.
52
- """
53
- provider = _choose_provider(args)
54
- if provider is None:
55
- return None, None, None
56
- from janito.provider_config import get_effective_model
57
-
58
- model = getattr(args, "model", None)
59
- if not model:
60
- model = get_effective_model(provider)
61
-
62
- # Validate that the chosen model is supported by the selected provider
63
- if model:
64
- from janito.provider_registry import ProviderRegistry
65
-
66
- provider_instance = None
67
- try:
68
- provider_instance = ProviderRegistry().get_instance(provider)
69
- available_models = [
70
- m["name"]
71
- for m in provider_instance.get_model_info().values()
72
- if isinstance(m, dict) and "name" in m
73
- ]
74
- if model not in available_models:
75
- print(
76
- f"Error: Model '{model}' is not available for provider '{provider}'."
77
- )
78
- print(f"Available models: {', '.join(available_models)}")
79
- return provider, None, None
80
- except Exception as e:
81
- print(f"Error validating model for provider '{provider}': {e}")
82
- return provider, None, None
83
- driver_config_data = _populate_driver_config_data(args, modifiers, provider, model)
84
- llm_driver_config = LLMDriverConfig(**driver_config_data)
85
- if getattr(llm_driver_config, "verbose_api", None):
86
- pass
87
- agent_role = modifiers.get("role", "software developer")
88
- return provider, llm_driver_config, agent_role
89
-
90
-
91
- def handle_runner(args, provider, llm_driver_config, agent_role, verbose_tools=False, exec_enabled=False):
92
- """
93
- Main runner for CLI execution. If exec_enabled is False, disables execution/run tools.
94
- """
95
- zero_mode = getattr(args, "zero", False)
96
- from janito.provider_registry import ProviderRegistry
97
-
98
- # Patch: disable execution/run tools if not enabled
99
- if not exec_enabled:
100
- import janito.tools
101
- adapter = janito.tools.get_local_tools_adapter()
102
- if hasattr(adapter, "disable_execution_tools"):
103
- adapter.disable_execution_tools()
104
- else:
105
- pass
106
-
107
- provider_instance = ProviderRegistry().get_instance(provider, llm_driver_config)
108
- mode = get_prompt_mode(args)
109
- if getattr(args, "verbose", False):
110
- print_verbose_info(
111
- "Active LLMDriverConfig (after provider)", llm_driver_config, style="green"
112
- )
113
- print_verbose_info("Agent role", agent_role, style="green")
114
- if mode == "single_shot":
115
- from janito.cli.single_shot_mode.handler import (
116
- PromptHandler as SingleShotPromptHandler,
117
- )
118
-
119
- handler = SingleShotPromptHandler(
120
- args, provider_instance, llm_driver_config, role=agent_role
121
- )
122
- handler.handle()
123
- else:
124
- from janito.cli.chat_mode.session import ChatSession
125
- from rich.console import Console
126
-
127
- console = Console()
128
- session = ChatSession(
129
- console,
130
- provider_instance,
131
- llm_driver_config,
132
- role=agent_role,
133
- args=args,
134
- verbose_tools=verbose_tools,
135
- verbose_agent=getattr(args, "verbose_agent", False),
136
- )
137
- session.run()
138
-
139
-
140
- def get_prompt_mode(args):
141
- return "single_shot" if getattr(args, "user_prompt", None) else "chat_mode"
1
+ """Handles LLM driver config preparation and execution modes."""
2
+
3
+ from janito.llm.driver_config import LLMDriverConfig
4
+ from janito.provider_config import get_config_provider
5
+ from janito.cli.verbose_output import print_verbose_info
6
+
7
+
8
+ def _choose_provider(args):
9
+ provider = getattr(args, "provider", None)
10
+ if provider is None:
11
+ provider = get_config_provider()
12
+ if provider and getattr(args, "verbose", False):
13
+ print_verbose_info(
14
+ "Default provider", provider, style="magenta", align_content=True
15
+ )
16
+ elif provider is None:
17
+ print(
18
+ "Error: No provider selected and no provider found in config. Please set a provider using '-p PROVIDER', '--set provider=name', or configure a provider."
19
+ )
20
+ return None
21
+ return provider
22
+
23
+
24
+ def _populate_driver_config_data(args, modifiers, provider, model):
25
+ from janito.provider_config import get_effective_setting
26
+
27
+ CONFIG_LOOKUP_KEYS = ("max_tokens", "base_url")
28
+ driver_config_data = {"model": model}
29
+ if getattr(args, "verbose_api", None) is not None:
30
+ driver_config_data["verbose_api"] = args.verbose_api
31
+ for field in LLMDriverConfig.__dataclass_fields__:
32
+ if field in CONFIG_LOOKUP_KEYS:
33
+ if field in modifiers and modifiers[field] is not None:
34
+ driver_config_data[field] = modifiers[field]
35
+ else:
36
+ value = get_effective_setting(provider, model, field)
37
+ if value is not None:
38
+ driver_config_data[field] = value
39
+ elif field in modifiers and field != "model":
40
+ driver_config_data[field] = modifiers[field]
41
+ return driver_config_data
42
+
43
+
44
+ def prepare_llm_driver_config(args, modifiers):
45
+ """Prepare the LLMDriverConfig instance based on CLI *args* and *modifiers*.
46
+
47
+ This helper additionally validates that the chosen ``--model`` (or the
48
+ resolved model coming from config precedence) is actually available for the
49
+ selected provider. If the combination is invalid an error is printed and
50
+ ``None`` is returned for the config so that the caller can abort execution
51
+ gracefully.
52
+ """
53
+ provider = _choose_provider(args)
54
+ if provider is None:
55
+ return None, None, None
56
+ from janito.provider_config import get_effective_model
57
+
58
+ model = getattr(args, "model", None)
59
+ if not model:
60
+ model = get_effective_model(provider)
61
+
62
+ # Validate that the chosen model is supported by the selected provider
63
+ if model:
64
+ from janito.provider_registry import ProviderRegistry
65
+
66
+ provider_instance = None
67
+ provider_instance = ProviderRegistry().get_instance(provider)
68
+ if provider_instance is None:
69
+ return provider, None, None
70
+ try:
71
+ if not provider_instance.is_model_available(model):
72
+ print(
73
+ f"Error: Model '{model}' is not available for provider '{provider}'."
74
+ )
75
+ # Optionally, print available models if possible
76
+ if hasattr(provider_instance, 'get_model_info'):
77
+ available_models = [
78
+ m["name"]
79
+ for m in provider_instance.get_model_info().values()
80
+ if isinstance(m, dict) and "name" in m
81
+ ]
82
+ print(f"Available models: {', '.join(available_models)}")
83
+ return provider, None, None
84
+ except Exception as e:
85
+ print(f"Error validating model for provider '{provider}': {e}")
86
+ return provider, None, None
87
+ driver_config_data = _populate_driver_config_data(args, modifiers, provider, model)
88
+ llm_driver_config = LLMDriverConfig(**driver_config_data)
89
+ if getattr(llm_driver_config, "verbose_api", None):
90
+ pass
91
+ agent_role = modifiers.get("role", "software developer")
92
+ return provider, llm_driver_config, agent_role
93
+
94
+
95
+ def handle_runner(args, provider, llm_driver_config, agent_role, verbose_tools=False, exec_enabled=False):
96
+ """
97
+ Main runner for CLI execution. If exec_enabled is False, disables execution/run tools.
98
+ """
99
+ zero_mode = getattr(args, "zero", False)
100
+ from janito.provider_registry import ProviderRegistry
101
+
102
+ # Patch: disable execution/run tools if not enabled
103
+ if not exec_enabled:
104
+ import janito.tools
105
+ adapter = janito.tools.get_local_tools_adapter(workdir=getattr(args, "workdir", None))
106
+ if hasattr(adapter, "disable_execution_tools"):
107
+ adapter.disable_execution_tools()
108
+ else:
109
+ import janito.tools
110
+ adapter = janito.tools.get_local_tools_adapter(workdir=getattr(args, "workdir", None))
111
+
112
+ provider_instance = ProviderRegistry().get_instance(provider, llm_driver_config)
113
+ if provider_instance is None:
114
+ return
115
+ mode = get_prompt_mode(args)
116
+ if getattr(args, "verbose", False):
117
+ print_verbose_info(
118
+ "Active LLMDriverConfig (after provider)", llm_driver_config, style="green"
119
+ )
120
+ print_verbose_info("Agent role", agent_role, style="green")
121
+ if mode == "single_shot":
122
+ from janito.cli.single_shot_mode.handler import (
123
+ PromptHandler as SingleShotPromptHandler,
124
+ )
125
+
126
+ handler = SingleShotPromptHandler(
127
+ args, provider_instance, llm_driver_config, role=agent_role
128
+ )
129
+ handler.handle()
130
+ else:
131
+ from janito.cli.chat_mode.session import ChatSession
132
+ from rich.console import Console
133
+
134
+ console = Console()
135
+ session = ChatSession(
136
+ console,
137
+ provider_instance,
138
+ llm_driver_config,
139
+ role=agent_role,
140
+ args=args,
141
+ verbose_tools=verbose_tools,
142
+ verbose_agent=getattr(args, "verbose_agent", False),
143
+ )
144
+ session.run()
145
+
146
+
147
+ def get_prompt_mode(args):
148
+ return "single_shot" if getattr(args, "user_prompt", None) else "chat_mode"
@@ -13,6 +13,14 @@ from janito.cli.core.event_logger import (
13
13
  )
14
14
 
15
15
  definition = [
16
+ (
17
+ ["-W", "--workdir"],
18
+ {
19
+ "metavar": "WORKDIR",
20
+ "help": "Working directory to chdir to before tool execution",
21
+ "default": None,
22
+ },
23
+ ),
16
24
  (
17
25
  ["--verbose-api"],
18
26
  {
@@ -0,0 +1,55 @@
1
+ from janito.drivers.openai.driver import OpenAIModelDriver
2
+
3
+ # Safe import of AzureOpenAI SDK
4
+ try:
5
+ from openai import AzureOpenAI
6
+
7
+ DRIVER_AVAILABLE = True
8
+ DRIVER_UNAVAILABLE_REASON = None
9
+ except ImportError:
10
+ DRIVER_AVAILABLE = False
11
+ DRIVER_UNAVAILABLE_REASON = "Missing dependency: openai (pip install openai)"
12
+
13
+ from janito.llm.driver_config import LLMDriverConfig
14
+
15
+
16
+ class AzureOpenAIModelDriver(OpenAIModelDriver):
17
+ available = DRIVER_AVAILABLE
18
+ unavailable_reason = DRIVER_UNAVAILABLE_REASON
19
+
20
+ @classmethod
21
+ def is_available(cls):
22
+ return cls.available
23
+
24
+ required_config = {"base_url"} # Update key as used in your config logic
25
+
26
+ def __init__(self, tools_adapter=None):
27
+ if not self.available:
28
+ raise ImportError(
29
+ f"AzureOpenAIModelDriver unavailable: {self.unavailable_reason}"
30
+ )
31
+ # Do NOT call super().__init__ if Azure SDK is not available
32
+ OpenAIModelDriver.__init__(self, tools_adapter=tools_adapter)
33
+ self.azure_endpoint = None
34
+ self.api_version = None
35
+ self.api_key = None
36
+
37
+ def _instantiate_openai_client(self, config):
38
+ try:
39
+ from openai import AzureOpenAI
40
+ api_key_display = str(config.api_key)
41
+ if api_key_display and len(api_key_display) > 8:
42
+ api_key_display = api_key_display[:4] + "..." + api_key_display[-4:]
43
+ client_kwargs = {
44
+ "api_key": config.api_key,
45
+ "azure_endpoint": getattr(config, "base_url", None),
46
+ "api_version": config.extra.get("api_version", "2023-05-15"),
47
+ }
48
+ client = AzureOpenAI(**client_kwargs)
49
+ return client
50
+ except Exception as e:
51
+ print(f"[ERROR] Exception during AzureOpenAI client instantiation: {e}", flush=True)
52
+ import traceback
53
+ print(traceback.format_exc(), flush=True)
54
+ raise
55
+
@@ -93,6 +93,15 @@ class LLMProvider(ABC):
93
93
  def driver(self) -> LLMDriver:
94
94
  pass
95
95
 
96
+ def is_model_available(self, model_name):
97
+ """
98
+ Returns True if the given model is available for this provider.
99
+ Default implementation checks MODEL_SPECS; override for dynamic providers.
100
+ """
101
+ if not hasattr(self, "MODEL_SPECS"):
102
+ return False
103
+ return model_name in self.MODEL_SPECS
104
+
96
105
  def get_model_info(self, model_name=None):
97
106
  """
98
107
  Return the info dict for a given model (driver, params, etc). If model_name is None, return all model info dicts.