janito 2.3.1__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 (96) hide show
  1. janito/__init__.py +1 -1
  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/commands/__init__.py +13 -7
  11. janito/cli/chat_mode/shell/commands/_priv_check.py +5 -0
  12. janito/cli/chat_mode/shell/commands/conversation_restart.py +30 -0
  13. janito/cli/chat_mode/shell/commands/execute.py +42 -0
  14. janito/cli/chat_mode/shell/commands/help.py +6 -3
  15. janito/cli/chat_mode/shell/commands/model.py +28 -0
  16. janito/cli/chat_mode/shell/commands/read.py +37 -0
  17. janito/cli/chat_mode/shell/commands/tools.py +45 -18
  18. janito/cli/chat_mode/shell/commands/write.py +37 -0
  19. janito/cli/chat_mode/shell/commands.bak.zip +0 -0
  20. janito/cli/chat_mode/shell/session.bak.zip +0 -0
  21. janito/cli/chat_mode/toolbar.py +44 -27
  22. janito/cli/cli_commands/list_tools.py +44 -11
  23. janito/cli/cli_commands/model_utils.py +95 -95
  24. janito/cli/cli_commands/show_system_prompt.py +57 -14
  25. janito/cli/config.py +5 -6
  26. janito/cli/core/getters.py +33 -33
  27. janito/cli/core/runner.py +25 -18
  28. janito/cli/core/setters.py +10 -1
  29. janito/cli/main_cli.py +28 -5
  30. janito/cli/prompt_core.py +18 -2
  31. janito/cli/prompt_setup.py +56 -0
  32. janito/cli/single_shot_mode/handler.py +14 -73
  33. janito/cli/verbose_output.py +1 -1
  34. janito/config_manager.py +125 -112
  35. janito/drivers/dashscope.bak.zip +0 -0
  36. janito/drivers/openai/README.md +20 -0
  37. janito/drivers/openai_responses.bak.zip +0 -0
  38. janito/event_bus/event.py +2 -2
  39. janito/i18n/pt.py +0 -1
  40. janito/llm/README.md +23 -0
  41. janito/llm/agent.py +80 -16
  42. janito/llm/auth.py +63 -63
  43. janito/llm/driver.py +8 -0
  44. janito/provider_registry.py +178 -176
  45. janito/providers/azure_openai/model_info.py +16 -16
  46. janito/providers/dashscope.bak.zip +0 -0
  47. janito/providers/registry.py +26 -26
  48. janito/shell.bak.zip +0 -0
  49. janito/tools/DOCSTRING_STANDARD.txt +33 -0
  50. janito/tools/README.md +3 -0
  51. janito/tools/__init__.py +20 -6
  52. janito/tools/adapters/local/__init__.py +65 -62
  53. janito/tools/adapters/local/adapter.py +18 -35
  54. janito/tools/adapters/local/ask_user.py +3 -4
  55. janito/tools/adapters/local/copy_file.py +2 -2
  56. janito/tools/adapters/local/create_directory.py +2 -2
  57. janito/tools/adapters/local/create_file.py +2 -2
  58. janito/tools/adapters/local/delete_text_in_file.py +2 -2
  59. janito/tools/adapters/local/fetch_url.py +2 -2
  60. janito/tools/adapters/local/find_files.py +2 -1
  61. janito/tools/adapters/local/get_file_outline/core.py +2 -2
  62. janito/tools/adapters/local/get_file_outline/search_outline.py +2 -2
  63. janito/tools/adapters/local/move_file.py +2 -2
  64. janito/tools/adapters/local/open_html_in_browser.py +2 -1
  65. janito/tools/adapters/local/open_url.py +2 -2
  66. janito/tools/adapters/local/python_code_run.py +3 -3
  67. janito/tools/adapters/local/python_command_run.py +3 -3
  68. janito/tools/adapters/local/python_file_run.py +3 -3
  69. janito/tools/adapters/local/remove_directory.py +2 -2
  70. janito/tools/adapters/local/remove_file.py +2 -2
  71. janito/tools/adapters/local/replace_text_in_file.py +2 -2
  72. janito/tools/adapters/local/run_bash_command.py +3 -3
  73. janito/tools/adapters/local/run_powershell_command.py +3 -3
  74. janito/tools/adapters/local/search_text/core.py +2 -2
  75. janito/tools/adapters/local/validate_file_syntax/core.py +2 -2
  76. janito/tools/adapters/local/view_file.py +2 -1
  77. janito/tools/outline_file.bak.zip +0 -0
  78. janito/tools/permissions.py +45 -0
  79. janito/tools/permissions_parse.py +12 -0
  80. janito/tools/tool_base.py +14 -1
  81. janito/tools/tool_utils.py +4 -6
  82. janito/tools/tools_adapter.py +25 -20
  83. {janito-2.3.1.dist-info → janito-2.4.0.dist-info}/METADATA +51 -16
  84. {janito-2.3.1.dist-info → janito-2.4.0.dist-info}/RECORD +88 -74
  85. janito/agent/templates/profiles/system_prompt_template_base_pt.txt.j2 +0 -13
  86. janito/agent/templates/profiles/system_prompt_template_main.txt.j2 +0 -37
  87. janito/cli/chat_mode/shell/commands/edit.py +0 -25
  88. janito/cli/chat_mode/shell/commands/exec.py +0 -27
  89. janito/cli/chat_mode/shell/commands/termweb_log.py +0 -92
  90. janito/cli/termweb_starter.py +0 -122
  91. janito/termweb/app.py +0 -95
  92. janito/version.py +0 -4
  93. {janito-2.3.1.dist-info → janito-2.4.0.dist-info}/WHEEL +0 -0
  94. {janito-2.3.1.dist-info → janito-2.4.0.dist-info}/entry_points.txt +0 -0
  95. {janito-2.3.1.dist-info → janito-2.4.0.dist-info}/licenses/LICENSE +0 -0
  96. {janito-2.3.1.dist-info → janito-2.4.0.dist-info}/top_level.txt +0 -0
janito/llm/auth.py CHANGED
@@ -1,63 +1,63 @@
1
- """
2
- LLMAuthManager: Handles authentication credentials for LLM providers, persisted in ~/.janito/auth.json or a custom path.
3
- """
4
-
5
- import os
6
- import json
7
- from typing import Dict, Optional
8
-
9
-
10
- class LLMAuthManager:
11
- """
12
- Manages authentication tokens, API keys, or credentials for LLM providers.
13
- Persists credentials in ~/.janito/auth.json or a custom path.
14
- """
15
-
16
- def __init__(self, auth_file: Optional[str] = None):
17
- if auth_file is not None:
18
- self._auth_file = os.path.expanduser(auth_file)
19
- else:
20
- self._auth_file = os.path.expanduser("~/.janito/auth.json")
21
- self._credentials: Dict[str, str] = {}
22
- self._load_credentials()
23
-
24
- def _load_credentials(self):
25
- if os.path.exists(self._auth_file):
26
- try:
27
- with open(self._auth_file, "r") as f:
28
- self._credentials = json.load(f)
29
- except Exception:
30
- self._credentials = {}
31
- else:
32
- self._credentials = {}
33
-
34
- def _save_credentials(self):
35
- os.makedirs(os.path.dirname(self._auth_file), exist_ok=True)
36
- with open(self._auth_file, "w") as f:
37
- json.dump(self._credentials, f, indent=2)
38
- f.write("\n")
39
-
40
- def set_credentials(self, provider_name: str, credentials: str) -> None:
41
- """
42
- Store credentials for a given provider and persist to disk. Raises ValueError if provider is unknown.
43
- """
44
- from janito.providers.registry import LLMProviderRegistry
45
-
46
- if provider_name not in LLMProviderRegistry.list_providers():
47
- raise ValueError(f"Unknown provider: {provider_name}")
48
- self._credentials[provider_name] = credentials
49
- self._save_credentials()
50
-
51
- def get_credentials(self, provider_name: str) -> Optional[str]:
52
- """
53
- Retrieve credentials for a given provider.
54
- """
55
- return self._credentials.get(provider_name)
56
-
57
- def remove_credentials(self, provider_name: str) -> None:
58
- """
59
- Remove credentials for a given provider and update disk.
60
- """
61
- if provider_name in self._credentials:
62
- del self._credentials[provider_name]
63
- self._save_credentials()
1
+ """
2
+ LLMAuthManager: Handles authentication credentials for LLM providers, persisted in ~/.janito/auth.json or a custom path.
3
+ """
4
+
5
+ import os
6
+ import json
7
+ from typing import Dict, Optional
8
+
9
+
10
+ class LLMAuthManager:
11
+ """
12
+ Manages authentication tokens, API keys, or credentials for LLM providers.
13
+ Persists credentials in ~/.janito/auth.json or a custom path.
14
+ """
15
+
16
+ def __init__(self, auth_file: Optional[str] = None):
17
+ if auth_file is not None:
18
+ self._auth_file = os.path.expanduser(auth_file)
19
+ else:
20
+ self._auth_file = os.path.expanduser("~/.janito/auth.json")
21
+ self._credentials: Dict[str, str] = {}
22
+ self._load_credentials()
23
+
24
+ def _load_credentials(self):
25
+ if os.path.exists(self._auth_file):
26
+ try:
27
+ with open(self._auth_file, "r") as f:
28
+ self._credentials = json.load(f)
29
+ except Exception:
30
+ self._credentials = {}
31
+ else:
32
+ self._credentials = {}
33
+
34
+ def _save_credentials(self):
35
+ os.makedirs(os.path.dirname(self._auth_file), exist_ok=True)
36
+ with open(self._auth_file, "w") as f:
37
+ json.dump(self._credentials, f, indent=2)
38
+ f.write("\n")
39
+
40
+ def set_credentials(self, provider_name: str, credentials: str) -> None:
41
+ """
42
+ Store credentials for a given provider and persist to disk. Raises ValueError if provider is unknown.
43
+ """
44
+ from janito.providers.registry import LLMProviderRegistry
45
+
46
+ if provider_name not in LLMProviderRegistry.list_providers():
47
+ raise ValueError(f"Unknown provider: {provider_name}")
48
+ self._credentials[provider_name] = credentials
49
+ self._save_credentials()
50
+
51
+ def get_credentials(self, provider_name: str) -> Optional[str]:
52
+ """
53
+ Retrieve credentials for a given provider.
54
+ """
55
+ return self._credentials.get(provider_name)
56
+
57
+ def remove_credentials(self, provider_name: str) -> None:
58
+ """
59
+ Remove credentials for a given provider and update disk.
60
+ """
61
+ if provider_name in self._credentials:
62
+ del self._credentials[provider_name]
63
+ self._save_credentials()
janito/llm/driver.py CHANGED
@@ -19,6 +19,14 @@ class LLMDriver(ABC):
19
19
  except Exception:
20
20
  pass
21
21
 
22
+ def clear_input_queue(self):
23
+ """Remove all items from the input queue."""
24
+ try:
25
+ while True:
26
+ self.input_queue.get_nowait()
27
+ except Exception:
28
+ pass
29
+
22
30
  """
23
31
  Abstract base class for LLM drivers (threaded, queue-based).
24
32
  Subclasses must implement:
@@ -1,176 +1,178 @@
1
- """
2
- ProviderRegistry: Handles provider listing and selection logic for janito CLI.
3
- """
4
-
5
- from rich.table import Table
6
- from janito.cli.console import shared_console
7
- from janito.providers.registry import LLMProviderRegistry
8
- from janito.providers.provider_static_info import STATIC_PROVIDER_METADATA
9
- from janito.llm.auth import LLMAuthManager
10
- import sys
11
- from janito.exceptions import MissingProviderSelectionException
12
-
13
-
14
- class ProviderRegistry:
15
- def list_providers(self):
16
- """List all supported LLM providers as a table using rich, showing if auth is configured and supported model names."""
17
- providers = self._get_provider_names()
18
- table = self._create_table()
19
- rows = self._get_all_provider_rows(providers)
20
- self._add_rows_to_table(table, rows)
21
- self._print_table(table)
22
-
23
- def _get_provider_names(self):
24
- return list(STATIC_PROVIDER_METADATA.keys())
25
-
26
- def _create_table(self):
27
- table = Table(title="Supported LLM Providers")
28
- table.add_column("Provider", style="cyan")
29
- table.add_column("Maintainer", style="yellow", justify="center")
30
- table.add_column("Model Names", style="magenta")
31
- return table
32
-
33
- def _get_all_provider_rows(self, providers):
34
- rows = []
35
- for p in providers:
36
- info = self._get_provider_info(p)
37
- # info is (provider_name, maintainer, model_names, skip)
38
- if len(info) == 4 and info[3]:
39
- continue # skip providers flagged as not implemented
40
- rows.append(info[:3])
41
- rows.sort(key=self._maintainer_sort_key)
42
- return rows
43
-
44
- def _add_rows_to_table(self, table, rows):
45
- for idx, (p, maintainer, model_names) in enumerate(rows):
46
- table.add_row(p, maintainer, model_names)
47
- if idx != len(rows) - 1:
48
- table.add_section()
49
-
50
- def _print_table(self, table):
51
- """Print the table using rich when running in a terminal; otherwise fall back to a plain ASCII listing.
52
- This avoids UnicodeDecodeError when the parent process captures the output with a non-UTF8 encoding.
53
- """
54
- import sys
55
-
56
- if sys.stdout.isatty():
57
- # Safe to use rich's unicode output when attached to an interactive terminal.
58
- shared_console.print(table)
59
- return
60
-
61
- # Fallback: plain ASCII output
62
- print("Supported LLM Providers")
63
- print("Provider | Maintainer | Model Names")
64
- for row in table.rows:
65
- # row is a rich.table.Row -> row.cells is a list of Text objects
66
- cells_text = [str(cell) for cell in row.cells]
67
- ascii_row = " | ".join(cells_text).encode("ascii", "ignore").decode("ascii")
68
- print(ascii_row)
69
- shared_console.print(table)
70
-
71
- def _get_provider_info(self, provider_name):
72
- static_info = STATIC_PROVIDER_METADATA.get(provider_name, {})
73
- maintainer_val = static_info.get("maintainer", "-")
74
- maintainer = (
75
- "[red]🚨 Needs maintainer[/red]"
76
- if maintainer_val == "Needs maintainer"
77
- else f"👤 {maintainer_val}"
78
- )
79
- model_names = "-"
80
- unavailable_reason = None
81
- skip = False
82
- try:
83
- provider_class = LLMProviderRegistry.get(provider_name)
84
- creds = LLMAuthManager().get_credentials(provider_name)
85
- provider_instance = None
86
- instantiation_failed = False
87
- try:
88
- provider_instance = provider_class()
89
- except NotImplementedError:
90
- skip = True
91
- unavailable_reason = "Not implemented"
92
- model_names = f"[red]❌ Not implemented[/red]"
93
- except Exception as e:
94
- instantiation_failed = True
95
- unavailable_reason = (
96
- f"Unavailable (import error or missing dependency): {str(e)}"
97
- )
98
- model_names = f"[red]❌ {unavailable_reason}[/red]"
99
- if not instantiation_failed and provider_instance is not None:
100
- available, unavailable_reason = self._get_availability(
101
- provider_instance
102
- )
103
- if (
104
- not available
105
- and unavailable_reason
106
- and "not implemented" in str(unavailable_reason).lower()
107
- ):
108
- skip = True
109
- if available:
110
- model_names = self._get_model_names(provider_name)
111
- else:
112
- model_names = f"[red]❌ {unavailable_reason}[/red]"
113
- except Exception as import_error:
114
- model_names = f"[red]❌ Unavailable (cannot import provider module): {str(import_error)}[/red]"
115
- return (provider_name, maintainer, model_names, skip)
116
-
117
- def _get_availability(self, provider_instance):
118
- try:
119
- available = getattr(provider_instance, "available", True)
120
- unavailable_reason = getattr(provider_instance, "unavailable_reason", None)
121
- except Exception as e:
122
- available = False
123
- unavailable_reason = f"Error reading runtime availability: {str(e)}"
124
- return available, unavailable_reason
125
-
126
- def _get_model_names(self, provider_name):
127
- provider_to_specs = {
128
- "openai": "janito.providers.openai.model_info",
129
- "azure_openai": "janito.providers.azure_openai.model_info",
130
- "google": "janito.providers.google.model_info",
131
- "mistralai": "janito.providers.mistralai.model_info",
132
- "deepseek": "janito.providers.deepseek.model_info",
133
- }
134
- if provider_name in provider_to_specs:
135
- try:
136
- mod = __import__(
137
- provider_to_specs[provider_name], fromlist=["MODEL_SPECS"]
138
- )
139
- return ", ".join(mod.MODEL_SPECS.keys())
140
- except Exception:
141
- return "(Error)"
142
- return "-"
143
-
144
- def _maintainer_sort_key(self, row):
145
- maint = row[1]
146
- is_needs_maint = "Needs maintainer" in maint
147
- return (is_needs_maint, row[2] != "✅ Auth")
148
-
149
- def get_provider(self, provider_name):
150
- """Return the provider class for the given provider name. Returns None if not found."""
151
- from janito.providers.registry import LLMProviderRegistry
152
-
153
- if not provider_name:
154
- print("Error: Provider name must be specified.")
155
- return None
156
- provider_class = LLMProviderRegistry.get(provider_name)
157
- if provider_class is None:
158
- available = ', '.join(LLMProviderRegistry.list_providers())
159
- print(f"Error: Provider '{provider_name}' is not recognized. Available providers: {available}.")
160
- return None
161
- return provider_class
162
-
163
- def get_instance(self, provider_name, config=None):
164
- """Return an instance of the provider for the given provider name, optionally passing a config object. Returns None if not found."""
165
- provider_class = self.get_provider(provider_name)
166
- if provider_class is None:
167
- return None
168
- if config is not None:
169
- return provider_class(config=config)
170
- return provider_class()
171
-
172
-
173
- # For backward compatibility
174
- def list_providers():
175
- """Legacy function for listing providers, now uses ProviderRegistry class."""
176
- ProviderRegistry().list_providers()
1
+ """
2
+ ProviderRegistry: Handles provider listing and selection logic for janito CLI.
3
+ """
4
+
5
+ from rich.table import Table
6
+ from janito.cli.console import shared_console
7
+ from janito.providers.registry import LLMProviderRegistry
8
+ from janito.providers.provider_static_info import STATIC_PROVIDER_METADATA
9
+ from janito.llm.auth import LLMAuthManager
10
+ import sys
11
+ from janito.exceptions import MissingProviderSelectionException
12
+
13
+
14
+ class ProviderRegistry:
15
+ def list_providers(self):
16
+ """List all supported LLM providers as a table using rich, showing if auth is configured and supported model names."""
17
+ providers = self._get_provider_names()
18
+ table = self._create_table()
19
+ rows = self._get_all_provider_rows(providers)
20
+ self._add_rows_to_table(table, rows)
21
+ self._print_table(table)
22
+
23
+ def _get_provider_names(self):
24
+ return list(STATIC_PROVIDER_METADATA.keys())
25
+
26
+ def _create_table(self):
27
+ table = Table(title="Supported LLM Providers")
28
+ table.add_column("Provider", style="cyan")
29
+ table.add_column("Maintainer", style="yellow", justify="center")
30
+ table.add_column("Model Names", style="magenta")
31
+ return table
32
+
33
+ def _get_all_provider_rows(self, providers):
34
+ rows = []
35
+ for p in providers:
36
+ info = self._get_provider_info(p)
37
+ # info is (provider_name, maintainer, model_names, skip)
38
+ if len(info) == 4 and info[3]:
39
+ continue # skip providers flagged as not implemented
40
+ rows.append(info[:3])
41
+ rows.sort(key=self._maintainer_sort_key)
42
+ return rows
43
+
44
+ def _add_rows_to_table(self, table, rows):
45
+ for idx, (p, maintainer, model_names) in enumerate(rows):
46
+ table.add_row(p, maintainer, model_names)
47
+ if idx != len(rows) - 1:
48
+ table.add_section()
49
+
50
+ def _print_table(self, table):
51
+ """Print the table using rich when running in a terminal; otherwise fall back to a plain ASCII listing.
52
+ This avoids UnicodeDecodeError when the parent process captures the output with a non-UTF8 encoding.
53
+ """
54
+ import sys
55
+
56
+ if sys.stdout.isatty():
57
+ # Safe to use rich's unicode output when attached to an interactive terminal.
58
+ shared_console.print(table)
59
+ return
60
+
61
+ # Fallback: plain ASCII output (render without rich formatting)
62
+ print("Supported LLM Providers")
63
+ # Build header from column titles
64
+ header_titles = [column.header or "" for column in table.columns]
65
+ print(" | ".join(header_titles))
66
+ # rich.table.Row objects in recent Rich versions don't expose a public `.cells` attribute.
67
+ # Instead, cell content is stored in each column's private `_cells` list.
68
+ for row_index, _ in enumerate(table.rows):
69
+ cells_text = [str(column._cells[row_index]) for column in table.columns]
70
+ ascii_row = " | ".join(cells_text).encode("ascii", "ignore").decode("ascii")
71
+ print(ascii_row)
72
+
73
+ def _get_provider_info(self, provider_name):
74
+ static_info = STATIC_PROVIDER_METADATA.get(provider_name, {})
75
+ maintainer_val = static_info.get("maintainer", "-")
76
+ maintainer = (
77
+ "[red]🚨 Needs maintainer[/red]"
78
+ if maintainer_val == "Needs maintainer"
79
+ else f"👤 {maintainer_val}"
80
+ )
81
+ model_names = "-"
82
+ unavailable_reason = None
83
+ skip = False
84
+ try:
85
+ provider_class = LLMProviderRegistry.get(provider_name)
86
+ creds = LLMAuthManager().get_credentials(provider_name)
87
+ provider_instance = None
88
+ instantiation_failed = False
89
+ try:
90
+ provider_instance = provider_class()
91
+ except NotImplementedError:
92
+ skip = True
93
+ unavailable_reason = "Not implemented"
94
+ model_names = f"[red]❌ Not implemented[/red]"
95
+ except Exception as e:
96
+ instantiation_failed = True
97
+ unavailable_reason = (
98
+ f"Unavailable (import error or missing dependency): {str(e)}"
99
+ )
100
+ model_names = f"[red]❌ {unavailable_reason}[/red]"
101
+ if not instantiation_failed and provider_instance is not None:
102
+ available, unavailable_reason = self._get_availability(
103
+ provider_instance
104
+ )
105
+ if (
106
+ not available
107
+ and unavailable_reason
108
+ and "not implemented" in str(unavailable_reason).lower()
109
+ ):
110
+ skip = True
111
+ if available:
112
+ model_names = self._get_model_names(provider_name)
113
+ else:
114
+ model_names = f"[red]❌ {unavailable_reason}[/red]"
115
+ except Exception as import_error:
116
+ model_names = f"[red]❌ Unavailable (cannot import provider module): {str(import_error)}[/red]"
117
+ return (provider_name, maintainer, model_names, skip)
118
+
119
+ def _get_availability(self, provider_instance):
120
+ try:
121
+ available = getattr(provider_instance, "available", True)
122
+ unavailable_reason = getattr(provider_instance, "unavailable_reason", None)
123
+ except Exception as e:
124
+ available = False
125
+ unavailable_reason = f"Error reading runtime availability: {str(e)}"
126
+ return available, unavailable_reason
127
+
128
+ def _get_model_names(self, provider_name):
129
+ provider_to_specs = {
130
+ "openai": "janito.providers.openai.model_info",
131
+ "azure_openai": "janito.providers.azure_openai.model_info",
132
+ "google": "janito.providers.google.model_info",
133
+ "mistralai": "janito.providers.mistralai.model_info",
134
+ "deepseek": "janito.providers.deepseek.model_info",
135
+ }
136
+ if provider_name in provider_to_specs:
137
+ try:
138
+ mod = __import__(
139
+ provider_to_specs[provider_name], fromlist=["MODEL_SPECS"]
140
+ )
141
+ return ", ".join(mod.MODEL_SPECS.keys())
142
+ except Exception:
143
+ return "(Error)"
144
+ return "-"
145
+
146
+ def _maintainer_sort_key(self, row):
147
+ maint = row[1]
148
+ is_needs_maint = "Needs maintainer" in maint
149
+ return (is_needs_maint, row[2] != "✅ Auth")
150
+
151
+ def get_provider(self, provider_name):
152
+ """Return the provider class for the given provider name. Returns None if not found."""
153
+ from janito.providers.registry import LLMProviderRegistry
154
+
155
+ if not provider_name:
156
+ print("Error: Provider name must be specified.")
157
+ return None
158
+ provider_class = LLMProviderRegistry.get(provider_name)
159
+ if provider_class is None:
160
+ available = ', '.join(LLMProviderRegistry.list_providers())
161
+ print(f"Error: Provider '{provider_name}' is not recognized. Available providers: {available}.")
162
+ return None
163
+ return provider_class
164
+
165
+ def get_instance(self, provider_name, config=None):
166
+ """Return an instance of the provider for the given provider name, optionally passing a config object. Returns None if not found."""
167
+ provider_class = self.get_provider(provider_name)
168
+ if provider_class is None:
169
+ return None
170
+ if config is not None:
171
+ return provider_class(config=config)
172
+ return provider_class()
173
+
174
+
175
+ # For backward compatibility
176
+ def list_providers():
177
+ """Legacy function for listing providers, now uses ProviderRegistry class."""
178
+ ProviderRegistry().list_providers()
@@ -1,16 +1,16 @@
1
- from janito.llm.model import LLMModelInfo
2
- from janito.providers.openai.model_info import MODEL_SPECS as OPENAI_MODEL_SPECS
3
-
4
- MODEL_SPECS = {
5
- "azure_openai_deployment": LLMModelInfo(
6
- name="azure_openai_deployment",
7
- context=OPENAI_MODEL_SPECS["gpt-4o"].context,
8
- max_input=OPENAI_MODEL_SPECS["gpt-4o"].max_input,
9
- max_cot=OPENAI_MODEL_SPECS["gpt-4o"].max_cot,
10
- max_response=OPENAI_MODEL_SPECS["gpt-4o"].max_response,
11
- thinking_supported=OPENAI_MODEL_SPECS["gpt-4o"].thinking_supported,
12
- default_temp=OPENAI_MODEL_SPECS["gpt-4o"].default_temp,
13
- open="azure_openai",
14
- driver="AzureOpenAIModelDriver",
15
- )
16
- }
1
+ from janito.llm.model import LLMModelInfo
2
+ from janito.providers.openai.model_info import MODEL_SPECS as OPENAI_MODEL_SPECS
3
+
4
+ MODEL_SPECS = {
5
+ "azure_openai_deployment": LLMModelInfo(
6
+ name="azure_openai_deployment",
7
+ context=OPENAI_MODEL_SPECS["gpt-4o"].context,
8
+ max_input=OPENAI_MODEL_SPECS["gpt-4o"].max_input,
9
+ max_cot=OPENAI_MODEL_SPECS["gpt-4o"].max_cot,
10
+ max_response=OPENAI_MODEL_SPECS["gpt-4o"].max_response,
11
+ thinking_supported=OPENAI_MODEL_SPECS["gpt-4o"].thinking_supported,
12
+ default_temp=OPENAI_MODEL_SPECS["gpt-4o"].default_temp,
13
+ open="azure_openai",
14
+ driver="AzureOpenAIModelDriver",
15
+ )
16
+ }
Binary file
@@ -1,26 +1,26 @@
1
- from typing import Type, Dict
2
- from janito.llm.provider import LLMProvider
3
-
4
-
5
- class LLMProviderRegistry:
6
- """
7
- Registry for LLM provider classes.
8
- """
9
-
10
- _providers: Dict[str, Type[LLMProvider]] = {}
11
-
12
- @classmethod
13
- def register(cls, name: str, provider_cls: Type[LLMProvider]):
14
- if name in cls._providers:
15
- raise ValueError(f"Provider '{name}' is already registered.")
16
- cls._providers[name] = provider_cls
17
-
18
- @classmethod
19
- def get(cls, name: str) -> Type[LLMProvider]:
20
- if name not in cls._providers:
21
- return None
22
- return cls._providers[name]
23
-
24
- @classmethod
25
- def list_providers(cls):
26
- return list(cls._providers.keys())
1
+ from typing import Type, Dict
2
+ from janito.llm.provider import LLMProvider
3
+
4
+
5
+ class LLMProviderRegistry:
6
+ """
7
+ Registry for LLM provider classes.
8
+ """
9
+
10
+ _providers: Dict[str, Type[LLMProvider]] = {}
11
+
12
+ @classmethod
13
+ def register(cls, name: str, provider_cls: Type[LLMProvider]):
14
+ if name in cls._providers:
15
+ raise ValueError(f"Provider '{name}' is already registered.")
16
+ cls._providers[name] = provider_cls
17
+
18
+ @classmethod
19
+ def get(cls, name: str) -> Type[LLMProvider]:
20
+ if name not in cls._providers:
21
+ return None
22
+ return cls._providers[name]
23
+
24
+ @classmethod
25
+ def list_providers(cls):
26
+ return list(cls._providers.keys())
janito/shell.bak.zip ADDED
Binary file
@@ -0,0 +1,33 @@
1
+ # Docstring Format Standard for Tools
2
+
3
+ All tool classes must use the following docstring style for schema compatibility and consistency:
4
+
5
+ - Use a single docstring in the tool class describing Args and Returns for all parameters of the `call` method.
6
+ - Args: List each parameter as `name (type): description` (type hints required for clarity).
7
+ - No blank lines between Args entries.
8
+ - Returns: Single line description, followed by examples if needed (no list markers).
9
+ - Keep formatting simple and consistent for schema compatibility.
10
+
11
+ Example:
12
+
13
+ class FindFilesTool(ToolBase):
14
+ """
15
+ Find files in one or more directories matching a pattern.
16
+
17
+ Args:
18
+ directories (list[str]): List of directories to search in.
19
+ pattern (str): File pattern to match. Uses Unix shell-style wildcards (fnmatch), e.g. '*.py', 'data_??.csv', '[a-z]*.txt'.
20
+
21
+ max_results (int, optional): Maximum number of results to return. Defaults to 100.
22
+ Returns:
23
+ str: Newline-separated list of matching file paths. Example:
24
+ "/path/to/file1.py\n/path/to/file2.py"
25
+ "Warning: Empty file pattern provided. Operation skipped."
26
+ """
27
+
28
+ # Tool Class Docstring Requirement
29
+
30
+ - All parameter documentation for OpenAI function tools must be in the class docstring, not the `call` method docstring.
31
+ - The class docstring is prepended to the tool's description in the OpenAI schema and is user-facing.
32
+ - Write class docstrings as concise, clear summaries of the tool's purpose and behavior, including parameter and return descriptions as shown above.
33
+ - Avoid implementation details; focus on what the tool does for the user.
janito/tools/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # Tools Reference
2
+
3
+ This documentation has moved to [docs/TOOLS_REFERENCE.md](../../../docs/TOOLS_REFERENCE.md).