autobyteus 1.2.0__py3-none-any.whl → 1.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. autobyteus/agent/context/agent_runtime_state.py +4 -0
  2. autobyteus/agent/events/notifiers.py +5 -1
  3. autobyteus/agent/message/send_message_to.py +5 -4
  4. autobyteus/agent/streaming/agent_event_stream.py +5 -0
  5. autobyteus/agent/streaming/stream_event_payloads.py +25 -0
  6. autobyteus/agent/streaming/stream_events.py +13 -1
  7. autobyteus/agent_team/bootstrap_steps/task_notifier_initialization_step.py +4 -4
  8. autobyteus/agent_team/bootstrap_steps/team_context_initialization_step.py +12 -12
  9. autobyteus/agent_team/context/agent_team_runtime_state.py +2 -2
  10. autobyteus/agent_team/streaming/agent_team_event_notifier.py +4 -4
  11. autobyteus/agent_team/streaming/agent_team_stream_event_payloads.py +3 -3
  12. autobyteus/agent_team/streaming/agent_team_stream_events.py +8 -8
  13. autobyteus/agent_team/task_notification/activation_policy.py +1 -1
  14. autobyteus/agent_team/task_notification/system_event_driven_agent_task_notifier.py +22 -22
  15. autobyteus/agent_team/task_notification/task_notification_mode.py +1 -1
  16. autobyteus/cli/agent_team_tui/app.py +4 -4
  17. autobyteus/cli/agent_team_tui/state.py +8 -8
  18. autobyteus/cli/agent_team_tui/widgets/focus_pane.py +3 -3
  19. autobyteus/cli/agent_team_tui/widgets/shared.py +1 -1
  20. autobyteus/cli/agent_team_tui/widgets/{task_board_panel.py → task_plan_panel.py} +5 -5
  21. autobyteus/events/event_types.py +4 -3
  22. autobyteus/multimedia/audio/api/__init__.py +3 -2
  23. autobyteus/multimedia/audio/api/openai_audio_client.py +112 -0
  24. autobyteus/multimedia/audio/audio_client_factory.py +37 -0
  25. autobyteus/multimedia/image/image_client_factory.py +1 -1
  26. autobyteus/task_management/__init__.py +43 -20
  27. autobyteus/task_management/{base_task_board.py → base_task_plan.py} +16 -13
  28. autobyteus/task_management/converters/__init__.py +2 -2
  29. autobyteus/task_management/converters/{task_board_converter.py → task_plan_converter.py} +13 -13
  30. autobyteus/task_management/events.py +7 -7
  31. autobyteus/task_management/{in_memory_task_board.py → in_memory_task_plan.py} +34 -22
  32. autobyteus/task_management/schemas/__init__.py +3 -0
  33. autobyteus/task_management/schemas/task_status_report.py +2 -2
  34. autobyteus/task_management/schemas/todo_definition.py +15 -0
  35. autobyteus/task_management/todo.py +29 -0
  36. autobyteus/task_management/todo_list.py +75 -0
  37. autobyteus/task_management/tools/__init__.py +24 -8
  38. autobyteus/task_management/tools/task_tools/__init__.py +19 -0
  39. autobyteus/task_management/tools/{assign_task_to.py → task_tools/assign_task_to.py} +18 -18
  40. autobyteus/task_management/tools/{publish_task.py → task_tools/create_task.py} +16 -18
  41. autobyteus/task_management/tools/{publish_tasks.py → task_tools/create_tasks.py} +19 -19
  42. autobyteus/task_management/tools/{get_my_tasks.py → task_tools/get_my_tasks.py} +15 -15
  43. autobyteus/task_management/tools/{get_task_board_status.py → task_tools/get_task_plan_status.py} +16 -16
  44. autobyteus/task_management/tools/{update_task_status.py → task_tools/update_task_status.py} +16 -16
  45. autobyteus/task_management/tools/todo_tools/__init__.py +18 -0
  46. autobyteus/task_management/tools/todo_tools/add_todo.py +78 -0
  47. autobyteus/task_management/tools/todo_tools/create_todo_list.py +79 -0
  48. autobyteus/task_management/tools/todo_tools/get_todo_list.py +55 -0
  49. autobyteus/task_management/tools/todo_tools/update_todo_status.py +85 -0
  50. autobyteus/tools/__init__.py +15 -11
  51. autobyteus/tools/bash/bash_executor.py +3 -3
  52. autobyteus/tools/browser/session_aware/browser_session_aware_navigate_to.py +5 -5
  53. autobyteus/tools/browser/session_aware/browser_session_aware_web_element_trigger.py +4 -4
  54. autobyteus/tools/browser/session_aware/browser_session_aware_webpage_reader.py +3 -3
  55. autobyteus/tools/browser/session_aware/browser_session_aware_webpage_screenshot_taker.py +3 -3
  56. autobyteus/tools/browser/standalone/navigate_to.py +13 -9
  57. autobyteus/tools/browser/standalone/web_page_pdf_generator.py +9 -5
  58. autobyteus/tools/browser/standalone/webpage_image_downloader.py +10 -6
  59. autobyteus/tools/browser/standalone/webpage_reader.py +13 -9
  60. autobyteus/tools/browser/standalone/webpage_screenshot_taker.py +9 -5
  61. autobyteus/tools/file/__init__.py +13 -0
  62. autobyteus/tools/file/{file_editor.py → edit_file.py} +11 -11
  63. autobyteus/tools/file/list_directory.py +168 -0
  64. autobyteus/tools/file/{file_reader.py → read_file.py} +3 -3
  65. autobyteus/tools/file/search_files.py +188 -0
  66. autobyteus/tools/file/{file_writer.py → write_file.py} +3 -3
  67. autobyteus/tools/functional_tool.py +10 -8
  68. autobyteus/tools/mcp/tool.py +3 -3
  69. autobyteus/tools/mcp/tool_registrar.py +5 -2
  70. autobyteus/tools/multimedia/__init__.py +2 -1
  71. autobyteus/tools/multimedia/audio_tools.py +2 -2
  72. autobyteus/tools/{download_media_tool.py → multimedia/download_media_tool.py} +3 -3
  73. autobyteus/tools/multimedia/image_tools.py +4 -4
  74. autobyteus/tools/multimedia/media_reader_tool.py +1 -1
  75. autobyteus/tools/registry/tool_definition.py +66 -13
  76. autobyteus/tools/registry/tool_registry.py +29 -0
  77. autobyteus/tools/search/__init__.py +17 -0
  78. autobyteus/tools/search/base_strategy.py +35 -0
  79. autobyteus/tools/search/client.py +24 -0
  80. autobyteus/tools/search/factory.py +81 -0
  81. autobyteus/tools/search/google_cse_strategy.py +68 -0
  82. autobyteus/tools/search/providers.py +10 -0
  83. autobyteus/tools/search/serpapi_strategy.py +65 -0
  84. autobyteus/tools/search/serper_strategy.py +87 -0
  85. autobyteus/tools/search_tool.py +83 -0
  86. autobyteus/tools/timer.py +4 -0
  87. autobyteus/tools/tool_meta.py +4 -24
  88. autobyteus/workflow/bootstrap_steps/coordinator_prompt_preparation_step.py +1 -2
  89. {autobyteus-1.2.0.dist-info → autobyteus-1.2.1.dist-info}/METADATA +5 -5
  90. {autobyteus-1.2.0.dist-info → autobyteus-1.2.1.dist-info}/RECORD +95 -80
  91. examples/run_agentic_software_engineer.py +239 -0
  92. examples/run_poem_writer.py +3 -3
  93. autobyteus/person/__init__.py +0 -0
  94. autobyteus/person/examples/__init__.py +0 -0
  95. autobyteus/person/examples/sample_persons.py +0 -14
  96. autobyteus/person/examples/sample_roles.py +0 -14
  97. autobyteus/person/person.py +0 -29
  98. autobyteus/person/role.py +0 -14
  99. autobyteus/tools/google_search.py +0 -149
  100. {autobyteus-1.2.0.dist-info → autobyteus-1.2.1.dist-info}/WHEEL +0 -0
  101. {autobyteus-1.2.0.dist-info → autobyteus-1.2.1.dist-info}/licenses/LICENSE +0 -0
  102. {autobyteus-1.2.0.dist-info → autobyteus-1.2.1.dist-info}/top_level.txt +0 -0
@@ -7,7 +7,7 @@ from autobyteus.tools.base_tool import BaseTool
7
7
  from autobyteus.tools.tool_category import ToolCategory
8
8
  from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
9
9
  from autobyteus.tools.pydantic_schema_converter import pydantic_to_parameter_schema
10
- from autobyteus.task_management.base_task_board import TaskStatus
10
+ from autobyteus.task_management.base_task_plan import TaskStatus
11
11
  from autobyteus.task_management.deliverable import FileDeliverable
12
12
  from autobyteus.task_management.schemas import FileDeliverableSchema
13
13
 
@@ -18,18 +18,18 @@ if TYPE_CHECKING:
18
18
  logger = logging.getLogger(__name__)
19
19
 
20
20
  class UpdateTaskStatus(BaseTool):
21
- """A tool for member agents to update their progress and submit file deliverables on the TaskBoard."""
21
+ """A tool for member agents to update their progress and submit file deliverables on the TaskPlan."""
22
22
 
23
23
  CATEGORY = ToolCategory.TASK_MANAGEMENT
24
24
 
25
25
  @classmethod
26
26
  def get_name(cls) -> str:
27
- return "UpdateTaskStatus"
27
+ return "update_task_status"
28
28
 
29
29
  @classmethod
30
30
  def get_description(cls) -> str:
31
31
  return (
32
- "Updates the status of a specific task on the team's shared task board. "
32
+ "Updates the status of a specific task on the team's shared task plan. "
33
33
  "When completing a task, this tool can also be used to formally submit a list of file deliverables."
34
34
  )
35
35
 
@@ -60,29 +60,29 @@ class UpdateTaskStatus(BaseTool):
60
60
 
61
61
  async def _execute(self, context: 'AgentContext', task_name: str, status: str, deliverables: Optional[List[Dict[str, Any]]] = None) -> str:
62
62
  agent_name = context.config.name
63
- log_msg = f"Agent '{agent_name}' is executing UpdateTaskStatus for task '{task_name}' to status '{status}'"
63
+ log_msg = f"Agent '{agent_name}' is executing update_task_status for task '{task_name}' to status '{status}'"
64
64
  if deliverables:
65
65
  log_msg += f" with {len(deliverables)} deliverable(s)."
66
66
  logger.info(log_msg)
67
67
 
68
68
  team_context: Optional['AgentTeamContext'] = context.custom_data.get("team_context")
69
69
  if not team_context:
70
- error_msg = "Error: Team context is not available. Cannot access the task board."
70
+ error_msg = "Error: Team context is not available. Cannot access the task plan."
71
71
  logger.error(f"Agent '{agent_name}': {error_msg}")
72
72
  return error_msg
73
73
 
74
- task_board = getattr(team_context.state, 'task_board', None)
75
- if not task_board:
76
- error_msg = "Error: Task board has not been initialized for this team."
74
+ task_plan = getattr(team_context.state, 'task_plan', None)
75
+ if not task_plan:
76
+ error_msg = "Error: Task plan has not been initialized for this team."
77
77
  logger.error(f"Agent '{agent_name}': {error_msg}")
78
78
  return error_msg
79
79
 
80
- if not task_board.tasks:
81
- error_msg = "Error: No tasks are currently loaded on the task board."
82
- logger.warning(f"Agent '{agent_name}' tried to update task status, but the board is empty.")
80
+ if not task_plan.tasks:
81
+ error_msg = "Error: No tasks are currently loaded on the task plan."
82
+ logger.warning(f"Agent '{agent_name}' tried to update task status, but the plan is empty.")
83
83
  return error_msg
84
84
 
85
- target_task = next((t for t in task_board.tasks if t.task_name == task_name), None)
85
+ target_task = next((t for t in task_plan.tasks if t.task_name == task_name), None)
86
86
 
87
87
  if not target_task:
88
88
  error_msg = f"Failed to update status for task '{task_name}'. The task name does not exist on the current plan."
@@ -93,7 +93,7 @@ class UpdateTaskStatus(BaseTool):
93
93
  status_enum = TaskStatus(status)
94
94
  except ValueError:
95
95
  error_msg = f"Invalid status '{status}'. Must be one of: {', '.join([s.value for s in TaskStatus])}."
96
- logger.warning(f"Agent '{agent_name}' provided invalid status for UpdateTaskStatus: {status}")
96
+ logger.warning(f"Agent '{agent_name}' provided invalid status for update_task_status: {status}")
97
97
  return f"Error: {error_msg}"
98
98
 
99
99
  if deliverables:
@@ -108,8 +108,8 @@ class UpdateTaskStatus(BaseTool):
108
108
  logger.warning(f"Agent '{agent_name}': {error_msg}")
109
109
  return f"Error: {error_msg}"
110
110
 
111
- if not task_board.update_task_status(target_task.task_id, status_enum, agent_name):
112
- error_msg = f"Failed to update status for task '{task_name}'. An unexpected error occurred on the task board."
111
+ if not task_plan.update_task_status(target_task.task_id, status_enum, agent_name):
112
+ error_msg = f"Failed to update status for task '{task_name}'. An unexpected error occurred on the task plan."
113
113
  logger.error(f"Agent '{agent_name}': {error_msg}")
114
114
  return f"Error: {error_msg}"
115
115
 
@@ -0,0 +1,18 @@
1
+ # file: autobyteus/task_management/tools/todo_tools/__init__.py
2
+ """
3
+ To-do management tool package containing list creation and update utilities.
4
+ """
5
+ from .create_todo_list import CreateToDoList
6
+ from .add_todo import AddToDo
7
+ from .get_todo_list import GetToDoList
8
+ from .update_todo_status import UpdateToDoStatus
9
+
10
+ UpdateToDoStatusTool = UpdateToDoStatus
11
+
12
+ __all__ = [
13
+ "CreateToDoList",
14
+ "AddToDo",
15
+ "GetToDoList",
16
+ "UpdateToDoStatus",
17
+ "UpdateToDoStatusTool",
18
+ ]
@@ -0,0 +1,78 @@
1
+ # file: autobyteus/autobyteus/task_management/tools/todo_tools/add_todo.py
2
+ import logging
3
+ from typing import TYPE_CHECKING, Any
4
+
5
+ from pydantic import ValidationError
6
+
7
+ from autobyteus.tools.base_tool import BaseTool
8
+ from autobyteus.tools.tool_category import ToolCategory
9
+ from autobyteus.tools.pydantic_schema_converter import pydantic_to_parameter_schema
10
+ from autobyteus.task_management.schemas.todo_definition import ToDoDefinitionSchema
11
+ from autobyteus.task_management.todo_list import ToDoList
12
+
13
+ if TYPE_CHECKING:
14
+ from autobyteus.agent.context import AgentContext
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+ def _notify_todo_update(context: 'AgentContext'):
19
+ if context.phase_manager and context.phase_manager.notifier:
20
+ todo_list = context.state.todo_list
21
+ if todo_list:
22
+ todos_for_llm = [todo.model_dump(mode='json') for todo in todo_list.get_all_todos()]
23
+ context.phase_manager.notifier.notify_agent_data_todo_list_updated(todos_for_llm)
24
+ logger.debug(f"Agent '{context.agent_id}': Notified ToDo list update with {len(todos_for_llm)} items.")
25
+
26
+ class AddToDo(BaseTool):
27
+ """A tool for an agent to add a new item to its personal to-do list."""
28
+
29
+ CATEGORY = ToolCategory.TASK_MANAGEMENT
30
+
31
+ @classmethod
32
+ def get_name(cls) -> str:
33
+ return "add_todo"
34
+
35
+ @classmethod
36
+ def get_description(cls) -> str:
37
+ return (
38
+ "Adds a single new item to your personal to-do list. "
39
+ "Use this if you discover a new step is needed to complete your task."
40
+ )
41
+
42
+ @classmethod
43
+ def get_argument_schema(cls) -> Any:
44
+ return pydantic_to_parameter_schema(ToDoDefinitionSchema)
45
+
46
+ async def _execute(self, context: 'AgentContext', **kwargs: Any) -> str:
47
+ agent_id = context.agent_id
48
+ logger.info(f"Agent '{agent_id}' is executing add_todo.")
49
+
50
+ if context.state.todo_list is None:
51
+ # If no list exists, create one.
52
+ context.state.todo_list = ToDoList(agent_id=agent_id)
53
+ logger.info(f"Agent '{agent_id}': No existing to-do list found, created a new one.")
54
+
55
+ todo_list = context.state.todo_list
56
+
57
+ try:
58
+ todo_def_schema = ToDoDefinitionSchema(**kwargs)
59
+ except ValidationError as e:
60
+ error_msg = f"Invalid to-do item definition provided: {e}"
61
+ logger.warning(f"Agent '{agent_id}' provided an invalid definition for add_todo: {error_msg}")
62
+ return f"Error: {error_msg}"
63
+
64
+ # The add_todo method now takes the definition and returns the created ToDo object
65
+ new_todo = todo_list.add_todo(todo_def_schema)
66
+
67
+ if new_todo:
68
+ # Notify about the update
69
+ _notify_todo_update(context)
70
+
71
+ success_msg = f"Successfully added new item to your to-do list: '{new_todo.description}' (ID: {new_todo.todo_id})."
72
+ logger.info(f"Agent '{agent_id}': {success_msg}")
73
+ return success_msg
74
+ else:
75
+ # This path is unlikely given the refactoring but kept for robustness.
76
+ error_msg = "Failed to add item to the to-do list for an unknown reason."
77
+ logger.error(f"Agent '{agent_id}': {error_msg}")
78
+ return f"Error: {error_msg}"
@@ -0,0 +1,79 @@
1
+ # file: autobyteus/autobyteus/task_management/tools/todo_tools/create_todo_list.py
2
+ import json
3
+ import logging
4
+ from typing import TYPE_CHECKING, Any
5
+
6
+ from pydantic import ValidationError
7
+
8
+ from autobyteus.tools.base_tool import BaseTool
9
+ from autobyteus.tools.tool_category import ToolCategory
10
+ from autobyteus.tools.pydantic_schema_converter import pydantic_to_parameter_schema
11
+ from autobyteus.task_management.schemas.todo_definition import ToDosDefinitionSchema
12
+ from autobyteus.task_management.todo_list import ToDoList
13
+
14
+ if TYPE_CHECKING:
15
+ from autobyteus.agent.context import AgentContext
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+ def _notify_todo_update(context: 'AgentContext'):
20
+ if context.phase_manager and context.phase_manager.notifier:
21
+ todo_list = context.state.todo_list
22
+ if todo_list:
23
+ todos_for_llm = [todo.model_dump(mode='json') for todo in todo_list.get_all_todos()]
24
+ context.phase_manager.notifier.notify_agent_data_todo_list_updated(todos_for_llm)
25
+ logger.debug(f"Agent '{context.agent_id}': Notified ToDo list update with {len(todos_for_llm)} items.")
26
+
27
+ class CreateToDoList(BaseTool):
28
+ """A tool for an agent to create or overwrite its own personal to-do list."""
29
+
30
+ CATEGORY = ToolCategory.TASK_MANAGEMENT
31
+
32
+ @classmethod
33
+ def get_name(cls) -> str:
34
+ return "create_todo_list"
35
+
36
+ @classmethod
37
+ def get_description(cls) -> str:
38
+ return (
39
+ "Creates a new personal to-do list for you to manage your own sub-tasks. "
40
+ "This will overwrite any existing to-do list you have. Use this to break down a larger task into smaller steps. "
41
+ "Returns the full list of created to-do items with their new IDs."
42
+ )
43
+
44
+ @classmethod
45
+ def get_argument_schema(cls) -> Any:
46
+ return pydantic_to_parameter_schema(ToDosDefinitionSchema)
47
+
48
+ async def _execute(self, context: 'AgentContext', **kwargs: Any) -> str:
49
+ agent_id = context.agent_id
50
+ logger.info(f"Agent '{agent_id}' is executing create_todo_list.")
51
+
52
+ try:
53
+ todos_def_schema = ToDosDefinitionSchema(**kwargs)
54
+ except ValidationError as e:
55
+ error_msg = f"Invalid to-do list definition provided: {e}"
56
+ logger.warning(f"Agent '{agent_id}' provided an invalid definition for create_todo_list: {error_msg}")
57
+ return f"Error: {error_msg}"
58
+
59
+ # Create a new ToDoList, which overwrites any existing one.
60
+ todo_list = ToDoList(agent_id=agent_id)
61
+ # Add items from definitions; this now returns the created ToDo objects.
62
+ new_todos = todo_list.add_todos(todos_def_schema.todos)
63
+
64
+ # Set the new list on the agent's state.
65
+ context.state.todo_list = todo_list
66
+
67
+ # Notify any UI components about the update.
68
+ _notify_todo_update(context)
69
+
70
+ # Return the created list to the LLM so it knows the new IDs.
71
+ try:
72
+ todos_for_llm = [todo.model_dump(mode='json') for todo in new_todos]
73
+ logger.info(f"Agent '{agent_id}' successfully created a new to-do list with {len(new_todos)} items.")
74
+ return json.dumps(todos_for_llm, indent=2)
75
+ except Exception as e:
76
+ error_msg = f"An unexpected error occurred while formatting the new to-do list: {e}"
77
+ logger.error(f"Agent '{agent_id}': {error_msg}", exc_info=True)
78
+ # Fallback message
79
+ return f"Successfully created {len(new_todos)} to-do items, but failed to return them in the response."
@@ -0,0 +1,55 @@
1
+ # file: autobyteus/autobyteus/task_management/tools/todo_tools/get_todo_list.py
2
+ import logging
3
+ import json
4
+ from typing import TYPE_CHECKING, Any
5
+
6
+ from autobyteus.tools.base_tool import BaseTool
7
+ from autobyteus.tools.tool_category import ToolCategory
8
+
9
+ if TYPE_CHECKING:
10
+ from autobyteus.agent.context import AgentContext
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+ class GetToDoList(BaseTool):
15
+ """A tool for an agent to retrieve its own personal to-do list."""
16
+
17
+ CATEGORY = ToolCategory.TASK_MANAGEMENT
18
+
19
+ @classmethod
20
+ def get_name(cls) -> str:
21
+ return "get_todo_list"
22
+
23
+ @classmethod
24
+ def get_description(cls) -> str:
25
+ return (
26
+ "Retrieves your current personal to-do list. "
27
+ "Use this to see your plan, check the status of your steps, and decide what to do next."
28
+ )
29
+
30
+ @classmethod
31
+ def get_argument_schema(cls) -> Any:
32
+ return None
33
+
34
+ async def _execute(self, context: 'AgentContext') -> str:
35
+ agent_id = context.agent_id
36
+ logger.info(f"Agent '{agent_id}' is executing get_todo_list.")
37
+
38
+ if context.state.todo_list is None or not context.state.todo_list.get_all_todos():
39
+ return "Your to-do list is empty."
40
+
41
+ todo_list = context.state.todo_list
42
+
43
+ try:
44
+ # Convert the internal ToDo objects to a JSON-friendly list of dicts
45
+ todos_for_llm = [
46
+ todo.model_dump(mode='json') for todo in todo_list.get_all_todos()
47
+ ]
48
+
49
+ logger.info(f"Agent '{agent_id}' retrieved {len(todos_for_llm)} items from their to-do list.")
50
+ return json.dumps(todos_for_llm, indent=2)
51
+
52
+ except Exception as e:
53
+ error_msg = f"An unexpected error occurred while formatting your to-do list: {e}"
54
+ logger.error(f"Agent '{agent_id}': {error_msg}", exc_info=True)
55
+ return f"Error: {error_msg}"
@@ -0,0 +1,85 @@
1
+ # file: autobyteus/autobyteus/task_management/tools/todo_tools/update_todo_status.py
2
+ import logging
3
+ from typing import TYPE_CHECKING, Any
4
+
5
+ from autobyteus.tools.base_tool import BaseTool
6
+ from autobyteus.tools.tool_category import ToolCategory
7
+ from autobyteus.utils.parameter_schema import ParameterSchema, ParameterDefinition, ParameterType
8
+ from autobyteus.task_management.todo import ToDoStatus
9
+
10
+ if TYPE_CHECKING:
11
+ from autobyteus.agent.context import AgentContext
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+ def _notify_todo_update(context: 'AgentContext'):
16
+ if context.phase_manager and context.phase_manager.notifier:
17
+ todo_list = context.state.todo_list
18
+ if todo_list:
19
+ todos_for_llm = [todo.model_dump(mode='json') for todo in todo_list.get_all_todos()]
20
+ context.phase_manager.notifier.notify_agent_data_todo_list_updated(todos_for_llm)
21
+ logger.debug(f"Agent '{context.agent_id}': Notified ToDo list update with {len(todos_for_llm)} items.")
22
+
23
+ class UpdateToDoStatus(BaseTool):
24
+ """A tool for an agent to update the status of an item on its personal to-do list."""
25
+
26
+ CATEGORY = ToolCategory.TASK_MANAGEMENT
27
+
28
+ @classmethod
29
+ def get_name(cls) -> str:
30
+ return "update_todo_status"
31
+
32
+ @classmethod
33
+ def get_description(cls) -> str:
34
+ return "Updates the status of a specific item on your personal to-do list."
35
+
36
+ @classmethod
37
+ def get_argument_schema(cls) -> Any:
38
+ schema = ParameterSchema()
39
+ schema.add_parameter(ParameterDefinition(
40
+ name="todo_id",
41
+ param_type=ParameterType.STRING,
42
+ description="The unique ID of the to-do item to update (e.g., 'todo_...').",
43
+ required=True
44
+ ))
45
+ schema.add_parameter(ParameterDefinition(
46
+ name="status",
47
+ param_type=ParameterType.ENUM,
48
+ description=f"The new status. Must be one of: {', '.join([s.value for s in ToDoStatus])}.",
49
+ required=True,
50
+ enum_values=[s.value for s in ToDoStatus]
51
+ ))
52
+ return schema
53
+
54
+ async def _execute(self, context: 'AgentContext', todo_id: str, status: str) -> str:
55
+ agent_id = context.agent_id
56
+ logger.info(f"Agent '{agent_id}' is executing update_todo_status for item '{todo_id}' to status '{status}'.")
57
+
58
+ if context.state.todo_list is None:
59
+ return "Error: You do not have a to-do list to update."
60
+
61
+ todo_list = context.state.todo_list
62
+
63
+ try:
64
+ status_enum = ToDoStatus(status)
65
+ except ValueError:
66
+ error_msg = f"Invalid status '{status}'. Must be one of: {', '.join([s.value for s in ToDoStatus])}."
67
+ logger.warning(f"Agent '{agent_id}' provided invalid status for update_todo_status: {status}")
68
+ return f"Error: {error_msg}"
69
+
70
+ if not todo_list.get_todo_by_id(todo_id):
71
+ error_msg = f"Failed to update status. A to-do item with ID '{todo_id}' does not exist on your list."
72
+ logger.warning(f"Agent '{agent_id}' failed to update status for non-existent to-do item '{todo_id}'.")
73
+ return f"Error: {error_msg}"
74
+
75
+ if todo_list.update_todo_status(todo_id, status_enum):
76
+ # Notify about the update
77
+ _notify_todo_update(context)
78
+
79
+ success_msg = f"Successfully updated status of to-do item '{todo_id}' to '{status}'."
80
+ logger.info(f"Agent '{agent_id}': {success_msg}")
81
+ return success_msg
82
+ else:
83
+ error_msg = f"Failed to update status for item '{todo_id}'. An unexpected error occurred."
84
+ logger.error(f"Agent '{agent_id}': {error_msg}")
85
+ return f"Error: {error_msg}"
@@ -21,16 +21,18 @@ logger = logging.getLogger(__name__)
21
21
 
22
22
  # Functional tools (decorated functions are now instances)
23
23
  from .bash.bash_executor import bash_executor
24
- from .file.file_reader import file_reader
25
- from .file.file_writer import file_writer
26
- from .file.file_editor import file_edit
24
+ from .file.read_file import read_file
25
+ from .file.write_file import write_file
26
+ from .file.edit_file import edit_file
27
+ from .file.search_files import search_files
28
+ from .file.list_directory import list_directory
27
29
 
28
30
  # General Class-based tools
29
31
  try:
30
- from .google_search import GoogleSearch
32
+ from .search_tool import Search
31
33
  except ModuleNotFoundError as import_err:
32
- logger.warning("GoogleSearch tool not available: %s", import_err)
33
- GoogleSearch = None
34
+ logger.warning("Search tool not available: %s", import_err)
35
+ Search = None
34
36
  from .timer import Timer
35
37
  try:
36
38
  from .multimedia.image_tools import GenerateImageTool, EditImageTool
@@ -44,7 +46,7 @@ except ModuleNotFoundError as import_err:
44
46
  logger.warning("Media reader tool not available: %s", import_err)
45
47
  ReadMediaFile = None
46
48
  try:
47
- from .download_media_tool import DownloadMediaTool
49
+ from autobyteus.multimedia.download_media_tool import DownloadMediaTool
48
50
  except ModuleNotFoundError as import_err:
49
51
  logger.warning("Download media tool not available: %s", import_err)
50
52
  DownloadMediaTool = None
@@ -91,12 +93,14 @@ __all__ = [
91
93
 
92
94
  # Re-exported functional tool instances
93
95
  "bash_executor",
94
- "file_reader",
95
- "file_writer",
96
- "file_edit",
96
+ "read_file",
97
+ "write_file",
98
+ "edit_file",
99
+ "search_files",
100
+ "list_directory",
97
101
 
98
102
  # Re-exported general class-based tools
99
- "GoogleSearch",
103
+ "Search",
100
104
  "Timer",
101
105
  "GenerateImageTool",
102
106
  "EditImageTool",
@@ -13,7 +13,7 @@ if TYPE_CHECKING:
13
13
 
14
14
  logger = logging.getLogger(__name__)
15
15
 
16
- @tool(name="BashExecutor", category=ToolCategory.SYSTEM)
16
+ @tool(name="execute_bash", category=ToolCategory.SYSTEM)
17
17
  async def bash_executor(context: Optional['AgentContext'], command: str) -> str:
18
18
  """
19
19
  Executes bash commands using the '/bin/bash' interpreter.
@@ -25,7 +25,7 @@ async def bash_executor(context: Optional['AgentContext'], command: str) -> str:
25
25
  The command is executed in the agent's workspace directory if available.
26
26
  """
27
27
  if not shutil.which("bash"):
28
- error_msg = "'bash' executable not found in system PATH. The BashExecutor tool cannot be used."
28
+ error_msg = "'bash' executable not found in system PATH. The execute_bash tool cannot be used."
29
29
  logger.error(error_msg)
30
30
  raise FileNotFoundError(error_msg)
31
31
 
@@ -51,7 +51,7 @@ async def bash_executor(context: Optional['AgentContext'], command: str) -> str:
51
51
  effective_cwd = tempfile.gettempdir()
52
52
  log_cwd_source = f"system temporary directory: {effective_cwd}"
53
53
 
54
- logger.debug(f"Functional BashExecutor tool executing for '{agent_id_str}': {command} in cwd from {log_cwd_source}")
54
+ logger.debug(f"Functional execute_bash tool executing for '{agent_id_str}': {command} in cwd from {log_cwd_source}")
55
55
 
56
56
  try:
57
57
  # Explicitly use 'bash -c' for reliable execution
@@ -21,11 +21,11 @@ class BrowserSessionAwareNavigateTo(BrowserSessionAwareTool):
21
21
 
22
22
  def __init__(self, config: Optional[ToolConfig] = None):
23
23
  super().__init__(config=config)
24
- logger.debug("BrowserSessionAwareNavigateTo tool initialized.")
24
+ logger.debug("navigate_to tool (session-aware) initialized.")
25
25
 
26
26
  @classmethod
27
27
  def get_name(cls) -> str:
28
- return "NavigateTo"
28
+ return "navigate_to"
29
29
 
30
30
  @classmethod
31
31
  def get_description(cls) -> str:
@@ -44,7 +44,7 @@ class BrowserSessionAwareNavigateTo(BrowserSessionAwareTool):
44
44
  return schema
45
45
 
46
46
  async def perform_action(self, shared_session: SharedBrowserSession, webpage_url: str) -> str:
47
- logger.info(f"BrowserSessionAwareNavigateTo performing action for URL: {webpage_url}")
47
+ logger.info(f"navigate_to (session-aware) performing action for URL: {webpage_url}")
48
48
 
49
49
  if not self._is_valid_url(webpage_url):
50
50
  raise ValueError(f"Invalid URL format: {webpage_url}. Must include scheme and netloc.")
@@ -53,12 +53,12 @@ class BrowserSessionAwareNavigateTo(BrowserSessionAwareTool):
53
53
  response = await shared_session.page.goto(webpage_url, wait_until="networkidle", timeout=60000)
54
54
 
55
55
  if response and response.ok:
56
- success_msg = f"The NavigateTo command to {webpage_url} is executed successfully."
56
+ success_msg = f"The navigate_to command to {webpage_url} is executed successfully."
57
57
  logger.info(success_msg)
58
58
  return success_msg
59
59
  else:
60
60
  status = response.status if response else "Unknown"
61
- failure_msg = f"The NavigationTo command to {webpage_url} failed with status {status}."
61
+ failure_msg = f"The navigate_to command to {webpage_url} failed with status {status}."
62
62
  logger.warning(failure_msg)
63
63
  return failure_msg
64
64
  except Exception as e:
@@ -24,11 +24,11 @@ class BrowserSessionAwareWebElementTrigger(BrowserSessionAwareTool):
24
24
 
25
25
  def __init__(self, config: Optional[ToolConfig] = None):
26
26
  super().__init__(config=config)
27
- logger.debug("BrowserSessionAwareWebElementTrigger tool initialized.")
27
+ logger.debug("trigger_web_element (session-aware) tool initialized.")
28
28
 
29
29
  @classmethod
30
30
  def get_name(cls) -> str:
31
- return "WebElementTrigger"
31
+ return "trigger_web_element"
32
32
 
33
33
  @classmethod
34
34
  def get_description(cls) -> str:
@@ -75,7 +75,7 @@ class BrowserSessionAwareWebElementTrigger(BrowserSessionAwareTool):
75
75
  webpage_url: str,
76
76
  params: Optional[str] = ""
77
77
  ) -> str:
78
- logger.info(f"WebElementTrigger performing action '{action}' on selector '{css_selector}' for page related to URL '{webpage_url}'. Params: '{params[:50]}...'")
78
+ logger.info(f"trigger_web_element performing action '{action}' on selector '{css_selector}' for page related to URL '{webpage_url}'. Params: '{params[:50]}...'")
79
79
 
80
80
  try:
81
81
  action_enum = WebElementAction.from_string(action)
@@ -124,7 +124,7 @@ class BrowserSessionAwareWebElementTrigger(BrowserSessionAwareTool):
124
124
  else:
125
125
  raise ValueError(f"Unsupported action: {action_enum}")
126
126
 
127
- success_msg = f"The WebElementTrigger action '{action_enum}' on selector '{css_selector}' was executed."
127
+ success_msg = f"The trigger_web_element action '{action_enum}' on selector '{css_selector}' was executed."
128
128
  logger.info(success_msg)
129
129
  return success_msg
130
130
 
@@ -37,11 +37,11 @@ class BrowserSessionAwareWebPageReader(BrowserSessionAwareTool):
37
37
  cleaning_mode_to_use = cleaning_mode_value
38
38
 
39
39
  self.cleaning_mode = cleaning_mode_to_use
40
- logger.debug(f"BrowserSessionAwareWebPageReader initialized with cleaning_mode: {self.cleaning_mode}")
40
+ logger.debug(f"read_webpage (session-aware) tool initialized with cleaning_mode: {self.cleaning_mode}")
41
41
 
42
42
  @classmethod
43
43
  def get_name(cls) -> str:
44
- return "WebPageReader"
44
+ return "read_webpage"
45
45
 
46
46
  @classmethod
47
47
  def get_description(cls) -> str:
@@ -77,7 +77,7 @@ class BrowserSessionAwareWebPageReader(BrowserSessionAwareTool):
77
77
  shared_session: SharedBrowserSession,
78
78
  webpage_url: str
79
79
  ) -> str:
80
- logger.info(f"BrowserSessionAwareWebPageReader performing action. Current page URL: {shared_session.page.url}, cleaning_mode: {self.cleaning_mode}")
80
+ logger.info(f"read_webpage (session-aware) performing action. Current page URL: {shared_session.page.url}, cleaning_mode: {self.cleaning_mode}")
81
81
 
82
82
  try:
83
83
  page_content = await shared_session.page.content()
@@ -32,11 +32,11 @@ class BrowserSessionAwareWebPageScreenshotTaker(BrowserSessionAwareTool):
32
32
  if self.image_format not in ["png", "jpeg"]:
33
33
  logger.warning(f"Invalid image_format '{self.image_format}' in config. Defaulting to 'png'.")
34
34
  self.image_format = "png"
35
- logger.debug(f"BrowserSessionAwareWebPageScreenshotTaker initialized. Full page: {self.full_page}, Format: {self.image_format}")
35
+ logger.debug(f"take_webpage_screenshot (session-aware) initialized. Full page: {self.full_page}, Format: {self.image_format}")
36
36
 
37
37
  @classmethod
38
38
  def get_name(cls) -> str:
39
- return "WebPageScreenshotTaker"
39
+ return "take_webpage_screenshot"
40
40
 
41
41
  @classmethod
42
42
  def get_description(cls) -> str:
@@ -87,7 +87,7 @@ class BrowserSessionAwareWebPageScreenshotTaker(BrowserSessionAwareTool):
87
87
  file_name: str,
88
88
  webpage_url: str
89
89
  ) -> str:
90
- logger.info(f"BrowserSessionAwareWebPageScreenshotTaker performing action. Saving to '{file_name}'. Current page: {shared_session.page.url}")
90
+ logger.info(f"take_webpage_screenshot (session-aware) performing action. Saving to '{file_name}'. Current page: {shared_session.page.url}")
91
91
 
92
92
  output_dir = os.path.dirname(file_name)
93
93
  if output_dir: