janito 1.7.0__tar.gz → 1.9.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 (223) hide show
  1. janito-1.9.0/MANIFEST.in +6 -0
  2. {janito-1.7.0/janito.egg-info → janito-1.9.0}/PKG-INFO +62 -26
  3. {janito-1.7.0 → janito-1.9.0}/README.md +61 -26
  4. janito-1.9.0/janito/__init__.py +1 -0
  5. {janito-1.7.0 → janito-1.9.0}/janito/agent/config.py +1 -1
  6. janito-1.9.0/janito/agent/config_defaults.py +36 -0
  7. janito-1.9.0/janito/agent/conversation.py +197 -0
  8. janito-1.9.0/janito/agent/conversation_api.py +228 -0
  9. {janito-1.7.0 → janito-1.9.0}/janito/agent/conversation_exceptions.py +6 -0
  10. janito-1.9.0/janito/agent/conversation_history.py +53 -0
  11. janito-1.9.0/janito/agent/conversation_tool_calls.py +39 -0
  12. janito-1.9.0/janito/agent/event.py +24 -0
  13. janito-1.9.0/janito/agent/event_dispatcher.py +24 -0
  14. janito-1.9.0/janito/agent/event_handler_protocol.py +5 -0
  15. janito-1.9.0/janito/agent/event_system.py +15 -0
  16. {janito-1.7.0 → janito-1.9.0}/janito/agent/message_handler.py +4 -1
  17. janito-1.9.0/janito/agent/message_handler_protocol.py +5 -0
  18. {janito-1.7.0 → janito-1.9.0}/janito/agent/openai_client.py +16 -11
  19. {janito-1.7.0 → janito-1.9.0}/janito/agent/openai_schema_generator.py +26 -4
  20. janito-1.9.0/janito/agent/profile_manager.py +96 -0
  21. janito-1.9.0/janito/agent/providers.py +77 -0
  22. {janito-1.7.0 → janito-1.9.0}/janito/agent/queued_message_handler.py +22 -3
  23. {janito-1.7.0 → janito-1.9.0}/janito/agent/rich_message_handler.py +66 -72
  24. janito-1.9.0/janito/agent/templates/profiles/system_prompt_template_base.txt.j2 +14 -0
  25. janito-1.9.0/janito/agent/templates/profiles/system_prompt_template_base_pt.txt.j2 +13 -0
  26. janito-1.9.0/janito/agent/test_handler_protocols.py +47 -0
  27. janito-1.9.0/janito/agent/tests/__init__.py +1 -0
  28. {janito-1.7.0 → janito-1.9.0}/janito/agent/tool_base.py +1 -1
  29. janito-1.9.0/janito/agent/tool_executor.py +117 -0
  30. janito-1.9.0/janito/agent/tool_registry.py +46 -0
  31. janito-1.9.0/janito/agent/tool_use_tracker.py +62 -0
  32. {janito-1.7.0 → janito-1.9.0}/janito/agent/tools/__init__.py +12 -15
  33. {janito-1.7.0 → janito-1.9.0}/janito/agent/tools/ask_user.py +19 -11
  34. janito-1.9.0/janito/agent/tools/create_directory.py +66 -0
  35. janito-1.9.0/janito/agent/tools/create_file.py +53 -0
  36. janito-1.9.0/janito/agent/tools/delete_text_in_file.py +97 -0
  37. {janito-1.7.0 → janito-1.9.0}/janito/agent/tools/fetch_url.py +18 -11
  38. janito-1.9.0/janito/agent/tools/find_files.py +81 -0
  39. janito-1.9.0/janito/agent/tools/get_file_outline/__init__.py +1 -0
  40. janito-1.9.0/janito/agent/tools/get_file_outline/core.py +82 -0
  41. janito-1.9.0/janito/agent/tools/get_file_outline/markdown_outline.py +14 -0
  42. janito-1.9.0/janito/agent/tools/get_file_outline/python_outline.py +134 -0
  43. janito-1.9.0/janito/agent/tools/get_file_outline/search_outline.py +26 -0
  44. janito-1.9.0/janito/agent/tools/get_lines.py +115 -0
  45. janito-1.9.0/janito/agent/tools/move_file.py +107 -0
  46. janito-1.9.0/janito/agent/tools/present_choices.py +62 -0
  47. janito-1.9.0/janito/agent/tools/remove_directory.py +55 -0
  48. janito-1.9.0/janito/agent/tools/remove_file.py +56 -0
  49. janito-1.9.0/janito/agent/tools/replace_file.py +62 -0
  50. janito-1.9.0/janito/agent/tools/replace_text_in_file.py +216 -0
  51. {janito-1.7.0 → janito-1.9.0}/janito/agent/tools/run_bash_command.py +44 -51
  52. janito-1.9.0/janito/agent/tools/run_powershell_command.py +180 -0
  53. {janito-1.7.0 → janito-1.9.0}/janito/agent/tools/run_python_command.py +48 -30
  54. janito-1.9.0/janito/agent/tools/search_text.py +204 -0
  55. janito-1.9.0/janito/agent/tools/validate_file_syntax/__init__.py +1 -0
  56. janito-1.9.0/janito/agent/tools/validate_file_syntax/core.py +92 -0
  57. janito-1.9.0/janito/agent/tools/validate_file_syntax/css_validator.py +35 -0
  58. janito-1.9.0/janito/agent/tools/validate_file_syntax/html_validator.py +77 -0
  59. janito-1.9.0/janito/agent/tools/validate_file_syntax/js_validator.py +27 -0
  60. janito-1.9.0/janito/agent/tools/validate_file_syntax/json_validator.py +6 -0
  61. janito-1.9.0/janito/agent/tools/validate_file_syntax/markdown_validator.py +66 -0
  62. janito-1.9.0/janito/agent/tools/validate_file_syntax/ps1_validator.py +32 -0
  63. janito-1.9.0/janito/agent/tools/validate_file_syntax/python_validator.py +5 -0
  64. janito-1.9.0/janito/agent/tools/validate_file_syntax/xml_validator.py +11 -0
  65. janito-1.9.0/janito/agent/tools/validate_file_syntax/yaml_validator.py +6 -0
  66. janito-1.9.0/janito/agent/tools_utils/__init__.py +1 -0
  67. janito-1.9.0/janito/agent/tools_utils/dir_walk_utils.py +23 -0
  68. janito-1.9.0/janito/agent/tools_utils/formatting.py +23 -0
  69. {janito-1.7.0/janito/agent/tools → janito-1.9.0/janito/agent/tools_utils}/gitignore_utils.py +0 -3
  70. janito-1.9.0/janito/agent/tools_utils/utils.py +30 -0
  71. janito-1.9.0/janito/cli/_livereload_log_utils.py +13 -0
  72. janito-1.9.0/janito/cli/_termweb_log_utils.py +17 -0
  73. {janito-1.7.0 → janito-1.9.0}/janito/cli/arg_parser.py +80 -6
  74. janito-1.9.0/janito/cli/cli_main.py +280 -0
  75. janito-1.7.0/janito/cli/runner/config.py → janito-1.9.0/janito/cli/config_runner.py +2 -2
  76. janito-1.9.0/janito/cli/livereload_starter.py +60 -0
  77. {janito-1.7.0 → janito-1.9.0}/janito/cli/logging_setup.py +7 -2
  78. janito-1.9.0/janito/cli/main.py +224 -0
  79. janito-1.9.0/janito/cli/one_shot.py +66 -0
  80. janito-1.9.0/janito/cli/termweb_starter.py +73 -0
  81. janito-1.9.0/janito/i18n/__init__.py +35 -0
  82. janito-1.9.0/janito/i18n/messages.py +23 -0
  83. janito-1.9.0/janito/i18n/pt.py +46 -0
  84. janito-1.9.0/janito/livereload/app.py +25 -0
  85. janito-1.9.0/janito/rich_utils.py +21 -0
  86. janito-1.9.0/janito/shell/commands/__init__.py +63 -0
  87. {janito-1.7.0/janito/cli_chat_shell → janito-1.9.0/janito/shell}/commands/config.py +4 -4
  88. janito-1.9.0/janito/shell/commands/conversation_restart.py +72 -0
  89. janito-1.9.0/janito/shell/commands/edit.py +21 -0
  90. janito-1.9.0/janito/shell/commands/history_view.py +18 -0
  91. janito-1.9.0/janito/shell/commands/lang.py +16 -0
  92. janito-1.9.0/janito/shell/commands/livelogs.py +40 -0
  93. janito-1.9.0/janito/shell/commands/prompt.py +46 -0
  94. janito-1.9.0/janito/shell/commands/session.py +32 -0
  95. janito-1.9.0/janito/shell/commands/session_control.py +42 -0
  96. {janito-1.7.0/janito/cli_chat_shell → janito-1.9.0/janito/shell}/commands/sum.py +6 -6
  97. janito-1.9.0/janito/shell/commands/termweb_log.py +86 -0
  98. janito-1.9.0/janito/shell/commands/tools.py +23 -0
  99. {janito-1.7.0/janito/cli_chat_shell → janito-1.9.0/janito/shell}/commands/utility.py +9 -5
  100. janito-1.9.0/janito/shell/commands/verbose.py +29 -0
  101. janito-1.9.0/janito/shell/commands.py +40 -0
  102. janito-1.9.0/janito/shell/main.py +321 -0
  103. janito-1.9.0/janito/shell/prompt/completer.py +20 -0
  104. janito-1.7.0/janito/cli_chat_shell/chat_ui.py → janito-1.9.0/janito/shell/prompt/session_setup.py +19 -6
  105. janito-1.9.0/janito/shell/session/manager.py +122 -0
  106. janito-1.9.0/janito/shell/ui/interactive.py +197 -0
  107. janito-1.9.0/janito/termweb/app.py +95 -0
  108. janito-1.9.0/janito/termweb/static/editor.css +146 -0
  109. janito-1.9.0/janito/termweb/static/editor.css.bak +27 -0
  110. janito-1.9.0/janito/termweb/static/editor.html +40 -0
  111. janito-1.9.0/janito/termweb/static/editor.html.bak +39 -0
  112. janito-1.9.0/janito/termweb/static/editor.js +209 -0
  113. janito-1.9.0/janito/termweb/static/editor.js.bak +227 -0
  114. janito-1.9.0/janito/termweb/static/explorer.html.bak +59 -0
  115. janito-1.9.0/janito/termweb/static/favicon.ico +0 -0
  116. janito-1.9.0/janito/termweb/static/favicon.ico.bak +0 -0
  117. janito-1.9.0/janito/termweb/static/index.html +54 -0
  118. janito-1.9.0/janito/termweb/static/index.html.bak +54 -0
  119. janito-1.9.0/janito/termweb/static/index.html.bak.bak +175 -0
  120. janito-1.9.0/janito/termweb/static/landing.html.bak +36 -0
  121. janito-1.9.0/janito/termweb/static/termicon.svg +1 -0
  122. janito-1.9.0/janito/termweb/static/termweb.css +235 -0
  123. janito-1.9.0/janito/termweb/static/termweb.css.bak +235 -0
  124. janito-1.9.0/janito/termweb/static/termweb.js +168 -0
  125. janito-1.9.0/janito/termweb/static/termweb.js.bak +169 -0
  126. janito-1.9.0/janito/termweb/static/termweb.js.bak.bak +157 -0
  127. janito-1.9.0/janito/termweb/static/termweb_quickopen.js +135 -0
  128. janito-1.9.0/janito/termweb/static/termweb_quickopen.js.bak +125 -0
  129. janito-1.9.0/janito/web/__init__.py +0 -0
  130. {janito-1.7.0 → janito-1.9.0}/janito/web/app.py +4 -4
  131. {janito-1.7.0 → janito-1.9.0/janito.egg-info}/PKG-INFO +62 -26
  132. janito-1.9.0/janito.egg-info/SOURCES.txt +171 -0
  133. {janito-1.7.0 → janito-1.9.0}/janito.egg-info/requires.txt +1 -0
  134. {janito-1.7.0 → janito-1.9.0}/pyproject.toml +8 -4
  135. janito-1.9.0/tests/test_conversation_history.py +67 -0
  136. janito-1.9.0/tests/test_find_files.py +55 -0
  137. janito-1.9.0/tests/test_outline_no_overlap.py +31 -0
  138. janito-1.9.0/tests/test_outline_python_file.py +35 -0
  139. janito-1.9.0/tests/test_outline_python_file_complex.py +52 -0
  140. janito-1.9.0/tests/test_outline_tool_run.py +46 -0
  141. {janito-1.7.0 → janito-1.9.0}/tests/test_run_powershell_command.py +1 -1
  142. {janito-1.7.0 → janito-1.9.0}/tests/test_set_role.py +1 -1
  143. {janito-1.7.0 → janito-1.9.0}/tests/test_tool_registry_docstring_formats.py +4 -4
  144. {janito-1.7.0 → janito-1.9.0}/tests/test_tool_registry_manual_sim.py +19 -10
  145. {janito-1.7.0 → janito-1.9.0}/tests/test_tool_registry_validation.py +10 -3
  146. janito-1.9.0/tests/test_tool_use_tracker.py +38 -0
  147. janito-1.9.0/tests/test_validate_file_syntax.py +66 -0
  148. janito-1.9.0/tests/test_validate_file_syntax_xml_html.py +42 -0
  149. janito-1.9.0/tests/test_validate_markdown_syntax.py +64 -0
  150. janito-1.7.0/MANIFEST.in +0 -3
  151. janito-1.7.0/janito/__init__.py +0 -1
  152. janito-1.7.0/janito/agent/config_defaults.py +0 -13
  153. janito-1.7.0/janito/agent/config_utils.py +0 -9
  154. janito-1.7.0/janito/agent/conversation.py +0 -132
  155. janito-1.7.0/janito/agent/conversation_api.py +0 -98
  156. janito-1.7.0/janito/agent/conversation_tool_calls.py +0 -22
  157. janito-1.7.0/janito/agent/profile_manager.py +0 -164
  158. janito-1.7.0/janito/agent/templates/profiles/system_prompt_template_base.toml +0 -76
  159. janito-1.7.0/janito/agent/templates/profiles/system_prompt_template_default.toml +0 -3
  160. janito-1.7.0/janito/agent/templates/profiles/system_prompt_template_technical.toml +0 -13
  161. janito-1.7.0/janito/agent/tests/test_prompt_toml.py +0 -61
  162. janito-1.7.0/janito/agent/tool_registry.py +0 -118
  163. janito-1.7.0/janito/agent/tool_registry_core.py +0 -2
  164. janito-1.7.0/janito/agent/tools/create_directory.py +0 -50
  165. janito-1.7.0/janito/agent/tools/create_file.py +0 -47
  166. janito-1.7.0/janito/agent/tools/find_files.py +0 -52
  167. janito-1.7.0/janito/agent/tools/get_file_outline.py +0 -146
  168. janito-1.7.0/janito/agent/tools/get_lines.py +0 -75
  169. janito-1.7.0/janito/agent/tools/memory.py +0 -68
  170. janito-1.7.0/janito/agent/tools/move_file.py +0 -59
  171. janito-1.7.0/janito/agent/tools/py_compile_file.py +0 -40
  172. janito-1.7.0/janito/agent/tools/remove_directory.py +0 -50
  173. janito-1.7.0/janito/agent/tools/remove_file.py +0 -40
  174. janito-1.7.0/janito/agent/tools/replace_file.py +0 -51
  175. janito-1.7.0/janito/agent/tools/replace_text_in_file.py +0 -117
  176. janito-1.7.0/janito/agent/tools/rich_live.py +0 -44
  177. janito-1.7.0/janito/agent/tools/run_powershell_command.py +0 -153
  178. janito-1.7.0/janito/agent/tools/search_files.py +0 -65
  179. janito-1.7.0/janito/agent/tools/tools_utils.py +0 -13
  180. janito-1.7.0/janito/agent/tools/utils.py +0 -34
  181. janito-1.7.0/janito/cli/main.py +0 -41
  182. janito-1.7.0/janito/cli/runner/cli_main.py +0 -138
  183. janito-1.7.0/janito/cli/runner/scan.py +0 -57
  184. janito-1.7.0/janito/cli_chat_shell/chat_loop.py +0 -128
  185. janito-1.7.0/janito/cli_chat_shell/chat_state.py +0 -38
  186. janito-1.7.0/janito/cli_chat_shell/commands/__init__.py +0 -47
  187. janito-1.7.0/janito/cli_chat_shell/commands/history_reset.py +0 -29
  188. janito-1.7.0/janito/cli_chat_shell/commands/session.py +0 -48
  189. janito-1.7.0/janito/cli_chat_shell/commands/session_control.py +0 -12
  190. janito-1.7.0/janito/cli_chat_shell/commands/system.py +0 -73
  191. janito-1.7.0/janito/cli_chat_shell/session_manager.py +0 -64
  192. janito-1.7.0/janito/cli_chat_shell/ui.py +0 -178
  193. janito-1.7.0/janito/rich_utils.py +0 -43
  194. janito-1.7.0/janito.egg-info/SOURCES.txt +0 -104
  195. janito-1.7.0/tests/test_detect_windows_shell.py +0 -12
  196. janito-1.7.0/tests/test_markdown_outline.py +0 -11
  197. janito-1.7.0/tests/test_memory_tool.py +0 -44
  198. janito-1.7.0/tests/test_sum_command.py +0 -46
  199. janito-1.7.0/tests/test_tools.py +0 -137
  200. {janito-1.7.0 → janito-1.9.0}/LICENSE +0 -0
  201. {janito-1.7.0 → janito-1.9.0}/janito/__main__.py +0 -0
  202. {janito-1.7.0 → janito-1.9.0}/janito/agent/__init__.py +0 -0
  203. /janito-1.7.0/janito/agent/content_handler.py → /janito-1.9.0/janito/agent/config_utils.py +0 -0
  204. /janito-1.7.0/janito/cli/__init__.py → /janito-1.9.0/janito/agent/content_handler.py +0 -0
  205. {janito-1.7.0 → janito-1.9.0}/janito/agent/conversation_ui.py +0 -0
  206. {janito-1.7.0 → janito-1.9.0}/janito/agent/platform_discovery.py +0 -0
  207. {janito-1.7.0 → janito-1.9.0}/janito/agent/rich_live.py +0 -0
  208. {janito-1.7.0 → janito-1.9.0}/janito/agent/runtime_config.py +0 -0
  209. {janito-1.7.0/janito/cli/runner → janito-1.9.0/janito/cli}/__init__.py +0 -0
  210. {janito-1.7.0 → janito-1.9.0}/janito/cli/_print_config.py +0 -0
  211. {janito-1.7.0 → janito-1.9.0}/janito/cli/_utils.py +0 -0
  212. {janito-1.7.0 → janito-1.9.0}/janito/cli/config_commands.py +0 -0
  213. /janito-1.7.0/janito/cli/runner/formatting.py → /janito-1.9.0/janito/cli/formatting_runner.py +0 -0
  214. {janito-1.7.0/janito/cli_chat_shell → janito-1.9.0/janito/shell}/__init__.py +0 -0
  215. {janito-1.7.0/janito/cli_chat_shell → janito-1.9.0/janito/shell/prompt}/load_prompt.py +0 -0
  216. /janito-1.7.0/janito/cli_chat_shell/config_shell.py → /janito-1.9.0/janito/shell/session/config.py +0 -0
  217. /janito-1.7.0/janito/web/__init__.py → /janito-1.9.0/janito/shell/session/history.py +0 -0
  218. {janito-1.7.0 → janito-1.9.0}/janito/web/__main__.py +0 -0
  219. {janito-1.7.0 → janito-1.9.0}/janito.egg-info/dependency_links.txt +0 -0
  220. {janito-1.7.0 → janito-1.9.0}/janito.egg-info/entry_points.txt +0 -0
  221. {janito-1.7.0 → janito-1.9.0}/janito.egg-info/top_level.txt +0 -0
  222. {janito-1.7.0 → janito-1.9.0}/setup.cfg +0 -0
  223. {janito-1.7.0 → janito-1.9.0}/tests/test_basic.py +0 -0
@@ -0,0 +1,6 @@
1
+ # Exclude all .bak files from the package
2
+ exclude *.bak
3
+ recursive-exclude * *.bak
4
+
5
+ # Include static files for termweb
6
+ recursive-include janito/termweb/static *.*
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: janito
3
- Version: 1.7.0
3
+ Version: 1.9.0
4
4
  Summary: Natural Language Coding Agent,
5
5
  Author-email: João Pinto <joao.pinto@gmail.com>
6
6
  License-Expression: MIT
@@ -22,6 +22,7 @@ Requires-Dist: prompt_toolkit
22
22
  Requires-Dist: requests
23
23
  Requires-Dist: rich
24
24
  Requires-Dist: toml
25
+ Requires-Dist: lxml
25
26
  Provides-Extra: docs
26
27
  Requires-Dist: mkdocs>=1.5.3; extra == "docs"
27
28
  Requires-Dist: mkdocs-material>=9.4.8; extra == "docs"
@@ -29,19 +30,53 @@ Dynamic: license-file
29
30
 
30
31
  # 🚀 Janito: Natural Language Coding Agent
31
32
 
32
- **Current Version: 1.7.0**
33
+ **Current Version: 1.8.1**
33
34
  See [CHANGELOG.md](./CHANGELOG.md) for details on the latest release.
34
35
 
35
36
  Janito is an AI-powered assistant for the command line and web that interprets natural language system_prompt_template to edit code, manage files, and analyze projects using patterns and tools designed by experienced software engineers. It prioritizes transparency, interactive clarification, and precise, reviewable changes.
36
37
 
37
38
  For a technical overview, see the [Architecture Guide](docs/reference/architecture.md).
38
39
 
40
+ ## 🧪 Experimental Feature: termweb File Viewer
41
+
42
+ Janito now includes an experimental lightweight web file viewer for use with the CLI chat shell. This feature allows you to click on file paths in the terminal (when using a Rich-compatible terminal) and instantly preview file contents in your browser—no full IDE required!
43
+
44
+ ### How to Use
45
+
46
+ - Start the CLI chat shell with the `--termweb` flag:
47
+ ```bash
48
+ janito --termweb
49
+ ```
50
+ - To disable the termweb file viewer, use the `--no-termweb` flag.
51
+ - By default, the viewer runs at http://localhost:8088 (or the next available port up to 8100).
52
+ - To specify a port, use `--termweb-port 8090`.
53
+ - File paths in CLI output become clickable links that open the file in your browser.
54
+
55
+ **Note:** This feature is experimental. It is intended for quick file previews and review, not for editing or production use. Feedback is welcome!
56
+
57
+ ### Why is this useful?
58
+ - Enables instant file previews from the CLI without a full IDE.
59
+ - Works with all Janito file tools and outputs that display file paths.
60
+ - Uses the Rich library’s link markup for clickable terminal links.
61
+
62
+ ---
63
+
39
64
  ## 📖 Full Documentation & Overview
40
65
  - For structured and in-depth guides, visit the [Janito Documentation Site](https://docs.janito.dev).
41
66
  - For a high-level, user-friendly overview, see [janito.dev](https://janito.dev).
42
67
 
43
68
  ---
44
69
 
70
+ ## Listing Available Tools
71
+
72
+ To list all registered tools on the command line, use the option:
73
+
74
+ ```sh
75
+ janito --list-tools
76
+ ```
77
+
78
+ This will display a colorful table with the name, description, and parameters of each available tool.
79
+
45
80
  ## ⚡ Quick Start
46
81
 
47
82
  ## 🖥️ Supported Human Interfaces
@@ -61,6 +96,7 @@ You can alter Janito's behavior in any interface using these flags:
61
96
  - `--no-tools`: Disable all tool usage (Janito will only use the language model, no file/code/shell actions).
62
97
  - `--trust-tools`/`-T`: Trusted tools mode (suppresses all tool output, only shows output file locations).
63
98
  - `--vanilla`: Disables tools, system prompt, and temperature settings for a pure LLM chat experience.
99
+ - `--no-termweb`: Disables the termweb file viewer for terminal links.
64
100
 
65
101
  These modifiers can be combined with any interface mode for tailored workflows.
66
102
 
@@ -89,7 +125,7 @@ janito --web
89
125
  - 📁 **File & Directory Management:** Navigate, create, move, or remove files and folders.
90
126
  - 🧠 **Context-Aware:** Understands your project structure for precise edits.
91
127
  - 💬 **Interactive User Prompts:** Asks for clarification when needed.
92
- - 🧩 **Extensible Tooling:** Built-in tools for file operations, shell commands, directory and file management, Python code execution and validation, text replacement, and more.
128
+ - 🛠️ **Extensible Tooling:** Built-in tools for file operations, shell commands, directory and file management, Python code execution and validation, text replacement, and more.
93
129
  - See [janito/agent/tools/README.md](janito/agent/tools/README.md) for the full list of built-in tools and their usage details. For the message handler model, see [docs/MESSAGE_HANDLER_MODEL.md](docs/MESSAGE_HANDLER_MODEL.md).
94
130
  - 🌐 **Web Interface (In Development):** Simple web UI for streaming responses and tool progress.
95
131
 
@@ -101,7 +137,7 @@ janito --web
101
137
 
102
138
  ### Contributing & Developer Guide
103
139
 
104
- If you want to extend Janito or add new tools, see the [Developer Guide](docs/README_DEV.md) for system_prompt_template, tool registration requirements, and code style guidelines. For the full list of built-in tools and their usage, see the [Tools Reference](janito/agent/tools/README.md).
140
+ If you want to extend Janito or add new tools, see the [Developer Guide](docs/README_DEV.md) for system_prompt_template, tool registration requirements, and code profile guidelines. For the full list of built-in tools and their usage, see the [Tools Reference](janito/agent/tools/README.md).
105
141
 
106
142
 
107
143
 
@@ -138,12 +174,12 @@ For details on using models hosted on Azure OpenAI, see [docs/AZURE_OPENAI.md](d
138
174
 
139
175
  ---
140
176
 
141
- ## 🧩 System Prompt & Role
177
+ ## 🧑‍💻 System Prompt & Role
142
178
 
143
- Janito operates using a system prompt template that defines its behavior, communication style, and capabilities. By default, Janito assumes the role of a "software engineer"—this means its responses and actions are tailored to the expectations and best practices of professional software engineering.
179
+ Janito operates using a system prompt template that defines its behavior, communication profile, and capabilities. By default, Janito assumes the role of a "software engineer"—this means its responses and actions are tailored to the expectations and best practices of professional software engineering.
144
180
 
145
181
  - **Role:** You can customize the agent's role (e.g., "data scientist", "DevOps engineer") using the `--role` flag or config. The default is `software engineer`.
146
- - **System Prompt Template:** The system prompt is rendered from a Jinja2 template (see `janito/agent/templates/system_prompt_template.j2`). This template governs how the agent interprets system_prompt_template, interacts with files, and communicates with users.
182
+ - **System Prompt Template:** The system prompt is rendered from a Jinja2 template (see `janito/agent/templates/prompt_prompt_template.j2`). This template governs how the agent interprets system_prompt_template, interacts with files, and communicates with users.
147
183
  - **Customization & Precedence:** Advanced users can override the system prompt with the `--system` flag (raw string), or point to a custom file using `--system-file`. The precedence is: `--system-file` > `--system`/config > default template.
148
184
 
149
185
  The default template ensures the agent:
@@ -152,7 +188,7 @@ The default template ensures the agent:
152
188
  - Provides concise plans before taking action
153
189
  - Documents any changes made
154
190
 
155
- For more details or to customize the prompt, see the template file at `janito/agent/templates/system_prompt_template.j2` and the architecture overview in [docs/reference/architecture.md](docs/reference/architecture.md).
191
+ For more details or to customize the prompt, see the template file at `janito/agent/templates/prompt_prompt_template.j2` and the architecture overview in [docs/reference/architecture.md](docs/reference/architecture.md).
156
192
 
157
193
  ---
158
194
 
@@ -184,18 +220,18 @@ Vanilla mode is ideal for:
184
220
 
185
221
  > Note: Vanilla mode is a runtime switch and does not change the Agent API or class signatures. It is controlled via CLI/config only.
186
222
 
187
- ## 🧑‍💻 AgentProfileManager: Profile, Role, and Prompt Management
223
+ ## 👨‍💻 AgentProfileManager: Profile, Role, and Prompt Management
188
224
 
189
- Janito now uses a dedicated `AgentProfileManager` class to manage user profiles, roles, interaction styles, and system prompt selection. This manager:
190
- - Stores the current role (e.g., "software engineer") and interaction style (e.g., "default", "technical").
191
- - Renders the system prompt from the appropriate template based on interaction style.
225
+ Janito now uses a dedicated `AgentProfileManager` class to manage user profiles, roles, interaction profiles, and system prompt selection. This manager:
226
+ - Stores the current role (e.g., "software engineer") and interaction profile (e.g., "default", "technical").
227
+ - Renders the system prompt from the appropriate template based on interaction profile.
192
228
  - Instantiates and manages the low-level LLM Agent, passing the correct prompt.
193
- - Provides methods to update the role, interaction style, and refresh the prompt at runtime.
229
+ - Provides methods to update the role, interaction profile, and refresh the prompt at runtime.
194
230
 
195
231
  ### Multiple System Prompt Templates
196
- - The system prompt template is now selected based on the interaction style (e.g., `default` or `technical`).
232
+ - The system prompt template is now selected based on the interaction profile (e.g., `default` or `technical`).
197
233
  - Templates are located in `janito/agent/templates/` (see `system_prompt_template.j2` and `system_prompt_template_technical.j2`).
198
- - You can switch interaction styles at runtime using the profile manager, enabling different agent behaviors for different user needs.
234
+ - You can switch interaction profiles at runtime using the profile manager, enabling different agent behaviors for different user needs.
199
235
 
200
236
  This separation ensures that the LLM Agent remains focused on language model interaction and tool execution, while all profile, role, and prompt logic is managed at a higher level.
201
237
 
@@ -203,45 +239,45 @@ See `janito/agent/profile_manager.py` for implementation details.
203
239
 
204
240
  ### Agent Interaction Style
205
241
 
206
- You can control the agent's behavior and prompt style globally or per-project using the `interaction_style` config key. Supported values:
242
+ You can control the agent's behavior and prompt profile globally or per-project using the `profile` config key. See [Prompt Profiles Guide](docs/guides/prompt_profiles.md) for all available styles and combinations.
207
243
  - `default`: Concise, general-purpose agent (default)
208
244
  - `technical`: Strict, workflow-oriented for technical/developer use
209
245
 
210
246
  Set globally:
211
247
  ```bash
212
- janito --set-global-config interaction_style=technical
248
+ janito --set-global-config profile=technical
213
249
  ```
214
250
  Or per-project (in your project root):
215
251
  ```bash
216
- janito --set-local-config interaction_style=technical
252
+ janito --set-local-config profile=technical
217
253
  ```
218
254
 
219
255
  You can also override for a session with the CLI flag:
220
256
  ```bash
221
- janito --style technical
257
+ janito --profile technical
222
258
  ```
223
259
 
224
260
  See [docs/CONFIGURATION.md](docs/CONFIGURATION.md) for full details.
225
261
 
226
- ## 🧩 Combinatorial Style System
262
+ ## 🧑‍💻 Combinatorial Style System
227
263
 
228
- Janito now supports combinatorial styles for system prompts, allowing you to combine a main style (such as `default` or `technical`) with one or more feature extensions (such as `commit_all`).
264
+ Janito now supports combinatorial profiles for system prompts, allowing you to combine a main profile (such as `default` or `technical`) with one or more feature extensions (such as `commit_all`).
229
265
 
230
- - **Main style:** The base agent behavior and workflow (e.g., `default`, `technical`).
231
- - **Feature extensions:** Optional features that override or extend the main style (e.g., `commit_all`).
266
+ - **Main profile:** The base agent behavior and workflow (e.g., `default`, `technical`).
267
+ - **Feature extensions:** Optional features that override or extend the main profile (e.g., `commit_all`).
232
268
  - **Syntax:** Use a hyphen to combine, e.g., `technical-commit_all`.
233
269
 
234
270
  **How it works:**
235
- - The main style template is loaded first.
271
+ - The main profile template is loaded first.
236
272
  - Each feature extension template is layered on top, overriding or extending specific blocks in the main template.
237
273
  - Feature templates must use `{% extends parent_template %}` for dynamic inheritance.
238
274
 
239
275
  **Example usage:**
240
276
  ```bash
241
- janito --style technical-commit_all
277
+ janito --profile technical-commit_all
242
278
  ```
243
279
 
244
- This will apply the `technical` style with the `commit_all` feature enabled in the agent's system prompt.
280
+ This will apply the `technical` profile with the `commit_all` feature enabled in the agent's system prompt.
245
281
 
246
282
  See `janito/render_prompt.py` and `janito/agent/templates/` for implementation details and to create your own feature extensions.
247
283
 
@@ -1,18 +1,52 @@
1
1
  # 🚀 Janito: Natural Language Coding Agent
2
2
 
3
- **Current Version: 1.7.0**
3
+ **Current Version: 1.8.1**
4
4
  See [CHANGELOG.md](./CHANGELOG.md) for details on the latest release.
5
5
 
6
6
  Janito is an AI-powered assistant for the command line and web that interprets natural language system_prompt_template to edit code, manage files, and analyze projects using patterns and tools designed by experienced software engineers. It prioritizes transparency, interactive clarification, and precise, reviewable changes.
7
7
 
8
8
  For a technical overview, see the [Architecture Guide](docs/reference/architecture.md).
9
9
 
10
+ ## 🧪 Experimental Feature: termweb File Viewer
11
+
12
+ Janito now includes an experimental lightweight web file viewer for use with the CLI chat shell. This feature allows you to click on file paths in the terminal (when using a Rich-compatible terminal) and instantly preview file contents in your browser—no full IDE required!
13
+
14
+ ### How to Use
15
+
16
+ - Start the CLI chat shell with the `--termweb` flag:
17
+ ```bash
18
+ janito --termweb
19
+ ```
20
+ - To disable the termweb file viewer, use the `--no-termweb` flag.
21
+ - By default, the viewer runs at http://localhost:8088 (or the next available port up to 8100).
22
+ - To specify a port, use `--termweb-port 8090`.
23
+ - File paths in CLI output become clickable links that open the file in your browser.
24
+
25
+ **Note:** This feature is experimental. It is intended for quick file previews and review, not for editing or production use. Feedback is welcome!
26
+
27
+ ### Why is this useful?
28
+ - Enables instant file previews from the CLI without a full IDE.
29
+ - Works with all Janito file tools and outputs that display file paths.
30
+ - Uses the Rich library’s link markup for clickable terminal links.
31
+
32
+ ---
33
+
10
34
  ## 📖 Full Documentation & Overview
11
35
  - For structured and in-depth guides, visit the [Janito Documentation Site](https://docs.janito.dev).
12
36
  - For a high-level, user-friendly overview, see [janito.dev](https://janito.dev).
13
37
 
14
38
  ---
15
39
 
40
+ ## Listing Available Tools
41
+
42
+ To list all registered tools on the command line, use the option:
43
+
44
+ ```sh
45
+ janito --list-tools
46
+ ```
47
+
48
+ This will display a colorful table with the name, description, and parameters of each available tool.
49
+
16
50
  ## ⚡ Quick Start
17
51
 
18
52
  ## 🖥️ Supported Human Interfaces
@@ -32,6 +66,7 @@ You can alter Janito's behavior in any interface using these flags:
32
66
  - `--no-tools`: Disable all tool usage (Janito will only use the language model, no file/code/shell actions).
33
67
  - `--trust-tools`/`-T`: Trusted tools mode (suppresses all tool output, only shows output file locations).
34
68
  - `--vanilla`: Disables tools, system prompt, and temperature settings for a pure LLM chat experience.
69
+ - `--no-termweb`: Disables the termweb file viewer for terminal links.
35
70
 
36
71
  These modifiers can be combined with any interface mode for tailored workflows.
37
72
 
@@ -60,7 +95,7 @@ janito --web
60
95
  - 📁 **File & Directory Management:** Navigate, create, move, or remove files and folders.
61
96
  - 🧠 **Context-Aware:** Understands your project structure for precise edits.
62
97
  - 💬 **Interactive User Prompts:** Asks for clarification when needed.
63
- - 🧩 **Extensible Tooling:** Built-in tools for file operations, shell commands, directory and file management, Python code execution and validation, text replacement, and more.
98
+ - 🛠️ **Extensible Tooling:** Built-in tools for file operations, shell commands, directory and file management, Python code execution and validation, text replacement, and more.
64
99
  - See [janito/agent/tools/README.md](janito/agent/tools/README.md) for the full list of built-in tools and their usage details. For the message handler model, see [docs/MESSAGE_HANDLER_MODEL.md](docs/MESSAGE_HANDLER_MODEL.md).
65
100
  - 🌐 **Web Interface (In Development):** Simple web UI for streaming responses and tool progress.
66
101
 
@@ -72,7 +107,7 @@ janito --web
72
107
 
73
108
  ### Contributing & Developer Guide
74
109
 
75
- If you want to extend Janito or add new tools, see the [Developer Guide](docs/README_DEV.md) for system_prompt_template, tool registration requirements, and code style guidelines. For the full list of built-in tools and their usage, see the [Tools Reference](janito/agent/tools/README.md).
110
+ If you want to extend Janito or add new tools, see the [Developer Guide](docs/README_DEV.md) for system_prompt_template, tool registration requirements, and code profile guidelines. For the full list of built-in tools and their usage, see the [Tools Reference](janito/agent/tools/README.md).
76
111
 
77
112
 
78
113
 
@@ -109,12 +144,12 @@ For details on using models hosted on Azure OpenAI, see [docs/AZURE_OPENAI.md](d
109
144
 
110
145
  ---
111
146
 
112
- ## 🧩 System Prompt & Role
147
+ ## 🧑‍💻 System Prompt & Role
113
148
 
114
- Janito operates using a system prompt template that defines its behavior, communication style, and capabilities. By default, Janito assumes the role of a "software engineer"—this means its responses and actions are tailored to the expectations and best practices of professional software engineering.
149
+ Janito operates using a system prompt template that defines its behavior, communication profile, and capabilities. By default, Janito assumes the role of a "software engineer"—this means its responses and actions are tailored to the expectations and best practices of professional software engineering.
115
150
 
116
151
  - **Role:** You can customize the agent's role (e.g., "data scientist", "DevOps engineer") using the `--role` flag or config. The default is `software engineer`.
117
- - **System Prompt Template:** The system prompt is rendered from a Jinja2 template (see `janito/agent/templates/system_prompt_template.j2`). This template governs how the agent interprets system_prompt_template, interacts with files, and communicates with users.
152
+ - **System Prompt Template:** The system prompt is rendered from a Jinja2 template (see `janito/agent/templates/prompt_prompt_template.j2`). This template governs how the agent interprets system_prompt_template, interacts with files, and communicates with users.
118
153
  - **Customization & Precedence:** Advanced users can override the system prompt with the `--system` flag (raw string), or point to a custom file using `--system-file`. The precedence is: `--system-file` > `--system`/config > default template.
119
154
 
120
155
  The default template ensures the agent:
@@ -123,7 +158,7 @@ The default template ensures the agent:
123
158
  - Provides concise plans before taking action
124
159
  - Documents any changes made
125
160
 
126
- For more details or to customize the prompt, see the template file at `janito/agent/templates/system_prompt_template.j2` and the architecture overview in [docs/reference/architecture.md](docs/reference/architecture.md).
161
+ For more details or to customize the prompt, see the template file at `janito/agent/templates/prompt_prompt_template.j2` and the architecture overview in [docs/reference/architecture.md](docs/reference/architecture.md).
127
162
 
128
163
  ---
129
164
 
@@ -155,18 +190,18 @@ Vanilla mode is ideal for:
155
190
 
156
191
  > Note: Vanilla mode is a runtime switch and does not change the Agent API or class signatures. It is controlled via CLI/config only.
157
192
 
158
- ## 🧑‍💻 AgentProfileManager: Profile, Role, and Prompt Management
193
+ ## 👨‍💻 AgentProfileManager: Profile, Role, and Prompt Management
159
194
 
160
- Janito now uses a dedicated `AgentProfileManager` class to manage user profiles, roles, interaction styles, and system prompt selection. This manager:
161
- - Stores the current role (e.g., "software engineer") and interaction style (e.g., "default", "technical").
162
- - Renders the system prompt from the appropriate template based on interaction style.
195
+ Janito now uses a dedicated `AgentProfileManager` class to manage user profiles, roles, interaction profiles, and system prompt selection. This manager:
196
+ - Stores the current role (e.g., "software engineer") and interaction profile (e.g., "default", "technical").
197
+ - Renders the system prompt from the appropriate template based on interaction profile.
163
198
  - Instantiates and manages the low-level LLM Agent, passing the correct prompt.
164
- - Provides methods to update the role, interaction style, and refresh the prompt at runtime.
199
+ - Provides methods to update the role, interaction profile, and refresh the prompt at runtime.
165
200
 
166
201
  ### Multiple System Prompt Templates
167
- - The system prompt template is now selected based on the interaction style (e.g., `default` or `technical`).
202
+ - The system prompt template is now selected based on the interaction profile (e.g., `default` or `technical`).
168
203
  - Templates are located in `janito/agent/templates/` (see `system_prompt_template.j2` and `system_prompt_template_technical.j2`).
169
- - You can switch interaction styles at runtime using the profile manager, enabling different agent behaviors for different user needs.
204
+ - You can switch interaction profiles at runtime using the profile manager, enabling different agent behaviors for different user needs.
170
205
 
171
206
  This separation ensures that the LLM Agent remains focused on language model interaction and tool execution, while all profile, role, and prompt logic is managed at a higher level.
172
207
 
@@ -174,47 +209,47 @@ See `janito/agent/profile_manager.py` for implementation details.
174
209
 
175
210
  ### Agent Interaction Style
176
211
 
177
- You can control the agent's behavior and prompt style globally or per-project using the `interaction_style` config key. Supported values:
212
+ You can control the agent's behavior and prompt profile globally or per-project using the `profile` config key. See [Prompt Profiles Guide](docs/guides/prompt_profiles.md) for all available styles and combinations.
178
213
  - `default`: Concise, general-purpose agent (default)
179
214
  - `technical`: Strict, workflow-oriented for technical/developer use
180
215
 
181
216
  Set globally:
182
217
  ```bash
183
- janito --set-global-config interaction_style=technical
218
+ janito --set-global-config profile=technical
184
219
  ```
185
220
  Or per-project (in your project root):
186
221
  ```bash
187
- janito --set-local-config interaction_style=technical
222
+ janito --set-local-config profile=technical
188
223
  ```
189
224
 
190
225
  You can also override for a session with the CLI flag:
191
226
  ```bash
192
- janito --style technical
227
+ janito --profile technical
193
228
  ```
194
229
 
195
230
  See [docs/CONFIGURATION.md](docs/CONFIGURATION.md) for full details.
196
231
 
197
- ## 🧩 Combinatorial Style System
232
+ ## 🧑‍💻 Combinatorial Style System
198
233
 
199
- Janito now supports combinatorial styles for system prompts, allowing you to combine a main style (such as `default` or `technical`) with one or more feature extensions (such as `commit_all`).
234
+ Janito now supports combinatorial profiles for system prompts, allowing you to combine a main profile (such as `default` or `technical`) with one or more feature extensions (such as `commit_all`).
200
235
 
201
- - **Main style:** The base agent behavior and workflow (e.g., `default`, `technical`).
202
- - **Feature extensions:** Optional features that override or extend the main style (e.g., `commit_all`).
236
+ - **Main profile:** The base agent behavior and workflow (e.g., `default`, `technical`).
237
+ - **Feature extensions:** Optional features that override or extend the main profile (e.g., `commit_all`).
203
238
  - **Syntax:** Use a hyphen to combine, e.g., `technical-commit_all`.
204
239
 
205
240
  **How it works:**
206
- - The main style template is loaded first.
241
+ - The main profile template is loaded first.
207
242
  - Each feature extension template is layered on top, overriding or extending specific blocks in the main template.
208
243
  - Feature templates must use `{% extends parent_template %}` for dynamic inheritance.
209
244
 
210
245
  **Example usage:**
211
246
  ```bash
212
- janito --style technical-commit_all
247
+ janito --profile technical-commit_all
213
248
  ```
214
249
 
215
- This will apply the `technical` style with the `commit_all` feature enabled in the agent's system prompt.
250
+ This will apply the `technical` profile with the `commit_all` feature enabled in the agent's system prompt.
216
251
 
217
252
  See `janito/render_prompt.py` and `janito/agent/templates/` for implementation details and to create your own feature extensions.
218
253
 
219
254
  ---
220
- _generated by janito.dev_
255
+ _generated by janito.dev_
@@ -0,0 +1 @@
1
+ __version__ = "1.9.0"
@@ -64,7 +64,7 @@ CONFIG_OPTIONS = {
64
64
  "use_azure_openai": "Whether to use Azure OpenAI client (default: False)",
65
65
  # Accept template.* keys as valid config keys (for CLI validation, etc.)
66
66
  "template": "Template context dictionary for Agent Profile prompt rendering (nested)",
67
- "interaction_style": "Interaction style for the Agent Profile (e.g., 'default' or 'technical')",
67
+ "profile": "Agent Profile name (only 'base' is supported)",
68
68
  # Note: template.* keys are validated dynamically, not statically here
69
69
  }
70
70
 
@@ -0,0 +1,36 @@
1
+ # Centralized config defaults for Janito
2
+ CONFIG_DEFAULTS = {
3
+ "api_key": None, # Must be set by user
4
+ "model": "openai/gpt-4.1", # Default model
5
+ "base_url": "https://openrouter.ai/api/v1",
6
+ "role": "software developer", # Part of the Agent Profile
7
+ "system_prompt_template": None, # None means auto-generate from Agent Profile role
8
+ "temperature": 0.2,
9
+ "max_tokens": 200000,
10
+ "use_azure_openai": False,
11
+ "azure_openai_api_version": "2023-05-15",
12
+ "profile": "base",
13
+ "providers": {
14
+ "openai": {
15
+ "api_key": None,
16
+ "base_url": "https://api.openai.com/v1",
17
+ "default_model": "gpt-3.5-turbo",
18
+ },
19
+ "azureai": {
20
+ "api_key": None,
21
+ "base_url": "https://your-azure-endpoint.openai.azure.com/",
22
+ "api_version": "2023-05-15",
23
+ "default_model": "gpt-35-turbo",
24
+ },
25
+ "openrouterai": {
26
+ "api_key": None,
27
+ "base_url": "https://openrouter.ai/api/v1",
28
+ "default_model": "openrouter/cognitive",
29
+ },
30
+ "fireworksai": {
31
+ "api_key": None,
32
+ "base_url": "https://api.fireworks.ai/inference/v1",
33
+ "default_model": "accounts/fireworks/models/firefunction-v1",
34
+ },
35
+ },
36
+ }
@@ -0,0 +1,197 @@
1
+ from janito.agent.conversation_api import (
2
+ get_openai_response,
3
+ get_openai_stream_response,
4
+ retry_api_call,
5
+ )
6
+ from janito.agent.conversation_tool_calls import handle_tool_calls
7
+ from janito.agent.conversation_ui import show_spinner, print_verbose_event
8
+ from janito.agent.conversation_exceptions import (
9
+ MaxRoundsExceededError,
10
+ EmptyResponseError,
11
+ NoToolSupportError,
12
+ )
13
+ from janito.agent.runtime_config import unified_config, runtime_config
14
+ import pprint
15
+
16
+
17
+ class ConversationHandler:
18
+ def __init__(self, client, model):
19
+ self.client = client
20
+ self.model = model
21
+ self.usage_history = []
22
+
23
+ @staticmethod
24
+ def remove_system_prompt(messages):
25
+ """
26
+ Return a new messages list with all system prompts removed.
27
+ """
28
+ return [msg for msg in messages if msg.get("role") != "system"]
29
+
30
+ def handle_conversation(
31
+ self,
32
+ messages,
33
+ max_rounds=100,
34
+ message_handler=None,
35
+ verbose_response=False,
36
+ spinner=False,
37
+ max_tokens=None,
38
+ verbose_events=False,
39
+ stream=False,
40
+ verbose_stream=False,
41
+ ):
42
+ from janito.agent.conversation_history import ConversationHistory
43
+
44
+ # Accept either ConversationHistory or a list for backward compatibility
45
+ if isinstance(messages, ConversationHistory):
46
+ history = messages
47
+ else:
48
+ history = ConversationHistory(messages)
49
+
50
+ if len(history) == 0:
51
+ raise ValueError("No prompt provided in messages")
52
+
53
+ resolved_max_tokens = max_tokens
54
+ if resolved_max_tokens is None:
55
+ resolved_max_tokens = unified_config.get("max_tokens", 200000)
56
+ try:
57
+ resolved_max_tokens = int(resolved_max_tokens)
58
+ except (TypeError, ValueError):
59
+ raise ValueError(
60
+ "max_tokens must be an integer, got: {resolved_max_tokens!r}".format(
61
+ resolved_max_tokens=resolved_max_tokens
62
+ )
63
+ )
64
+
65
+ # If vanilla mode is set and max_tokens was not provided, default to 8000
66
+ if runtime_config.get("vanilla_mode", False) and max_tokens is None:
67
+ resolved_max_tokens = 8000
68
+
69
+ for _ in range(max_rounds):
70
+ try:
71
+ if stream:
72
+ # Streaming mode
73
+ def get_stream():
74
+ return get_openai_stream_response(
75
+ self.client,
76
+ self.model,
77
+ history.get_messages(),
78
+ resolved_max_tokens,
79
+ verbose_stream=runtime_config.get("verbose_stream", False),
80
+ message_handler=message_handler,
81
+ )
82
+
83
+ retry_api_call(get_stream)
84
+ return None
85
+ else:
86
+ # Non-streaming mode
87
+ def api_call():
88
+ return get_openai_response(
89
+ self.client,
90
+ self.model,
91
+ history.get_messages(),
92
+ resolved_max_tokens,
93
+ )
94
+
95
+ if spinner:
96
+ response = show_spinner(
97
+ "Waiting for AI response...", retry_api_call, api_call
98
+ )
99
+ else:
100
+ response = retry_api_call(api_call)
101
+ except NoToolSupportError:
102
+ print(
103
+ "⚠️ Endpoint does not support tool use. Proceeding in vanilla mode (tools disabled)."
104
+ )
105
+ runtime_config.set("vanilla_mode", True)
106
+ if max_tokens is None:
107
+ runtime_config.set("max_tokens", 8000)
108
+ resolved_max_tokens = 8000
109
+
110
+ # Remove system prompt for vanilla mode if needed (call this externally when appropriate)
111
+ # messages = ConversationHandler.remove_system_prompt(messages)
112
+ # Retry once with tools disabled
113
+ def api_call_vanilla():
114
+ return get_openai_response(
115
+ self.client, self.model, messages, resolved_max_tokens
116
+ )
117
+
118
+ if spinner:
119
+ response = show_spinner(
120
+ "Waiting for AI response (tools disabled)...",
121
+ retry_api_call,
122
+ api_call_vanilla,
123
+ )
124
+ else:
125
+ response = retry_api_call(api_call_vanilla)
126
+ print(
127
+ "[DEBUG] OpenAI API raw response (tools disabled):",
128
+ repr(response),
129
+ )
130
+ if runtime_config.get("verbose_response", False):
131
+ pprint.pprint(response)
132
+ if response is None or not getattr(response, "choices", None):
133
+ raise EmptyResponseError(
134
+ f"No choices in response; possible API or LLM error. Raw response: {response!r}"
135
+ )
136
+ choice = response.choices[0]
137
+ usage = getattr(response, "usage", None)
138
+ usage_info = (
139
+ {
140
+ # DEBUG: Show usage extraction
141
+ "_debug_raw_usage": getattr(response, "usage", None),
142
+ "prompt_tokens": getattr(usage, "prompt_tokens", None),
143
+ "completion_tokens": getattr(usage, "completion_tokens", None),
144
+ "total_tokens": getattr(usage, "total_tokens", None),
145
+ }
146
+ if usage
147
+ else None
148
+ )
149
+ event = {"type": "content", "message": choice.message.content}
150
+ if runtime_config.get("verbose_events", False):
151
+ print_verbose_event(event)
152
+ if message_handler is not None and choice.message.content:
153
+ message_handler.handle_message(event)
154
+ if not choice.message.tool_calls:
155
+ agent_idx = len(
156
+ [m for m in history.get_messages() if m.get("role") == "agent"]
157
+ )
158
+ self.usage_history.append(
159
+ {"agent_index": agent_idx, "usage": usage_info}
160
+ )
161
+ # Add assistant response to history
162
+ history.add_message(
163
+ {
164
+ "role": "assistant",
165
+ "content": choice.message.content,
166
+ }
167
+ )
168
+ return {
169
+ "content": choice.message.content,
170
+ "usage": usage_info,
171
+ "usage_history": self.usage_history,
172
+ }
173
+ # Tool calls
174
+ tool_responses = handle_tool_calls(
175
+ choice.message.tool_calls, message_handler=message_handler
176
+ )
177
+ agent_idx = len(
178
+ [m for m in history.get_messages() if m.get("role") == "agent"]
179
+ )
180
+ self.usage_history.append({"agent_index": agent_idx, "usage": usage_info})
181
+ # Add assistant response with tool calls
182
+ history.add_message(
183
+ {
184
+ "role": "assistant",
185
+ "content": choice.message.content,
186
+ "tool_calls": [tc.to_dict() for tc in choice.message.tool_calls],
187
+ }
188
+ )
189
+ for tool_response in tool_responses:
190
+ history.add_message(
191
+ {
192
+ "role": "tool",
193
+ "tool_call_id": tool_response["tool_call_id"],
194
+ "content": tool_response["content"],
195
+ }
196
+ )
197
+ raise MaxRoundsExceededError(f"Max conversation rounds exceeded ({max_rounds})")