janito 2.3.0__py3-none-any.whl → 2.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. janito/__init__.py +6 -6
  2. janito/_version.py +57 -0
  3. janito/agent/setup_agent.py +92 -18
  4. janito/agent/templates/profiles/system_prompt_template_developer.txt.j2 +44 -0
  5. janito/cli/chat_mode/bindings.py +21 -2
  6. janito/cli/chat_mode/chat_entry.py +2 -3
  7. janito/cli/chat_mode/prompt_style.py +5 -0
  8. janito/cli/chat_mode/session.py +80 -94
  9. janito/cli/chat_mode/session_profile_select.py +80 -0
  10. janito/cli/chat_mode/shell/autocomplete.py +21 -21
  11. janito/cli/chat_mode/shell/commands/__init__.py +13 -7
  12. janito/cli/chat_mode/shell/commands/_priv_check.py +5 -0
  13. janito/cli/chat_mode/shell/commands/clear.py +12 -12
  14. janito/cli/chat_mode/shell/commands/conversation_restart.py +30 -0
  15. janito/cli/chat_mode/shell/commands/execute.py +42 -0
  16. janito/cli/chat_mode/shell/commands/help.py +6 -3
  17. janito/cli/chat_mode/shell/commands/model.py +28 -0
  18. janito/cli/chat_mode/shell/commands/multi.py +51 -51
  19. janito/cli/chat_mode/shell/commands/read.py +37 -0
  20. janito/cli/chat_mode/shell/commands/tools.py +45 -18
  21. janito/cli/chat_mode/shell/commands/write.py +37 -0
  22. janito/cli/chat_mode/shell/commands.bak.zip +0 -0
  23. janito/cli/chat_mode/shell/input_history.py +62 -62
  24. janito/cli/chat_mode/shell/session.bak.zip +0 -0
  25. janito/cli/chat_mode/toolbar.py +44 -27
  26. janito/cli/cli_commands/list_models.py +35 -35
  27. janito/cli/cli_commands/list_providers.py +9 -9
  28. janito/cli/cli_commands/list_tools.py +86 -53
  29. janito/cli/cli_commands/model_selection.py +50 -50
  30. janito/cli/cli_commands/set_api_key.py +19 -19
  31. janito/cli/cli_commands/show_config.py +51 -51
  32. janito/cli/cli_commands/show_system_prompt.py +105 -62
  33. janito/cli/config.py +5 -6
  34. janito/cli/core/__init__.py +4 -4
  35. janito/cli/core/event_logger.py +59 -59
  36. janito/cli/core/runner.py +25 -18
  37. janito/cli/core/setters.py +10 -1
  38. janito/cli/core/unsetters.py +54 -54
  39. janito/cli/main_cli.py +28 -5
  40. janito/cli/prompt_core.py +18 -2
  41. janito/cli/prompt_setup.py +56 -0
  42. janito/cli/single_shot_mode/__init__.py +6 -6
  43. janito/cli/single_shot_mode/handler.py +14 -73
  44. janito/cli/verbose_output.py +1 -1
  45. janito/config.py +5 -5
  46. janito/config_manager.py +13 -0
  47. janito/drivers/anthropic/driver.py +113 -113
  48. janito/drivers/dashscope.bak.zip +0 -0
  49. janito/drivers/openai/README.md +20 -0
  50. janito/drivers/openai_responses.bak.zip +0 -0
  51. janito/event_bus/event.py +2 -2
  52. janito/formatting_token.py +54 -54
  53. janito/i18n/__init__.py +35 -35
  54. janito/i18n/messages.py +23 -23
  55. janito/i18n/pt.py +46 -47
  56. janito/llm/README.md +23 -0
  57. janito/llm/__init__.py +5 -5
  58. janito/llm/agent.py +507 -443
  59. janito/llm/driver.py +8 -0
  60. janito/llm/driver_config_builder.py +34 -34
  61. janito/llm/driver_input.py +12 -12
  62. janito/llm/message_parts.py +60 -60
  63. janito/llm/model.py +38 -38
  64. janito/llm/provider.py +196 -196
  65. janito/provider_registry.py +8 -6
  66. janito/providers/anthropic/model_info.py +22 -22
  67. janito/providers/anthropic/provider.py +2 -0
  68. janito/providers/azure_openai/provider.py +3 -0
  69. janito/providers/dashscope.bak.zip +0 -0
  70. janito/providers/deepseek/__init__.py +1 -1
  71. janito/providers/deepseek/model_info.py +16 -16
  72. janito/providers/deepseek/provider.py +94 -91
  73. janito/providers/google/provider.py +3 -0
  74. janito/providers/mistralai/provider.py +3 -0
  75. janito/providers/openai/provider.py +4 -0
  76. janito/providers/registry.py +26 -26
  77. janito/shell.bak.zip +0 -0
  78. janito/tools/DOCSTRING_STANDARD.txt +33 -0
  79. janito/tools/README.md +3 -0
  80. janito/tools/__init__.py +20 -6
  81. janito/tools/adapters/__init__.py +1 -1
  82. janito/tools/adapters/local/__init__.py +65 -62
  83. janito/tools/adapters/local/adapter.py +18 -35
  84. janito/tools/adapters/local/ask_user.py +101 -102
  85. janito/tools/adapters/local/copy_file.py +84 -84
  86. janito/tools/adapters/local/create_directory.py +69 -69
  87. janito/tools/adapters/local/create_file.py +82 -82
  88. janito/tools/adapters/local/delete_text_in_file.py +2 -2
  89. janito/tools/adapters/local/fetch_url.py +97 -97
  90. janito/tools/adapters/local/find_files.py +139 -138
  91. janito/tools/adapters/local/get_file_outline/__init__.py +1 -1
  92. janito/tools/adapters/local/get_file_outline/core.py +117 -117
  93. janito/tools/adapters/local/get_file_outline/java_outline.py +40 -40
  94. janito/tools/adapters/local/get_file_outline/markdown_outline.py +14 -14
  95. janito/tools/adapters/local/get_file_outline/python_outline.py +303 -303
  96. janito/tools/adapters/local/get_file_outline/python_outline_v2.py +156 -156
  97. janito/tools/adapters/local/get_file_outline/search_outline.py +33 -33
  98. janito/tools/adapters/local/move_file.py +2 -2
  99. janito/tools/adapters/local/open_html_in_browser.py +2 -1
  100. janito/tools/adapters/local/open_url.py +2 -2
  101. janito/tools/adapters/local/python_code_run.py +166 -166
  102. janito/tools/adapters/local/python_command_run.py +164 -164
  103. janito/tools/adapters/local/python_file_run.py +163 -163
  104. janito/tools/adapters/local/remove_directory.py +2 -2
  105. janito/tools/adapters/local/remove_file.py +2 -2
  106. janito/tools/adapters/local/replace_text_in_file.py +2 -2
  107. janito/tools/adapters/local/run_bash_command.py +176 -176
  108. janito/tools/adapters/local/run_powershell_command.py +219 -219
  109. janito/tools/adapters/local/search_text/__init__.py +1 -1
  110. janito/tools/adapters/local/search_text/core.py +201 -201
  111. janito/tools/adapters/local/search_text/pattern_utils.py +73 -73
  112. janito/tools/adapters/local/search_text/traverse_directory.py +145 -145
  113. janito/tools/adapters/local/validate_file_syntax/__init__.py +1 -1
  114. janito/tools/adapters/local/validate_file_syntax/core.py +106 -106
  115. janito/tools/adapters/local/validate_file_syntax/css_validator.py +35 -35
  116. janito/tools/adapters/local/validate_file_syntax/html_validator.py +93 -93
  117. janito/tools/adapters/local/validate_file_syntax/js_validator.py +27 -27
  118. janito/tools/adapters/local/validate_file_syntax/json_validator.py +6 -6
  119. janito/tools/adapters/local/validate_file_syntax/markdown_validator.py +109 -109
  120. janito/tools/adapters/local/validate_file_syntax/ps1_validator.py +32 -32
  121. janito/tools/adapters/local/validate_file_syntax/python_validator.py +5 -5
  122. janito/tools/adapters/local/validate_file_syntax/xml_validator.py +11 -11
  123. janito/tools/adapters/local/validate_file_syntax/yaml_validator.py +6 -6
  124. janito/tools/adapters/local/view_file.py +168 -167
  125. janito/tools/inspect_registry.py +17 -17
  126. janito/tools/outline_file.bak.zip +0 -0
  127. janito/tools/permissions.py +45 -0
  128. janito/tools/permissions_parse.py +12 -0
  129. janito/tools/tool_base.py +118 -105
  130. janito/tools/tool_events.py +58 -58
  131. janito/tools/tool_run_exception.py +12 -12
  132. janito/tools/tool_use_tracker.py +81 -81
  133. janito/tools/tool_utils.py +43 -45
  134. janito/tools/tools_adapter.py +25 -20
  135. janito/tools/tools_schema.py +104 -104
  136. {janito-2.3.0.dist-info → janito-2.4.0.dist-info}/METADATA +425 -388
  137. janito-2.4.0.dist-info/RECORD +195 -0
  138. janito/agent/templates/profiles/system_prompt_template_base_pt.txt.j2 +0 -13
  139. janito/agent/templates/profiles/system_prompt_template_main.txt.j2 +0 -37
  140. janito/cli/chat_mode/shell/commands/edit.py +0 -25
  141. janito/cli/chat_mode/shell/commands/exec.py +0 -27
  142. janito/cli/chat_mode/shell/commands/termweb_log.py +0 -92
  143. janito/cli/termweb_starter.py +0 -122
  144. janito/termweb/app.py +0 -95
  145. janito/version.py +0 -4
  146. janito-2.3.0.dist-info/RECORD +0 -181
  147. {janito-2.3.0.dist-info → janito-2.4.0.dist-info}/WHEEL +0 -0
  148. {janito-2.3.0.dist-info → janito-2.4.0.dist-info}/entry_points.txt +0 -0
  149. {janito-2.3.0.dist-info → janito-2.4.0.dist-info}/licenses/LICENSE +0 -0
  150. {janito-2.3.0.dist-info → janito-2.4.0.dist-info}/top_level.txt +0 -0
@@ -1,54 +1,54 @@
1
- """
2
- Token summary formatter for rich and pt markup.
3
- - Used to display token/message counters after completions.
4
- """
5
-
6
- from janito.perf_singleton import performance_collector
7
-
8
- from rich.rule import Rule
9
-
10
-
11
- def format_tokens(n, tag=None, use_rich=False):
12
- if n is None:
13
- return "?"
14
- if n < 1000:
15
- val = str(n)
16
- elif n < 1000000:
17
- val = f"{n/1000:.1f}k"
18
- else:
19
- val = f"{n/1000000:.1f}M"
20
- if tag:
21
- if use_rich:
22
- return f"[{tag}]{val}[/{tag}]"
23
- else:
24
- return f"<{tag}>{val}</{tag}>"
25
- return val
26
-
27
-
28
- def format_token_message_summary(msg_count, usage, width=96, use_rich=False):
29
- """
30
- Returns a string (rich or pt markup) summarizing message count and last token usage.
31
- """
32
- left = f" Messages: {'[' if use_rich else '<'}msg_count{']' if use_rich else '>'}{msg_count}{'[/msg_count]' if use_rich else '</msg_count>'}"
33
- tokens_part = ""
34
- if usage:
35
- prompt_tokens = usage.get("prompt_tokens")
36
- completion_tokens = usage.get("completion_tokens")
37
- total_tokens = usage.get("total_tokens")
38
- tokens_part = (
39
- f" | Tokens - Prompt: {format_tokens(prompt_tokens, 'tokens_in', use_rich)}, "
40
- f"Completion: {format_tokens(completion_tokens, 'tokens_out', use_rich)}, "
41
- f"Total: {format_tokens(total_tokens, 'tokens_total', use_rich)}"
42
- )
43
- return f"{left}{tokens_part}"
44
-
45
-
46
- def print_token_message_summary(console, msg_count=None, usage=None, width=96):
47
- """Prints the summary using rich markup, using defaults from perf_singleton if not given."""
48
- if usage is None:
49
- usage = performance_collector.get_last_request_usage()
50
- if msg_count is None:
51
- msg_count = performance_collector.get_total_turns() or 0
52
- line = format_token_message_summary(msg_count, usage, width, use_rich=True)
53
- if line.strip():
54
- console.print(Rule(line))
1
+ """
2
+ Token summary formatter for rich and pt markup.
3
+ - Used to display token/message counters after completions.
4
+ """
5
+
6
+ from janito.perf_singleton import performance_collector
7
+
8
+ from rich.rule import Rule
9
+
10
+
11
+ def format_tokens(n, tag=None, use_rich=False):
12
+ if n is None:
13
+ return "?"
14
+ if n < 1000:
15
+ val = str(n)
16
+ elif n < 1000000:
17
+ val = f"{n/1000:.1f}k"
18
+ else:
19
+ val = f"{n/1000000:.1f}M"
20
+ if tag:
21
+ if use_rich:
22
+ return f"[{tag}]{val}[/{tag}]"
23
+ else:
24
+ return f"<{tag}>{val}</{tag}>"
25
+ return val
26
+
27
+
28
+ def format_token_message_summary(msg_count, usage, width=96, use_rich=False):
29
+ """
30
+ Returns a string (rich or pt markup) summarizing message count and last token usage.
31
+ """
32
+ left = f" Messages: {'[' if use_rich else '<'}msg_count{']' if use_rich else '>'}{msg_count}{'[/msg_count]' if use_rich else '</msg_count>'}"
33
+ tokens_part = ""
34
+ if usage:
35
+ prompt_tokens = usage.get("prompt_tokens")
36
+ completion_tokens = usage.get("completion_tokens")
37
+ total_tokens = usage.get("total_tokens")
38
+ tokens_part = (
39
+ f" | Tokens - Prompt: {format_tokens(prompt_tokens, 'tokens_in', use_rich)}, "
40
+ f"Completion: {format_tokens(completion_tokens, 'tokens_out', use_rich)}, "
41
+ f"Total: {format_tokens(total_tokens, 'tokens_total', use_rich)}"
42
+ )
43
+ return f"{left}{tokens_part}"
44
+
45
+
46
+ def print_token_message_summary(console, msg_count=None, usage=None, width=96):
47
+ """Prints the summary using rich markup, using defaults from perf_singleton if not given."""
48
+ if usage is None:
49
+ usage = performance_collector.get_last_request_usage()
50
+ if msg_count is None:
51
+ msg_count = performance_collector.get_total_turns() or 0
52
+ line = format_token_message_summary(msg_count, usage, width, use_rich=True)
53
+ if line.strip():
54
+ console.print(Rule(line))
janito/i18n/__init__.py CHANGED
@@ -1,35 +1,35 @@
1
- import importlib
2
- import threading
3
- import hashlib
4
-
5
- _current_locale = "en"
6
- _translations = {}
7
- _lock = threading.Lock()
8
-
9
-
10
- def set_locale(locale):
11
- global _current_locale, _translations
12
- with _lock:
13
- _current_locale = locale
14
- if locale == "en":
15
- _translations = {}
16
- else:
17
- try:
18
- mod = importlib.import_module(f"janito.i18n.{locale}")
19
- _translations = getattr(mod, "translations", {})
20
- except ImportError:
21
- _translations = {}
22
-
23
-
24
- def tr(msg, **kwargs):
25
- """Translate message to current locale, usando hash SHA-1 da mensagem como chave."""
26
- msg_hash = hashlib.sha1(msg.encode("utf-8", errors="surrogatepass")).hexdigest()
27
- template = _translations.get(msg_hash, msg)
28
- try:
29
- return template.format(**kwargs)
30
- except Exception:
31
- return template # fallback if formatting fails
32
-
33
-
34
- # Inicializa com o idioma padrão (en)
35
- set_locale("en")
1
+ import importlib
2
+ import threading
3
+ import hashlib
4
+
5
+ _current_locale = "en"
6
+ _translations = {}
7
+ _lock = threading.Lock()
8
+
9
+
10
+ def set_locale(locale):
11
+ global _current_locale, _translations
12
+ with _lock:
13
+ _current_locale = locale
14
+ if locale == "en":
15
+ _translations = {}
16
+ else:
17
+ try:
18
+ mod = importlib.import_module(f"janito.i18n.{locale}")
19
+ _translations = getattr(mod, "translations", {})
20
+ except ImportError:
21
+ _translations = {}
22
+
23
+
24
+ def tr(msg, **kwargs):
25
+ """Translate message to current locale, usando hash SHA-1 da mensagem como chave."""
26
+ msg_hash = hashlib.sha1(msg.encode("utf-8", errors="surrogatepass")).hexdigest()
27
+ template = _translations.get(msg_hash, msg)
28
+ try:
29
+ return template.format(**kwargs)
30
+ except Exception:
31
+ return template # fallback if formatting fails
32
+
33
+
34
+ # Inicializa com o idioma padrão (en)
35
+ set_locale("en")
janito/i18n/messages.py CHANGED
@@ -1,23 +1,23 @@
1
- # Arquivo base de mensagens para i18n
2
- # Chave = SHA-1 da string original em inglês
3
-
4
- MESSAGES = {
5
- # create_directory.py
6
- "e3d8e1e5e0b3e4a2a7a5e2e1e4e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0": "Successfully created the directory at '{path}'.",
7
- "f2b7e4e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1": "Cannot create directory: '{path}' already exists.",
8
- "d3e2e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5": "Path '{path}' exists and is not a directory.",
9
- "b1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1": "Error creating directory '{path}': {error}",
10
- # create_file.py
11
- "a2e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0": "File already exists at '{path}'. Use overwrite=True to overwrite.",
12
- "c3e2e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5": "Created file ({lines} lines).",
13
- "d4e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0": "Updated file ({lines} lines, backup at {backup_path}).",
14
- # remove_file.py
15
- "e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5": "File '{path}' does not exist.",
16
- "f6e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0": "Path '{path}' is not a file.",
17
- "a7e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1": "Successfully removed the file at '{path}'.",
18
- "b8e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0": "Error removing file: {error}",
19
- # replace_text_in_file.py (exemplo)
20
- "c9e2e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5": "Text replaced in {file_path} (backup at {backup_path}). {details}",
21
- "d0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0": "No changes made. {warning_detail}",
22
- "e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1": "Error replacing text: {error}",
23
- }
1
+ # Arquivo base de mensagens para i18n
2
+ # Chave = SHA-1 da string original em inglês
3
+
4
+ MESSAGES = {
5
+ # create_directory.py
6
+ "e3d8e1e5e0b3e4a2a7a5e2e1e4e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0": "Successfully created the directory at '{path}'.",
7
+ "f2b7e4e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1": "Cannot create directory: '{path}' already exists.",
8
+ "d3e2e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5": "Path '{path}' exists and is not a directory.",
9
+ "b1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1": "Error creating directory '{path}': {error}",
10
+ # create_file.py
11
+ "a2e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0": "File already exists at '{path}'. Use overwrite=True to overwrite.",
12
+ "c3e2e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5": "Created file ({lines} lines).",
13
+ "d4e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0": "Updated file ({lines} lines, backup at {backup_path}).",
14
+ # remove_file.py
15
+ "e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5": "File '{path}' does not exist.",
16
+ "f6e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0": "Path '{path}' is not a file.",
17
+ "a7e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1": "Successfully removed the file at '{path}'.",
18
+ "b8e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0": "Error removing file: {error}",
19
+ # replace_text_in_file.py (exemplo)
20
+ "c9e2e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5": "Text replaced in {file_path} (backup at {backup_path}). {details}",
21
+ "d0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0": "No changes made. {warning_detail}",
22
+ "e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1e5e0e1": "Error replacing text: {error}",
23
+ }
janito/i18n/pt.py CHANGED
@@ -1,47 +1,46 @@
1
- # pragma: allowlist secret
2
- translations = {
3
- "36107ed78ab25f6fb12ad8ce13018cd1ce6735d1": "Iniciando servidor web...",
4
- "70a0d194687568a47aa617fd85036ace1e69a982": "Deseja realmente sair? (s/n): ",
5
- "5c9ebcbbd7632ecb328bd52958b17158afaa32c6": "F12 = Ação Rápida (segue a ação recomendada)",
6
- "e4034394acca752c021b2ab50f60da8273e3c314": "TermWeb iniciado... Disponível em http://localhost:{selected_port}",
7
- "fe21121e2934234b68d19b2757532117d440c1e3": "Chave de API não encontrada. Por favor, configure 'api_key' no seu arquivo de configuração.",
8
- "c9e3759b1756eba35b381ce2b72cd659e132b01f": "Olá, {name}!",
9
- "ca1fee2f55baabdc2e4b0e9529c89ee024e62079": "Nenhum prompt fornecido nas mensagens",
10
- "f7449d23d0c500ae2a0b31e04f92b47a4d8ae845": "max_tokens deve ser um inteiro, recebido: {resolved_max_tokens!r}",
11
- "70a9ed8edb6da12e208431a31aa16ba54419b26f": "Resposta inválida/malformada do OpenAI (tentativa {attempt}/{max_retries}). Tentando novamente em {wait_time} segundos...",
12
- "a873085e3b06184fb5d27e842f97b06b6190976d": "Número máximo de tentativas para resposta inválida atingido. Gerando erro.",
13
- "66a34568bbe846bb1bde3619eb4d6dfa10211104": "A API não suporta o uso de ferramentas.",
14
- "09b81476b75586da4116b83f8be70d77b174cec3": "Limit de taxa da API OpenAI (429) (tentativa {attempt}/{max_retries}): {e}. Tentando novamente em {wait_time} segundos...",
15
- "5717a35dd2a1533fb7e15edc8c9329cb69f3410b": "Erro do servidor da API OpenAI (tentativa {attempt}/{max_retries}): {e}. Tentando novamente em {wait_time} segundos...",
16
- "02e760ba15ed863176c1290ac8a9b923963103cd": "Erro do client da API OpenAI {status_code}: {e}. Não será feita nova tentativa.",
17
- "2e52b0bbc8f16226b70e3e20f95c9245d2bcdb47": "Erro da API OpenAI (tentativa {attempt}/{max_retries}): {e}. Tentando novamente em {wait_time} segundos...",
18
- "012cc970e039fdd79c452fc676202c814ffc76ae": "Número máximo de tentativas para erro da API OpenAI atingido. Gerando erro.",
19
- "d0438e45667d31e0022b2497b5901cd4300f084b": "QueuedMessageHandler.handle_message espera um dicionário com 'type' e 'message', recebido {msg_type}: {msg!r}",
20
- "9d3460187ffa19c7c8a4020157072b1087e1bd2f": "[QueuedMessageHandler] {msg_type}: {msg}",
21
- "3813833343430e8afa8fce33385c5e39fb24dd60": "[QueuedMessageHandler] {msg_type}: {message}",
22
- "0be9a22226e16a40797010d23a0f581542dca40e": "[ToolExecutor] {tool_name} chamado com arguments: {args}",
23
- "42c68edcb25442f518b1af77c6a2ddc07461aae0": "[ToolExecutor] Motivo da chamada: {tool_call_reason}",
24
- "002ff598115d84595ffeee6219cb5c03d3a1d4a6": "Pergunta",
25
- "35747d13dcd91e8e8790c7f767d5ed764f541b9e": "prosseguir",
26
- "33dde3a1afbc418768a69fa53168d9b0638fe1aa": "avançar",
27
- "eee0bbba4ff92adbeb038a77df0466d660f15716": "continuar",
28
- "edee9402d198b04ac77dcf5dc9cc3dac44573782": "próximo",
29
- "8fdb7e2fa84f4faf0d9b92f466df424ec47a165b": "ok",
30
- "5f8f924671cda79b5205a6bf1b776f347c4a7a07": "Opções de configuração disponíveis:\n",
31
- "cef780a309cd234750764d42697882c24168ddab": "{key:15} {desc} (padrão: {default})",
32
- "68c2cc7f0ceaa3e499ecb4db331feb4debbbcc23": "Modelo",
33
- "c3f104d1365744b538bfde9f4adb6a6df4b80355": "Função",
34
- "99a0efc6cfd85d8ff2732a6718140f822cb90472": "Estilo",
35
- "f1702b4686278becffc88baabe6f4b7a8355532c": "Mensagens",
36
- "c38c6c1f3a2743f8626703abb302e403d20ff81c": "Tokens",
37
- "a817d7eb8e0f1dab755ab5203a082e5c3c094fce": "Prompt",
38
- "2ff255684a2277f806fcebf3fe338ed27857f350": "Conclusão",
39
- "b25928c69902557b0ef0a628490a3a1768d7b82f": "Total",
40
- "76e63d65c883ed50df40ac3aeef0c2d6a1c4ad60": "Ação Rápida",
41
- "5397e0583f14f6c88de06b1ef28f460a1fb5b0ae": "Sim",
42
- "816c52fd2bdd94a63cd0944823a6c0aa9384c103": "Não",
43
- "c47ae15370cfe1ed2781eedc1dc2547d12d9e972": "Ajuda",
44
- "cc3dbd47e1cf9003a55d3366b3adbcd72275e525": "Nova Tarefa",
45
- "efa5a8b84e1afe65c81ecfce28c398c48f19ddc2": "Bem-vindo ao Janito{version_str}! Entrando no modo de chat. Digite /exit para sair.",
46
- "b314d6e1460f86e0f21abc5aceb7935a2a0667e8": "Bem-vindo ao Janito{version_str} no [white on magenta]MODO VANILLA[/white on magenta]! Ferramentas, prompt do sistema e temperatura estão desativados, a menos que sejam substituídos.",
47
- }
1
+ # pragma: allowlist secret
2
+ translations = {
3
+ "36107ed78ab25f6fb12ad8ce13018cd1ce6735d1": "Iniciando servidor web...",
4
+ "70a0d194687568a47aa617fd85036ace1e69a982": "Deseja realmente sair? (s/n): ",
5
+ "5c9ebcbbd7632ecb328bd52958b17158afaa32c6": "F12 = Ação Rápida (segue a ação recomendada)",
6
+ "fe21121e2934234b68d19b2757532117d440c1e3": "Chave de API não encontrada. Por favor, configure 'api_key' no seu arquivo de configuração.",
7
+ "c9e3759b1756eba35b381ce2b72cd659e132b01f": "Olá, {name}!",
8
+ "ca1fee2f55baabdc2e4b0e9529c89ee024e62079": "Nenhum prompt fornecido nas mensagens",
9
+ "f7449d23d0c500ae2a0b31e04f92b47a4d8ae845": "max_tokens deve ser um inteiro, recebido: {resolved_max_tokens!r}",
10
+ "70a9ed8edb6da12e208431a31aa16ba54419b26f": "Resposta inválida/malformada do OpenAI (tentativa {attempt}/{max_retries}). Tentando novamente em {wait_time} segundos...",
11
+ "a873085e3b06184fb5d27e842f97b06b6190976d": "Número máximo de tentativas para resposta inválida atingido. Gerando erro.",
12
+ "66a34568bbe846bb1bde3619eb4d6dfa10211104": "A API não suporta o uso de ferramentas.",
13
+ "09b81476b75586da4116b83f8be70d77b174cec3": "Limit de taxa da API OpenAI (429) (tentativa {attempt}/{max_retries}): {e}. Tentando novamente em {wait_time} segundos...",
14
+ "5717a35dd2a1533fb7e15edc8c9329cb69f3410b": "Erro do servidor da API OpenAI (tentativa {attempt}/{max_retries}): {e}. Tentando novamente em {wait_time} segundos...",
15
+ "02e760ba15ed863176c1290ac8a9b923963103cd": "Erro do client da API OpenAI {status_code}: {e}. Não será feita nova tentativa.",
16
+ "2e52b0bbc8f16226b70e3e20f95c9245d2bcdb47": "Erro da API OpenAI (tentativa {attempt}/{max_retries}): {e}. Tentando novamente em {wait_time} segundos...",
17
+ "012cc970e039fdd79c452fc676202c814ffc76ae": "Número máximo de tentativas para erro da API OpenAI atingido. Gerando erro.",
18
+ "d0438e45667d31e0022b2497b5901cd4300f084b": "QueuedMessageHandler.handle_message espera um dicionário com 'type' e 'message', recebido {msg_type}: {msg!r}",
19
+ "9d3460187ffa19c7c8a4020157072b1087e1bd2f": "[QueuedMessageHandler] {msg_type}: {msg}",
20
+ "3813833343430e8afa8fce33385c5e39fb24dd60": "[QueuedMessageHandler] {msg_type}: {message}",
21
+ "0be9a22226e16a40797010d23a0f581542dca40e": "[ToolExecutor] {tool_name} chamado com arguments: {args}",
22
+ "42c68edcb25442f518b1af77c6a2ddc07461aae0": "[ToolExecutor] Motivo da chamada: {tool_call_reason}",
23
+ "002ff598115d84595ffeee6219cb5c03d3a1d4a6": "Pergunta",
24
+ "35747d13dcd91e8e8790c7f767d5ed764f541b9e": "prosseguir",
25
+ "33dde3a1afbc418768a69fa53168d9b0638fe1aa": "avançar",
26
+ "eee0bbba4ff92adbeb038a77df0466d660f15716": "continuar",
27
+ "edee9402d198b04ac77dcf5dc9cc3dac44573782": "próximo",
28
+ "8fdb7e2fa84f4faf0d9b92f466df424ec47a165b": "ok",
29
+ "5f8f924671cda79b5205a6bf1b776f347c4a7a07": "Opções de configuração disponíveis:\n",
30
+ "cef780a309cd234750764d42697882c24168ddab": "{key:15} {desc} (padrão: {default})",
31
+ "68c2cc7f0ceaa3e499ecb4db331feb4debbbcc23": "Modelo",
32
+ "c3f104d1365744b538bfde9f4adb6a6df4b80355": "Função",
33
+ "99a0efc6cfd85d8ff2732a6718140f822cb90472": "Estilo",
34
+ "f1702b4686278becffc88baabe6f4b7a8355532c": "Mensagens",
35
+ "c38c6c1f3a2743f8626703abb302e403d20ff81c": "Tokens",
36
+ "a817d7eb8e0f1dab755ab5203a082e5c3c094fce": "Prompt",
37
+ "2ff255684a2277f806fcebf3fe338ed27857f350": "Conclusão",
38
+ "b25928c69902557b0ef0a628490a3a1768d7b82f": "Total",
39
+ "76e63d65c883ed50df40ac3aeef0c2d6a1c4ad60": "Ação Rápida",
40
+ "5397e0583f14f6c88de06b1ef28f460a1fb5b0ae": "Sim",
41
+ "816c52fd2bdd94a63cd0944823a6c0aa9384c103": "Não",
42
+ "c47ae15370cfe1ed2781eedc1dc2547d12d9e972": "Ajuda",
43
+ "cc3dbd47e1cf9003a55d3366b3adbcd72275e525": "Nova Tarefa",
44
+ "efa5a8b84e1afe65c81ecfce28c398c48f19ddc2": "Bem-vindo ao Janito{version_str}! Entrando no modo de chat. Digite /exit para sair.",
45
+ "b314d6e1460f86e0f21abc5aceb7935a2a0667e8": "Bem-vindo ao Janito{version_str} no [white on magenta]MODO VANILLA[/white on magenta]! Ferramentas, prompt do sistema e temperatura estão desativados, a menos que sejam substituídos.",
46
+ }
janito/llm/README.md ADDED
@@ -0,0 +1,23 @@
1
+ # janito.llm Package
2
+
3
+ This directory contains generic, provider-agnostic classes and methods for working with Large Language Models (LLMs) in the `janito` framework. Its purpose is to provide base abstractions that can be extended by provider-specific implementations.
4
+
5
+ ## Scope and Contents
6
+
7
+ - **driver.py**
8
+ - Contains `LLMDriver`, an abstract base class defining the core methods for LLM drivers. Subclasses should implement provider/model-specific logic, while benefiting from consistent streaming and event interfaces.
9
+ - **provider.py**
10
+ - Contains `LLMProvider`, an abstract base class for LLM API providers. This outlines the required interface for integrating new providers and retrieving model info or driver classes.
11
+
12
+ ## Usage
13
+ - Extend these base classes when adding new drivers or providers.
14
+ - Do not include provider-specific logic here; only generic mechanisms, patterns, or utilities applicable to any LLM integration belong in this package.
15
+
16
+ ## Example
17
+ ```python
18
+ from janito.llm.driver import LLMDriver
19
+ from janito.llm.provider import LLMProvider
20
+ ```
21
+
22
+ ---
23
+ This README clarifies the intention of the `llm` package as the generic/static contract for LLM drivers and providers.
janito/llm/__init__.py CHANGED
@@ -1,5 +1,5 @@
1
- # janito.llm package
2
-
3
- from .driver import LLMDriver
4
- from .provider import LLMProvider
5
- from .driver_config import LLMDriverConfig
1
+ # janito.llm package
2
+
3
+ from .driver import LLMDriver
4
+ from .provider import LLMProvider
5
+ from .driver_config import LLMDriverConfig