autobyteus 1.1.8__py3-none-any.whl → 1.1.9__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/bootstrap_steps/system_prompt_processing_step.py +6 -2
- autobyteus/agent/handlers/inter_agent_message_event_handler.py +17 -19
- autobyteus/agent/handlers/llm_complete_response_received_event_handler.py +6 -3
- autobyteus/agent/handlers/tool_result_event_handler.py +61 -18
- autobyteus/agent/handlers/user_input_message_event_handler.py +19 -10
- autobyteus/agent/hooks/base_phase_hook.py +17 -0
- autobyteus/agent/hooks/hook_registry.py +15 -27
- autobyteus/agent/input_processor/base_user_input_processor.py +17 -1
- autobyteus/agent/input_processor/processor_registry.py +15 -27
- autobyteus/agent/llm_response_processor/base_processor.py +17 -1
- autobyteus/agent/llm_response_processor/processor_registry.py +15 -24
- autobyteus/agent/llm_response_processor/provider_aware_tool_usage_processor.py +14 -0
- autobyteus/agent/message/agent_input_user_message.py +15 -2
- autobyteus/agent/message/send_message_to.py +1 -1
- autobyteus/agent/processor_option.py +17 -0
- autobyteus/agent/sender_type.py +1 -0
- autobyteus/agent/system_prompt_processor/base_processor.py +17 -1
- autobyteus/agent/system_prompt_processor/processor_registry.py +15 -27
- autobyteus/agent/system_prompt_processor/tool_manifest_injector_processor.py +10 -0
- autobyteus/agent/tool_execution_result_processor/base_processor.py +17 -1
- autobyteus/agent/tool_execution_result_processor/processor_registry.py +15 -1
- autobyteus/agent/workspace/base_workspace.py +1 -1
- autobyteus/agent/workspace/workspace_definition.py +1 -1
- autobyteus/agent_team/bootstrap_steps/team_context_initialization_step.py +1 -1
- autobyteus/agent_team/streaming/agent_team_stream_event_payloads.py +2 -2
- autobyteus/agent_team/task_notification/__init__.py +4 -0
- autobyteus/agent_team/task_notification/activation_policy.py +70 -0
- autobyteus/agent_team/task_notification/system_event_driven_agent_task_notifier.py +56 -122
- autobyteus/agent_team/task_notification/task_activator.py +66 -0
- autobyteus/cli/agent_team_tui/state.py +17 -20
- autobyteus/cli/agent_team_tui/widgets/focus_pane.py +1 -1
- autobyteus/cli/agent_team_tui/widgets/task_board_panel.py +1 -1
- autobyteus/events/event_types.py +2 -2
- autobyteus/llm/api/gemini_llm.py +45 -54
- autobyteus/llm/api/qwen_llm.py +25 -0
- autobyteus/llm/autobyteus_provider.py +8 -2
- autobyteus/llm/llm_factory.py +16 -0
- autobyteus/multimedia/audio/api/autobyteus_audio_client.py +4 -1
- autobyteus/multimedia/audio/api/gemini_audio_client.py +84 -153
- autobyteus/multimedia/audio/audio_client_factory.py +47 -22
- autobyteus/multimedia/audio/audio_model.py +13 -6
- autobyteus/multimedia/audio/autobyteus_audio_provider.py +8 -2
- autobyteus/multimedia/audio/base_audio_client.py +3 -1
- autobyteus/multimedia/image/api/autobyteus_image_client.py +12 -5
- autobyteus/multimedia/image/api/gemini_image_client.py +72 -130
- autobyteus/multimedia/image/api/openai_image_client.py +4 -2
- autobyteus/multimedia/image/autobyteus_image_provider.py +8 -2
- autobyteus/multimedia/image/base_image_client.py +6 -2
- autobyteus/multimedia/image/image_client_factory.py +20 -19
- autobyteus/multimedia/image/image_model.py +13 -6
- autobyteus/multimedia/providers.py +1 -0
- autobyteus/task_management/__init__.py +9 -10
- autobyteus/task_management/base_task_board.py +14 -6
- autobyteus/task_management/converters/__init__.py +0 -2
- autobyteus/task_management/converters/task_board_converter.py +7 -16
- autobyteus/task_management/events.py +6 -6
- autobyteus/task_management/in_memory_task_board.py +48 -38
- autobyteus/task_management/schemas/__init__.py +2 -2
- autobyteus/task_management/schemas/{plan_definition.py → task_definition.py} +5 -6
- autobyteus/task_management/schemas/task_status_report.py +0 -1
- autobyteus/task_management/task.py +60 -0
- autobyteus/task_management/tools/__init__.py +4 -2
- autobyteus/task_management/tools/get_my_tasks.py +80 -0
- autobyteus/task_management/tools/get_task_board_status.py +3 -3
- autobyteus/task_management/tools/publish_task.py +77 -0
- autobyteus/task_management/tools/publish_tasks.py +74 -0
- autobyteus/task_management/tools/update_task_status.py +5 -5
- autobyteus/tools/__init__.py +3 -1
- autobyteus/tools/base_tool.py +4 -4
- autobyteus/tools/browser/session_aware/browser_session_aware_navigate_to.py +1 -1
- autobyteus/tools/browser/session_aware/browser_session_aware_web_element_trigger.py +1 -1
- autobyteus/tools/browser/session_aware/browser_session_aware_webpage_reader.py +1 -1
- autobyteus/tools/browser/session_aware/browser_session_aware_webpage_screenshot_taker.py +1 -1
- autobyteus/tools/browser/standalone/navigate_to.py +1 -1
- autobyteus/tools/browser/standalone/web_page_pdf_generator.py +1 -1
- autobyteus/tools/browser/standalone/webpage_image_downloader.py +1 -1
- autobyteus/tools/browser/standalone/webpage_reader.py +1 -1
- autobyteus/tools/browser/standalone/webpage_screenshot_taker.py +1 -1
- autobyteus/tools/functional_tool.py +1 -1
- autobyteus/tools/google_search.py +1 -1
- autobyteus/tools/image_downloader.py +1 -1
- autobyteus/tools/mcp/factory.py +1 -1
- autobyteus/tools/mcp/schema_mapper.py +1 -1
- autobyteus/tools/mcp/tool.py +1 -1
- autobyteus/tools/multimedia/__init__.py +2 -0
- autobyteus/tools/multimedia/audio_tools.py +10 -20
- autobyteus/tools/multimedia/image_tools.py +21 -22
- autobyteus/tools/multimedia/media_reader_tool.py +117 -0
- autobyteus/tools/pydantic_schema_converter.py +1 -1
- autobyteus/tools/registry/tool_definition.py +1 -1
- autobyteus/tools/timer.py +1 -1
- autobyteus/tools/tool_meta.py +1 -1
- autobyteus/tools/usage/formatters/default_json_example_formatter.py +1 -1
- autobyteus/tools/usage/formatters/default_xml_example_formatter.py +1 -1
- autobyteus/tools/usage/formatters/default_xml_schema_formatter.py +59 -3
- autobyteus/tools/usage/formatters/gemini_json_example_formatter.py +1 -1
- autobyteus/tools/usage/formatters/google_json_example_formatter.py +1 -1
- autobyteus/tools/usage/formatters/openai_json_example_formatter.py +1 -1
- autobyteus/{tools → utils}/parameter_schema.py +1 -1
- {autobyteus-1.1.8.dist-info → autobyteus-1.1.9.dist-info}/METADATA +2 -2
- {autobyteus-1.1.8.dist-info → autobyteus-1.1.9.dist-info}/RECORD +105 -99
- examples/run_poem_writer.py +1 -1
- autobyteus/task_management/converters/task_plan_converter.py +0 -48
- autobyteus/task_management/task_plan.py +0 -110
- autobyteus/task_management/tools/publish_task_plan.py +0 -101
- {autobyteus-1.1.8.dist-info → autobyteus-1.1.9.dist-info}/WHEEL +0 -0
- {autobyteus-1.1.8.dist-info → autobyteus-1.1.9.dist-info}/licenses/LICENSE +0 -0
- {autobyteus-1.1.8.dist-info → autobyteus-1.1.9.dist-info}/top_level.txt +0 -0
|
@@ -5,7 +5,7 @@ from typing import Optional, TYPE_CHECKING, Any
|
|
|
5
5
|
from autobyteus.tools.browser.session_aware.browser_session_aware_tool import BrowserSessionAwareTool
|
|
6
6
|
from autobyteus.tools.browser.session_aware.shared_browser_session import SharedBrowserSession
|
|
7
7
|
from autobyteus.tools.tool_config import ToolConfig
|
|
8
|
-
from autobyteus.
|
|
8
|
+
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
|
|
9
9
|
from autobyteus.tools.tool_category import ToolCategory
|
|
10
10
|
from autobyteus.utils.html_cleaner import clean, CleaningMode
|
|
11
11
|
|
|
@@ -6,7 +6,7 @@ from typing import Optional, TYPE_CHECKING, Any
|
|
|
6
6
|
from autobyteus.tools.browser.session_aware.browser_session_aware_tool import BrowserSessionAwareTool
|
|
7
7
|
from autobyteus.tools.browser.session_aware.shared_browser_session import SharedBrowserSession
|
|
8
8
|
from autobyteus.tools.tool_config import ToolConfig
|
|
9
|
-
from autobyteus.
|
|
9
|
+
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
|
|
10
10
|
from autobyteus.tools.tool_category import ToolCategory
|
|
11
11
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
@@ -6,7 +6,7 @@ from urllib.parse import urlparse
|
|
|
6
6
|
from typing import Optional, TYPE_CHECKING, Any
|
|
7
7
|
import logging
|
|
8
8
|
|
|
9
|
-
from autobyteus.
|
|
9
|
+
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
|
|
10
10
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
12
|
from autobyteus.agent.context import AgentContext
|
|
@@ -7,7 +7,7 @@ import logging
|
|
|
7
7
|
from typing import Optional, TYPE_CHECKING, Any
|
|
8
8
|
from urllib.parse import urlparse
|
|
9
9
|
|
|
10
|
-
from autobyteus.
|
|
10
|
+
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
|
|
11
11
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
13
13
|
from autobyteus.agent.context import AgentContext
|
|
@@ -7,7 +7,7 @@ import logging
|
|
|
7
7
|
from urllib.parse import urljoin, urlparse
|
|
8
8
|
from typing import Optional, TYPE_CHECKING, Any, List
|
|
9
9
|
|
|
10
|
-
from autobyteus.
|
|
10
|
+
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
|
|
11
11
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
13
13
|
from autobyteus.agent.context import AgentContext
|
|
@@ -7,7 +7,7 @@ import logging
|
|
|
7
7
|
from typing import Optional, TYPE_CHECKING, Any
|
|
8
8
|
from autobyteus.tools.base_tool import BaseTool
|
|
9
9
|
from autobyteus.tools.tool_config import ToolConfig
|
|
10
|
-
from autobyteus.
|
|
10
|
+
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
|
|
11
11
|
from autobyteus.tools.tool_category import ToolCategory
|
|
12
12
|
from brui_core.ui_integrator import UIIntegrator
|
|
13
13
|
from autobyteus.utils.html_cleaner import clean, CleaningMode
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Optional, TYPE_CHECKING, Any
|
|
2
2
|
from autobyteus.tools.base_tool import BaseTool
|
|
3
3
|
from autobyteus.tools.tool_config import ToolConfig
|
|
4
|
-
from autobyteus.
|
|
4
|
+
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
|
|
5
5
|
from autobyteus.tools.tool_category import ToolCategory
|
|
6
6
|
from brui_core.ui_integrator import UIIntegrator
|
|
7
7
|
import logging
|
|
@@ -5,7 +5,7 @@ import asyncio
|
|
|
5
5
|
from typing import Callable, Optional, Any, Dict, Tuple, Union, get_origin, get_args, List as TypingList, TYPE_CHECKING, Type
|
|
6
6
|
|
|
7
7
|
from autobyteus.tools.base_tool import BaseTool
|
|
8
|
-
from autobyteus.
|
|
8
|
+
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
|
|
9
9
|
from autobyteus.tools.tool_config import ToolConfig
|
|
10
10
|
from autobyteus.tools.registry import default_tool_registry, ToolDefinition
|
|
11
11
|
from autobyteus.tools.tool_origin import ToolOrigin
|
|
@@ -6,7 +6,7 @@ from typing import Optional, TYPE_CHECKING, Any, Dict, List
|
|
|
6
6
|
|
|
7
7
|
from autobyteus.tools.base_tool import BaseTool
|
|
8
8
|
from autobyteus.tools.tool_config import ToolConfig
|
|
9
|
-
from autobyteus.
|
|
9
|
+
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
|
|
10
10
|
from autobyteus.tools.tool_category import ToolCategory
|
|
11
11
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
@@ -6,7 +6,7 @@ from typing import Optional, TYPE_CHECKING, Any
|
|
|
6
6
|
|
|
7
7
|
from autobyteus.tools.base_tool import BaseTool
|
|
8
8
|
from autobyteus.tools.tool_config import ToolConfig
|
|
9
|
-
from autobyteus.
|
|
9
|
+
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
|
|
10
10
|
from autobyteus.tools.tool_category import ToolCategory
|
|
11
11
|
from PIL import Image
|
|
12
12
|
from io import BytesIO
|
autobyteus/tools/mcp/factory.py
CHANGED
|
@@ -6,7 +6,7 @@ from .tool import GenericMcpTool
|
|
|
6
6
|
from autobyteus.tools.factory.tool_factory import ToolFactory
|
|
7
7
|
|
|
8
8
|
if TYPE_CHECKING:
|
|
9
|
-
from autobyteus.
|
|
9
|
+
from autobyteus.utils.parameter_schema import ParameterSchema
|
|
10
10
|
from autobyteus.tools.tool_config import ToolConfig
|
|
11
11
|
from autobyteus.tools.base_tool import BaseTool
|
|
12
12
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import logging
|
|
3
3
|
from typing import Dict, Any, List, Optional
|
|
4
4
|
|
|
5
|
-
from autobyteus.
|
|
5
|
+
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
|
|
6
6
|
|
|
7
7
|
logger = logging.getLogger(__name__)
|
|
8
8
|
|
autobyteus/tools/mcp/tool.py
CHANGED
|
@@ -3,7 +3,7 @@ import logging
|
|
|
3
3
|
from typing import Any, Optional, TYPE_CHECKING
|
|
4
4
|
|
|
5
5
|
from autobyteus.tools.base_tool import BaseTool
|
|
6
|
-
from autobyteus.
|
|
6
|
+
from autobyteus.utils.parameter_schema import ParameterSchema
|
|
7
7
|
from .server.proxy import McpServerProxy
|
|
8
8
|
|
|
9
9
|
if TYPE_CHECKING:
|
|
@@ -3,7 +3,7 @@ import logging
|
|
|
3
3
|
from typing import Optional, List
|
|
4
4
|
|
|
5
5
|
from autobyteus.tools.base_tool import BaseTool
|
|
6
|
-
from autobyteus.
|
|
6
|
+
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
|
|
7
7
|
from autobyteus.tools.tool_category import ToolCategory
|
|
8
8
|
from autobyteus.multimedia.audio import audio_client_factory, AudioModel, AudioClientFactory
|
|
9
9
|
|
|
@@ -34,24 +34,8 @@ def _build_dynamic_audio_schema(base_params: List[ParameterDefinition], model_en
|
|
|
34
34
|
logger.error(f"Cannot generate audio tool schema. Check environment and model registry. Error: {e}")
|
|
35
35
|
raise RuntimeError(f"Failed to configure audio tool. Error: {e}")
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
for name, meta in model.parameter_schema.items():
|
|
40
|
-
param_type_str = meta.get("type", "string").upper()
|
|
41
|
-
param_type = getattr(ParameterType, param_type_str, ParameterType.STRING)
|
|
42
|
-
|
|
43
|
-
allowed_values = meta.get("allowed_values")
|
|
44
|
-
if param_type == ParameterType.STRING and allowed_values:
|
|
45
|
-
param_type = ParameterType.ENUM
|
|
46
|
-
|
|
47
|
-
config_schema.add_parameter(ParameterDefinition(
|
|
48
|
-
name=name,
|
|
49
|
-
param_type=param_type,
|
|
50
|
-
description=meta.get("description", ""),
|
|
51
|
-
required=False,
|
|
52
|
-
default_value=meta.get("default"),
|
|
53
|
-
enum_values=allowed_values
|
|
54
|
-
))
|
|
37
|
+
# The model's parameter schema is now a ParameterSchema object, so we can use it directly.
|
|
38
|
+
config_schema = model.parameter_schema
|
|
55
39
|
|
|
56
40
|
schema = ParameterSchema()
|
|
57
41
|
for param in base_params:
|
|
@@ -70,6 +54,7 @@ def _build_dynamic_audio_schema(base_params: List[ParameterDefinition], model_en
|
|
|
70
54
|
|
|
71
55
|
class GenerateSpeechTool(BaseTool):
|
|
72
56
|
"""
|
|
57
|
+
|
|
73
58
|
An agent tool for generating speech from text using a Text-to-Speech (TTS) model.
|
|
74
59
|
"""
|
|
75
60
|
CATEGORY = ToolCategory.MULTIMEDIA
|
|
@@ -93,7 +78,12 @@ class GenerateSpeechTool(BaseTool):
|
|
|
93
78
|
ParameterDefinition(
|
|
94
79
|
name="prompt",
|
|
95
80
|
param_type=ParameterType.STRING,
|
|
96
|
-
description=
|
|
81
|
+
description=(
|
|
82
|
+
"The text to be converted into spoken audio. For multi-speaker mode, you must format the prompt "
|
|
83
|
+
"with speaker labels that match the speakers defined in 'speaker_mapping'. "
|
|
84
|
+
"CRITICAL: Each speaker's dialogue MUST be on a new line. "
|
|
85
|
+
"Example: 'Joe: Hello Jane.\\nJane: Hi Joe, how are you?'"
|
|
86
|
+
),
|
|
97
87
|
required=True
|
|
98
88
|
)
|
|
99
89
|
]
|
|
@@ -3,7 +3,7 @@ import logging
|
|
|
3
3
|
from typing import Optional, List
|
|
4
4
|
|
|
5
5
|
from autobyteus.tools.base_tool import BaseTool
|
|
6
|
-
from autobyteus.
|
|
6
|
+
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
|
|
7
7
|
from autobyteus.tools.tool_category import ToolCategory
|
|
8
8
|
from autobyteus.multimedia.image import image_client_factory, ImageModel, ImageClientFactory
|
|
9
9
|
|
|
@@ -34,24 +34,8 @@ def _build_dynamic_image_schema(base_params: List[ParameterDefinition], model_en
|
|
|
34
34
|
logger.error(f"Cannot generate image tool schema. Check environment and model registry. Error: {e}")
|
|
35
35
|
raise RuntimeError(f"Failed to configure image tool. Error: {e}")
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
for name, meta in model.parameter_schema.items():
|
|
40
|
-
param_type_str = meta.get("type", "string").upper()
|
|
41
|
-
param_type = getattr(ParameterType, param_type_str, ParameterType.STRING)
|
|
42
|
-
|
|
43
|
-
allowed_values = meta.get("allowed_values")
|
|
44
|
-
if param_type == ParameterType.STRING and allowed_values:
|
|
45
|
-
param_type = ParameterType.ENUM
|
|
46
|
-
|
|
47
|
-
config_schema.add_parameter(ParameterDefinition(
|
|
48
|
-
name=name,
|
|
49
|
-
param_type=param_type,
|
|
50
|
-
description=meta.get("description", ""),
|
|
51
|
-
required=False,
|
|
52
|
-
default_value=meta.get("default"),
|
|
53
|
-
enum_values=allowed_values
|
|
54
|
-
))
|
|
37
|
+
# The model's parameter schema is now a ParameterSchema object, so we can use it directly.
|
|
38
|
+
config_schema = model.parameter_schema
|
|
55
39
|
|
|
56
40
|
schema = ParameterSchema()
|
|
57
41
|
for param in base_params:
|
|
@@ -84,6 +68,7 @@ class GenerateImageTool(BaseTool):
|
|
|
84
68
|
def get_description(cls) -> str:
|
|
85
69
|
return (
|
|
86
70
|
"Generates one or more images based on a textual description (prompt) using the system's default image model. "
|
|
71
|
+
"Can optionally accept reference images to influence the style or content. "
|
|
87
72
|
"Returns a list of URLs to the generated images upon success."
|
|
88
73
|
)
|
|
89
74
|
|
|
@@ -95,17 +80,31 @@ class GenerateImageTool(BaseTool):
|
|
|
95
80
|
param_type=ParameterType.STRING,
|
|
96
81
|
description="A detailed textual description of the image to generate.",
|
|
97
82
|
required=True
|
|
83
|
+
),
|
|
84
|
+
ParameterDefinition(
|
|
85
|
+
name="input_image_urls",
|
|
86
|
+
param_type=ParameterType.STRING,
|
|
87
|
+
description="Optional. A comma-separated string of URLs to reference images. The generated image will try to match the style or content of these images.",
|
|
88
|
+
required=False
|
|
98
89
|
)
|
|
99
90
|
]
|
|
100
91
|
return _build_dynamic_image_schema(base_params, cls.MODEL_ENV_VAR, cls.DEFAULT_MODEL)
|
|
101
92
|
|
|
102
|
-
async def _execute(self, context, prompt: str, generation_config: Optional[dict] = None) -> List[str]:
|
|
93
|
+
async def _execute(self, context, prompt: str, input_image_urls: Optional[str] = None, generation_config: Optional[dict] = None) -> List[str]:
|
|
103
94
|
model_identifier = _get_configured_model_identifier(self.MODEL_ENV_VAR, self.DEFAULT_MODEL)
|
|
104
95
|
logger.info(f"GenerateImageTool executing with configured model '{model_identifier}'.")
|
|
105
96
|
client = None
|
|
106
97
|
try:
|
|
98
|
+
urls_list = None
|
|
99
|
+
if input_image_urls:
|
|
100
|
+
urls_list = [url.strip() for url in input_image_urls.split(',') if url.strip()]
|
|
101
|
+
|
|
107
102
|
client = image_client_factory.create_image_client(model_identifier=model_identifier)
|
|
108
|
-
response = await client.generate_image(
|
|
103
|
+
response = await client.generate_image(
|
|
104
|
+
prompt=prompt,
|
|
105
|
+
input_image_urls=urls_list,
|
|
106
|
+
generation_config=generation_config
|
|
107
|
+
)
|
|
109
108
|
|
|
110
109
|
if not response.image_urls:
|
|
111
110
|
raise ValueError("Image generation failed to return any image URLs.")
|
|
@@ -121,7 +120,7 @@ class EditImageTool(BaseTool):
|
|
|
121
120
|
An agent tool for editing an existing image using a text prompt and a pre-configured model.
|
|
122
121
|
"""
|
|
123
122
|
CATEGORY = ToolCategory.MULTIMEDIA
|
|
124
|
-
MODEL_ENV_VAR = "
|
|
123
|
+
MODEL_ENV_VAR = "DEFAULT_IMAGE_EDIT_MODEL"
|
|
125
124
|
DEFAULT_MODEL = "gpt-image-1"
|
|
126
125
|
|
|
127
126
|
@classmethod
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# file: autobyteus/autobyteus/tools/multimedia/media_reader_tool.py
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
from typing import TYPE_CHECKING, Optional
|
|
5
|
+
|
|
6
|
+
from autobyteus.tools.base_tool import BaseTool
|
|
7
|
+
from autobyteus.tools.tool_category import ToolCategory
|
|
8
|
+
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
|
|
9
|
+
from autobyteus.agent.message.context_file import ContextFile
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from autobyteus.agent.context import AgentContext
|
|
13
|
+
from autobyteus.agent.workspace.base_workspace import BaseAgentWorkspace
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
class ReadMediaFile(BaseTool):
|
|
18
|
+
"""
|
|
19
|
+
A tool that loads a media file (image, audio, video) into the context for
|
|
20
|
+
the next LLM turn. This allows a multimodal LLM to directly 'see' or 'hear'
|
|
21
|
+
the file's content. The tool's result is a structured object that the system
|
|
22
|
+
uses to construct a multimodal prompt, not plain text.
|
|
23
|
+
"""
|
|
24
|
+
TOOL_NAME = "ReadMediaFile"
|
|
25
|
+
CATEGORY = ToolCategory.MULTIMEDIA
|
|
26
|
+
|
|
27
|
+
@classmethod
|
|
28
|
+
def get_name(cls) -> str:
|
|
29
|
+
return cls.TOOL_NAME
|
|
30
|
+
|
|
31
|
+
@classmethod
|
|
32
|
+
def get_description(cls) -> str:
|
|
33
|
+
return (
|
|
34
|
+
"Loads a media file (image, audio, video) into the context for the next turn, "
|
|
35
|
+
"allowing the LLM to directly analyze its content. Use this when you need to 'see' an image, "
|
|
36
|
+
"'listen' to audio, or 'watch' a video that you know exists in the workspace or file system."
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
def get_argument_schema(cls) -> Optional[ParameterSchema]:
|
|
41
|
+
schema = ParameterSchema()
|
|
42
|
+
schema.add_parameter(ParameterDefinition(
|
|
43
|
+
name="file_path",
|
|
44
|
+
param_type=ParameterType.STRING,
|
|
45
|
+
description="The absolute path or workspace-relative path to the media file.",
|
|
46
|
+
required=True
|
|
47
|
+
))
|
|
48
|
+
return schema
|
|
49
|
+
|
|
50
|
+
async def _execute(self,
|
|
51
|
+
context: 'AgentContext',
|
|
52
|
+
file_path: str) -> 'ContextFile':
|
|
53
|
+
"""
|
|
54
|
+
Resolves the file path and returns a ContextFile object, which signals
|
|
55
|
+
the system to include this file in the next multimodal LLM prompt.
|
|
56
|
+
It handles both absolute paths and paths relative to the agent's workspace.
|
|
57
|
+
"""
|
|
58
|
+
logger.debug(f"Tool '{self.get_name()}': Received request to read media file at '{file_path}'.")
|
|
59
|
+
|
|
60
|
+
absolute_path: str
|
|
61
|
+
workspace: Optional['BaseAgentWorkspace'] = context.workspace
|
|
62
|
+
|
|
63
|
+
if os.path.isabs(file_path):
|
|
64
|
+
absolute_path = os.path.normpath(file_path)
|
|
65
|
+
logger.debug(f"Path '{file_path}' is absolute. Using resolved path: '{absolute_path}'.")
|
|
66
|
+
|
|
67
|
+
# Security Note: This allows reading from outside the workspace.
|
|
68
|
+
# We log a warning if this occurs.
|
|
69
|
+
if workspace and hasattr(workspace, 'get_base_path'):
|
|
70
|
+
try:
|
|
71
|
+
workspace_root = os.path.abspath(workspace.get_base_path())
|
|
72
|
+
resolved_target = os.path.abspath(absolute_path)
|
|
73
|
+
if not os.path.commonpath([workspace_root]) == os.path.commonpath([workspace_root, resolved_target]):
|
|
74
|
+
logger.warning(
|
|
75
|
+
f"Security Note: Tool '{self.get_name()}' is accessing an absolute path "
|
|
76
|
+
f"'{absolute_path}' which is outside the agent's workspace '{workspace_root}'."
|
|
77
|
+
)
|
|
78
|
+
except Exception:
|
|
79
|
+
# Failsafe if get_base_path has an issue.
|
|
80
|
+
pass
|
|
81
|
+
else:
|
|
82
|
+
# Handle relative paths, which MUST be resolved against a workspace that supports file paths.
|
|
83
|
+
if not (workspace and hasattr(workspace, 'get_base_path') and callable(getattr(workspace, 'get_base_path'))):
|
|
84
|
+
raise ValueError(
|
|
85
|
+
f"A relative path '{file_path}' was provided, but the agent's workspace does not support "
|
|
86
|
+
"file system path resolution. Please provide an absolute path or configure a suitable workspace."
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
try:
|
|
90
|
+
base_path = os.path.abspath(workspace.get_base_path())
|
|
91
|
+
# Securely join the path and resolve it to a final absolute path
|
|
92
|
+
absolute_path = os.path.abspath(os.path.join(base_path, file_path))
|
|
93
|
+
|
|
94
|
+
# Security Check: Ensure the resolved path is still within the workspace directory.
|
|
95
|
+
if os.path.commonpath([base_path]) != os.path.commonpath([base_path, absolute_path]):
|
|
96
|
+
raise ValueError(f"Security error: Path '{file_path}' attempts to access files outside the agent's workspace.")
|
|
97
|
+
|
|
98
|
+
logger.debug(f"Path '{file_path}' is relative. Resolved against workspace to '{absolute_path}'.")
|
|
99
|
+
|
|
100
|
+
except ValueError as e:
|
|
101
|
+
# Re-raise security errors with more context.
|
|
102
|
+
logger.error(f"Tool '{self.get_name()}': Security error resolving relative path '{file_path}': {e}")
|
|
103
|
+
raise
|
|
104
|
+
|
|
105
|
+
try:
|
|
106
|
+
if not os.path.exists(absolute_path) or not os.path.isfile(absolute_path):
|
|
107
|
+
raise FileNotFoundError(f"The file '{file_path}' does not exist or is not a regular file at the resolved path '{absolute_path}'.")
|
|
108
|
+
|
|
109
|
+
logger.info(f"Tool '{self.get_name()}': Staging file '{absolute_path}' for next LLM turn.")
|
|
110
|
+
|
|
111
|
+
# The ContextFile constructor will automatically infer file_type from the path.
|
|
112
|
+
# This is the special object that the ToolResultEventHandler will look for.
|
|
113
|
+
return ContextFile(uri=absolute_path)
|
|
114
|
+
|
|
115
|
+
except (ValueError, FileNotFoundError) as e:
|
|
116
|
+
logger.error(f"Tool '{self.get_name()}': Error processing path '{file_path}': {e}")
|
|
117
|
+
raise
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import logging
|
|
3
3
|
from typing import Type, get_origin, get_args, Union, List, Dict
|
|
4
4
|
from pydantic import BaseModel
|
|
5
|
-
from autobyteus.
|
|
5
|
+
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
|
|
6
6
|
|
|
7
7
|
logger = logging.getLogger(__name__)
|
|
8
8
|
|
|
@@ -5,7 +5,7 @@ from typing import Dict, Any, List as TypingList, Type, TYPE_CHECKING, Optional,
|
|
|
5
5
|
|
|
6
6
|
from autobyteus.llm.providers import LLMProvider
|
|
7
7
|
from autobyteus.tools.tool_config import ToolConfig
|
|
8
|
-
from autobyteus.
|
|
8
|
+
from autobyteus.utils.parameter_schema import ParameterSchema
|
|
9
9
|
from autobyteus.tools.tool_origin import ToolOrigin
|
|
10
10
|
# Import default formatters directly to provide convenience methods
|
|
11
11
|
from autobyteus.tools.usage.formatters import (
|
autobyteus/tools/timer.py
CHANGED
|
@@ -2,7 +2,7 @@ import asyncio
|
|
|
2
2
|
from typing import Optional, TYPE_CHECKING, Any
|
|
3
3
|
from autobyteus.tools.base_tool import BaseTool
|
|
4
4
|
from autobyteus.tools.tool_config import ToolConfig
|
|
5
|
-
from autobyteus.
|
|
5
|
+
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
|
|
6
6
|
from autobyteus.tools.tool_category import ToolCategory
|
|
7
7
|
from autobyteus.events.event_emitter import EventEmitter
|
|
8
8
|
from autobyteus.events.event_types import EventType
|
autobyteus/tools/tool_meta.py
CHANGED
|
@@ -4,7 +4,7 @@ from abc import ABCMeta
|
|
|
4
4
|
from typing import Dict, Any
|
|
5
5
|
|
|
6
6
|
from autobyteus.tools.registry import default_tool_registry, ToolDefinition
|
|
7
|
-
from autobyteus.
|
|
7
|
+
from autobyteus.utils.parameter_schema import ParameterSchema
|
|
8
8
|
from autobyteus.tools.tool_origin import ToolOrigin
|
|
9
9
|
from autobyteus.tools.tool_category import ToolCategory
|
|
10
10
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import json
|
|
3
3
|
from typing import Dict, Any, TYPE_CHECKING, List, Optional, Union
|
|
4
4
|
|
|
5
|
-
from autobyteus.
|
|
5
|
+
from autobyteus.utils.parameter_schema import ParameterType, ParameterDefinition, ParameterSchema
|
|
6
6
|
from .base_formatter import BaseExampleFormatter
|
|
7
7
|
|
|
8
8
|
if TYPE_CHECKING:
|
|
@@ -3,7 +3,7 @@ import xml.sax.saxutils
|
|
|
3
3
|
import re
|
|
4
4
|
from typing import Any, TYPE_CHECKING, List, Optional
|
|
5
5
|
|
|
6
|
-
from autobyteus.
|
|
6
|
+
from autobyteus.utils.parameter_schema import ParameterType, ParameterDefinition, ParameterSchema
|
|
7
7
|
from .base_formatter import BaseExampleFormatter
|
|
8
8
|
|
|
9
9
|
if TYPE_CHECKING:
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# file: autobyteus/autobyteus/tools/usage/formatters/default_xml_schema_formatter.py
|
|
2
2
|
import xml.sax.saxutils
|
|
3
|
-
from typing import TYPE_CHECKING, List
|
|
3
|
+
from typing import TYPE_CHECKING, List, Dict
|
|
4
4
|
|
|
5
|
-
from autobyteus.
|
|
5
|
+
from autobyteus.utils.parameter_schema import ParameterType, ParameterDefinition, ParameterSchema
|
|
6
6
|
from .base_formatter import BaseSchemaFormatter
|
|
7
7
|
|
|
8
8
|
if TYPE_CHECKING:
|
|
@@ -30,6 +30,49 @@ class DefaultXmlSchemaFormatter(BaseSchemaFormatter):
|
|
|
30
30
|
xml_parts.append("</tool>")
|
|
31
31
|
return "\n".join(xml_parts)
|
|
32
32
|
|
|
33
|
+
def _json_schema_props_to_param_defs(self, schema_dict: Dict) -> List[ParameterDefinition]:
|
|
34
|
+
"""
|
|
35
|
+
Converts a JSON schema's 'properties' dictionary into a list of ParameterDefinition objects.
|
|
36
|
+
This is used to bridge raw JSON schemas with the internal formatting logic.
|
|
37
|
+
"""
|
|
38
|
+
param_defs = []
|
|
39
|
+
properties = schema_dict.get("properties", {})
|
|
40
|
+
required_fields = schema_dict.get("required", [])
|
|
41
|
+
|
|
42
|
+
for prop_name, prop_schema in properties.items():
|
|
43
|
+
if not isinstance(prop_schema, dict):
|
|
44
|
+
continue
|
|
45
|
+
|
|
46
|
+
param_type_str = prop_schema.get("type", "string").upper()
|
|
47
|
+
param_type = getattr(ParameterType, param_type_str, ParameterType.STRING)
|
|
48
|
+
|
|
49
|
+
# JSON Schema uses 'enum' key for enumerations
|
|
50
|
+
allowed_values = prop_schema.get("enum")
|
|
51
|
+
if param_type == ParameterType.STRING and allowed_values:
|
|
52
|
+
param_type = ParameterType.ENUM
|
|
53
|
+
|
|
54
|
+
object_schema = None
|
|
55
|
+
if param_type == ParameterType.OBJECT and "properties" in prop_schema:
|
|
56
|
+
# Recursively build a ParameterSchema for nested objects
|
|
57
|
+
nested_param_defs = self._json_schema_props_to_param_defs(prop_schema)
|
|
58
|
+
object_schema = ParameterSchema(parameters=nested_param_defs)
|
|
59
|
+
|
|
60
|
+
array_item_schema = None
|
|
61
|
+
if param_type == ParameterType.ARRAY and "items" in prop_schema:
|
|
62
|
+
# Pass the nested schema down; it will be handled by the next recursive call
|
|
63
|
+
array_item_schema = prop_schema["items"]
|
|
64
|
+
|
|
65
|
+
param_defs.append(ParameterDefinition(
|
|
66
|
+
name=prop_name,
|
|
67
|
+
param_type=param_type,
|
|
68
|
+
description=prop_schema.get("description", ""),
|
|
69
|
+
required=(prop_name in required_fields),
|
|
70
|
+
enum_values=allowed_values,
|
|
71
|
+
object_schema=object_schema,
|
|
72
|
+
array_item_schema=array_item_schema
|
|
73
|
+
))
|
|
74
|
+
return param_defs
|
|
75
|
+
|
|
33
76
|
def _format_params_recursively(self, params: List[ParameterDefinition], indent_level: int) -> List[str]:
|
|
34
77
|
"""Recursively formats parameter definitions into XML strings."""
|
|
35
78
|
xml_lines = []
|
|
@@ -61,13 +104,26 @@ class DefaultXmlSchemaFormatter(BaseSchemaFormatter):
|
|
|
61
104
|
elif is_array:
|
|
62
105
|
xml_lines.append(f'{indent}<arg {" ".join(attrs)}>')
|
|
63
106
|
if isinstance(param.array_item_schema, ParameterSchema):
|
|
64
|
-
# Array of objects
|
|
107
|
+
# Array of objects defined with our internal ParameterSchema
|
|
65
108
|
xml_lines.append(f'{indent} <items type="object">')
|
|
66
109
|
xml_lines.extend(self._format_params_recursively(param.array_item_schema.parameters, indent_level + 2))
|
|
67
110
|
xml_lines.append(f'{indent} </items>')
|
|
68
111
|
elif isinstance(param.array_item_schema, ParameterType):
|
|
69
112
|
# Array of primitives
|
|
70
113
|
xml_lines.append(f'{indent} <items type="{param.array_item_schema.value}" />')
|
|
114
|
+
elif isinstance(param.array_item_schema, dict):
|
|
115
|
+
# FIX: Handle array of objects defined with a raw JSON schema dict
|
|
116
|
+
item_schema_dict = param.array_item_schema
|
|
117
|
+
item_type = item_schema_dict.get("type", "string")
|
|
118
|
+
|
|
119
|
+
xml_lines.append(f'{indent} <items type="{item_type}">')
|
|
120
|
+
|
|
121
|
+
if item_type == "object":
|
|
122
|
+
# Convert the JSON schema properties to our internal ParameterDefinition list
|
|
123
|
+
param_defs = self._json_schema_props_to_param_defs(item_schema_dict)
|
|
124
|
+
xml_lines.extend(self._format_params_recursively(param_defs, indent_level + 2))
|
|
125
|
+
|
|
126
|
+
xml_lines.append(f'{indent} </items>')
|
|
71
127
|
xml_lines.append(f'{indent}</arg>')
|
|
72
128
|
else:
|
|
73
129
|
# This is a simple/primitive type or a generic array
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import json
|
|
3
3
|
from typing import Dict, Any, TYPE_CHECKING, Optional
|
|
4
4
|
|
|
5
|
-
from autobyteus.
|
|
5
|
+
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition
|
|
6
6
|
from .base_formatter import BaseExampleFormatter
|
|
7
7
|
from .default_json_example_formatter import DefaultJsonExampleFormatter # Import for reuse
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import json
|
|
3
3
|
from typing import Dict, Any, TYPE_CHECKING, Optional
|
|
4
4
|
|
|
5
|
-
from autobyteus.
|
|
5
|
+
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition
|
|
6
6
|
from .base_formatter import BaseExampleFormatter
|
|
7
7
|
# Import for reuse of the intelligent example generation logic
|
|
8
8
|
from .default_json_example_formatter import DefaultJsonExampleFormatter
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import json
|
|
3
3
|
from typing import Dict, Any, TYPE_CHECKING, Optional
|
|
4
4
|
|
|
5
|
-
from autobyteus.
|
|
5
|
+
from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition
|
|
6
6
|
from .base_formatter import BaseExampleFormatter
|
|
7
7
|
from .default_json_example_formatter import DefaultJsonExampleFormatter # Import for reuse
|
|
8
8
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: autobyteus
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.9
|
|
4
4
|
Summary: Multi-Agent framework
|
|
5
5
|
Home-page: https://github.com/AutoByteus/autobyteus
|
|
6
6
|
Author: Ryan Zheng
|
|
@@ -23,7 +23,7 @@ Requires-Dist: botocore
|
|
|
23
23
|
Requires-Dist: brui-core==1.0.9
|
|
24
24
|
Requires-Dist: certifi==2025.4.26
|
|
25
25
|
Requires-Dist: google-api-python-client
|
|
26
|
-
Requires-Dist: google-
|
|
26
|
+
Requires-Dist: google-genai==1.38.0
|
|
27
27
|
Requires-Dist: Jinja2
|
|
28
28
|
Requires-Dist: mcp[cli]
|
|
29
29
|
Requires-Dist: mistral_common
|