autobyteus 1.1.5__py3-none-any.whl → 1.1.7__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 (103) hide show
  1. autobyteus/agent/context/agent_config.py +6 -1
  2. autobyteus/agent/context/agent_runtime_state.py +7 -1
  3. autobyteus/agent/handlers/llm_user_message_ready_event_handler.py +30 -7
  4. autobyteus/agent/handlers/tool_result_event_handler.py +100 -88
  5. autobyteus/agent/handlers/user_input_message_event_handler.py +22 -25
  6. autobyteus/agent/llm_response_processor/provider_aware_tool_usage_processor.py +7 -1
  7. autobyteus/agent/message/__init__.py +7 -5
  8. autobyteus/agent/message/agent_input_user_message.py +6 -16
  9. autobyteus/agent/message/context_file.py +24 -24
  10. autobyteus/agent/message/context_file_type.py +29 -8
  11. autobyteus/agent/message/multimodal_message_builder.py +47 -0
  12. autobyteus/agent/streaming/stream_event_payloads.py +23 -4
  13. autobyteus/agent/system_prompt_processor/tool_manifest_injector_processor.py +6 -2
  14. autobyteus/agent/tool_invocation.py +27 -2
  15. autobyteus/agent_team/agent_team_builder.py +22 -1
  16. autobyteus/agent_team/bootstrap_steps/agent_configuration_preparation_step.py +9 -2
  17. autobyteus/agent_team/context/agent_team_config.py +1 -0
  18. autobyteus/agent_team/context/agent_team_runtime_state.py +0 -2
  19. autobyteus/llm/api/autobyteus_llm.py +33 -33
  20. autobyteus/llm/api/bedrock_llm.py +13 -5
  21. autobyteus/llm/api/claude_llm.py +13 -27
  22. autobyteus/llm/api/gemini_llm.py +108 -42
  23. autobyteus/llm/api/groq_llm.py +4 -3
  24. autobyteus/llm/api/mistral_llm.py +97 -51
  25. autobyteus/llm/api/nvidia_llm.py +6 -5
  26. autobyteus/llm/api/ollama_llm.py +37 -12
  27. autobyteus/llm/api/openai_compatible_llm.py +91 -91
  28. autobyteus/llm/autobyteus_provider.py +1 -1
  29. autobyteus/llm/base_llm.py +42 -139
  30. autobyteus/llm/extensions/base_extension.py +6 -6
  31. autobyteus/llm/extensions/token_usage_tracking_extension.py +3 -2
  32. autobyteus/llm/llm_factory.py +131 -61
  33. autobyteus/llm/ollama_provider_resolver.py +1 -0
  34. autobyteus/llm/providers.py +1 -0
  35. autobyteus/llm/token_counter/token_counter_factory.py +3 -1
  36. autobyteus/llm/user_message.py +43 -35
  37. autobyteus/llm/utils/llm_config.py +34 -18
  38. autobyteus/llm/utils/media_payload_formatter.py +99 -0
  39. autobyteus/llm/utils/messages.py +32 -25
  40. autobyteus/llm/utils/response_types.py +9 -3
  41. autobyteus/llm/utils/token_usage.py +6 -5
  42. autobyteus/multimedia/__init__.py +31 -0
  43. autobyteus/multimedia/audio/__init__.py +11 -0
  44. autobyteus/multimedia/audio/api/__init__.py +4 -0
  45. autobyteus/multimedia/audio/api/autobyteus_audio_client.py +59 -0
  46. autobyteus/multimedia/audio/api/gemini_audio_client.py +219 -0
  47. autobyteus/multimedia/audio/audio_client_factory.py +120 -0
  48. autobyteus/multimedia/audio/audio_model.py +97 -0
  49. autobyteus/multimedia/audio/autobyteus_audio_provider.py +108 -0
  50. autobyteus/multimedia/audio/base_audio_client.py +40 -0
  51. autobyteus/multimedia/image/__init__.py +11 -0
  52. autobyteus/multimedia/image/api/__init__.py +9 -0
  53. autobyteus/multimedia/image/api/autobyteus_image_client.py +97 -0
  54. autobyteus/multimedia/image/api/gemini_image_client.py +188 -0
  55. autobyteus/multimedia/image/api/openai_image_client.py +142 -0
  56. autobyteus/multimedia/image/autobyteus_image_provider.py +109 -0
  57. autobyteus/multimedia/image/base_image_client.py +67 -0
  58. autobyteus/multimedia/image/image_client_factory.py +118 -0
  59. autobyteus/multimedia/image/image_model.py +97 -0
  60. autobyteus/multimedia/providers.py +5 -0
  61. autobyteus/multimedia/runtimes.py +8 -0
  62. autobyteus/multimedia/utils/__init__.py +10 -0
  63. autobyteus/multimedia/utils/api_utils.py +19 -0
  64. autobyteus/multimedia/utils/multimedia_config.py +29 -0
  65. autobyteus/multimedia/utils/response_types.py +13 -0
  66. autobyteus/task_management/tools/publish_task_plan.py +4 -16
  67. autobyteus/task_management/tools/update_task_status.py +4 -19
  68. autobyteus/tools/__init__.py +5 -4
  69. autobyteus/tools/base_tool.py +98 -29
  70. autobyteus/tools/browser/standalone/__init__.py +0 -1
  71. autobyteus/tools/google_search.py +149 -0
  72. autobyteus/tools/mcp/schema_mapper.py +29 -71
  73. autobyteus/tools/multimedia/__init__.py +8 -0
  74. autobyteus/tools/multimedia/audio_tools.py +116 -0
  75. autobyteus/tools/multimedia/image_tools.py +186 -0
  76. autobyteus/tools/parameter_schema.py +82 -89
  77. autobyteus/tools/pydantic_schema_converter.py +81 -0
  78. autobyteus/tools/tool_category.py +1 -0
  79. autobyteus/tools/usage/formatters/default_json_example_formatter.py +89 -20
  80. autobyteus/tools/usage/formatters/default_xml_example_formatter.py +115 -41
  81. autobyteus/tools/usage/formatters/default_xml_schema_formatter.py +50 -20
  82. autobyteus/tools/usage/formatters/gemini_json_example_formatter.py +55 -22
  83. autobyteus/tools/usage/formatters/google_json_example_formatter.py +54 -21
  84. autobyteus/tools/usage/formatters/openai_json_example_formatter.py +53 -23
  85. autobyteus/tools/usage/parsers/default_xml_tool_usage_parser.py +270 -94
  86. autobyteus/tools/usage/parsers/provider_aware_tool_usage_parser.py +5 -2
  87. autobyteus/tools/usage/providers/tool_manifest_provider.py +43 -16
  88. autobyteus/tools/usage/registries/tool_formatting_registry.py +9 -2
  89. autobyteus/tools/usage/registries/tool_usage_parser_registry.py +9 -2
  90. autobyteus-1.1.7.dist-info/METADATA +204 -0
  91. {autobyteus-1.1.5.dist-info → autobyteus-1.1.7.dist-info}/RECORD +98 -71
  92. examples/run_browser_agent.py +1 -1
  93. examples/run_google_slides_agent.py +2 -2
  94. examples/run_mcp_google_slides_client.py +1 -1
  95. examples/run_sqlite_agent.py +1 -1
  96. autobyteus/llm/utils/image_payload_formatter.py +0 -89
  97. autobyteus/tools/ask_user_input.py +0 -40
  98. autobyteus/tools/browser/standalone/factory/google_search_factory.py +0 -25
  99. autobyteus/tools/browser/standalone/google_search_ui.py +0 -126
  100. autobyteus-1.1.5.dist-info/METADATA +0 -161
  101. {autobyteus-1.1.5.dist-info → autobyteus-1.1.7.dist-info}/WHEEL +0 -0
  102. {autobyteus-1.1.5.dist-info → autobyteus-1.1.7.dist-info}/licenses/LICENSE +0 -0
  103. {autobyteus-1.1.5.dist-info → autobyteus-1.1.7.dist-info}/top_level.txt +0 -0
@@ -15,15 +15,6 @@ class BaseLLM(ABC):
15
15
  DEFAULT_SYSTEM_MESSAGE = "You are a helpful assistant"
16
16
 
17
17
  def __init__(self, model: LLMModel, llm_config: LLMConfig):
18
- """
19
- Base class for all LLMs. Provides core messaging functionality
20
- and extension support.
21
-
22
- Args:
23
- model (LLMModel): An LLMModel enum value.
24
- llm_config (LLMConfig): Configuration for the LLM including system message,
25
- rate limits, token limits, etc.
26
- """
27
18
  if not isinstance(model, LLMModel):
28
19
  raise TypeError(f"Expected LLMModel, got {type(model)}")
29
20
  if not isinstance(llm_config, LLMConfig):
@@ -33,100 +24,65 @@ class BaseLLM(ABC):
33
24
  self.config = llm_config
34
25
  self._extension_registry = ExtensionRegistry()
35
26
 
36
- # Register TokenUsageTrackingExtension by default
37
27
  self._token_usage_extension: TokenUsageTrackingExtension = self.register_extension(TokenUsageTrackingExtension)
38
28
 
39
29
  self.messages: List[Message] = []
40
- # Use system_message from config, with fallback to default if not provided
41
30
  self.system_message = self.config.system_message or self.DEFAULT_SYSTEM_MESSAGE
42
31
  self.add_system_message(self.system_message)
43
32
 
44
33
  @property
45
34
  def latest_token_usage(self):
46
- """
47
- Get the token usage from the last interaction with the LLM.
48
-
49
- Returns:
50
- The token usage information from the last interaction
51
- """
52
35
  return self._token_usage_extension.latest_token_usage
53
36
 
54
37
  def register_extension(self, extension_class: Type[LLMExtension]) -> LLMExtension:
55
- """
56
- Register a new extension.
57
-
58
- Args:
59
- extension_class: The extension class to instantiate and register
60
-
61
- Returns:
62
- LLMExtension: The instantiated extension
63
- """
64
38
  extension = extension_class(self)
65
39
  self._extension_registry.register(extension)
66
40
  return extension
67
41
 
68
42
  def unregister_extension(self, extension: LLMExtension) -> None:
69
- """
70
- Unregister an existing extension.
71
-
72
- Args:
73
- extension (LLMExtension): The extension to unregister
74
- """
75
43
  self._extension_registry.unregister(extension)
76
44
 
77
45
  def get_extension(self, extension_class: Type[LLMExtension]) -> Optional[LLMExtension]:
78
- """
79
- Get a registered extension by its class.
80
-
81
- Args:
82
- extension_class: The class of the extension to retrieve
83
-
84
- Returns:
85
- Optional[LLMExtension]: The extension instance if found, None otherwise
86
- """
87
46
  return self._extension_registry.get(extension_class)
88
47
 
89
48
  def add_system_message(self, message: str):
90
- """
91
- Add a system message to the conversation history.
49
+ self.messages.append(Message(MessageRole.SYSTEM, content=message))
92
50
 
93
- Args:
94
- message (str): The system message content.
51
+ def add_user_message(self, user_message: LLMUserMessage):
95
52
  """
96
- self.messages.append(Message(MessageRole.SYSTEM, message))
97
-
98
- def add_user_message(self, user_message: Union[str, List[Dict]]):
53
+ Adds a user message to history, converting from LLMUserMessage to Message.
99
54
  """
100
- Add a user message to the conversation history.
101
-
102
- Args:
103
- user_message (Union[str, List[Dict]]): The user message content. Can be a simple string
104
- or a list of dictionaries for multimodal content.
105
- """
106
- msg = Message(MessageRole.USER, user_message)
55
+ msg = Message(
56
+ role=MessageRole.USER,
57
+ content=user_message.content,
58
+ image_urls=user_message.image_urls,
59
+ audio_urls=user_message.audio_urls,
60
+ video_urls=user_message.video_urls
61
+ )
107
62
  self.messages.append(msg)
108
63
  self._trigger_on_user_message_added(msg)
109
64
 
110
- def add_assistant_message(self, message: str, reasoning_content: Optional[str] = None):
111
- """
112
- Add an assistant message to the conversation history.
113
-
114
- Args:
115
- message (str): The assistant message content.
116
- reasoning_content (Optional[str]): Optional reasoning content to attach.
117
- """
118
- msg = Message(MessageRole.ASSISTANT, message, reasoning_content=reasoning_content)
65
+ def add_assistant_message(self,
66
+ content: Optional[str],
67
+ reasoning_content: Optional[str] = None,
68
+ image_urls: Optional[List[str]] = None,
69
+ audio_urls: Optional[List[str]] = None,
70
+ video_urls: Optional[List[str]] = None):
71
+ """
72
+ Adds a multimodal assistant message to the conversation history.
73
+ """
74
+ msg = Message(
75
+ role=MessageRole.ASSISTANT,
76
+ content=content,
77
+ reasoning_content=reasoning_content,
78
+ image_urls=image_urls,
79
+ audio_urls=audio_urls,
80
+ video_urls=video_urls
81
+ )
119
82
  self.messages.append(msg)
120
83
  self._trigger_on_assistant_message_added(msg)
121
84
 
122
85
  def configure_system_prompt(self, new_system_prompt: str):
123
- """
124
- Updates the system prompt for the LLM instance after initialization.
125
- This will replace the existing system message in the conversation history.
126
-
127
- Args:
128
- new_system_prompt (str): The new system prompt content.
129
- """
130
86
  if not new_system_prompt or not isinstance(new_system_prompt, str):
131
87
  logging.warning("Attempted to configure an empty or invalid system prompt. No changes made.")
132
88
  return
@@ -134,7 +90,6 @@ class BaseLLM(ABC):
134
90
  self.system_message = new_system_prompt
135
91
  self.config.system_message = new_system_prompt
136
92
 
137
- # Find and update the existing system message, or add a new one if not found.
138
93
  system_message_found = False
139
94
  for i, msg in enumerate(self.messages):
140
95
  if msg.role == MessageRole.SYSTEM:
@@ -144,113 +99,65 @@ class BaseLLM(ABC):
144
99
  break
145
100
 
146
101
  if not system_message_found:
147
- # If for some reason no system message was there, insert it at the beginning.
148
102
  self.messages.insert(0, Message(MessageRole.SYSTEM, new_system_prompt))
149
103
  logging.debug("No existing system message found, inserted new one at the beginning.")
150
104
 
151
105
  logging.info(f"LLM instance system prompt updated. New prompt length: {len(new_system_prompt)}")
152
106
 
153
107
  def _trigger_on_user_message_added(self, message: Message):
154
- """
155
- Internal helper to invoke the on_user_message_added hook on every extension.
156
-
157
- Args:
158
- message (Message): The user message that was added
159
- """
160
108
  for extension in self._extension_registry.get_all():
161
109
  extension.on_user_message_added(message)
162
110
 
163
111
  def _trigger_on_assistant_message_added(self, message: Message):
164
- """
165
- Internal helper to invoke the on_assistant_message_added hook on every extension.
166
-
167
- Args:
168
- message (Message): The assistant message that was added
169
- """
170
112
  for extension in self._extension_registry.get_all():
171
113
  extension.on_assistant_message_added(message)
172
114
 
173
115
  async def _execute_before_hooks(self, user_message: LLMUserMessage, **kwargs) -> None:
174
- """
175
- Execute all registered before_invoke hooks.
176
- """
177
116
  for extension in self._extension_registry.get_all():
178
- await extension.before_invoke(user_message.content, user_message.image_urls, **kwargs)
117
+ await extension.before_invoke(user_message, **kwargs)
179
118
 
180
119
  async def _execute_after_hooks(self, user_message: LLMUserMessage, response: CompleteResponse = None, **kwargs) -> None:
181
- """
182
- Execute all registered after_invoke hooks.
183
-
184
- Args:
185
- user_message (LLMUserMessage): The user message object
186
- response (CompleteResponse): The complete response from the LLM
187
- **kwargs: Additional arguments for LLM-specific usage
188
- """
189
120
  for extension in self._extension_registry.get_all():
190
- await extension.after_invoke(user_message.content, user_message.image_urls, response, **kwargs)
121
+ await extension.after_invoke(user_message, response, **kwargs)
191
122
 
192
123
  async def send_user_message(self, user_message: LLMUserMessage, **kwargs) -> CompleteResponse:
193
- """
194
- Sends a user message to the LLM and returns the complete LLM response.
195
-
196
- Args:
197
- user_message (LLMUserMessage): The user message object.
198
- **kwargs: Additional arguments for LLM-specific usage.
199
-
200
- Returns:
201
- CompleteResponse: The complete response from the LLM including content and usage.
202
- """
203
124
  await self._execute_before_hooks(user_message, **kwargs)
204
- response = await self._send_user_message_to_llm(
205
- user_message.content,
206
- user_message.image_urls if user_message.image_urls else None,
207
- **kwargs
208
- )
125
+ response = await self._send_user_message_to_llm(user_message, **kwargs)
209
126
  await self._execute_after_hooks(user_message, response, **kwargs)
210
127
  return response
211
128
 
212
129
  async def stream_user_message(self, user_message: LLMUserMessage, **kwargs) -> AsyncGenerator[ChunkResponse, None]:
213
- """
214
- Streams the LLM response as ChunkResponse objects.
215
-
216
- Args:
217
- user_message (LLMUserMessage): The user message object.
218
- **kwargs: Additional arguments for LLM-specific usage.
219
-
220
- Yields:
221
- AsyncGenerator[ChunkResponse, None]: ChunkResponse objects from the LLM.
222
- """
223
130
  await self._execute_before_hooks(user_message, **kwargs)
224
131
 
225
132
  accumulated_content = ""
133
+ accumulated_reasoning = ""
226
134
  final_chunk = None
227
135
 
228
- async for chunk in self._stream_user_message_to_llm(
229
- user_message.content,
230
- user_message.image_urls if user_message.image_urls else None,
231
- **kwargs
232
- ):
233
- accumulated_content += chunk.content
136
+ async for chunk in self._stream_user_message_to_llm(user_message, **kwargs):
137
+ if chunk.content:
138
+ accumulated_content += chunk.content
139
+ if chunk.reasoning:
140
+ accumulated_reasoning += chunk.reasoning
141
+
234
142
  if chunk.is_complete:
235
143
  final_chunk = chunk
236
144
  yield chunk
237
145
 
238
- # Create a CompleteResponse from the accumulated content and final chunk's usage
239
146
  complete_response = CompleteResponse(
240
147
  content=accumulated_content,
148
+ reasoning=accumulated_reasoning if accumulated_reasoning else None,
241
149
  usage=final_chunk.usage if final_chunk else None
242
150
  )
243
151
 
244
152
  await self._execute_after_hooks(user_message, complete_response, **kwargs)
245
153
 
246
154
  @abstractmethod
247
- async def _send_user_message_to_llm(self, user_message: str, image_urls: Optional[List[str]] = None, **kwargs) -> CompleteResponse:
155
+ async def _send_user_message_to_llm(self, user_message: LLMUserMessage, **kwargs) -> CompleteResponse:
248
156
  """
249
157
  Abstract method for sending a user message to an LLM. Must be implemented by subclasses.
250
158
 
251
159
  Args:
252
- user_message (str): The user message content.
253
- image_urls (Optional[List[str]]): Optional list of image URLs or file paths.
160
+ user_message (LLMUserMessage): The user message object.
254
161
  **kwargs: Additional arguments for LLM-specific usage.
255
162
 
256
163
  Returns:
@@ -259,13 +166,12 @@ class BaseLLM(ABC):
259
166
  pass
260
167
 
261
168
  @abstractmethod
262
- async def _stream_user_message_to_llm(self, user_message: str, image_urls: Optional[List[str]] = None, **kwargs) -> AsyncGenerator[ChunkResponse, None]:
169
+ async def _stream_user_message_to_llm(self, user_message: LLMUserMessage, **kwargs) -> AsyncGenerator[ChunkResponse, None]:
263
170
  """
264
171
  Abstract method for streaming a user message response from the LLM. Must be implemented by subclasses.
265
172
 
266
173
  Args:
267
- user_message (str): The user message content.
268
- image_urls (Optional[List[str]]): Optional list of image URLs or file paths.
174
+ user_message (LLMUserMessage): The user message object.
269
175
  **kwargs: Additional arguments for LLM-specific usage.
270
176
 
271
177
  Yields:
@@ -274,9 +180,6 @@ class BaseLLM(ABC):
274
180
  pass
275
181
 
276
182
  async def cleanup(self):
277
- """
278
- Perform cleanup operations for the LLM and all extensions.
279
- """
280
183
  for extension in self._extension_registry.get_all():
281
184
  await extension.cleanup()
282
185
  self._extension_registry.clear()
@@ -2,6 +2,7 @@ from abc import ABC, abstractmethod
2
2
  from typing import List, Optional, TYPE_CHECKING
3
3
  from autobyteus.llm.utils.messages import Message
4
4
  from autobyteus.llm.utils.response_types import CompleteResponse
5
+ from autobyteus.llm.user_message import LLMUserMessage
5
6
 
6
7
  if TYPE_CHECKING:
7
8
  from autobyteus.llm.base_llm import BaseLLM
@@ -12,7 +13,7 @@ class LLMExtension(ABC):
12
13
 
13
14
  @abstractmethod
14
15
  async def before_invoke(
15
- self, user_message: str, image_urls: Optional[List[str]] = None, **kwargs
16
+ self, user_message: LLMUserMessage, **kwargs
16
17
  ) -> None:
17
18
  """
18
19
  Called before invoking the LLM with a user message.
@@ -21,16 +22,15 @@ class LLMExtension(ABC):
21
22
 
22
23
  @abstractmethod
23
24
  async def after_invoke(
24
- self, user_message: str, image_urls: Optional[List[str]] = None, response: CompleteResponse = None, **kwargs
25
+ self, user_message: LLMUserMessage, response: CompleteResponse = None, **kwargs
25
26
  ) -> None:
26
27
  """
27
28
  Called after receiving the response from the LLM.
28
29
 
29
30
  Args:
30
- user_message: Original user message
31
- image_urls: Optional image URLs used in request
32
- response: Complete response including content and usage information
33
- kwargs: Additional arguments
31
+ user_message: The original user message object.
32
+ response: Complete response including content and usage information.
33
+ kwargs: Additional arguments.
34
34
  """
35
35
  pass
36
36
 
@@ -6,6 +6,7 @@ from autobyteus.llm.utils.token_usage import TokenUsage
6
6
  from autobyteus.llm.utils.token_usage_tracker import TokenUsageTracker
7
7
  from autobyteus.llm.utils.messages import Message, MessageRole
8
8
  from autobyteus.llm.utils.response_types import CompleteResponse
9
+ from autobyteus.llm.user_message import LLMUserMessage
9
10
 
10
11
  if TYPE_CHECKING:
11
12
  from autobyteus.llm.base_llm import BaseLLM
@@ -29,12 +30,12 @@ class TokenUsageTrackingExtension(LLMExtension):
29
30
  return self._latest_usage
30
31
 
31
32
  async def before_invoke(
32
- self, user_message: str, image_urls: Optional[List[str]] = None, **kwargs
33
+ self, user_message: LLMUserMessage, **kwargs
33
34
  ) -> None:
34
35
  pass
35
36
 
36
37
  async def after_invoke(
37
- self, user_message: str, image_urls: Optional[List[str]] = None, response: CompleteResponse = None, **kwargs
38
+ self, user_message: LLMUserMessage, response: CompleteResponse = None, **kwargs
38
39
  ) -> None:
39
40
  """
40
41
  Get the latest usage from tracker and optionally override token counts with provider's usage if available
@@ -10,9 +10,11 @@ from autobyteus.llm.utils.llm_config import LLMConfig, TokenPricingConfig
10
10
  from autobyteus.llm.base_llm import BaseLLM
11
11
 
12
12
  from autobyteus.llm.api.claude_llm import ClaudeLLM
13
+ from autobyteus.llm.api.bedrock_llm import BedrockLLM
13
14
  from autobyteus.llm.api.mistral_llm import MistralLLM
14
15
  from autobyteus.llm.api.openai_llm import OpenAILLM
15
16
  from autobyteus.llm.api.deepseek_llm import DeepSeekLLM
17
+ from autobyteus.llm.api.gemini_llm import GeminiLLM
16
18
  from autobyteus.llm.api.grok_llm import GrokLLM
17
19
  from autobyteus.llm.api.kimi_llm import KimiLLM
18
20
  from autobyteus.llm.ollama_provider import OllamaModelProvider
@@ -61,6 +63,83 @@ class LLMFactory(metaclass=SingletonMeta):
61
63
  pricing_config=TokenPricingConfig(2.50, 10.00)
62
64
  )
63
65
  ),
66
+ LLMModel(
67
+ name="gpt-5",
68
+ value="gpt-5",
69
+ provider=LLMProvider.OPENAI,
70
+ llm_class=OpenAILLM,
71
+ canonical_name="gpt-5",
72
+ default_config=LLMConfig(
73
+ uses_max_completion_tokens=True,
74
+ pricing_config=TokenPricingConfig(1.25, 10.00)
75
+ )
76
+ ),
77
+ LLMModel(
78
+ name="gpt-5-mini",
79
+ value="gpt-5-mini",
80
+ provider=LLMProvider.OPENAI,
81
+ llm_class=OpenAILLM,
82
+ canonical_name="gpt-5-mini",
83
+ default_config=LLMConfig(
84
+ uses_max_completion_tokens=True,
85
+ pricing_config=TokenPricingConfig(0.25, 2.00)
86
+ )
87
+ ),
88
+ LLMModel(
89
+ name="gpt-5-nano",
90
+ value="gpt-5-nano",
91
+ provider=LLMProvider.OPENAI,
92
+ llm_class=OpenAILLM,
93
+ canonical_name="gpt-5-nano",
94
+ default_config=LLMConfig(
95
+ uses_max_completion_tokens=True,
96
+ pricing_config=TokenPricingConfig(0.05, 0.40)
97
+ )
98
+ ),
99
+ LLMModel(
100
+ name="gpt-5-chat-latest",
101
+ value="gpt-5-chat-latest",
102
+ provider=LLMProvider.OPENAI,
103
+ llm_class=OpenAILLM,
104
+ canonical_name="gpt-5-chat-latest",
105
+ default_config=LLMConfig(
106
+ uses_max_completion_tokens=True,
107
+ pricing_config=TokenPricingConfig(1.25, 10.00)
108
+ )
109
+ ),
110
+ LLMModel(
111
+ name="gpt-4.1",
112
+ value="gpt-4.1",
113
+ provider=LLMProvider.OPENAI,
114
+ llm_class=OpenAILLM,
115
+ canonical_name="gpt-4.1",
116
+ default_config=LLMConfig(
117
+ uses_max_completion_tokens=True,
118
+ pricing_config=TokenPricingConfig(2.00, 8.00)
119
+ )
120
+ ),
121
+ LLMModel(
122
+ name="gpt-4.1-mini",
123
+ value="gpt-4.1-mini",
124
+ provider=LLMProvider.OPENAI,
125
+ llm_class=OpenAILLM,
126
+ canonical_name="gpt-4.1-mini",
127
+ default_config=LLMConfig(
128
+ uses_max_completion_tokens=True,
129
+ pricing_config=TokenPricingConfig(0.40, 1.60)
130
+ )
131
+ ),
132
+ LLMModel(
133
+ name="gpt-4.1-nano",
134
+ value="gpt-4.1-nano",
135
+ provider=LLMProvider.OPENAI,
136
+ llm_class=OpenAILLM,
137
+ canonical_name="gpt-4.1-nano",
138
+ default_config=LLMConfig(
139
+ uses_max_completion_tokens=True,
140
+ pricing_config=TokenPricingConfig(0.10, 0.40)
141
+ )
142
+ ),
64
143
  LLMModel(
65
144
  name="o3",
66
145
  value="o3",
@@ -68,6 +147,7 @@ class LLMFactory(metaclass=SingletonMeta):
68
147
  llm_class=OpenAILLM,
69
148
  canonical_name="o3",
70
149
  default_config=LLMConfig(
150
+ uses_max_completion_tokens=True,
71
151
  pricing_config=TokenPricingConfig(15.00, 60.00)
72
152
  )
73
153
  ),
@@ -78,6 +158,7 @@ class LLMFactory(metaclass=SingletonMeta):
78
158
  llm_class=OpenAILLM,
79
159
  canonical_name="o4-mini",
80
160
  default_config=LLMConfig(
161
+ uses_max_completion_tokens=True,
81
162
  pricing_config=TokenPricingConfig(1.0, 4.00)
82
163
  )
83
164
  ),
@@ -104,12 +185,13 @@ class LLMFactory(metaclass=SingletonMeta):
104
185
  )
105
186
  ),
106
187
  LLMModel(
107
- name="bedrock-claude-4-opus",
108
- value="anthropic.claude-opus-4-20250514-v1:0",
188
+ name="claude-4.1-opus",
189
+ value="claude-opus-4-1-20250805",
109
190
  provider=LLMProvider.ANTHROPIC,
110
191
  llm_class=ClaudeLLM,
111
- canonical_name="claude-4-opus",
192
+ canonical_name="claude-4.1-opus",
112
193
  default_config=LLMConfig(
194
+ # NOTE: Pricing is assumed to be the same as claude-4-opus
113
195
  pricing_config=TokenPricingConfig(15.00, 75.00)
114
196
  )
115
197
  ),
@@ -123,11 +205,32 @@ class LLMFactory(metaclass=SingletonMeta):
123
205
  pricing_config=TokenPricingConfig(3.00, 15.00)
124
206
  )
125
207
  ),
208
+ LLMModel(
209
+ name="bedrock-claude-4-opus",
210
+ value="anthropic.claude-opus-4-20250514-v1:0",
211
+ provider=LLMProvider.ANTHROPIC,
212
+ llm_class=BedrockLLM,
213
+ canonical_name="claude-4-opus",
214
+ default_config=LLMConfig(
215
+ pricing_config=TokenPricingConfig(15.00, 75.00)
216
+ )
217
+ ),
218
+ LLMModel(
219
+ name="bedrock-claude-4.1-opus",
220
+ value="anthropic.claude-opus-4-1-20250805-v1:0",
221
+ provider=LLMProvider.ANTHROPIC,
222
+ llm_class=BedrockLLM,
223
+ canonical_name="claude-4.1-opus",
224
+ default_config=LLMConfig(
225
+ # NOTE: Pricing is assumed to be the same as claude-4-opus
226
+ pricing_config=TokenPricingConfig(15.00, 75.00)
227
+ )
228
+ ),
126
229
  LLMModel(
127
230
  name="bedrock-claude-4-sonnet",
128
231
  value="anthropic.claude-sonnet-4-20250514-v1:0",
129
232
  provider=LLMProvider.ANTHROPIC,
130
- llm_class=ClaudeLLM,
233
+ llm_class=BedrockLLM,
131
234
  canonical_name="claude-4-sonnet",
132
235
  default_config=LLMConfig(
133
236
  pricing_config=TokenPricingConfig(3.00, 15.00)
@@ -164,106 +267,73 @@ class LLMFactory(metaclass=SingletonMeta):
164
267
  name="gemini-2.5-pro",
165
268
  value="gemini-2.5-pro",
166
269
  provider=LLMProvider.GEMINI,
167
- llm_class=OpenAILLM,
270
+ llm_class=GeminiLLM,
168
271
  canonical_name="gemini-2.5-pro",
169
272
  default_config=LLMConfig(
170
- pricing_config=TokenPricingConfig(2.50, 10.00)
273
+ pricing_config=TokenPricingConfig(2.50, 15.00)
171
274
  )
172
275
  ),
173
276
  LLMModel(
174
277
  name="gemini-2.5-flash",
175
278
  value="gemini-2.5-flash",
176
279
  provider=LLMProvider.GEMINI,
177
- llm_class=OpenAILLM,
280
+ llm_class=GeminiLLM,
178
281
  canonical_name="gemini-2.5-flash",
179
282
  default_config=LLMConfig(
180
- pricing_config=TokenPricingConfig(0.15, 0.60)
181
- )
182
- ),
183
- LLMModel(
184
- name="gemini-2.0-flash",
185
- value="gemini-2.0-flash",
186
- provider=LLMProvider.GEMINI,
187
- llm_class=OpenAILLM,
188
- canonical_name="gemini-2.0-flash",
189
- default_config=LLMConfig(
190
- pricing_config=TokenPricingConfig(0.1, 0.40)
283
+ pricing_config=TokenPricingConfig(0.30, 2.50)
191
284
  )
192
285
  ),
193
286
  LLMModel(
194
- name="gemini-2.0-flash-lite",
195
- value="gemini-2.0-flash-lite",
287
+ name="gemini-2.5-flash-lite",
288
+ value="gemini-2.5-flash-lite",
196
289
  provider=LLMProvider.GEMINI,
197
- llm_class=OpenAILLM,
198
- canonical_name="gemini-2.0-flash-lite",
290
+ llm_class=GeminiLLM,
291
+ canonical_name="gemini-2.5-flash-lite",
199
292
  default_config=LLMConfig(
200
- pricing_config=TokenPricingConfig(0.075, 0.30)
201
- )
202
- ),
203
- # GROK Provider Models
204
- LLMModel(
205
- name="grok-2-1212",
206
- value="grok-2-1212",
207
- provider=LLMProvider.GROK,
208
- llm_class=GrokLLM,
209
- canonical_name="grok-2",
210
- default_config=LLMConfig(
211
- rate_limit=60,
212
- token_limit=8000,
213
- pricing_config=TokenPricingConfig(2.0, 6.0)
293
+ pricing_config=TokenPricingConfig(0.10, 0.40)
214
294
  )
215
295
  ),
216
296
  # KIMI Provider Models
217
297
  LLMModel(
218
- name="kimi-latest",
219
- value="kimi-latest",
298
+ name="kimi-k2-0711-preview",
299
+ value="kimi-k2-0711-preview",
220
300
  provider=LLMProvider.KIMI,
221
301
  llm_class=KimiLLM,
222
- canonical_name="kimi-latest",
302
+ canonical_name="kimi-k2-0711-preview",
223
303
  default_config=LLMConfig(
224
- pricing_config=TokenPricingConfig(1.38, 4.14)
304
+ pricing_config=TokenPricingConfig(0.55, 2.21)
225
305
  )
226
306
  ),
227
307
  LLMModel(
228
- name="moonshot-v1-8k",
229
- value="moonshot-v1-8k",
308
+ name="kimi-k2-0905-preview",
309
+ value="kimi-k2-0905-preview",
230
310
  provider=LLMProvider.KIMI,
231
311
  llm_class=KimiLLM,
232
- canonical_name="moonshot-v1-8k",
312
+ canonical_name="kimi-k2-0905-preview",
233
313
  default_config=LLMConfig(
234
- pricing_config=TokenPricingConfig(0.28, 1.38)
314
+ pricing_config=TokenPricingConfig(0.55, 2.21)
235
315
  )
236
316
  ),
237
317
  LLMModel(
238
- name="moonshot-v1-32k",
239
- value="moonshot-v1-32k",
318
+ name="kimi-k2-turbo-preview",
319
+ value="kimi-k2-turbo-preview",
240
320
  provider=LLMProvider.KIMI,
241
321
  llm_class=KimiLLM,
242
- canonical_name="moonshot-v1-32k",
322
+ canonical_name="kimi-k2-turbo-preview",
243
323
  default_config=LLMConfig(
244
- pricing_config=TokenPricingConfig(0.69, 2.76)
324
+ pricing_config=TokenPricingConfig(2.76, 2.76)
245
325
  )
246
326
  ),
247
327
  LLMModel(
248
- name="moonshot-v1-128k",
249
- value="moonshot-v1-128k",
328
+ name="kimi-latest",
329
+ value="kimi-latest",
250
330
  provider=LLMProvider.KIMI,
251
331
  llm_class=KimiLLM,
252
- canonical_name="moonshot-v1-128k",
332
+ canonical_name="kimi-latest",
253
333
  default_config=LLMConfig(
254
334
  pricing_config=TokenPricingConfig(1.38, 4.14)
255
335
  )
256
336
  ),
257
- LLMModel(
258
- name="kimi-k2-0711-preview",
259
- value="kimi-k2-0711-preview",
260
- provider=LLMProvider.KIMI,
261
- llm_class=KimiLLM,
262
- canonical_name="kimi-k2-0711-preview",
263
- default_config=LLMConfig(
264
- pricing_config=TokenPricingConfig(0.55, 2.21)
265
- )
266
- ),
267
337
  LLMModel(
268
338
  name="kimi-thinking-preview",
269
339
  value="kimi-thinking-preview",
@@ -18,6 +18,7 @@ class OllamaProviderResolver:
18
18
  (['llama'], LLMProvider.GROQ),
19
19
  (['mistral'], LLMProvider.MISTRAL),
20
20
  (['deepseek'], LLMProvider.DEEPSEEK),
21
+ (['qwen'], LLMProvider.QWEN),
21
22
  ]
22
23
 
23
24
  @staticmethod
@@ -13,4 +13,5 @@ class LLMProvider(Enum):
13
13
  GROK = "GROK"
14
14
  AUTOBYTEUS = "AUTOBYTEUS"
15
15
  KIMI = "KIMI"
16
+ QWEN = "QWEN"
16
17
  LMSTUDIO = "LMSTUDIO"