janito 2.16.0__tar.gz → 2.17.1__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 (323) hide show
  1. {janito-2.16.0 → janito-2.17.1}/CHANGELOG.md +28 -0
  2. {janito-2.16.0 → janito-2.17.1}/PKG-INFO +1 -1
  3. janito-2.17.1/docs/cerebras-setup.md +56 -0
  4. {janito-2.16.0 → janito-2.17.1}/docs/supported-providers-models.md +19 -1
  5. {janito-2.16.0 → janito-2.17.1}/janito/agent/setup_agent.py +1 -1
  6. {janito-2.16.0 → janito-2.17.1}/janito/cli/cli_commands/list_drivers.py +1 -0
  7. janito-2.17.1/janito/cli/cli_commands/set_api_key.py +30 -0
  8. {janito-2.16.0 → janito-2.17.1}/janito/cli/prompt_setup.py +3 -0
  9. janito-2.17.1/janito/drivers/cerebras/__init__.py +1 -0
  10. {janito-2.16.0 → janito-2.17.1}/janito/providers/__init__.py +1 -0
  11. {janito-2.16.0 → janito-2.17.1}/janito/providers/alibaba/provider.py +1 -3
  12. janito-2.17.1/janito/providers/cerebras/__init__.py +1 -0
  13. janito-2.17.1/janito/providers/cerebras/model_info.py +76 -0
  14. janito-2.17.1/janito/providers/cerebras/provider.py +145 -0
  15. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/read_files.py +1 -1
  16. {janito-2.16.0 → janito-2.17.1}/janito/tools/path_security.py +14 -0
  17. {janito-2.16.0 → janito-2.17.1}/janito/tools/tools_adapter.py +118 -26
  18. {janito-2.16.0 → janito-2.17.1}/janito.egg-info/PKG-INFO +1 -1
  19. {janito-2.16.0 → janito-2.17.1}/janito.egg-info/SOURCES.txt +6 -1
  20. {janito-2.16.0 → janito-2.17.1}/mkdocs.yml +1 -1
  21. {janito-2.16.0 → janito-2.17.1}/tests/adapters/local/test_read_files.py +1 -1
  22. janito-2.17.1/tests/test_provider_cerebras.py +93 -0
  23. janito-2.16.0/docs/index.md +0 -26
  24. janito-2.16.0/janito/cli/cli_commands/set_api_key.py +0 -19
  25. {janito-2.16.0 → janito-2.17.1}/.codespellrc +0 -0
  26. {janito-2.16.0 → janito-2.17.1}/.gitattributes +0 -0
  27. {janito-2.16.0 → janito-2.17.1}/.github/workflows/python-app.yml.disabled +0 -0
  28. {janito-2.16.0 → janito-2.17.1}/.gitignore +0 -0
  29. {janito-2.16.0 → janito-2.17.1}/.pre-commit-config.yaml +0 -0
  30. {janito-2.16.0 → janito-2.17.1}/.secrets.baseline +0 -0
  31. {janito-2.16.0 → janito-2.17.1}/.vscode/settings.json +0 -0
  32. {janito-2.16.0 → janito-2.17.1}/CHANGELOG_2.16.0.md +0 -0
  33. {janito-2.16.0 → janito-2.17.1}/LICENSE +0 -0
  34. {janito-2.16.0 → janito-2.17.1}/README-dev.md +0 -0
  35. {janito-2.16.0 → janito-2.17.1}/README.md +0 -0
  36. {janito-2.16.0 → janito-2.17.1}/UPDATING_DOCS.md +0 -0
  37. {janito-2.16.0 → janito-2.17.1}/adding_mcp.txt +0 -0
  38. {janito-2.16.0 → janito-2.17.1}/docs/DIV.md +0 -0
  39. {janito-2.16.0 → janito-2.17.1}/docs/Interfaces.txt +0 -0
  40. {janito-2.16.0 → janito-2.17.1}/docs/TOOLBAR-STYLING.md +0 -0
  41. {janito-2.16.0 → janito-2.17.1}/docs/about/costs.md +0 -0
  42. {janito-2.16.0 → janito-2.17.1}/docs/about/vs-webchats.md +0 -0
  43. {janito-2.16.0 → janito-2.17.1}/docs/about/why.md +0 -0
  44. {janito-2.16.0 → janito-2.17.1}/docs/alternatives.md +0 -0
  45. {janito-2.16.0 → janito-2.17.1}/docs/code_intelligence/agentic-frameworks-comparison.md +0 -0
  46. {janito-2.16.0 → janito-2.17.1}/docs/code_intelligence/code-generation-challenges.md +0 -0
  47. {janito-2.16.0 → janito-2.17.1}/docs/code_intelligence/code-generation-observability.md +0 -0
  48. {janito-2.16.0 → janito-2.17.1}/docs/code_intelligence/our-approach.md +0 -0
  49. {janito-2.16.0 → janito-2.17.1}/docs/code_intelligence/why-string-replacement.md +0 -0
  50. {janito-2.16.0 → janito-2.17.1}/docs/concepts/analysis-style.md +0 -0
  51. {janito-2.16.0 → janito-2.17.1}/docs/concepts/human-guided-ai.md +0 -0
  52. {janito-2.16.0 → janito-2.17.1}/docs/concepts/index.md +0 -0
  53. {janito-2.16.0 → janito-2.17.1}/docs/concepts/language-model-clients.md +0 -0
  54. {janito-2.16.0 → janito-2.17.1}/docs/concepts/prompt-design-style.md +0 -0
  55. {janito-2.16.0 → janito-2.17.1}/docs/deepseek-setup.md +0 -0
  56. {janito-2.16.0 → janito-2.17.1}/docs/driver-flow.md +0 -0
  57. {janito-2.16.0 → janito-2.17.1}/docs/driver-request-cancellation.md +0 -0
  58. {janito-2.16.0 → janito-2.17.1}/docs/drivers/events.md +0 -0
  59. {janito-2.16.0 → janito-2.17.1}/docs/drivers.md +0 -0
  60. {janito-2.16.0 → janito-2.17.1}/docs/event-bus.md +0 -0
  61. {janito-2.16.0 → janito-2.17.1}/docs/guides/configuration.md +0 -0
  62. {janito-2.16.0 → janito-2.17.1}/docs/guides/developing.md +0 -0
  63. {janito-2.16.0 → janito-2.17.1}/docs/guides/disabled-tools.md +0 -0
  64. {janito-2.16.0 → janito-2.17.1}/docs/guides/installation.md +0 -0
  65. {janito-2.16.0 → janito-2.17.1}/docs/guides/profiles.md +0 -0
  66. {janito-2.16.0 → janito-2.17.1}/docs/guides/prompting/README.md +0 -0
  67. {janito-2.16.0 → janito-2.17.1}/docs/guides/single-shot-terminal.md +0 -0
  68. {janito-2.16.0 → janito-2.17.1}/docs/guides/terminal-shell.md +0 -0
  69. {janito-2.16.0 → janito-2.17.1}/docs/guides/tools-developer-guide.md +0 -0
  70. {janito-2.16.0 → janito-2.17.1}/docs/guides/using.md +0 -0
  71. {janito-2.16.0 → janito-2.17.1}/docs/guides/using_tools.md +0 -0
  72. {janito-2.16.0 → janito-2.17.1}/docs/imgs/code-generation-observability.png +0 -0
  73. {janito-2.16.0 → janito-2.17.1}/docs/imgs/code_generation_observability.png +0 -0
  74. {janito-2.16.0 → janito-2.17.1}/docs/imgs/happy-programmer.png +0 -0
  75. {janito-2.16.0 → janito-2.17.1}/docs/imgs/happy-programmer.svg +0 -0
  76. {janito-2.16.0 → janito-2.17.1}/docs/imgs/terminal-one-shot.png +0 -0
  77. {janito-2.16.0 → janito-2.17.1}/docs/imgs/terminal-shell.png +0 -0
  78. {janito-2.16.0 → janito-2.17.1}/docs/imgs/terminal_one_shot.png +0 -0
  79. {janito-2.16.0 → janito-2.17.1}/docs/imgs/terminal_shell.png +0 -0
  80. {janito-2.16.0 → janito-2.17.1}/docs/llm-drivers-required-config.md +0 -0
  81. {janito-2.16.0 → janito-2.17.1}/docs/llm-drivers.md +0 -0
  82. {janito-2.16.0 → janito-2.17.1}/docs/meta/developer-toolchain.md +0 -0
  83. {janito-2.16.0 → janito-2.17.1}/docs/meta/quality-checks.txt +0 -0
  84. {janito-2.16.0 → janito-2.17.1}/docs/moonshotai-setup.md +0 -0
  85. {janito-2.16.0 → janito-2.17.1}/docs/reference/api.md +0 -0
  86. {janito-2.16.0 → janito-2.17.1}/docs/reference/azure-openai.md +0 -0
  87. {janito-2.16.0 → janito-2.17.1}/docs/reference/cli-options.md +0 -0
  88. {janito-2.16.0 → janito-2.17.1}/docs/reference/message-handler-model.md +0 -0
  89. {janito-2.16.0 → janito-2.17.1}/docs/reference/rich-message-handler.md +0 -0
  90. {janito-2.16.0 → janito-2.17.1}/docs/security.md +0 -0
  91. {janito-2.16.0 → janito-2.17.1}/docs/tools/search-text.md +0 -0
  92. {janito-2.16.0 → janito-2.17.1}/docs/tools-index.md +0 -0
  93. {janito-2.16.0 → janito-2.17.1}/docs/tools-natural-results.md +0 -0
  94. {janito-2.16.0 → janito-2.17.1}/docs/tools-precision.md +0 -0
  95. {janito-2.16.0 → janito-2.17.1}/docs/z-ai-setup.md +0 -0
  96. {janito-2.16.0 → janito-2.17.1}/git_diff.txt +0 -0
  97. {janito-2.16.0 → janito-2.17.1}/github_diff +0 -0
  98. {janito-2.16.0 → janito-2.17.1}/janito/README.md +0 -0
  99. {janito-2.16.0 → janito-2.17.1}/janito/__init__.py +0 -0
  100. {janito-2.16.0 → janito-2.17.1}/janito/__main__.py +0 -0
  101. {janito-2.16.0 → janito-2.17.1}/janito/_version.py +0 -0
  102. {janito-2.16.0 → janito-2.17.1}/janito/agent/templates/profiles/system_prompt_template_Developer_with_Python_Tools.txt.j2 +0 -0
  103. {janito-2.16.0 → janito-2.17.1}/janito/agent/templates/profiles/system_prompt_template_developer.txt.j2 +0 -0
  104. {janito-2.16.0 → janito-2.17.1}/janito/agent/templates/profiles/system_prompt_template_model_conversation_without_tools_or_context.txt.j2 +0 -0
  105. {janito-2.16.0 → janito-2.17.1}/janito/cli/__init__.py +0 -0
  106. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/bindings.py +0 -0
  107. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/chat_entry.py +0 -0
  108. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/prompt_style.py +0 -0
  109. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/script_runner.py +0 -0
  110. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/session.py +0 -0
  111. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/session_profile_select.py +0 -0
  112. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/autocomplete.py +0 -0
  113. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/__init__.py +0 -0
  114. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/_priv_check.py +0 -0
  115. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/_priv_status.py +0 -0
  116. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/bang.py +0 -0
  117. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/base.py +0 -0
  118. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/clear.py +0 -0
  119. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/conversation_restart.py +0 -0
  120. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/execute.py +0 -0
  121. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/help.py +0 -0
  122. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/history_view.py +0 -0
  123. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/lang.py +0 -0
  124. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/model.py +0 -0
  125. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/multi.py +0 -0
  126. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/privileges.py +0 -0
  127. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/prompt.py +0 -0
  128. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/read.py +0 -0
  129. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/role.py +0 -0
  130. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/session.py +0 -0
  131. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/session_control.py +0 -0
  132. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/tools.py +0 -0
  133. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/utility.py +0 -0
  134. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/verbose.py +0 -0
  135. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands/write.py +0 -0
  136. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/commands.bak.zip +0 -0
  137. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/input_history.py +0 -0
  138. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/session/__init__.py +0 -0
  139. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/session/history.py +0 -0
  140. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/session/manager.py +0 -0
  141. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/shell/session.bak.zip +0 -0
  142. {janito-2.16.0 → janito-2.17.1}/janito/cli/chat_mode/toolbar.py +0 -0
  143. {janito-2.16.0 → janito-2.17.1}/janito/cli/cli_commands/list_config.py +0 -0
  144. {janito-2.16.0 → janito-2.17.1}/janito/cli/cli_commands/list_models.py +0 -0
  145. {janito-2.16.0 → janito-2.17.1}/janito/cli/cli_commands/list_profiles.py +0 -0
  146. {janito-2.16.0 → janito-2.17.1}/janito/cli/cli_commands/list_providers.py +0 -0
  147. {janito-2.16.0 → janito-2.17.1}/janito/cli/cli_commands/list_providers_region.py +0 -0
  148. {janito-2.16.0 → janito-2.17.1}/janito/cli/cli_commands/list_tools.py +0 -0
  149. {janito-2.16.0 → janito-2.17.1}/janito/cli/cli_commands/model_selection.py +0 -0
  150. {janito-2.16.0 → janito-2.17.1}/janito/cli/cli_commands/model_utils.py +0 -0
  151. {janito-2.16.0 → janito-2.17.1}/janito/cli/cli_commands/show_config.py +0 -0
  152. {janito-2.16.0 → janito-2.17.1}/janito/cli/cli_commands/show_system_prompt.py +0 -0
  153. {janito-2.16.0 → janito-2.17.1}/janito/cli/config.py +0 -0
  154. {janito-2.16.0 → janito-2.17.1}/janito/cli/console.py +0 -0
  155. {janito-2.16.0 → janito-2.17.1}/janito/cli/core/__init__.py +0 -0
  156. {janito-2.16.0 → janito-2.17.1}/janito/cli/core/event_logger.py +0 -0
  157. {janito-2.16.0 → janito-2.17.1}/janito/cli/core/getters.py +0 -0
  158. {janito-2.16.0 → janito-2.17.1}/janito/cli/core/model_guesser.py +0 -0
  159. {janito-2.16.0 → janito-2.17.1}/janito/cli/core/runner.py +0 -0
  160. {janito-2.16.0 → janito-2.17.1}/janito/cli/core/setters.py +0 -0
  161. {janito-2.16.0 → janito-2.17.1}/janito/cli/core/unsetters.py +0 -0
  162. {janito-2.16.0 → janito-2.17.1}/janito/cli/main.py +0 -0
  163. {janito-2.16.0 → janito-2.17.1}/janito/cli/main_cli.py +0 -0
  164. {janito-2.16.0 → janito-2.17.1}/janito/cli/prompt_core.py +0 -0
  165. {janito-2.16.0 → janito-2.17.1}/janito/cli/prompt_handler.py +0 -0
  166. {janito-2.16.0 → janito-2.17.1}/janito/cli/rich_terminal_reporter.py +0 -0
  167. {janito-2.16.0 → janito-2.17.1}/janito/cli/single_shot_mode/__init__.py +0 -0
  168. {janito-2.16.0 → janito-2.17.1}/janito/cli/single_shot_mode/handler.py +0 -0
  169. {janito-2.16.0 → janito-2.17.1}/janito/cli/utils.py +0 -0
  170. {janito-2.16.0 → janito-2.17.1}/janito/cli/verbose_output.py +0 -0
  171. {janito-2.16.0 → janito-2.17.1}/janito/config.py +0 -0
  172. {janito-2.16.0 → janito-2.17.1}/janito/config_manager.py +0 -0
  173. {janito-2.16.0 → janito-2.17.1}/janito/conversation_history.py +0 -0
  174. {janito-2.16.0 → janito-2.17.1}/janito/dir_walk_utils.py +0 -0
  175. {janito-2.16.0 → janito-2.17.1}/janito/docs/GETTING_STARTED.md +0 -0
  176. {janito-2.16.0 → janito-2.17.1}/janito/driver_events.py +0 -0
  177. {janito-2.16.0 → janito-2.17.1}/janito/drivers/azure_openai/driver.py +0 -0
  178. {janito-2.16.0 → janito-2.17.1}/janito/drivers/dashscope.bak.zip +0 -0
  179. {janito-2.16.0 → janito-2.17.1}/janito/drivers/openai/README.md +0 -0
  180. {janito-2.16.0 → janito-2.17.1}/janito/drivers/openai/driver.py +0 -0
  181. {janito-2.16.0 → janito-2.17.1}/janito/drivers/openai_responses.bak.zip +0 -0
  182. {janito-2.16.0 → janito-2.17.1}/janito/drivers/zai/__init__.py +0 -0
  183. {janito-2.16.0 → janito-2.17.1}/janito/drivers/zai/driver.py +0 -0
  184. {janito-2.16.0 → janito-2.17.1}/janito/event_bus/__init__.py +0 -0
  185. {janito-2.16.0 → janito-2.17.1}/janito/event_bus/bus.py +0 -0
  186. {janito-2.16.0 → janito-2.17.1}/janito/event_bus/event.py +0 -0
  187. {janito-2.16.0 → janito-2.17.1}/janito/event_bus/handler.py +0 -0
  188. {janito-2.16.0 → janito-2.17.1}/janito/event_bus/queue_bus.py +0 -0
  189. {janito-2.16.0 → janito-2.17.1}/janito/exceptions.py +0 -0
  190. {janito-2.16.0 → janito-2.17.1}/janito/formatting.py +0 -0
  191. {janito-2.16.0 → janito-2.17.1}/janito/formatting_token.py +0 -0
  192. {janito-2.16.0 → janito-2.17.1}/janito/gitignore_utils.py +0 -0
  193. {janito-2.16.0 → janito-2.17.1}/janito/i18n/__init__.py +0 -0
  194. {janito-2.16.0 → janito-2.17.1}/janito/i18n/messages.py +0 -0
  195. {janito-2.16.0 → janito-2.17.1}/janito/i18n/pt.py +0 -0
  196. {janito-2.16.0 → janito-2.17.1}/janito/llm/README.md +0 -0
  197. {janito-2.16.0 → janito-2.17.1}/janito/llm/__init__.py +0 -0
  198. {janito-2.16.0 → janito-2.17.1}/janito/llm/agent.py +0 -0
  199. {janito-2.16.0 → janito-2.17.1}/janito/llm/auth.py +0 -0
  200. {janito-2.16.0 → janito-2.17.1}/janito/llm/auth_utils.py +0 -0
  201. {janito-2.16.0 → janito-2.17.1}/janito/llm/driver.py +0 -0
  202. {janito-2.16.0 → janito-2.17.1}/janito/llm/driver_config.py +0 -0
  203. {janito-2.16.0 → janito-2.17.1}/janito/llm/driver_config_builder.py +0 -0
  204. {janito-2.16.0 → janito-2.17.1}/janito/llm/driver_input.py +0 -0
  205. {janito-2.16.0 → janito-2.17.1}/janito/llm/message_parts.py +0 -0
  206. {janito-2.16.0 → janito-2.17.1}/janito/llm/model.py +0 -0
  207. {janito-2.16.0 → janito-2.17.1}/janito/llm/provider.py +0 -0
  208. {janito-2.16.0 → janito-2.17.1}/janito/mkdocs.yml +0 -0
  209. {janito-2.16.0 → janito-2.17.1}/janito/perf_singleton.py +0 -0
  210. {janito-2.16.0 → janito-2.17.1}/janito/performance_collector.py +0 -0
  211. {janito-2.16.0 → janito-2.17.1}/janito/platform_discovery.py +0 -0
  212. {janito-2.16.0 → janito-2.17.1}/janito/provider_config.py +0 -0
  213. {janito-2.16.0 → janito-2.17.1}/janito/provider_registry.py +0 -0
  214. {janito-2.16.0 → janito-2.17.1}/janito/providers/alibaba/__init__.py +0 -0
  215. {janito-2.16.0 → janito-2.17.1}/janito/providers/alibaba/model_info.py +0 -0
  216. {janito-2.16.0 → janito-2.17.1}/janito/providers/anthropic/model_info.py +0 -0
  217. {janito-2.16.0 → janito-2.17.1}/janito/providers/anthropic/provider.py +0 -0
  218. {janito-2.16.0 → janito-2.17.1}/janito/providers/azure_openai/model_info.py +0 -0
  219. {janito-2.16.0 → janito-2.17.1}/janito/providers/azure_openai/provider.py +0 -0
  220. {janito-2.16.0 → janito-2.17.1}/janito/providers/dashscope.bak.zip +0 -0
  221. {janito-2.16.0 → janito-2.17.1}/janito/providers/deepseek/__init__.py +0 -0
  222. {janito-2.16.0 → janito-2.17.1}/janito/providers/deepseek/model_info.py +0 -0
  223. {janito-2.16.0 → janito-2.17.1}/janito/providers/deepseek/provider.py +0 -0
  224. {janito-2.16.0 → janito-2.17.1}/janito/providers/google/__init__.py +0 -0
  225. {janito-2.16.0 → janito-2.17.1}/janito/providers/google/model_info.py +0 -0
  226. {janito-2.16.0 → janito-2.17.1}/janito/providers/google/provider.py +0 -0
  227. {janito-2.16.0 → janito-2.17.1}/janito/providers/moonshotai/__init__.py +0 -0
  228. {janito-2.16.0 → janito-2.17.1}/janito/providers/moonshotai/model_info.py +0 -0
  229. {janito-2.16.0 → janito-2.17.1}/janito/providers/moonshotai/provider.py +0 -0
  230. {janito-2.16.0 → janito-2.17.1}/janito/providers/openai/__init__.py +0 -0
  231. {janito-2.16.0 → janito-2.17.1}/janito/providers/openai/model_info.py +0 -0
  232. {janito-2.16.0 → janito-2.17.1}/janito/providers/openai/provider.py +0 -0
  233. {janito-2.16.0 → janito-2.17.1}/janito/providers/openai/schema_generator.py +0 -0
  234. {janito-2.16.0 → janito-2.17.1}/janito/providers/registry.py +0 -0
  235. {janito-2.16.0 → janito-2.17.1}/janito/providers/zai/__init__.py +0 -0
  236. {janito-2.16.0 → janito-2.17.1}/janito/providers/zai/model_info.py +0 -0
  237. {janito-2.16.0 → janito-2.17.1}/janito/providers/zai/provider.py +0 -0
  238. {janito-2.16.0 → janito-2.17.1}/janito/providers/zai/schema_generator.py +0 -0
  239. {janito-2.16.0 → janito-2.17.1}/janito/regions/__init__.py +0 -0
  240. {janito-2.16.0 → janito-2.17.1}/janito/regions/cli.py +0 -0
  241. {janito-2.16.0 → janito-2.17.1}/janito/regions/geo_utils.py +0 -0
  242. {janito-2.16.0 → janito-2.17.1}/janito/regions/provider_regions.py +0 -0
  243. {janito-2.16.0 → janito-2.17.1}/janito/report_events.py +0 -0
  244. {janito-2.16.0 → janito-2.17.1}/janito/shell.bak.zip +0 -0
  245. {janito-2.16.0 → janito-2.17.1}/janito/tools/DOCSTRING_STANDARD.txt +0 -0
  246. {janito-2.16.0 → janito-2.17.1}/janito/tools/README.md +0 -0
  247. {janito-2.16.0 → janito-2.17.1}/janito/tools/__init__.py +0 -0
  248. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/__init__.py +0 -0
  249. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/__init__.py +0 -0
  250. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/adapter.py +0 -0
  251. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/ask_user.py +0 -0
  252. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/copy_file.py +0 -0
  253. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/create_directory.py +0 -0
  254. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/create_file.py +0 -0
  255. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/delete_text_in_file.py +0 -0
  256. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/fetch_url.py +0 -0
  257. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/find_files.py +0 -0
  258. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/get_file_outline/__init__.py +0 -0
  259. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/get_file_outline/core.py +0 -0
  260. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/get_file_outline/java_outline.py +0 -0
  261. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/get_file_outline/markdown_outline.py +0 -0
  262. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/get_file_outline/python_outline.py +0 -0
  263. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/get_file_outline/search_outline.py +0 -0
  264. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/move_file.py +0 -0
  265. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/open_html_in_browser.py +0 -0
  266. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/open_url.py +0 -0
  267. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/python_code_run.py +0 -0
  268. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/python_command_run.py +0 -0
  269. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/python_file_run.py +0 -0
  270. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/remove_directory.py +0 -0
  271. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/remove_file.py +0 -0
  272. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/replace_text_in_file.py +0 -0
  273. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/run_bash_command.py +0 -0
  274. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/run_powershell_command.py +0 -0
  275. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/search_text/__init__.py +0 -0
  276. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/search_text/core.py +0 -0
  277. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/search_text/match_lines.py +0 -0
  278. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/search_text/pattern_utils.py +0 -0
  279. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/search_text/traverse_directory.py +0 -0
  280. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/validate_file_syntax/__init__.py +0 -0
  281. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/validate_file_syntax/core.py +0 -0
  282. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/validate_file_syntax/css_validator.py +0 -0
  283. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/validate_file_syntax/html_validator.py +0 -0
  284. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/validate_file_syntax/js_validator.py +0 -0
  285. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/validate_file_syntax/json_validator.py +0 -0
  286. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/validate_file_syntax/markdown_validator.py +0 -0
  287. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/validate_file_syntax/ps1_validator.py +0 -0
  288. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/validate_file_syntax/python_validator.py +0 -0
  289. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/validate_file_syntax/xml_validator.py +0 -0
  290. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/validate_file_syntax/yaml_validator.py +0 -0
  291. {janito-2.16.0 → janito-2.17.1}/janito/tools/adapters/local/view_file.py +0 -0
  292. {janito-2.16.0 → janito-2.17.1}/janito/tools/disabled_tools.py +0 -0
  293. {janito-2.16.0 → janito-2.17.1}/janito/tools/inspect_registry.py +0 -0
  294. {janito-2.16.0 → janito-2.17.1}/janito/tools/outline_file.bak.zip +0 -0
  295. {janito-2.16.0 → janito-2.17.1}/janito/tools/permissions.py +0 -0
  296. {janito-2.16.0 → janito-2.17.1}/janito/tools/permissions_parse.py +0 -0
  297. {janito-2.16.0 → janito-2.17.1}/janito/tools/tool_base.py +0 -0
  298. {janito-2.16.0 → janito-2.17.1}/janito/tools/tool_events.py +0 -0
  299. {janito-2.16.0 → janito-2.17.1}/janito/tools/tool_run_exception.py +0 -0
  300. {janito-2.16.0 → janito-2.17.1}/janito/tools/tool_use_tracker.py +0 -0
  301. {janito-2.16.0 → janito-2.17.1}/janito/tools/tool_utils.py +0 -0
  302. {janito-2.16.0 → janito-2.17.1}/janito/tools/tools_schema.py +0 -0
  303. {janito-2.16.0 → janito-2.17.1}/janito/utils.py +0 -0
  304. {janito-2.16.0 → janito-2.17.1}/janito.egg-info/dependency_links.txt +0 -0
  305. {janito-2.16.0 → janito-2.17.1}/janito.egg-info/entry_points.txt +0 -0
  306. {janito-2.16.0 → janito-2.17.1}/janito.egg-info/requires.txt +0 -0
  307. {janito-2.16.0 → janito-2.17.1}/janito.egg-info/top_level.txt +0 -0
  308. {janito-2.16.0 → janito-2.17.1}/pyproject.toml +0 -0
  309. {janito-2.16.0 → janito-2.17.1}/pytest.ini +0 -0
  310. {janito-2.16.0 → janito-2.17.1}/requirements-dev.txt +0 -0
  311. {janito-2.16.0 → janito-2.17.1}/requirements.txt +0 -0
  312. {janito-2.16.0 → janito-2.17.1}/setup.cfg +0 -0
  313. {janito-2.16.0 → janito-2.17.1}/tests/adapters/local/get_file_outline/test_core_outline.py +0 -0
  314. {janito-2.16.0 → janito-2.17.1}/tests/test_cli_list_models.py +0 -0
  315. {janito-2.16.0 → janito-2.17.1}/tests/test_cli_list_providers.py +0 -0
  316. {janito-2.16.0 → janito-2.17.1}/tests/test_cli_list_providers_alibaba.py +0 -0
  317. {janito-2.16.0 → janito-2.17.1}/tests/test_cli_list_providers_moonshotai.py +0 -0
  318. {janito-2.16.0 → janito-2.17.1}/tests/test_cli_version.py +0 -0
  319. {janito-2.16.0 → janito-2.17.1}/tests/test_disabled_tools.py +0 -0
  320. {janito-2.16.0 → janito-2.17.1}/tests/test_provider_alibaba.py +0 -0
  321. {janito-2.16.0 → janito-2.17.1}/tests/test_provider_moonshotai.py +0 -0
  322. {janito-2.16.0 → janito-2.17.1}/tools/release.py +0 -0
  323. {janito-2.16.0 → janito-2.17.1}/tox.ini +0 -0
@@ -4,6 +4,34 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [2.17.0] - 2025-08-05
8
+
9
+ ### Added
10
+
11
+ - **New Provider Support**
12
+ - **Cerebras Provider**: Added complete support for Cerebras with qwen-3-coder-480b model
13
+ - qwen-3-coder-480b: 32k context, reasoning-focused model with function calling support
14
+
15
+ - **Enhanced UX**
16
+ - Improved error handling for invalid provider names in set-api-key command
17
+ - Better error messages when provider is not found
18
+
19
+ ### Changed
20
+
21
+ - **Provider Improvements**
22
+ - Updated Alibaba endpoint to international URL for better global access
23
+ - Simplified region display to 2-letter codes for cleaner output
24
+ - Improved driver listing and region display functionality
25
+
26
+ - **Zero Mode Enhancement**
27
+ - Zero mode now properly disables system prompt and tools for minimal interaction
28
+
29
+ ### Fixed
30
+
31
+ - **Bug Fixes**
32
+ - Added missing tools adapter to Cerebras provider
33
+ - Improved error handling for invalid provider names in set-api-key command
34
+
7
35
  ## [2.16.0] - 2025-01-08
8
36
 
9
37
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: janito
3
- Version: 2.16.0
3
+ Version: 2.17.1
4
4
  Summary: A new Python package called janito.
5
5
  Author-email: João Pinto <janito@ikignosis.org>
6
6
  Project-URL: Homepage, https://github.com/ikignosis/janito
@@ -0,0 +1,56 @@
1
+ # Cerebras Setup Guide
2
+
3
+ This guide will help you set up Janito to use Cerebras as an LLM provider.
4
+
5
+ ## Prerequisites
6
+
7
+ 1. A Cerebras account
8
+ 2. An API key from Cerebras
9
+
10
+ ## Getting an API Key
11
+
12
+ 1. Visit the [Cerebras API Keys page](https://api.cerebras.ai/)
13
+ 2. Log in to your account
14
+ 3. Generate a new API key
15
+ 4. Copy the API key for use in Janito
16
+
17
+ ## Configuration
18
+
19
+ To configure Janito to use Cerebras, you need to set your API key:
20
+
21
+ ```bash
22
+ janito --set-api-key YOUR_CEREBRAS_API_KEY -p cerebras
23
+ ```
24
+
25
+ Replace `YOUR_CEREBRAS_API_KEY` with the API key you obtained from Cerebras.
26
+
27
+ ## Usage
28
+
29
+ After setting up your API key, you can use Cerebras models with Janito:
30
+
31
+ ```bash
32
+ janito -p cerebras "Hello, how are you?"
33
+ ```
34
+
35
+ By default, Janito will use the `qwen-3-coder-480b` model. You can specify a different model if needed:
36
+
37
+ ```bash
38
+ janito -p cerebras -m qwen-3-coder-480b "Explain quantum computing"
39
+ ```
40
+
41
+ ## Available Models
42
+
43
+ Cerebras offers several models through their API:
44
+
45
+ - `qwen-3-coder-480b`: 32k context, reasoning-focused model with function calling support
46
+
47
+ ## Troubleshooting
48
+
49
+ If you encounter issues:
50
+
51
+ 1. Verify your API key is correct and active
52
+ 2. Check that you have internet connectivity
53
+ 3. Ensure you're using a supported model name
54
+ 4. Check the Cerebras status page for any service outages
55
+
56
+ For further assistance, consult the [Cerebras documentation](https://api.cerebras.ai/docs) or [Janito documentation](https://docs.janito.dev).
@@ -36,7 +36,7 @@ This page lists the supported providers and their available models.
36
36
  - qwen-turbo
37
37
  - qwen-plus
38
38
  - qwen-max
39
- - qwen3-coder-plus
39
+ - qwen3-coder-plus (default)
40
40
  - qwen3-coder-480b-a35b-instruct
41
41
 
42
42
  ## Z.AI
@@ -44,4 +44,22 @@ This page lists the supported providers and their available models.
44
44
  - glm-4.5
45
45
  - glm-4.5-air
46
46
 
47
+ ## Cerebras
48
+
49
+ **Production Models:**
50
+ - llama-4-scout-17b-16e-instruct
51
+ - llama-3.3-70b
52
+ - llama3.1-8b
53
+ - qwen-3-32b
54
+
55
+ **Preview Models:**
56
+ - llama-4-maverick-17b-128e-instruct
57
+ - qwen-3-235b-a22b-instruct-2507
58
+ - qwen-3-235b-a22b-thinking-2507
59
+ - qwen-3-coder-480b
60
+ - gpt-oss-120b
61
+
62
+ **Notes:**
63
+ - qwen-3-coder-480b: 32k context, reasoning-focused model with function calling support
64
+
47
65
  <!-- Removed links to model_info.py files for all providers to avoid broken references. -->
@@ -167,7 +167,7 @@ def setup_agent(
167
167
  """
168
168
  Creates an agent. A system prompt is rendered from a template only when a profile is specified.
169
169
  """
170
- if no_tools_mode:
170
+ if no_tools_mode or zero_mode:
171
171
  tools_provider = None
172
172
  else:
173
173
  tools_provider = get_local_tools_adapter()
@@ -92,6 +92,7 @@ def get_driver_info():
92
92
  ("janito.drivers.openai.driver", "OpenAIModelDriver"),
93
93
  ("janito.drivers.azure_openai.driver", "AzureOpenAIModelDriver"),
94
94
  ("janito.drivers.zai.driver", "ZAIModelDriver"),
95
+ ("janito.drivers.cerebras.driver", "CerebrasModelDriver"),
95
96
  ]
96
97
 
97
98
  for module_path, class_name in driver_modules:
@@ -0,0 +1,30 @@
1
+ """
2
+ CLI Command: Set API key for the current or selected provider
3
+ """
4
+
5
+ from janito.provider_config import set_api_key
6
+ from janito.llm.auth import LLMAuthManager
7
+ from janito.providers.registry import LLMProviderRegistry
8
+
9
+
10
+ def handle_set_api_key(args):
11
+ api_key = getattr(args, "set_api_key", None)
12
+ provider = getattr(args, "provider", None)
13
+ if not provider:
14
+ print("Error: --set-api-key requires -p/--provider to be specified.")
15
+ return
16
+
17
+ # Validate provider name
18
+ if provider not in LLMProviderRegistry.list_providers():
19
+ valid_providers = LLMProviderRegistry.list_providers()
20
+ print(f"Error: Unknown provider '{provider}'. Valid providers are: {', '.join(valid_providers)}")
21
+ return
22
+
23
+ try:
24
+ set_api_key(provider, api_key)
25
+ auth_manager = LLMAuthManager()
26
+ print(
27
+ f"API key set for provider '{provider}'. Auth file updated: {auth_manager._auth_file}"
28
+ )
29
+ except ValueError as e:
30
+ print(f"Error: {e}")
@@ -37,6 +37,8 @@ def setup_agent_and_prompt_handler(
37
37
  no_tools_mode = False
38
38
  if hasattr(args, 'no_tools_mode'):
39
39
  no_tools_mode = getattr(args, 'no_tools_mode', False)
40
+
41
+ zero_mode = getattr(args, 'zero', False)
40
42
  agent = create_configured_agent(
41
43
  provider_instance=provider_instance,
42
44
  llm_driver_config=llm_driver_config,
@@ -46,6 +48,7 @@ def setup_agent_and_prompt_handler(
46
48
  allowed_permissions=allowed_permissions,
47
49
  profile=profile,
48
50
  profile_system_prompt=profile_system_prompt,
51
+ zero_mode=zero_mode,
49
52
  no_tools_mode=no_tools_mode,
50
53
  )
51
54
 
@@ -0,0 +1 @@
1
+ # Cerebras driver package
@@ -7,3 +7,4 @@ import janito.providers.deepseek.provider
7
7
  import janito.providers.moonshotai.provider
8
8
  import janito.providers.alibaba.provider
9
9
  import janito.providers.zai.provider
10
+ import janito.providers.cerebras.provider
@@ -17,9 +17,7 @@ class AlibabaProvider(LLMProvider):
17
17
  NAME = "alibaba"
18
18
  MAINTAINER = "João Pinto <janito@ikignosis.org>"
19
19
  MODEL_SPECS = MODEL_SPECS
20
- DEFAULT_MODEL = (
21
- "qwen3-coder-plus" # Options: qwen-turbo, qwen-plus, qwen-max, qwen3-coder-plus
22
- )
20
+ DEFAULT_MODEL = "qwen3-coder-plus" # 128k context, coding-focused model
23
21
 
24
22
  def __init__(
25
23
  self, auth_manager: LLMAuthManager = None, config: LLMDriverConfig = None
@@ -0,0 +1 @@
1
+ # Cerebras provider package
@@ -0,0 +1,76 @@
1
+ """Model specifications for Cerebras Inference API."""
2
+
3
+ from janito.llm.model import LLMModelInfo
4
+
5
+ MODEL_SPECS = {
6
+ "qwen-3-32b": LLMModelInfo(
7
+ name="qwen-3-32b",
8
+ max_input=128000,
9
+ max_response=16384,
10
+ default_temp=0.7,
11
+ driver="CerebrasModelDriver",
12
+ other={
13
+ "description": "Qwen 3 32B model for general instruction following",
14
+ "pricing": {
15
+ "input_per_1k_tokens": 0.0002,
16
+ "output_per_1k_tokens": 0.0006
17
+ }
18
+ }
19
+ ),
20
+ "qwen-3-235b-a22b-instruct-2507": LLMModelInfo(
21
+ name="qwen-3-235b-a22b-instruct-2507",
22
+ max_input=128000,
23
+ max_response=16384,
24
+ default_temp=0.7,
25
+ driver="CerebrasModelDriver",
26
+ other={
27
+ "description": "Qwen 3 235B A22B instruction-tuned model (preview)",
28
+ "pricing": {
29
+ "input_per_1k_tokens": 0.001,
30
+ "output_per_1k_tokens": 0.003
31
+ }
32
+ }
33
+ ),
34
+ "qwen-3-235b-a22b-thinking-2507": LLMModelInfo(
35
+ name="qwen-3-235b-a22b-thinking-2507",
36
+ max_input=128000,
37
+ max_response=16384,
38
+ default_temp=0.7,
39
+ driver="CerebrasModelDriver",
40
+ other={
41
+ "description": "Qwen 3 235B A22B thinking model for reasoning tasks (preview)",
42
+ "pricing": {
43
+ "input_per_1k_tokens": 0.001,
44
+ "output_per_1k_tokens": 0.003
45
+ }
46
+ }
47
+ ),
48
+ "qwen-3-coder-480b": LLMModelInfo(
49
+ name="qwen-3-coder-480b",
50
+ max_input=128000,
51
+ max_response=16384,
52
+ default_temp=0.7,
53
+ driver="CerebrasModelDriver",
54
+ other={
55
+ "description": "Qwen 3 Coder 480B model for programming tasks (preview)",
56
+ "pricing": {
57
+ "input_per_1k_tokens": 0.002,
58
+ "output_per_1k_tokens": 0.006
59
+ }
60
+ }
61
+ ),
62
+ "gpt-oss-120b": LLMModelInfo(
63
+ name="gpt-oss-120b",
64
+ max_input=128000,
65
+ max_response=16384,
66
+ default_temp=0.7,
67
+ driver="CerebrasModelDriver",
68
+ other={
69
+ "description": "GPT-OSS 120B open-source model (preview)",
70
+ "pricing": {
71
+ "input_per_1k_tokens": 0.0008,
72
+ "output_per_1k_tokens": 0.0024
73
+ }
74
+ }
75
+ )
76
+ }
@@ -0,0 +1,145 @@
1
+ """Cerebras Inference provider implementation."""
2
+
3
+ from typing import Dict, Any
4
+ from janito.llm.provider import LLMProvider
5
+ from janito.llm.auth import LLMAuthManager
6
+ from janito.llm.driver_config import LLMDriverConfig
7
+ from janito.drivers.openai.driver import OpenAIModelDriver
8
+ from janito.tools import get_local_tools_adapter
9
+ from janito.providers.registry import LLMProviderRegistry
10
+ from .model_info import MODEL_SPECS
11
+
12
+
13
+ class CerebrasProvider(LLMProvider):
14
+ """Cerebras Inference API provider."""
15
+
16
+ name = "cerebras"
17
+ NAME = "cerebras"
18
+ DEFAULT_MODEL = "qwen-3-coder-480b"
19
+ MAINTAINER = "João Pinto <janito@ikignosis.org>"
20
+ MODEL_SPECS = MODEL_SPECS
21
+
22
+ def __init__(self, auth_manager: LLMAuthManager = None, config: LLMDriverConfig = None):
23
+ """Initialize Cerebras provider with optional configuration."""
24
+ super().__init__()
25
+ self._tools_adapter = get_local_tools_adapter()
26
+ self._driver = None
27
+ self._tools_adapter = get_local_tools_adapter()
28
+ self._driver = None
29
+ if not self.available:
30
+ return
31
+
32
+ self._initialize_config(auth_manager, config)
33
+ self._setup_model_config()
34
+ self.fill_missing_device_info(self._driver_config)
35
+
36
+ if not self.available:
37
+ return
38
+
39
+ self._initialize_config(None, None)
40
+ self._driver_config.base_url = "https://api.cerebras.ai/v1"
41
+
42
+ def _initialize_config(self, auth_manager, config):
43
+ """Initialize configuration and API key."""
44
+ self.auth_manager = auth_manager or LLMAuthManager()
45
+ self._api_key = self.auth_manager.get_credentials(type(self).NAME)
46
+ if not self._api_key:
47
+ from janito.llm.auth_utils import handle_missing_api_key
48
+
49
+ handle_missing_api_key(self.name, "CEREBRAS_API_KEY")
50
+
51
+ self._driver_config = config or LLMDriverConfig(model=None)
52
+ if not self._driver_config.model:
53
+ self._driver_config.model = self.DEFAULT_MODEL
54
+ if not self._driver_config.api_key:
55
+ self._driver_config.api_key = self._api_key
56
+
57
+ self._setup_model_config()
58
+ self.fill_missing_device_info(self._driver_config)
59
+
60
+ def _setup_model_config(self):
61
+ """Configure token limits based on model specifications."""
62
+ model_name = self._driver_config.model
63
+ model_spec = self.MODEL_SPECS.get(model_name)
64
+
65
+ # Reset token parameters
66
+ if hasattr(self._driver_config, "max_tokens"):
67
+ self._driver_config.max_tokens = None
68
+ if hasattr(self._driver_config, "max_completion_tokens"):
69
+ self._driver_config.max_completion_tokens = None
70
+
71
+ if model_spec:
72
+ # Set context length
73
+ if hasattr(model_spec, "context") and model_spec.context:
74
+ self._driver_config.context_length = model_spec.context
75
+
76
+ # Set max tokens based on model spec
77
+ if hasattr(model_spec, "max_response") and model_spec.max_response:
78
+ self._driver_config.max_tokens = model_spec.max_response
79
+
80
+ # Set max completion tokens if thinking is supported
81
+ if getattr(model_spec, "thinking_supported", False):
82
+ max_cot = getattr(model_spec, "max_cot", None)
83
+ if max_cot and max_cot != "N/A":
84
+ self._driver_config.max_completion_tokens = int(max_cot)
85
+ else:
86
+ max_response = getattr(model_spec, "max_response", None)
87
+ if max_response and max_response != "N/A":
88
+ self._driver_config.max_tokens = int(max_response)
89
+
90
+ @property
91
+ @property
92
+ def driver(self) -> OpenAIModelDriver:
93
+ if not self.available:
94
+ raise ImportError(
95
+ f"CerebrasProvider unavailable: {self.unavailable_reason}"
96
+ )
97
+ if self._driver is None:
98
+ self._driver = self.create_driver()
99
+ return self._driver
100
+
101
+ @property
102
+ def available(self):
103
+ return OpenAIModelDriver.available
104
+
105
+ @property
106
+ def unavailable_reason(self):
107
+ return OpenAIModelDriver.unavailable_reason
108
+
109
+ def create_driver(self) -> OpenAIModelDriver:
110
+ """Create and return an OpenAI-compatible Cerebras driver instance."""
111
+ driver = OpenAIModelDriver(
112
+ tools_adapter=self._tools_adapter, provider_name=self.name
113
+ )
114
+ driver.config = self._driver_config
115
+ return driver
116
+
117
+ @property
118
+ def driver_config(self):
119
+ """Return the driver configuration."""
120
+ return self._driver_config
121
+
122
+ def is_model_available(self, model_name: str) -> bool:
123
+ """Check if a model is available for this provider."""
124
+ return model_name in self.MODEL_SPECS
125
+
126
+ def get_model_info(self, model_name: str = None) -> Dict[str, Any]:
127
+ """Get model information for the specified model or all models."""
128
+ if model_name is None:
129
+ return {
130
+ name: model_info.to_dict()
131
+ for name, model_info in self.MODEL_SPECS.items()
132
+ }
133
+
134
+ if model_name in self.MODEL_SPECS:
135
+ return self.MODEL_SPECS[model_name].to_dict()
136
+
137
+ return None
138
+
139
+ def execute_tool(self, tool_name: str, event_bus, *args, **kwargs):
140
+ self._tools_adapter.event_bus = event_bus
141
+ return self._tools_adapter.execute_by_name(tool_name, *args, **kwargs)
142
+
143
+
144
+ # Register the provider
145
+ LLMProviderRegistry.register(CerebrasProvider.name, CerebrasProvider)
@@ -52,4 +52,4 @@ class ReadFilesTool(ToolBase):
52
52
  results.append(
53
53
  f"--- File: {disp_path} (error) ---\nError reading file: {e}\n"
54
54
  )
55
- return "\n".join(results)
55
+ return "\n".join(results)
@@ -135,6 +135,7 @@ def _extract_path_keys_from_schema(schema: Mapping[str, Any]) -> set[str]:
135
135
  path_keys: set[str] = set()
136
136
  if schema is not None:
137
137
  for k, v in schema.get("properties", {}).items():
138
+ # Handle direct path strings
138
139
  if v.get("format") == "path" or (
139
140
  v.get("type") == "string"
140
141
  and (
@@ -144,6 +145,19 @@ def _extract_path_keys_from_schema(schema: Mapping[str, Any]) -> set[str]:
144
145
  )
145
146
  ):
146
147
  path_keys.add(k)
148
+ # Handle arrays of path strings
149
+ elif v.get("type") == "array" and "items" in v:
150
+ items = v["items"]
151
+ if items.get("format") == "path" or (
152
+ items.get("type") == "string"
153
+ and (
154
+ "path" in items.get("description", "").lower()
155
+ or "path" in v.get("description", "").lower()
156
+ or k.endswith("paths")
157
+ or k == "paths"
158
+ )
159
+ ):
160
+ path_keys.add(k)
147
161
  return path_keys
148
162
 
149
163
 
@@ -131,9 +131,15 @@ class ToolsAdapterBase:
131
131
 
132
132
  if arguments is None:
133
133
  arguments = {}
134
- # Ensure the input is a dict to avoid breaking the inspect-based logic
134
+ # If arguments are provided as a non-dict (e.g. a list or a scalar)
135
+ # we skip signature *keyword* validation completely and defer the
136
+ # decision to Python's own call mechanics when the function is
137
+ # eventually invoked. This allows positional / variadic arguments to
138
+ # be supplied by callers that intentionally bypass the structured
139
+ # JSON-schema style interface.
135
140
  if not isinstance(arguments, dict):
136
- return "Tool arguments should be provided as an object / mapping"
141
+ # Nothing to validate at this stage treat as OK.
142
+ return None
137
143
 
138
144
  sig = inspect.signature(func)
139
145
  params = sig.parameters
@@ -193,30 +199,32 @@ class ToolsAdapterBase:
193
199
  )
194
200
 
195
201
  schema = getattr(tool, "schema", None)
196
- try:
197
- validate_paths_in_arguments(arguments, workdir, schema=schema)
198
- except PathSecurityError as sec_err:
199
- # Publish both a ToolCallError and a user-facing ReportEvent for path security errors
200
- self._publish_tool_call_error(
201
- tool_name, request_id, str(sec_err), arguments
202
- )
203
- if self._event_bus:
204
- from janito.report_events import (
205
- ReportEvent,
206
- ReportSubtype,
207
- ReportAction,
202
+ # Only validate paths for dictionary-style arguments
203
+ if isinstance(arguments, dict):
204
+ try:
205
+ validate_paths_in_arguments(arguments, workdir, schema=schema)
206
+ except PathSecurityError as sec_err:
207
+ # Publish both a ToolCallError and a user-facing ReportEvent for path security errors
208
+ self._publish_tool_call_error(
209
+ tool_name, request_id, str(sec_err), arguments
208
210
  )
211
+ if self._event_bus:
212
+ from janito.report_events import (
213
+ ReportEvent,
214
+ ReportSubtype,
215
+ ReportAction,
216
+ )
209
217
 
210
- self._event_bus.publish(
211
- ReportEvent(
212
- subtype=ReportSubtype.ERROR,
213
- message=f"[SECURITY] Path access denied: {sec_err}",
214
- action=ReportAction.EXECUTE,
215
- tool=tool_name,
216
- context={"arguments": arguments, "request_id": request_id},
218
+ self._event_bus.publish(
219
+ ReportEvent(
220
+ subtype=ReportSubtype.ERROR,
221
+ message=f"[SECURITY] Path access denied: {sec_err}",
222
+ action=ReportAction.EXECUTE,
223
+ tool=tool_name,
224
+ context={"arguments": arguments, "request_id": request_id},
225
+ )
217
226
  )
218
- )
219
- return f"Security error: {sec_err}"
227
+ return f"Security error: {sec_err}"
220
228
  # --- END SECURITY ---
221
229
 
222
230
  self._publish_tool_call_started(tool_name, request_id, arguments)
@@ -224,7 +232,18 @@ class ToolsAdapterBase:
224
232
  f"[tools-adapter] Executing tool: {tool_name} with arguments: {arguments}"
225
233
  )
226
234
  try:
227
- result = self.execute(tool, **(arguments or {}), **kwargs)
235
+ # Normalize arguments to ensure proper type handling
236
+ normalized_args = self._normalize_arguments(arguments, tool, func)
237
+
238
+ if isinstance(normalized_args, (list, tuple)):
239
+ # Positional arguments supplied as an array → expand as *args
240
+ result = self.execute(tool, *normalized_args, **kwargs)
241
+ elif isinstance(normalized_args, dict) or normalized_args is None:
242
+ # Keyword-style arguments (the default) – pass as **kwargs
243
+ result = self.execute(tool, **(normalized_args or {}), **kwargs)
244
+ else:
245
+ # Single positional argument (scalar/str/int/…)
246
+ result = self.execute(tool, normalized_args, **kwargs)
228
247
  except Exception as e:
229
248
  self._handle_execution_error(tool_name, request_id, e, arguments)
230
249
  self._print_verbose(
@@ -281,6 +300,65 @@ class ToolsAdapterBase:
281
300
  if self.verbose_tools:
282
301
  print(message)
283
302
 
303
+ def _normalize_arguments(self, arguments, tool, func):
304
+ """
305
+ Normalize arguments to ensure proper type handling at the adapter level.
306
+
307
+ This handles cases where:
308
+ 1. String is passed instead of list for array parameters
309
+ 2. JSON string parsing issues
310
+ 3. Other type mismatches that can be automatically resolved
311
+ """
312
+ import inspect
313
+ import json
314
+
315
+ # If arguments is already a dict or None, return as-is
316
+ if isinstance(arguments, dict) or arguments is None:
317
+ return arguments
318
+
319
+ # If arguments is a list/tuple, return as-is (positional args)
320
+ if isinstance(arguments, (list, tuple)):
321
+ return arguments
322
+
323
+ # Handle string arguments
324
+ if isinstance(arguments, str):
325
+ # Try to parse as JSON if it looks like JSON
326
+ stripped = arguments.strip()
327
+ if (stripped.startswith('{') and stripped.endswith('}')) or \
328
+ (stripped.startswith('[') and stripped.endswith(']')):
329
+ try:
330
+ parsed = json.loads(arguments)
331
+ return parsed
332
+ except json.JSONDecodeError:
333
+ # If it looks like JSON but failed, try to handle common issues
334
+ pass
335
+
336
+ # Check if the function expects a list parameter
337
+ try:
338
+ sig = inspect.signature(func)
339
+ params = list(sig.parameters.values())
340
+
341
+ # Skip 'self' parameter for methods
342
+ if len(params) > 0 and params[0].name == 'self':
343
+ params = params[1:]
344
+
345
+ # If there's exactly one parameter that expects a list, wrap string in list
346
+ if len(params) == 1:
347
+ param = params[0]
348
+ annotation = param.annotation
349
+
350
+ # Check if annotation is list[str] or similar
351
+ if hasattr(annotation, '__origin__') and annotation.__origin__ is list:
352
+ return [arguments]
353
+ elif str(annotation).startswith('list[') or str(annotation) == 'list':
354
+ return [arguments]
355
+
356
+ except (ValueError, TypeError):
357
+ pass
358
+
359
+ # Return original arguments for other cases
360
+ return arguments
361
+
284
362
  def execute_function_call_message_part(self, function_call_message_part):
285
363
  """
286
364
  Execute a FunctionCallMessagePart by extracting the tool name and arguments and dispatching to execute_by_name.
@@ -298,9 +376,23 @@ class ToolsAdapterBase:
298
376
  # Parse arguments if they are a JSON string
299
377
  if isinstance(arguments, str):
300
378
  try:
379
+ # Try to parse as JSON first
301
380
  arguments = json.loads(arguments)
302
- except Exception:
303
- pass # Leave as string if not JSON
381
+ except json.JSONDecodeError:
382
+ # Handle single quotes in JSON strings
383
+ try:
384
+ # Replace single quotes with double quotes for JSON compatibility
385
+ fixed_json = arguments.replace("'", '"')
386
+ arguments = json.loads(fixed_json)
387
+ except (json.JSONDecodeError, ValueError):
388
+ # If it's a string that looks like it might be a single path parameter,
389
+ # try to handle it gracefully
390
+ if arguments.startswith("{") and arguments.endswith("}"):
391
+ # Looks like JSON but failed to parse - this is likely an error
392
+ pass
393
+ else:
394
+ # Single string argument - let the normalization handle it
395
+ pass
304
396
  if self.verbose_tools:
305
397
  print(
306
398
  f"[tools-adapter] Executing FunctionCallMessagePart: tool={tool_name}, arguments={arguments}, tool_call_id={tool_call_id}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: janito
3
- Version: 2.16.0
3
+ Version: 2.17.1
4
4
  Summary: A new Python package called janito.
5
5
  Author-email: João Pinto <janito@ikignosis.org>
6
6
  Project-URL: Homepage, https://github.com/ikignosis/janito