autobyteus 1.0.4__tar.gz → 1.0.5__tar.gz
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-1.0.4 → autobyteus-1.0.5}/PKG-INFO +1 -1
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/agent.py +1 -1
- autobyteus-1.0.5/autobyteus/agent/factory/agent_factory.py +94 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/message/send_message_to.py +0 -3
- autobyteus-1.0.5/autobyteus/agent/registry/__init__.py +11 -0
- autobyteus-1.0.5/autobyteus/agent/registry/agent_definition.py +94 -0
- autobyteus-1.0.5/autobyteus/agent/registry/agent_registry.py +114 -0
- autobyteus-1.0.5/autobyteus/agent/remote_agent.py +9 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/autobyteus_provider.py +2 -1
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/llm_factory.py +33 -13
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/models.py +12 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/ollama_provider.py +1 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/ask_user_input.py +8 -19
- autobyteus-1.0.5/autobyteus/tools/base_tool.py +77 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/bash/bash_executor.py +3 -15
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/session_aware/browser_session_aware_navigate_to.py +8 -4
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/session_aware/browser_session_aware_web_element_trigger.py +12 -55
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/session_aware/browser_session_aware_webpage_reader.py +9 -5
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/session_aware/browser_session_aware_webpage_screenshot_taker.py +8 -4
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/standalone/google_search_ui.py +6 -32
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/standalone/navigate_to.py +8 -16
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/standalone/webpage_image_downloader.py +9 -60
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/standalone/webpage_reader.py +8 -6
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/standalone/webpage_screenshot_taker.py +9 -6
- autobyteus-1.0.5/autobyteus/tools/factory/tool_factory.py +10 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/file/file_reader.py +6 -8
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/file/file_writer.py +6 -9
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/image_downloader.py +18 -41
- autobyteus-1.0.5/autobyteus/tools/mcp_remote_tool.py +82 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/pdf_downloader.py +8 -13
- autobyteus-1.0.5/autobyteus/tools/registry/__init__.py +11 -0
- autobyteus-1.0.5/autobyteus/tools/registry/tool_definition.py +60 -0
- autobyteus-1.0.5/autobyteus/tools/registry/tool_registry.py +106 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/timer.py +16 -18
- autobyteus-1.0.5/autobyteus/tools/tool_meta.py +52 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/utils.py +1 -1
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/web_page_pdf_generator.py +8 -4
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus.egg-info/PKG-INFO +1 -1
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus.egg-info/SOURCES.txt +10 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/setup.py +1 -1
- autobyteus-1.0.4/autobyteus/tools/base_tool.py +0 -49
- autobyteus-1.0.4/autobyteus/tools/factory/tool_factory.py +0 -8
- {autobyteus-1.0.4 → autobyteus-1.0.5}/LICENSE +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/README.md +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/async_agent.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/async_group_aware_agent.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/exceptions.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/factory/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/group/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/group/async_group_aware_agent.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/group/coordinator_agent.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/group/group_aware_agent.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/message/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/message/message.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/message/message_types.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/orchestrator/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/orchestrator/base_agent_orchestrator.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/orchestrator/multi_replica_agent_orchestrator.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/orchestrator/single_replica_agent_orchestrator.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/response_parser/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/response_parser/tool_usage_command_parser.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/status.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/agent/tool_invocation.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/check_requirements.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/conversation/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/conversation/conversation.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/conversation/user_message.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/events/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/events/decorators.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/events/event_emitter.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/events/event_manager.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/events/event_types.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/api/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/api/autobyteus_llm.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/api/bedrock_llm.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/api/claude_llm.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/api/deepseek_llm.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/api/gemini_llm.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/api/grok_llm.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/api/groq_llm.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/api/mistral_llm.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/api/nvidia_llm.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/api/ollama_llm.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/api/openai_llm.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/base_llm.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/extensions/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/extensions/base_extension.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/extensions/extension_registry.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/extensions/token_usage_tracking_extension.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/providers.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/token_counter/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/token_counter/base_token_counter.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/token_counter/claude_token_counter.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/token_counter/deepseek_token_counter.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/token_counter/mistral_token_counter.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/token_counter/openai_token_counter.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/token_counter/token_counter_factory.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/utils/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/utils/image_payload_formatter.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/utils/llm_config.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/utils/messages.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/utils/rate_limiter.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/utils/response_types.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/utils/token_pricing_config.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/utils/token_usage.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/llm/utils/token_usage_tracker.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/person/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/person/examples/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/person/examples/sample_persons.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/person/examples/sample_roles.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/person/person.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/person/role.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/prompt/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/prompt/prompt_builder.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/prompt/prompt_template.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/prompt/prompt_version_manager.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/prompt/storage/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/prompt/storage/prompt_version_model.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/prompt/storage/prompt_version_repository.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/bash/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/bash/factory/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/bash/factory/bash_executor_factory.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/session_aware/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/session_aware/browser_session_aware_tool.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/session_aware/factory/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/session_aware/factory/browser_session_aware_web_element_trigger_factory.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/session_aware/factory/browser_session_aware_webpage_reader_factory.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/session_aware/factory/browser_session_aware_webpage_screenshot_taker_factory.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/session_aware/shared_browser_session.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/session_aware/shared_browser_session_manager.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/session_aware/web_element_action.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/standalone/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/standalone/factory/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/standalone/factory/google_search_factory.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/standalone/factory/webpage_reader_factory.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/browser/standalone/factory/webpage_screenshot_taker_factory.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/factory/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/factory/ask_user_input_factory.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/factory/image_downloader_factory.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/factory/pdf_downloader_factory.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/factory/webpage_image_downloader_factory.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/file/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/file/factory/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/file/factory/file_reader_factory.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/file/factory/file_writer_factory.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/handlers/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/handlers/shell_handler.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/operation/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/operation/file_operation.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/operation/file_rename_operation.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/operation/operation.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/tools/operation/shell_operation.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/utils/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/utils/dynamic_enum.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/utils/file_utils.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/utils/html_cleaner.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/utils/singleton.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/workflow/__init__.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/workflow/simple_task.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/workflow/task.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus/workflow/workflow.py +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus.egg-info/dependency_links.txt +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus.egg-info/requires.txt +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/autobyteus.egg-info/top_level.txt +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/pyproject.toml +0 -0
- {autobyteus-1.0.4 → autobyteus-1.0.5}/setup.cfg +0 -0
|
@@ -223,7 +223,7 @@ class Agent(EventEmitter):
|
|
|
223
223
|
|
|
224
224
|
external_tools_section = ""
|
|
225
225
|
for i, tool in enumerate(self.tools):
|
|
226
|
-
external_tools_section += f" {i + 1} {tool.
|
|
226
|
+
external_tools_section += f" {i + 1} {tool.tool_usage()}\n\n"
|
|
227
227
|
return external_tools_section.strip()
|
|
228
228
|
|
|
229
229
|
def on_task_completed(self, *args, **kwargs):
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# file: autobyteus/agent/factory/agent_factory.py
|
|
2
|
+
import logging
|
|
3
|
+
from autobyteus.agent.agent import Agent
|
|
4
|
+
from autobyteus.agent.group.group_aware_agent import GroupAwareAgent
|
|
5
|
+
from autobyteus.llm.llm_factory import LLMFactory
|
|
6
|
+
from autobyteus.tools.factory.tool_factory import ToolFactory
|
|
7
|
+
from autobyteus.prompt.prompt_builder import PromptBuilder
|
|
8
|
+
from autobyteus.llm.models import LLMModel
|
|
9
|
+
from typing import List, Union
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
class AgentFactory:
|
|
14
|
+
"""
|
|
15
|
+
Factory class for creating different types of agents.
|
|
16
|
+
|
|
17
|
+
This factory simplifies the creation of Agent instances by encapsulating
|
|
18
|
+
the necessary dependencies and configurations.
|
|
19
|
+
"""
|
|
20
|
+
def __init__(self,
|
|
21
|
+
role: str,
|
|
22
|
+
agent_type: str,
|
|
23
|
+
tool_factory: ToolFactory,
|
|
24
|
+
llm_factory: LLMFactory,
|
|
25
|
+
prompt_builder: PromptBuilder, # Agent requires prompt_builder or initial_user_message
|
|
26
|
+
llm_model: LLMModel,
|
|
27
|
+
tool_names: List[str]):
|
|
28
|
+
"""
|
|
29
|
+
Initializes the AgentFactory.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
role: The role the created agents will fulfill.
|
|
33
|
+
agent_type: The type of agent to create ("standalone" or "group_aware").
|
|
34
|
+
tool_factory: A factory to create tool instances.
|
|
35
|
+
llm_factory: A factory to create LLM instances.
|
|
36
|
+
prompt_builder: The PromptBuilder instance to configure the agent's system prompt.
|
|
37
|
+
llm_model: The specific LLM model configuration to use.
|
|
38
|
+
tool_names: A list of tool names the agent should be equipped with.
|
|
39
|
+
"""
|
|
40
|
+
self.role = role
|
|
41
|
+
self.agent_type = agent_type
|
|
42
|
+
self.tool_factory = tool_factory
|
|
43
|
+
self.llm_factory = llm_factory
|
|
44
|
+
self.prompt_builder = prompt_builder
|
|
45
|
+
self.llm_model = llm_model
|
|
46
|
+
self.tool_names = tool_names
|
|
47
|
+
logger.info(f"AgentFactory initialized for role '{role}' and type '{agent_type}'")
|
|
48
|
+
|
|
49
|
+
def create_agent(self, agent_id: str) -> Union[Agent, GroupAwareAgent]:
|
|
50
|
+
"""
|
|
51
|
+
Creates an agent instance based on the factory's configuration.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
agent_id: The unique identifier for the agent being created.
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
An instance of Agent or GroupAwareAgent.
|
|
58
|
+
|
|
59
|
+
Raises:
|
|
60
|
+
ValueError: If the configured agent_type is unsupported.
|
|
61
|
+
"""
|
|
62
|
+
logger.info(f"Creating agent with id '{agent_id}' for role '{self.role}' and type '{self.agent_type}'")
|
|
63
|
+
try:
|
|
64
|
+
tools = [self.tool_factory.create_tool(name) for name in self.tool_names]
|
|
65
|
+
logger.debug(f"Tools created for agent '{agent_id}': {[tool.get_name() for tool in tools]}")
|
|
66
|
+
except Exception as e:
|
|
67
|
+
logger.error(f"Error creating tools for agent '{agent_id}': {e}")
|
|
68
|
+
raise ValueError(f"Failed to create tools for agent {agent_id}: {e}") from e
|
|
69
|
+
|
|
70
|
+
try:
|
|
71
|
+
llm = self.llm_factory.create_llm(self.llm_model)
|
|
72
|
+
logger.debug(f"LLM instance created for agent '{agent_id}' using model '{self.llm_model.model_name}'")
|
|
73
|
+
except Exception as e:
|
|
74
|
+
logger.error(f"Error creating LLM for agent '{agent_id}': {e}")
|
|
75
|
+
raise ValueError(f"Failed to create LLM for agent {agent_id}: {e}") from e
|
|
76
|
+
|
|
77
|
+
agent_args = {
|
|
78
|
+
"agent_id": agent_id,
|
|
79
|
+
"role": self.role,
|
|
80
|
+
"prompt_builder": self.prompt_builder,
|
|
81
|
+
"llm": llm,
|
|
82
|
+
"tools": tools
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if self.agent_type == "standalone":
|
|
86
|
+
logger.debug(f"Instantiating Agent with args: {agent_args}")
|
|
87
|
+
return Agent(**agent_args)
|
|
88
|
+
elif self.agent_type == "group_aware":
|
|
89
|
+
logger.debug(f"Instantiating GroupAwareAgent with args: {agent_args}")
|
|
90
|
+
return GroupAwareAgent(**agent_args)
|
|
91
|
+
else:
|
|
92
|
+
logger.error(f"Unsupported agent type specified in factory: {self.agent_type}")
|
|
93
|
+
raise ValueError(f"Unsupported agent type: {self.agent_type}")
|
|
94
|
+
|
|
@@ -18,9 +18,6 @@ class SendMessageTo(BaseTool):
|
|
|
18
18
|
except ValueError as e:
|
|
19
19
|
return f"Error: {str(e)}"
|
|
20
20
|
|
|
21
|
-
def tool_usage(self) -> str:
|
|
22
|
-
return self.tool_usage_xml()
|
|
23
|
-
|
|
24
21
|
def tool_usage_xml(self) -> str:
|
|
25
22
|
return '''SendMessageTo: Sends a message to another agent in the group. Usage:
|
|
26
23
|
<command name="SendMessageTo">
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# file: autobyteus/autobyteus/agent/registry/__init__.py
|
|
2
|
+
from .agent_definition import AgentDefinition
|
|
3
|
+
from .agent_registry import AgentRegistry, default_agent_registry
|
|
4
|
+
from autobyteus.agent.factory.agent_factory import AgentFactory
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"AgentDefinition",
|
|
8
|
+
"AgentRegistry",
|
|
9
|
+
"default_agent_registry",
|
|
10
|
+
"AgentFactory"
|
|
11
|
+
]
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Dict, List, Any, Optional
|
|
3
|
+
|
|
4
|
+
logger = logging.getLogger(__name__)
|
|
5
|
+
|
|
6
|
+
class AgentDefinition:
|
|
7
|
+
"""
|
|
8
|
+
Represents the static definition of an agent, containing its role, description,
|
|
9
|
+
tools, optional system prompt, and optional initial user message.
|
|
10
|
+
"""
|
|
11
|
+
def __init__(self,
|
|
12
|
+
role: str,
|
|
13
|
+
description: str,
|
|
14
|
+
tools: List[str],
|
|
15
|
+
system_prompt: Optional[str] = None,
|
|
16
|
+
initial_user_message: Optional[str] = None):
|
|
17
|
+
"""
|
|
18
|
+
Initializes the AgentDefinition.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
role: The unique role identifier of the agent (e.g., 'coordinator', 'worker').
|
|
22
|
+
description: A human-readable description of the agent's purpose.
|
|
23
|
+
tools: A list of tool names the agent can use.
|
|
24
|
+
system_prompt: An optional system prompt to configure the LLM's behavior.
|
|
25
|
+
initial_user_message: An optional initial user message to start the agent's conversation.
|
|
26
|
+
|
|
27
|
+
Raises:
|
|
28
|
+
ValueError: If role, description, or tools are invalid, or if system_prompt or
|
|
29
|
+
initial_user_message are not strings when provided.
|
|
30
|
+
"""
|
|
31
|
+
if not role or not isinstance(role, str):
|
|
32
|
+
raise ValueError("AgentDefinition requires a non-empty string 'role'.")
|
|
33
|
+
if not description or not isinstance(description, str):
|
|
34
|
+
raise ValueError(f"AgentDefinition '{role}' requires a non-empty string 'description'.")
|
|
35
|
+
if not isinstance(tools, list) or not all(isinstance(t, str) and t for t in tools):
|
|
36
|
+
raise ValueError(f"AgentDefinition '{role}' requires a non-empty list of tool name strings.")
|
|
37
|
+
if system_prompt is not None and not isinstance(system_prompt, str):
|
|
38
|
+
raise ValueError(f"AgentDefinition '{role}' system_prompt must be a string or None.")
|
|
39
|
+
if initial_user_message is not None and not isinstance(initial_user_message, str):
|
|
40
|
+
raise ValueError(f"AgentDefinition '{role}' initial_user_message must be a string or None.")
|
|
41
|
+
|
|
42
|
+
self._role = role
|
|
43
|
+
self._description = description
|
|
44
|
+
self._tools = tools
|
|
45
|
+
self._system_prompt = system_prompt
|
|
46
|
+
self._initial_user_message = initial_user_message
|
|
47
|
+
|
|
48
|
+
logger.debug(f"AgentDefinition created for role '{self.role}'.")
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def role(self) -> str:
|
|
52
|
+
"""The unique role identifier of the agent."""
|
|
53
|
+
return self._role
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def description(self) -> str:
|
|
57
|
+
"""The human-readable description of the agent's purpose."""
|
|
58
|
+
return self._description
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def tools(self) -> List[str]:
|
|
62
|
+
"""The list of tool names the agent can use."""
|
|
63
|
+
return self._tools
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def system_prompt(self) -> Optional[str]:
|
|
67
|
+
"""The optional system prompt for the agent."""
|
|
68
|
+
return self._system_prompt
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def initial_user_message(self) -> Optional[str]:
|
|
72
|
+
"""The optional initial user message for the agent."""
|
|
73
|
+
return self._initial_user_message
|
|
74
|
+
|
|
75
|
+
def __repr__(self) -> str:
|
|
76
|
+
"""Provides a developer-friendly string representation."""
|
|
77
|
+
desc_repr = self.description
|
|
78
|
+
if len(desc_repr) > 70:
|
|
79
|
+
desc_repr = desc_repr[:67] + "..."
|
|
80
|
+
# Remove newlines/tabs for cleaner logging
|
|
81
|
+
desc_repr = desc_repr.replace('\n', '\\n').replace('\t', '\\t')
|
|
82
|
+
return (f"AgentDefinition(role='{self.role}', description='{desc_repr}', "
|
|
83
|
+
f"tools={self.tools}, system_prompt='{self.system_prompt}', "
|
|
84
|
+
f"initial_user_message='{self.initial_user_message}')")
|
|
85
|
+
|
|
86
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
87
|
+
"""Returns a dictionary representation of the agent definition."""
|
|
88
|
+
return {
|
|
89
|
+
"role": self.role,
|
|
90
|
+
"description": self.description,
|
|
91
|
+
"tools": self.tools,
|
|
92
|
+
"system_prompt": self.system_prompt,
|
|
93
|
+
"initial_user_message": self.initial_user_message
|
|
94
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# file: autobyteus/autobyteus/agent/registry/agent_registry.py
|
|
2
|
+
import logging
|
|
3
|
+
from typing import Dict, List, Optional
|
|
4
|
+
|
|
5
|
+
from autobyteus.utils.singleton import SingletonMeta
|
|
6
|
+
from autobyteus.agent.factory.agent_factory import AgentFactory
|
|
7
|
+
from .agent_definition import AgentDefinition
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
class AgentRegistry(metaclass=SingletonMeta):
|
|
12
|
+
"""
|
|
13
|
+
Manages AgentDefinitions (role, description, tools, initial_user_message, agent_class),
|
|
14
|
+
populated exclusively via programmatic registration. Uses AgentFactory to create agent instances.
|
|
15
|
+
"""
|
|
16
|
+
_definitions: Dict[str, AgentDefinition] = {}
|
|
17
|
+
|
|
18
|
+
def __init__(self, agent_factory: AgentFactory):
|
|
19
|
+
"""
|
|
20
|
+
Initializes the AgentRegistry with an AgentFactory.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
agent_factory: The AgentFactory instance used to create agent instances.
|
|
24
|
+
"""
|
|
25
|
+
self.agent_factory = agent_factory
|
|
26
|
+
logger.info("AgentRegistry initialized with AgentFactory.")
|
|
27
|
+
|
|
28
|
+
def register_agent(self, definition: AgentDefinition):
|
|
29
|
+
"""
|
|
30
|
+
Registers an agent definition (role, description, tools, initial_user_message, agent_class) programmatically.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
definition: The AgentDefinition object to register.
|
|
34
|
+
|
|
35
|
+
Raises:
|
|
36
|
+
ValueError: If the definition is invalid. Overwrites existing definitions with the same role.
|
|
37
|
+
"""
|
|
38
|
+
if not isinstance(definition, AgentDefinition):
|
|
39
|
+
raise ValueError("Attempted to register an object that is not an AgentDefinition.")
|
|
40
|
+
|
|
41
|
+
role = definition.role
|
|
42
|
+
if role in self._definitions:
|
|
43
|
+
logger.warning(f"Overwriting existing agent definition for role: '{role}'")
|
|
44
|
+
AgentRegistry._definitions[role] = definition
|
|
45
|
+
logger.info(f"Successfully registered agent definition: '{role}'")
|
|
46
|
+
|
|
47
|
+
def get_agent_definition(self, role: str) -> Optional[AgentDefinition]:
|
|
48
|
+
"""
|
|
49
|
+
Retrieves the definition for a specific agent role.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
role: The unique role of the agent definition to retrieve.
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
The AgentDefinition object if found, otherwise None.
|
|
56
|
+
"""
|
|
57
|
+
definition = self._definitions.get(role)
|
|
58
|
+
if not definition:
|
|
59
|
+
logger.debug(f"Agent definition not found for role: '{role}'")
|
|
60
|
+
return definition
|
|
61
|
+
|
|
62
|
+
def create_agent(self, role: str, agent_id: str):
|
|
63
|
+
"""
|
|
64
|
+
Creates an agent instance using the AgentFactory based on the agent definition.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
role: The role of the agent to create.
|
|
68
|
+
agent_id: The unique identifier for the agent instance.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
The agent instance if the definition exists, otherwise None.
|
|
72
|
+
|
|
73
|
+
Raises:
|
|
74
|
+
ValueError: If the agent definition is not found.
|
|
75
|
+
"""
|
|
76
|
+
definition = self.get_agent_definition(role)
|
|
77
|
+
if not definition:
|
|
78
|
+
logger.error(f"Cannot create agent: No definition found for role '{role}'")
|
|
79
|
+
raise ValueError(f"No agent definition found for role '{role}'")
|
|
80
|
+
|
|
81
|
+
logger.info(f"Creating agent instance for role '{role}' with id '{agent_id}' using AgentFactory")
|
|
82
|
+
return self.agent_factory.create_agent(agent_id)
|
|
83
|
+
|
|
84
|
+
def list_agents(self) -> List[AgentDefinition]:
|
|
85
|
+
"""
|
|
86
|
+
Returns a list of all registered agent definitions.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
A list of AgentDefinition objects.
|
|
90
|
+
"""
|
|
91
|
+
return list(self._definitions.values())
|
|
92
|
+
|
|
93
|
+
def list_agent_roles(self) -> List[str]:
|
|
94
|
+
"""
|
|
95
|
+
Returns a list of the roles of all registered agents.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
A list of agent role strings.
|
|
99
|
+
"""
|
|
100
|
+
return list(self._definitions.keys())
|
|
101
|
+
|
|
102
|
+
def get_all_definitions(self) -> Dict[str, AgentDefinition]:
|
|
103
|
+
"""Returns the internal dictionary of definitions."""
|
|
104
|
+
return dict(AgentRegistry._definitions)
|
|
105
|
+
|
|
106
|
+
default_agent_registry = AgentRegistry(agent_factory=AgentFactory(
|
|
107
|
+
role="default",
|
|
108
|
+
agent_type="group_aware",
|
|
109
|
+
tool_factory=ToolFactory(),
|
|
110
|
+
llm_factory=LLMFactory(),
|
|
111
|
+
prompt_builder=PromptBuilder(),
|
|
112
|
+
llm_model=LLMModel(),
|
|
113
|
+
tool_names=[]
|
|
114
|
+
))
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# file: autobyteus/autobyteus/agent/remote_agent.py
|
|
2
|
+
from autobyteus.agent.agent import Agent
|
|
3
|
+
|
|
4
|
+
class RemoteAgent(Agent):
|
|
5
|
+
"""
|
|
6
|
+
A placeholder class for remote agents that will interact with external systems
|
|
7
|
+
(e.g., via MCP or HTTP protocols). To be implemented in the future.
|
|
8
|
+
"""
|
|
9
|
+
pass
|
|
@@ -56,12 +56,13 @@ class AutobyteusModelProvider:
|
|
|
56
56
|
value=model_info["value"],
|
|
57
57
|
provider=LLMProvider(model_info["provider"]), # Convert string to enum
|
|
58
58
|
llm_class=AutobyteusLLM,
|
|
59
|
+
canonical_name=model_info["canonical_name"], # Add canonical_name
|
|
59
60
|
default_config=llm_config
|
|
60
61
|
)
|
|
61
62
|
|
|
62
63
|
LLMFactory.register_model(llm_model)
|
|
63
64
|
registered_count += 1
|
|
64
|
-
logger.debug(f"Registered model: {model_info['name']}")
|
|
65
|
+
logger.debug(f"Registered model: {model_info['name']} with canonical name: {model_info['canonical_name']}")
|
|
65
66
|
|
|
66
67
|
except Exception as e:
|
|
67
68
|
logger.error(f"Model registration failed: {str(e)}")
|
|
@@ -98,6 +98,7 @@ class LLMFactory:
|
|
|
98
98
|
value="gpt-4o",
|
|
99
99
|
provider=LLMProvider.OPENAI,
|
|
100
100
|
llm_class=OpenAILLM,
|
|
101
|
+
canonical_name="gpt-4o",
|
|
101
102
|
default_config=LLMConfig(
|
|
102
103
|
rate_limit=40,
|
|
103
104
|
token_limit=8192,
|
|
@@ -105,38 +106,32 @@ class LLMFactory:
|
|
|
105
106
|
)
|
|
106
107
|
),
|
|
107
108
|
LLMModel(
|
|
108
|
-
name="
|
|
109
|
-
value="
|
|
109
|
+
name="o3_API",
|
|
110
|
+
value="o3",
|
|
110
111
|
provider=LLMProvider.OPENAI,
|
|
111
112
|
llm_class=OpenAILLM,
|
|
113
|
+
canonical_name="o3",
|
|
112
114
|
default_config=LLMConfig(
|
|
113
115
|
pricing_config=TokenPricingConfig(15.00, 60.00)
|
|
114
116
|
)
|
|
115
117
|
),
|
|
116
118
|
LLMModel(
|
|
117
|
-
name="
|
|
118
|
-
value="
|
|
119
|
+
name="o4_MINI_API",
|
|
120
|
+
value="o4-mini",
|
|
119
121
|
provider=LLMProvider.OPENAI,
|
|
120
122
|
llm_class=OpenAILLM,
|
|
123
|
+
canonical_name="o4-mini",
|
|
121
124
|
default_config=LLMConfig(
|
|
122
125
|
pricing_config=TokenPricingConfig(1.0, 4.00)
|
|
123
126
|
)
|
|
124
127
|
),
|
|
125
|
-
LLMModel(
|
|
126
|
-
name="GPT_3_5_TURBO_API",
|
|
127
|
-
value="gpt-3.5-turbo",
|
|
128
|
-
provider=LLMProvider.OPENAI,
|
|
129
|
-
llm_class=OpenAILLM,
|
|
130
|
-
default_config=LLMConfig(
|
|
131
|
-
pricing_config=TokenPricingConfig(1.50, 2.00)
|
|
132
|
-
)
|
|
133
|
-
),
|
|
134
128
|
# MISTRAL Provider Models
|
|
135
129
|
LLMModel(
|
|
136
130
|
name="MISTRAL_LARGE_API",
|
|
137
131
|
value="mistral-large-latest",
|
|
138
132
|
provider=LLMProvider.MISTRAL,
|
|
139
133
|
llm_class=MistralLLM,
|
|
134
|
+
canonical_name="mistral-large",
|
|
140
135
|
default_config=LLMConfig(
|
|
141
136
|
pricing_config=TokenPricingConfig(2.00, 6.00)
|
|
142
137
|
)
|
|
@@ -147,6 +142,7 @@ class LLMFactory:
|
|
|
147
142
|
value="claude-3-7-sonnet-20250219",
|
|
148
143
|
provider=LLMProvider.ANTHROPIC,
|
|
149
144
|
llm_class=ClaudeLLM,
|
|
145
|
+
canonical_name="claude-3.7",
|
|
150
146
|
default_config=LLMConfig(
|
|
151
147
|
pricing_config=TokenPricingConfig(3.00, 15.00)
|
|
152
148
|
)
|
|
@@ -156,6 +152,7 @@ class LLMFactory:
|
|
|
156
152
|
value="anthropic.claude-3-7-sonnet-20250219-v1:0",
|
|
157
153
|
provider=LLMProvider.ANTHROPIC,
|
|
158
154
|
llm_class=ClaudeLLM,
|
|
155
|
+
canonical_name="claude-3.7",
|
|
159
156
|
default_config=LLMConfig(
|
|
160
157
|
pricing_config=TokenPricingConfig(3.00, 15.00)
|
|
161
158
|
)
|
|
@@ -166,6 +163,7 @@ class LLMFactory:
|
|
|
166
163
|
value="deepseek-chat",
|
|
167
164
|
provider=LLMProvider.DEEPSEEK,
|
|
168
165
|
llm_class=DeepSeekLLM,
|
|
166
|
+
canonical_name="deepseek-chat",
|
|
169
167
|
default_config=LLMConfig(
|
|
170
168
|
rate_limit=60,
|
|
171
169
|
token_limit=8000,
|
|
@@ -178,6 +176,7 @@ class LLMFactory:
|
|
|
178
176
|
value="deepseek-reasoner",
|
|
179
177
|
provider=LLMProvider.DEEPSEEK,
|
|
180
178
|
llm_class=DeepSeekLLM,
|
|
179
|
+
canonical_name="deepseek-reasoner",
|
|
181
180
|
default_config=LLMConfig(
|
|
182
181
|
rate_limit=60,
|
|
183
182
|
token_limit=8000,
|
|
@@ -190,6 +189,7 @@ class LLMFactory:
|
|
|
190
189
|
value="gemini-1-5-pro",
|
|
191
190
|
provider=LLMProvider.GEMINI,
|
|
192
191
|
llm_class=OpenAILLM,
|
|
192
|
+
canonical_name="gemini-1.5-pro",
|
|
193
193
|
default_config=LLMConfig(
|
|
194
194
|
pricing_config=TokenPricingConfig(1.25, 5.00)
|
|
195
195
|
)
|
|
@@ -199,6 +199,7 @@ class LLMFactory:
|
|
|
199
199
|
value="gemini-1-5-flash",
|
|
200
200
|
provider=LLMProvider.GEMINI,
|
|
201
201
|
llm_class=OpenAILLM,
|
|
202
|
+
canonical_name="gemini-1.5-flash",
|
|
202
203
|
default_config=LLMConfig(
|
|
203
204
|
pricing_config=TokenPricingConfig(0.075, 0.30)
|
|
204
205
|
)
|
|
@@ -209,6 +210,7 @@ class LLMFactory:
|
|
|
209
210
|
value="grok-2-1212",
|
|
210
211
|
provider=LLMProvider.GROK,
|
|
211
212
|
llm_class=GrokLLM,
|
|
213
|
+
canonical_name="grok-2",
|
|
212
214
|
default_config=LLMConfig(
|
|
213
215
|
rate_limit=60,
|
|
214
216
|
token_limit=8000,
|
|
@@ -290,3 +292,21 @@ class LLMFactory:
|
|
|
290
292
|
"""
|
|
291
293
|
LLMFactory.ensure_initialized()
|
|
292
294
|
return LLMFactory._models_by_provider.get(provider, [])
|
|
295
|
+
|
|
296
|
+
@staticmethod
|
|
297
|
+
def get_canonical_name(model_name: str) -> Optional[str]:
|
|
298
|
+
"""
|
|
299
|
+
Get the canonical name for a model by its name.
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
model_name (str): The model name (e.g., "GPT_4o_API")
|
|
303
|
+
|
|
304
|
+
Returns:
|
|
305
|
+
Optional[str]: The canonical name if found, None otherwise
|
|
306
|
+
"""
|
|
307
|
+
LLMFactory.ensure_initialized()
|
|
308
|
+
for models in LLMFactory._models_by_provider.values():
|
|
309
|
+
for model_instance in models:
|
|
310
|
+
if model_instance.name == model_name:
|
|
311
|
+
return model_instance.canonical_name
|
|
312
|
+
return None
|
|
@@ -13,6 +13,7 @@ class LLMModel:
|
|
|
13
13
|
Represents a single model's metadata:
|
|
14
14
|
- name (str): A human-readable label, e.g. "GPT-4 Official"
|
|
15
15
|
- value (str): A unique identifier used in code or APIs, e.g. "gpt-4o"
|
|
16
|
+
- canonical_name (str): A shorter, standardized reference name for prompts, e.g. "gpt-4o" or "claude-3.7"
|
|
16
17
|
- provider (LLMProvider): The provider enum
|
|
17
18
|
- llm_class (Type[BaseLLM]): Which Python class to instantiate
|
|
18
19
|
- default_config (LLMConfig): Default configuration (token limit, etc.)
|
|
@@ -26,6 +27,7 @@ class LLMModel:
|
|
|
26
27
|
value: str,
|
|
27
28
|
provider: LLMProvider,
|
|
28
29
|
llm_class: Type["BaseLLM"],
|
|
30
|
+
canonical_name: str,
|
|
29
31
|
default_config: Optional[LLMConfig] = None
|
|
30
32
|
):
|
|
31
33
|
# Validate name doesn't already exist as a class attribute
|
|
@@ -36,6 +38,7 @@ class LLMModel:
|
|
|
36
38
|
|
|
37
39
|
self._name = name
|
|
38
40
|
self._value = value
|
|
41
|
+
self._canonical_name = canonical_name
|
|
39
42
|
self.provider = provider
|
|
40
43
|
self.llm_class = llm_class
|
|
41
44
|
self.default_config = default_config if default_config else LLMConfig()
|
|
@@ -58,6 +61,14 @@ class LLMModel:
|
|
|
58
61
|
"""
|
|
59
62
|
return self._value
|
|
60
63
|
|
|
64
|
+
@property
|
|
65
|
+
def canonical_name(self) -> str:
|
|
66
|
+
"""
|
|
67
|
+
A standardized, shorter reference name for this model.
|
|
68
|
+
Useful for prompt engineering and cross-referencing similar models.
|
|
69
|
+
"""
|
|
70
|
+
return self._canonical_name
|
|
71
|
+
|
|
61
72
|
def create_llm(self, custom_config: Optional[LLMConfig] = None) -> "BaseLLM":
|
|
62
73
|
"""
|
|
63
74
|
Instantiate the LLM class for this model, applying
|
|
@@ -69,5 +80,6 @@ class LLMModel:
|
|
|
69
80
|
def __repr__(self):
|
|
70
81
|
return (
|
|
71
82
|
f"LLMModel(name='{self._name}', value='{self._value}', "
|
|
83
|
+
f"canonical_name='{self._canonical_name}', "
|
|
72
84
|
f"provider='{self.provider.name}', llm_class='{self.llm_class.__name__}')"
|
|
73
85
|
)
|
|
@@ -12,27 +12,16 @@ class AskUserInput(BaseTool):
|
|
|
12
12
|
super().__init__()
|
|
13
13
|
self.logger = logging.getLogger(__name__)
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
@classmethod
|
|
16
|
+
def tool_usage_xml(cls):
|
|
16
17
|
"""
|
|
17
|
-
Return
|
|
18
|
+
Return an XML string describing the usage of the AskUserInput tool.
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
str: An XML description of how to use the AskUserInput tool.
|
|
18
22
|
"""
|
|
19
|
-
return '''AskUserInput: Requests input from the user based on LLM's prompt.
|
|
20
|
-
Usage: <<<AskUserInput(request="[Your request here]")>>>
|
|
21
|
-
|
|
22
|
-
Examples:
|
|
23
|
-
1. When needing to request user for search input:
|
|
24
|
-
<<<AskUserInput(request="What would you like to search for?")>>>
|
|
25
|
-
|
|
26
|
-
2. When needing to request user for form input:
|
|
27
|
-
<<<AskUserInput(request="Please enter your full name:")>>>
|
|
28
|
-
|
|
29
|
-
3. When needing to request user for a choice:
|
|
30
|
-
<<<AskUserInput(request="Select an option (1, 2, or 3):")>>>
|
|
31
|
-
'''
|
|
32
|
-
|
|
33
|
-
def tool_usage_xml(self):
|
|
34
23
|
return '''AskUserInput: Requests input from the user based on a given context or prompt.
|
|
35
|
-
<command name="AskUserInput"
|
|
24
|
+
<command name="AskUserInput">
|
|
36
25
|
<arg name="request">[Your request here]</arg>
|
|
37
26
|
</command>
|
|
38
27
|
|
|
@@ -90,4 +79,4 @@ class AskUserInput(BaseTool):
|
|
|
90
79
|
except Exception as e:
|
|
91
80
|
error_message = f"An error occurred while getting user input: {str(e)}"
|
|
92
81
|
self.logger.error(error_message)
|
|
93
|
-
return f"[Error: {error_message}]"
|
|
82
|
+
return f"[Error: {error_message}]"
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# File: autobyteus/tools/base_tool.py
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from abc import ABC, abstractmethod
|
|
5
|
+
from typing import Optional, Any
|
|
6
|
+
|
|
7
|
+
from autobyteus.events.event_emitter import EventEmitter
|
|
8
|
+
from autobyteus.events.event_types import EventType
|
|
9
|
+
|
|
10
|
+
from .tool_meta import ToolMeta
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger('autobyteus')
|
|
13
|
+
|
|
14
|
+
class BaseTool(ABC, EventEmitter, metaclass=ToolMeta):
|
|
15
|
+
"""
|
|
16
|
+
Abstract base class for all tools, with auto-registration via ToolMeta.
|
|
17
|
+
|
|
18
|
+
Subclasses inherit a default `get_name` (the class name) and MUST implement
|
|
19
|
+
the abstract class method `tool_usage_xml`, and the abstract instance
|
|
20
|
+
method `_execute`.
|
|
21
|
+
"""
|
|
22
|
+
def __init__(self):
|
|
23
|
+
super().__init__()
|
|
24
|
+
self.agent_id: Optional[str] = None
|
|
25
|
+
logger.debug(f"BaseTool instance initializing for potential class {self.__class__.__name__}")
|
|
26
|
+
|
|
27
|
+
@classmethod
|
|
28
|
+
def get_name(cls) -> str:
|
|
29
|
+
"""
|
|
30
|
+
Return the name of the tool. Defaults to the class name.
|
|
31
|
+
Can be overridden by child classes if a different registration name is needed.
|
|
32
|
+
"""
|
|
33
|
+
return cls.__name__
|
|
34
|
+
|
|
35
|
+
@classmethod
|
|
36
|
+
def tool_usage_xml(cls) -> str:
|
|
37
|
+
"""
|
|
38
|
+
Return the static usage description string for the tool in XML format.
|
|
39
|
+
Must be implemented by subclasses.
|
|
40
|
+
"""
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
def set_agent_id(self, agent_id: str):
|
|
44
|
+
"""Sets the ID of the agent using this tool instance."""
|
|
45
|
+
self.agent_id = agent_id
|
|
46
|
+
logger.debug(f"Agent ID '{agent_id}' set for tool instance '{self.__class__.get_name()}'")
|
|
47
|
+
|
|
48
|
+
async def execute(self, **kwargs):
|
|
49
|
+
"""
|
|
50
|
+
Execute the tool's main functionality by calling _execute.
|
|
51
|
+
Argument validation must be handled within _execute.
|
|
52
|
+
"""
|
|
53
|
+
tool_name = self.__class__.get_name()
|
|
54
|
+
logger.info(f"Executing tool '{tool_name}' for agent '{self.agent_id}' with args: {kwargs}")
|
|
55
|
+
try:
|
|
56
|
+
result = await self._execute(**kwargs)
|
|
57
|
+
logger.info(f"Tool '{tool_name}' execution completed successfully.")
|
|
58
|
+
return result
|
|
59
|
+
except Exception as e:
|
|
60
|
+
logger.error(f"Tool '{tool_name}' execution failed: {str(e)}", exc_info=True)
|
|
61
|
+
return f"Error executing tool '{tool_name}': {str(e)}"
|
|
62
|
+
|
|
63
|
+
@abstractmethod
|
|
64
|
+
async def _execute(self, **kwargs) -> Any:
|
|
65
|
+
"""
|
|
66
|
+
Implement the actual execution logic in subclasses.
|
|
67
|
+
MUST handle own argument validation.
|
|
68
|
+
"""
|
|
69
|
+
pass
|
|
70
|
+
|
|
71
|
+
@classmethod
|
|
72
|
+
def tool_usage(cls) -> str:
|
|
73
|
+
"""
|
|
74
|
+
Returns the tool's static XML usage description by calling the class method tool_usage_xml.
|
|
75
|
+
This is a convenience class method.
|
|
76
|
+
"""
|
|
77
|
+
return cls.tool_usage_xml()
|