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.
- autobyteus/agent/context/agent_config.py +6 -1
- autobyteus/agent/context/agent_runtime_state.py +7 -1
- autobyteus/agent/handlers/llm_user_message_ready_event_handler.py +30 -7
- autobyteus/agent/handlers/tool_result_event_handler.py +100 -88
- autobyteus/agent/handlers/user_input_message_event_handler.py +22 -25
- autobyteus/agent/llm_response_processor/provider_aware_tool_usage_processor.py +7 -1
- autobyteus/agent/message/__init__.py +7 -5
- autobyteus/agent/message/agent_input_user_message.py +6 -16
- autobyteus/agent/message/context_file.py +24 -24
- autobyteus/agent/message/context_file_type.py +29 -8
- autobyteus/agent/message/multimodal_message_builder.py +47 -0
- autobyteus/agent/streaming/stream_event_payloads.py +23 -4
- autobyteus/agent/system_prompt_processor/tool_manifest_injector_processor.py +6 -2
- autobyteus/agent/tool_invocation.py +27 -2
- autobyteus/agent_team/agent_team_builder.py +22 -1
- autobyteus/agent_team/bootstrap_steps/agent_configuration_preparation_step.py +9 -2
- autobyteus/agent_team/context/agent_team_config.py +1 -0
- autobyteus/agent_team/context/agent_team_runtime_state.py +0 -2
- autobyteus/llm/api/autobyteus_llm.py +33 -33
- autobyteus/llm/api/bedrock_llm.py +13 -5
- autobyteus/llm/api/claude_llm.py +13 -27
- autobyteus/llm/api/gemini_llm.py +108 -42
- autobyteus/llm/api/groq_llm.py +4 -3
- autobyteus/llm/api/mistral_llm.py +97 -51
- autobyteus/llm/api/nvidia_llm.py +6 -5
- autobyteus/llm/api/ollama_llm.py +37 -12
- autobyteus/llm/api/openai_compatible_llm.py +91 -91
- autobyteus/llm/autobyteus_provider.py +1 -1
- autobyteus/llm/base_llm.py +42 -139
- autobyteus/llm/extensions/base_extension.py +6 -6
- autobyteus/llm/extensions/token_usage_tracking_extension.py +3 -2
- autobyteus/llm/llm_factory.py +131 -61
- autobyteus/llm/ollama_provider_resolver.py +1 -0
- autobyteus/llm/providers.py +1 -0
- autobyteus/llm/token_counter/token_counter_factory.py +3 -1
- autobyteus/llm/user_message.py +43 -35
- autobyteus/llm/utils/llm_config.py +34 -18
- autobyteus/llm/utils/media_payload_formatter.py +99 -0
- autobyteus/llm/utils/messages.py +32 -25
- autobyteus/llm/utils/response_types.py +9 -3
- autobyteus/llm/utils/token_usage.py +6 -5
- autobyteus/multimedia/__init__.py +31 -0
- autobyteus/multimedia/audio/__init__.py +11 -0
- autobyteus/multimedia/audio/api/__init__.py +4 -0
- autobyteus/multimedia/audio/api/autobyteus_audio_client.py +59 -0
- autobyteus/multimedia/audio/api/gemini_audio_client.py +219 -0
- autobyteus/multimedia/audio/audio_client_factory.py +120 -0
- autobyteus/multimedia/audio/audio_model.py +97 -0
- autobyteus/multimedia/audio/autobyteus_audio_provider.py +108 -0
- autobyteus/multimedia/audio/base_audio_client.py +40 -0
- autobyteus/multimedia/image/__init__.py +11 -0
- autobyteus/multimedia/image/api/__init__.py +9 -0
- autobyteus/multimedia/image/api/autobyteus_image_client.py +97 -0
- autobyteus/multimedia/image/api/gemini_image_client.py +188 -0
- autobyteus/multimedia/image/api/openai_image_client.py +142 -0
- autobyteus/multimedia/image/autobyteus_image_provider.py +109 -0
- autobyteus/multimedia/image/base_image_client.py +67 -0
- autobyteus/multimedia/image/image_client_factory.py +118 -0
- autobyteus/multimedia/image/image_model.py +97 -0
- autobyteus/multimedia/providers.py +5 -0
- autobyteus/multimedia/runtimes.py +8 -0
- autobyteus/multimedia/utils/__init__.py +10 -0
- autobyteus/multimedia/utils/api_utils.py +19 -0
- autobyteus/multimedia/utils/multimedia_config.py +29 -0
- autobyteus/multimedia/utils/response_types.py +13 -0
- autobyteus/task_management/tools/publish_task_plan.py +4 -16
- autobyteus/task_management/tools/update_task_status.py +4 -19
- autobyteus/tools/__init__.py +5 -4
- autobyteus/tools/base_tool.py +98 -29
- autobyteus/tools/browser/standalone/__init__.py +0 -1
- autobyteus/tools/google_search.py +149 -0
- autobyteus/tools/mcp/schema_mapper.py +29 -71
- autobyteus/tools/multimedia/__init__.py +8 -0
- autobyteus/tools/multimedia/audio_tools.py +116 -0
- autobyteus/tools/multimedia/image_tools.py +186 -0
- autobyteus/tools/parameter_schema.py +82 -89
- autobyteus/tools/pydantic_schema_converter.py +81 -0
- autobyteus/tools/tool_category.py +1 -0
- autobyteus/tools/usage/formatters/default_json_example_formatter.py +89 -20
- autobyteus/tools/usage/formatters/default_xml_example_formatter.py +115 -41
- autobyteus/tools/usage/formatters/default_xml_schema_formatter.py +50 -20
- autobyteus/tools/usage/formatters/gemini_json_example_formatter.py +55 -22
- autobyteus/tools/usage/formatters/google_json_example_formatter.py +54 -21
- autobyteus/tools/usage/formatters/openai_json_example_formatter.py +53 -23
- autobyteus/tools/usage/parsers/default_xml_tool_usage_parser.py +270 -94
- autobyteus/tools/usage/parsers/provider_aware_tool_usage_parser.py +5 -2
- autobyteus/tools/usage/providers/tool_manifest_provider.py +43 -16
- autobyteus/tools/usage/registries/tool_formatting_registry.py +9 -2
- autobyteus/tools/usage/registries/tool_usage_parser_registry.py +9 -2
- autobyteus-1.1.7.dist-info/METADATA +204 -0
- {autobyteus-1.1.5.dist-info → autobyteus-1.1.7.dist-info}/RECORD +98 -71
- examples/run_browser_agent.py +1 -1
- examples/run_google_slides_agent.py +2 -2
- examples/run_mcp_google_slides_client.py +1 -1
- examples/run_sqlite_agent.py +1 -1
- autobyteus/llm/utils/image_payload_formatter.py +0 -89
- autobyteus/tools/ask_user_input.py +0 -40
- autobyteus/tools/browser/standalone/factory/google_search_factory.py +0 -25
- autobyteus/tools/browser/standalone/google_search_ui.py +0 -126
- autobyteus-1.1.5.dist-info/METADATA +0 -161
- {autobyteus-1.1.5.dist-info → autobyteus-1.1.7.dist-info}/WHEEL +0 -0
- {autobyteus-1.1.5.dist-info → autobyteus-1.1.7.dist-info}/licenses/LICENSE +0 -0
- {autobyteus-1.1.5.dist-info → autobyteus-1.1.7.dist-info}/top_level.txt +0 -0
autobyteus/llm/base_llm.py
CHANGED
|
@@ -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
|
-
|
|
94
|
-
message (str): The system message content.
|
|
51
|
+
def add_user_message(self, user_message: LLMUserMessage):
|
|
95
52
|
"""
|
|
96
|
-
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
user_message
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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,
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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:
|
|
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 (
|
|
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:
|
|
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 (
|
|
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:
|
|
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:
|
|
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:
|
|
31
|
-
|
|
32
|
-
|
|
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:
|
|
33
|
+
self, user_message: LLMUserMessage, **kwargs
|
|
33
34
|
) -> None:
|
|
34
35
|
pass
|
|
35
36
|
|
|
36
37
|
async def after_invoke(
|
|
37
|
-
self, user_message:
|
|
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
|
autobyteus/llm/llm_factory.py
CHANGED
|
@@ -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="
|
|
108
|
-
value="
|
|
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=
|
|
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=
|
|
270
|
+
llm_class=GeminiLLM,
|
|
168
271
|
canonical_name="gemini-2.5-pro",
|
|
169
272
|
default_config=LLMConfig(
|
|
170
|
-
pricing_config=TokenPricingConfig(2.50,
|
|
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=
|
|
280
|
+
llm_class=GeminiLLM,
|
|
178
281
|
canonical_name="gemini-2.5-flash",
|
|
179
282
|
default_config=LLMConfig(
|
|
180
|
-
pricing_config=TokenPricingConfig(0.
|
|
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.
|
|
195
|
-
value="gemini-2.
|
|
287
|
+
name="gemini-2.5-flash-lite",
|
|
288
|
+
value="gemini-2.5-flash-lite",
|
|
196
289
|
provider=LLMProvider.GEMINI,
|
|
197
|
-
llm_class=
|
|
198
|
-
canonical_name="gemini-2.
|
|
290
|
+
llm_class=GeminiLLM,
|
|
291
|
+
canonical_name="gemini-2.5-flash-lite",
|
|
199
292
|
default_config=LLMConfig(
|
|
200
|
-
pricing_config=TokenPricingConfig(0.
|
|
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-
|
|
219
|
-
value="kimi-
|
|
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-
|
|
302
|
+
canonical_name="kimi-k2-0711-preview",
|
|
223
303
|
default_config=LLMConfig(
|
|
224
|
-
pricing_config=TokenPricingConfig(
|
|
304
|
+
pricing_config=TokenPricingConfig(0.55, 2.21)
|
|
225
305
|
)
|
|
226
306
|
),
|
|
227
307
|
LLMModel(
|
|
228
|
-
name="
|
|
229
|
-
value="
|
|
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="
|
|
312
|
+
canonical_name="kimi-k2-0905-preview",
|
|
233
313
|
default_config=LLMConfig(
|
|
234
|
-
pricing_config=TokenPricingConfig(0.
|
|
314
|
+
pricing_config=TokenPricingConfig(0.55, 2.21)
|
|
235
315
|
)
|
|
236
316
|
),
|
|
237
317
|
LLMModel(
|
|
238
|
-
name="
|
|
239
|
-
value="
|
|
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="
|
|
322
|
+
canonical_name="kimi-k2-turbo-preview",
|
|
243
323
|
default_config=LLMConfig(
|
|
244
|
-
pricing_config=TokenPricingConfig(
|
|
324
|
+
pricing_config=TokenPricingConfig(2.76, 2.76)
|
|
245
325
|
)
|
|
246
326
|
),
|
|
247
327
|
LLMModel(
|
|
248
|
-
name="
|
|
249
|
-
value="
|
|
328
|
+
name="kimi-latest",
|
|
329
|
+
value="kimi-latest",
|
|
250
330
|
provider=LLMProvider.KIMI,
|
|
251
331
|
llm_class=KimiLLM,
|
|
252
|
-
canonical_name="
|
|
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",
|