janito 2.6.0__py3-none-any.whl → 2.7.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 (33) hide show
  1. janito/__init__.py +1 -0
  2. janito/__main__.py +1 -0
  3. janito/_version.py +1 -0
  4. janito/agent/setup_agent.py +240 -230
  5. janito/agent/templates/profiles/{system_prompt_template_software_developer.txt.j2 → system_prompt_template_plain_software_developer.txt.j2} +39 -39
  6. janito/cli/__init__.py +1 -0
  7. janito/cli/chat_mode/bindings.py +1 -0
  8. janito/cli/chat_mode/chat_entry.py +1 -0
  9. janito/cli/chat_mode/prompt_style.py +1 -0
  10. janito/cli/chat_mode/script_runner.py +1 -0
  11. janito/cli/chat_mode/session.py +282 -282
  12. janito/cli/chat_mode/session_profile_select.py +5 -5
  13. janito/cli/single_shot_mode/handler.py +95 -95
  14. janito/drivers/driver_registry.py +27 -27
  15. janito/drivers/openai/driver.py +435 -435
  16. janito/provider_registry.py +178 -178
  17. janito/providers/__init__.py +1 -0
  18. janito/providers/anthropic/model_info.py +41 -41
  19. janito/providers/anthropic/provider.py +80 -80
  20. janito/providers/moonshotai/__init__.py +1 -0
  21. janito/providers/moonshotai/model_info.py +15 -0
  22. janito/providers/moonshotai/provider.py +82 -0
  23. janito/providers/openai/model_info.py +1 -0
  24. janito/providers/provider_static_info.py +21 -18
  25. janito/tools/adapters/local/__init__.py +66 -66
  26. janito/tools/adapters/local/move_file.py +3 -3
  27. janito/tools/adapters/local/read_files.py +40 -40
  28. {janito-2.6.0.dist-info → janito-2.7.0.dist-info}/METADATA +419 -412
  29. {janito-2.6.0.dist-info → janito-2.7.0.dist-info}/RECORD +33 -30
  30. {janito-2.6.0.dist-info → janito-2.7.0.dist-info}/WHEEL +0 -0
  31. {janito-2.6.0.dist-info → janito-2.7.0.dist-info}/entry_points.txt +0 -0
  32. {janito-2.6.0.dist-info → janito-2.7.0.dist-info}/licenses/LICENSE +0 -0
  33. {janito-2.6.0.dist-info → janito-2.7.0.dist-info}/top_level.txt +0 -0
@@ -1,178 +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 (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
- "anthropic": "janito.providers.anthropic.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
+ """
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
+ "anthropic": "janito.providers.anthropic.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()
@@ -4,3 +4,4 @@ import janito.providers.google.provider
4
4
  import janito.providers.azure_openai.provider
5
5
  import janito.providers.anthropic.provider
6
6
  import janito.providers.deepseek.provider
7
+ import janito.providers.moonshotai.provider
@@ -1,41 +1,41 @@
1
- from janito.llm.model import LLMModelInfo
2
-
3
- MODEL_SPECS = {
4
- "claude-opus-4-20250514": LLMModelInfo(
5
- name="claude-opus-4-20250514",
6
- max_response=32000,
7
- default_temp=0.7,
8
- driver="OpenAIModelDriver",
9
- ),
10
- "claude-sonnet-4-20250514": LLMModelInfo(
11
- name="claude-sonnet-4-20250514",
12
- max_response=64000,
13
- default_temp=0.7,
14
- driver="OpenAIModelDriver",
15
- ),
16
- "claude-3-7-sonnet-20250219": LLMModelInfo(
17
- name="claude-3-7-sonnet-20250219",
18
- max_response=64000,
19
- default_temp=0.7,
20
- driver="OpenAIModelDriver",
21
- ),
22
- "claude-3-5-haiku-20241022": LLMModelInfo(
23
- name="claude-3-5-haiku-20241022",
24
- max_response=8192,
25
- default_temp=0.7,
26
- driver="OpenAIModelDriver",
27
- ),
28
- "claude-3-5-sonnet-20241022": LLMModelInfo(
29
- name="claude-3-5-sonnet-20241022",
30
- max_response=8192,
31
- default_temp=0.7,
32
- driver="OpenAIModelDriver",
33
- ),
34
- "claude-3-haiku-20240307": LLMModelInfo(
35
- name="claude-3-haiku-20240307",
36
- max_response=4096,
37
- default_temp=0.7,
38
- driver="OpenAIModelDriver",
39
- ),
40
- }
41
-
1
+ from janito.llm.model import LLMModelInfo
2
+
3
+ MODEL_SPECS = {
4
+ "claude-opus-4-20250514": LLMModelInfo(
5
+ name="claude-opus-4-20250514",
6
+ max_response=32000,
7
+ default_temp=0.7,
8
+ driver="OpenAIModelDriver",
9
+ ),
10
+ "claude-sonnet-4-20250514": LLMModelInfo(
11
+ name="claude-sonnet-4-20250514",
12
+ max_response=64000,
13
+ default_temp=0.7,
14
+ driver="OpenAIModelDriver",
15
+ ),
16
+ "claude-3-7-sonnet-20250219": LLMModelInfo(
17
+ name="claude-3-7-sonnet-20250219",
18
+ max_response=64000,
19
+ default_temp=0.7,
20
+ driver="OpenAIModelDriver",
21
+ ),
22
+ "claude-3-5-haiku-20241022": LLMModelInfo(
23
+ name="claude-3-5-haiku-20241022",
24
+ max_response=8192,
25
+ default_temp=0.7,
26
+ driver="OpenAIModelDriver",
27
+ ),
28
+ "claude-3-5-sonnet-20241022": LLMModelInfo(
29
+ name="claude-3-5-sonnet-20241022",
30
+ max_response=8192,
31
+ default_temp=0.7,
32
+ driver="OpenAIModelDriver",
33
+ ),
34
+ "claude-3-haiku-20240307": LLMModelInfo(
35
+ name="claude-3-haiku-20240307",
36
+ max_response=4096,
37
+ default_temp=0.7,
38
+ driver="OpenAIModelDriver",
39
+ ),
40
+ }
41
+
@@ -1,80 +1,80 @@
1
- from janito.llm.provider import LLMProvider
2
- from janito.llm.model import LLMModelInfo
3
- from janito.llm.auth import LLMAuthManager
4
- from janito.llm.driver_config import LLMDriverConfig
5
- from janito.tools import get_local_tools_adapter
6
- from janito.providers.registry import LLMProviderRegistry
7
-
8
- from .model_info import MODEL_SPECS
9
-
10
- from janito.llm.provider import LLMProvider
11
- from janito.llm.model import LLMModelInfo
12
- from janito.llm.auth import LLMAuthManager
13
- from janito.llm.driver_config import LLMDriverConfig
14
- from janito.tools import get_local_tools_adapter
15
- from janito.providers.registry import LLMProviderRegistry
16
- from .model_info import MODEL_SPECS
17
- from janito.drivers.openai.driver import OpenAIModelDriver
18
-
19
- class AnthropicProvider(LLMProvider):
20
- name = "anthropic"
21
- maintainer = "Needs maintainer"
22
- MODEL_SPECS = MODEL_SPECS
23
- DEFAULT_MODEL = "claude-3-7-sonnet-20250219"
24
-
25
- def __init__(
26
- self, auth_manager: LLMAuthManager = None, config: LLMDriverConfig = None
27
- ):
28
- self._tools_adapter = get_local_tools_adapter()
29
- self.auth_manager = auth_manager or LLMAuthManager()
30
- self._api_key = self.auth_manager.get_credentials(type(self).name)
31
- self._tools_adapter = get_local_tools_adapter()
32
- self._driver_config = config or LLMDriverConfig(model=None)
33
- if not getattr(self._driver_config, 'model', None):
34
- self._driver_config.model = self.DEFAULT_MODEL
35
- if not self._driver_config.api_key:
36
- self._driver_config.api_key = self._api_key
37
- # Set the Anthropic OpenAI-compatible API endpoint
38
- self._driver_config.base_url = "https://api.anthropic.com/v1/"
39
- self.fill_missing_device_info(self._driver_config)
40
- self._driver = None # to be provided by factory/agent
41
-
42
- @property
43
- def driver(self) -> OpenAIModelDriver:
44
- if not self.available:
45
- raise ImportError(f"AnthropicProvider unavailable: {self.unavailable_reason}")
46
- return self._driver
47
-
48
- @property
49
- def available(self):
50
- return OpenAIModelDriver.available
51
-
52
- @property
53
- def unavailable_reason(self):
54
- return OpenAIModelDriver.unavailable_reason
55
-
56
- def create_driver(self):
57
- """
58
- Creates and returns a new OpenAIModelDriver instance configured for Anthropic API.
59
- """
60
- driver = OpenAIModelDriver(
61
- tools_adapter=self._tools_adapter, provider_name=self.name
62
- )
63
- driver.config = self._driver_config
64
- return driver
65
-
66
- @property
67
- def model_name(self):
68
- return self._driver_config.model
69
-
70
- @property
71
- def driver_config(self):
72
- """Public, read-only access to the provider's LLMDriverConfig object."""
73
- return self._driver_config
74
-
75
- def execute_tool(self, tool_name: str, event_bus, *args, **kwargs):
76
- self._tools_adapter.event_bus = event_bus
77
- return self._tools_adapter.execute_by_name(tool_name, *args, **kwargs)
78
-
79
-
80
- LLMProviderRegistry.register(AnthropicProvider.name, AnthropicProvider)
1
+ from janito.llm.provider import LLMProvider
2
+ from janito.llm.model import LLMModelInfo
3
+ from janito.llm.auth import LLMAuthManager
4
+ from janito.llm.driver_config import LLMDriverConfig
5
+ from janito.tools import get_local_tools_adapter
6
+ from janito.providers.registry import LLMProviderRegistry
7
+
8
+ from .model_info import MODEL_SPECS
9
+
10
+ from janito.llm.provider import LLMProvider
11
+ from janito.llm.model import LLMModelInfo
12
+ from janito.llm.auth import LLMAuthManager
13
+ from janito.llm.driver_config import LLMDriverConfig
14
+ from janito.tools import get_local_tools_adapter
15
+ from janito.providers.registry import LLMProviderRegistry
16
+ from .model_info import MODEL_SPECS
17
+ from janito.drivers.openai.driver import OpenAIModelDriver
18
+
19
+ class AnthropicProvider(LLMProvider):
20
+ name = "anthropic"
21
+ maintainer = "Needs maintainer"
22
+ MODEL_SPECS = MODEL_SPECS
23
+ DEFAULT_MODEL = "claude-3-7-sonnet-20250219"
24
+
25
+ def __init__(
26
+ self, auth_manager: LLMAuthManager = None, config: LLMDriverConfig = None
27
+ ):
28
+ self._tools_adapter = get_local_tools_adapter()
29
+ self.auth_manager = auth_manager or LLMAuthManager()
30
+ self._api_key = self.auth_manager.get_credentials(type(self).name)
31
+ self._tools_adapter = get_local_tools_adapter()
32
+ self._driver_config = config or LLMDriverConfig(model=None)
33
+ if not getattr(self._driver_config, 'model', None):
34
+ self._driver_config.model = self.DEFAULT_MODEL
35
+ if not self._driver_config.api_key:
36
+ self._driver_config.api_key = self._api_key
37
+ # Set the Anthropic OpenAI-compatible API endpoint
38
+ self._driver_config.base_url = "https://api.anthropic.com/v1/"
39
+ self.fill_missing_device_info(self._driver_config)
40
+ self._driver = None # to be provided by factory/agent
41
+
42
+ @property
43
+ def driver(self) -> OpenAIModelDriver:
44
+ if not self.available:
45
+ raise ImportError(f"AnthropicProvider unavailable: {self.unavailable_reason}")
46
+ return self._driver
47
+
48
+ @property
49
+ def available(self):
50
+ return OpenAIModelDriver.available
51
+
52
+ @property
53
+ def unavailable_reason(self):
54
+ return OpenAIModelDriver.unavailable_reason
55
+
56
+ def create_driver(self):
57
+ """
58
+ Creates and returns a new OpenAIModelDriver instance configured for Anthropic API.
59
+ """
60
+ driver = OpenAIModelDriver(
61
+ tools_adapter=self._tools_adapter, provider_name=self.name
62
+ )
63
+ driver.config = self._driver_config
64
+ return driver
65
+
66
+ @property
67
+ def model_name(self):
68
+ return self._driver_config.model
69
+
70
+ @property
71
+ def driver_config(self):
72
+ """Public, read-only access to the provider's LLMDriverConfig object."""
73
+ return self._driver_config
74
+
75
+ def execute_tool(self, tool_name: str, event_bus, *args, **kwargs):
76
+ self._tools_adapter.event_bus = event_bus
77
+ return self._tools_adapter.execute_by_name(tool_name, *args, **kwargs)
78
+
79
+
80
+ LLMProviderRegistry.register(AnthropicProvider.name, AnthropicProvider)
@@ -0,0 +1 @@
1
+ # MoonshotAI provider package
@@ -0,0 +1,15 @@
1
+ from janito.llm.model import LLMModelInfo
2
+
3
+ MOONSHOTAI_MODEL_SPECS = {
4
+ "kimi-k2-0711-preview": LLMModelInfo(
5
+ name="kimi-k2-0711-preview",
6
+ context=128000,
7
+ max_input=100000,
8
+ max_cot="N/A",
9
+ max_response=4096,
10
+ thinking_supported=False,
11
+ default_temp=0.2,
12
+ open="moonshotai",
13
+ driver="OpenAIModelDriver",
14
+ ),
15
+ }