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
@@ -35,6 +35,7 @@ class EventType(Enum):
35
35
  AGENT_DATA_TOOL_LOG = "agent_data_tool_log"
36
36
  AGENT_DATA_TOOL_LOG_STREAM_END = "agent_data_tool_log_stream_end"
37
37
  AGENT_DATA_SYSTEM_TASK_NOTIFICATION_RECEIVED = "agent_data_system_task_notification_received" # NEW
38
+ AGENT_DATA_TODO_LIST_UPDATED = "agent_data_todo_list_updated"
38
39
 
39
40
  # --- Agent Requests for External Interaction ---
40
41
  AGENT_REQUEST_TOOL_INVOCATION_APPROVAL = "agent_request_tool_invocation_approval"
@@ -46,9 +47,9 @@ class EventType(Enum):
46
47
  # --- Agent Team Events ---
47
48
  TEAM_STREAM_EVENT = "team_stream_event" # For unified agent team event stream
48
49
 
49
- # --- Task Board Events ---
50
- TASK_BOARD_TASKS_ADDED = "task_board.tasks.added"
51
- TASK_BOARD_STATUS_UPDATED = "task_board.status.updated"
50
+ # --- Task Plan Events ---
51
+ TASK_PLAN_TASKS_CREATED = "task_plan.tasks.created"
52
+ TASK_PLAN_STATUS_UPDATED = "task_plan.status.updated"
52
53
 
53
54
  def __str__(self):
54
55
  return self.value
@@ -1,4 +1,5 @@
1
- from .gemini_audio_client import GeminiAudioClient
2
1
  from .autobyteus_audio_client import AutobyteusAudioClient
2
+ from .gemini_audio_client import GeminiAudioClient
3
+ from .openai_audio_client import OpenAIAudioClient
3
4
 
4
- __all__ = ["GeminiAudioClient", "AutobyteusAudioClient"]
5
+ __all__ = ["AutobyteusAudioClient", "GeminiAudioClient", "OpenAIAudioClient"]
@@ -0,0 +1,112 @@
1
+ import asyncio
2
+ import logging
3
+ import os
4
+ import uuid
5
+ from pathlib import Path
6
+ from typing import Optional, Dict, Any, TYPE_CHECKING
7
+
8
+ from openai import OpenAI
9
+
10
+ from autobyteus.multimedia.audio.base_audio_client import BaseAudioClient
11
+ from autobyteus.multimedia.utils.response_types import SpeechGenerationResponse
12
+
13
+ if TYPE_CHECKING:
14
+ from autobyteus.multimedia.audio.audio_model import AudioModel
15
+ from autobyteus.multimedia.utils.multimedia_config import MultimediaConfig
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+ _AUDIO_TEMP_DIR = Path("/tmp/autobyteus_audio")
20
+
21
+
22
+ def _save_audio_bytes(audio_bytes: bytes, file_extension: Optional[str]) -> str:
23
+ """Saves audio bytes to disk with a random file name."""
24
+ _AUDIO_TEMP_DIR.mkdir(parents=True, exist_ok=True)
25
+ suffix = (file_extension or "mp3").lstrip(".")
26
+ file_path = _AUDIO_TEMP_DIR / f"{uuid.uuid4()}.{suffix}"
27
+ file_path.write_bytes(audio_bytes)
28
+ logger.info(f"Successfully saved generated audio to {file_path}")
29
+ return str(file_path)
30
+
31
+
32
+ class OpenAIAudioClient(BaseAudioClient):
33
+ """
34
+ An audio client that uses OpenAI's Text-to-Speech (Speech) API.
35
+
36
+ **Setup Requirements:**
37
+ 1. Set the `OPENAI_API_KEY` environment variable with your OpenAI API key.
38
+ """
39
+
40
+ def __init__(self, model: "AudioModel", config: "MultimediaConfig"):
41
+ super().__init__(model, config)
42
+ api_key = os.getenv("OPENAI_API_KEY")
43
+ if not api_key:
44
+ logger.error("OPENAI_API_KEY environment variable is not set.")
45
+ raise ValueError("OPENAI_API_KEY environment variable is not set.")
46
+
47
+ try:
48
+ self.client = OpenAI(api_key=api_key, base_url="https://api.openai.com/v1")
49
+ logger.info(f"OpenAIAudioClient initialized for model '{self.model.name}'.")
50
+ except Exception as exc:
51
+ logger.error(f"Failed to configure OpenAI client: {exc}")
52
+ raise RuntimeError(f"Failed to configure OpenAI client: {exc}") from exc
53
+
54
+ async def generate_speech(
55
+ self,
56
+ prompt: str,
57
+ generation_config: Optional[Dict[str, Any]] = None,
58
+ **kwargs
59
+ ) -> SpeechGenerationResponse:
60
+ """
61
+ Generates speech using OpenAI's Speech endpoint and returns a local file path.
62
+ """
63
+ try:
64
+ final_config = self.config.to_dict().copy()
65
+ if generation_config:
66
+ final_config.update(generation_config)
67
+
68
+ voice = final_config.get("voice", "alloy")
69
+ response_format = (
70
+ final_config.get("response_format")
71
+ or final_config.get("format")
72
+ or "mp3"
73
+ )
74
+ instructions = final_config.get("instructions")
75
+
76
+ logger.info(
77
+ "Generating speech with OpenAI TTS model '%s' using voice '%s' and format '%s'.",
78
+ self.model.value,
79
+ voice,
80
+ response_format,
81
+ )
82
+
83
+ request_kwargs = {
84
+ "model": self.model.value,
85
+ "voice": voice,
86
+ "input": prompt,
87
+ }
88
+
89
+ if instructions:
90
+ request_kwargs["instructions"] = instructions
91
+
92
+ if response_format:
93
+ request_kwargs["response_format"] = response_format
94
+
95
+ response = await asyncio.to_thread(
96
+ self.client.audio.speech.create,
97
+ **request_kwargs,
98
+ )
99
+
100
+ audio_bytes = getattr(response, "content", None)
101
+ if not audio_bytes:
102
+ raise ValueError("OpenAI Speech API returned an empty response.")
103
+
104
+ audio_path = _save_audio_bytes(audio_bytes, response_format)
105
+ return SpeechGenerationResponse(audio_urls=[audio_path])
106
+
107
+ except Exception as exc:
108
+ logger.error("Error during OpenAI speech generation: %s", exc)
109
+ raise ValueError(f"OpenAI speech generation failed: {exc}") from exc
110
+
111
+ async def cleanup(self):
112
+ logger.debug("OpenAIAudioClient cleanup called.")
@@ -5,6 +5,7 @@ from autobyteus.multimedia.audio.base_audio_client import BaseAudioClient
5
5
  from autobyteus.multimedia.audio.audio_model import AudioModel
6
6
  from autobyteus.multimedia.providers import MultimediaProvider
7
7
  from autobyteus.multimedia.audio.api.gemini_audio_client import GeminiAudioClient
8
+ from autobyteus.multimedia.audio.api.openai_audio_client import OpenAIAudioClient
8
9
  from autobyteus.multimedia.audio.autobyteus_audio_provider import AutobyteusAudioModelProvider
9
10
  from autobyteus.multimedia.utils.multimedia_config import MultimediaConfig
10
11
  from autobyteus.utils.singleton import SingletonMeta
@@ -20,6 +21,11 @@ GEMINI_TTS_VOICES = [
20
21
  "Vindemiatrix", "Sadachbia", "Sadaltager", "Sulafat"
21
22
  ]
22
23
 
24
+ OPENAI_TTS_VOICES = [
25
+ "alloy", "ash", "ballad", "coral", "echo", "fable", "onyx",
26
+ "nova", "sage", "shimmer", "verse"
27
+ ]
28
+
23
29
  class AudioClientFactory(metaclass=SingletonMeta):
24
30
  """
25
31
  A factory for creating instances of audio clients based on registered AudioModels.
@@ -101,7 +107,38 @@ class AudioClientFactory(metaclass=SingletonMeta):
101
107
  parameter_schema=gemini_tts_schema
102
108
  )
103
109
 
110
+ openai_tts_schema = ParameterSchema(parameters=[
111
+ ParameterDefinition(
112
+ name="voice",
113
+ param_type=ParameterType.ENUM,
114
+ default_value="alloy",
115
+ enum_values=OPENAI_TTS_VOICES,
116
+ description="The OpenAI TTS voice to use for generation."
117
+ ),
118
+ ParameterDefinition(
119
+ name="format",
120
+ param_type=ParameterType.ENUM,
121
+ default_value="mp3",
122
+ enum_values=["mp3", "wav"],
123
+ description="The audio format to generate."
124
+ ),
125
+ ParameterDefinition(
126
+ name="instructions",
127
+ param_type=ParameterType.STRING,
128
+ description="Optional delivery instructions (tone, pacing, accent, etc.)."
129
+ )
130
+ ])
131
+
132
+ openai_tts_model = AudioModel(
133
+ name="gpt-4o-mini-tts",
134
+ value="gpt-4o-mini-tts",
135
+ provider=MultimediaProvider.OPENAI,
136
+ client_class=OpenAIAudioClient,
137
+ parameter_schema=openai_tts_schema
138
+ )
139
+
104
140
  models_to_register = [
141
+ openai_tts_model,
105
142
  gemini_tts_model,
106
143
  ]
107
144
 
@@ -49,7 +49,7 @@ class ImageClientFactory(metaclass=SingletonMeta):
49
49
 
50
50
  gpt_image_1_model = ImageModel(
51
51
  name="gpt-image-1",
52
- value="dall-e-3",
52
+ value="gpt-image-1",
53
53
  provider=MultimediaProvider.OPENAI,
54
54
  client_class=OpenAIImageClient,
55
55
  parameter_schema=gpt_image_1_schema
@@ -1,23 +1,36 @@
1
1
  # file: autobyteus/autobyteus/task_management/__init__.py
2
2
  """
3
3
  This package defines components for task management and state tracking,
4
- including task plans and live task boards. It is designed to be a general-purpose
5
- module usable by various components, such as agents or agent teams.
4
+ including task plans and live plan execution tracking. It is designed to be a
5
+ general-purpose module usable by various components, such as agents or agent teams.
6
6
  """
7
7
  from .task import Task
8
8
  from .schemas import (TasksDefinitionSchema, TaskDefinitionSchema, TaskStatusReportSchema,
9
- TaskStatusReportItemSchema, FileDeliverableSchema)
10
- from .base_task_board import BaseTaskBoard, TaskStatus
11
- from .in_memory_task_board import InMemoryTaskBoard
9
+ TaskStatusReportItemSchema, FileDeliverableSchema, ToDoDefinitionSchema, ToDosDefinitionSchema)
10
+ from .base_task_plan import BaseTaskPlan, TaskStatus
11
+ from .in_memory_task_plan import InMemoryTaskPlan
12
12
  from .deliverable import FileDeliverable
13
- from .tools import GetTaskBoardStatus, PublishTasks, PublishTask, UpdateTaskStatus, AssignTaskTo
14
- from .converters import TaskBoardConverter
15
- from .events import BaseTaskBoardEvent, TasksAddedEvent, TaskStatusUpdatedEvent
13
+ from .tools import (
14
+ GetTaskPlanStatus,
15
+ CreateTasks,
16
+ CreateTask,
17
+ UpdateTaskStatus,
18
+ AssignTaskTo,
19
+ GetMyTasks,
20
+ CreateToDoList,
21
+ AddToDo,
22
+ GetToDoList,
23
+ UpdateToDoStatus as UpdateToDoStatusTool,
24
+ )
25
+ from .converters import TaskPlanConverter
26
+ from .events import BaseTaskPlanEvent, TasksCreatedEvent, TaskStatusUpdatedEvent
27
+ from .todo import ToDo, ToDoStatus
28
+ from .todo_list import ToDoList
16
29
 
17
- # For convenience, we can alias InMemoryTaskBoard as the default TaskBoard.
18
- # This allows other parts of the code to import `TaskBoard` without needing
30
+ # For convenience, we can alias InMemoryTaskPlan as the default TaskPlan.
31
+ # This allows other parts of the code to import `TaskPlan` without needing
19
32
  # to know the specific implementation being used by default.
20
- TaskBoard = InMemoryTaskBoard
33
+ TaskPlan = InMemoryTaskPlan
21
34
 
22
35
  __all__ = [
23
36
  "Task",
@@ -26,18 +39,28 @@ __all__ = [
26
39
  "TaskStatusReportSchema",
27
40
  "TaskStatusReportItemSchema",
28
41
  "FileDeliverableSchema",
29
- "BaseTaskBoard",
42
+ "ToDoDefinitionSchema",
43
+ "ToDosDefinitionSchema",
44
+ "BaseTaskPlan",
30
45
  "TaskStatus",
31
- "InMemoryTaskBoard",
32
- "TaskBoard", # Exposing the alias
46
+ "InMemoryTaskPlan",
47
+ "TaskPlan", # Exposing the alias
33
48
  "FileDeliverable",
34
- "GetTaskBoardStatus",
35
- "PublishTasks",
36
- "PublishTask",
49
+ "GetTaskPlanStatus",
50
+ "CreateTasks",
51
+ "CreateTask",
37
52
  "UpdateTaskStatus",
38
53
  "AssignTaskTo",
39
- "TaskBoardConverter",
40
- "BaseTaskBoardEvent",
41
- "TasksAddedEvent",
54
+ "GetMyTasks",
55
+ "CreateToDoList",
56
+ "AddToDo",
57
+ "GetToDoList",
58
+ "UpdateToDoStatusTool",
59
+ "TaskPlanConverter",
60
+ "BaseTaskPlanEvent",
61
+ "TasksCreatedEvent",
42
62
  "TaskStatusUpdatedEvent",
63
+ "ToDo",
64
+ "ToDoStatus",
65
+ "ToDoList",
43
66
  ]
@@ -1,19 +1,22 @@
1
- # file: autobyteus/autobyteus/task_management/base_task_board.py
1
+ # file: autobyteus/autobyteus/task_management/base_task_plan.py
2
2
  """
3
- Defines the abstract interface for a TaskBoard and its related enums.
3
+ Defines the abstract interface for a TaskPlan and its related enums.
4
4
  """
5
5
  import logging
6
6
  from abc import ABC, abstractmethod
7
7
  from enum import Enum
8
- from typing import Dict, Any, List, Optional
8
+ from typing import Dict, Any, List, Optional, TYPE_CHECKING
9
9
 
10
10
  from autobyteus.events.event_emitter import EventEmitter
11
11
  from .task import Task
12
12
 
13
+ if TYPE_CHECKING:
14
+ from autobyteus.task_management.schemas import TaskDefinitionSchema
15
+
13
16
  logger = logging.getLogger(__name__)
14
17
 
15
18
  class TaskStatus(str, Enum):
16
- """Enumerates the possible lifecycle states of a task on the TaskBoard."""
19
+ """Enumerates the possible lifecycle states of a task on the TaskPlan."""
17
20
  NOT_STARTED = "not_started"
18
21
  QUEUED = "queued"
19
22
  IN_PROGRESS = "in_progress"
@@ -25,12 +28,12 @@ class TaskStatus(str, Enum):
25
28
  """Returns True if the status is a final state."""
26
29
  return self in {TaskStatus.COMPLETED, TaskStatus.FAILED}
27
30
 
28
- class BaseTaskBoard(ABC, EventEmitter):
31
+ class BaseTaskPlan(ABC, EventEmitter):
29
32
  """
30
- Abstract base class for a TaskBoard.
33
+ Abstract base class for a TaskPlan.
31
34
 
32
35
  This class defines the contract for any component that manages the live state
33
- of tasks for a team. It is a dynamic board, not a static plan.
36
+ of tasks for a team. It is a dynamic plan, not a static document.
34
37
  It inherits from EventEmitter to broadcast state changes.
35
38
  """
36
39
 
@@ -38,19 +41,19 @@ class BaseTaskBoard(ABC, EventEmitter):
38
41
  EventEmitter.__init__(self)
39
42
  self.team_id = team_id
40
43
  self.tasks: List[Task] = []
41
- logger.debug(f"BaseTaskBoard initialized for team '{self.team_id}'.")
44
+ logger.debug(f"BaseTaskPlan initialized for team '{self.team_id}'.")
42
45
 
43
46
  @abstractmethod
44
- def add_tasks(self, tasks: List[Task]) -> bool:
47
+ def add_tasks(self, task_definitions: List['TaskDefinitionSchema']) -> List[Task]:
45
48
  """
46
- Adds a list of new tasks to the board. This is an additive-only operation.
49
+ Creates new tasks from definitions, adds them to the plan, and returns the created Task objects.
47
50
  """
48
51
  raise NotImplementedError
49
52
 
50
53
  @abstractmethod
51
- def add_task(self, task: Task) -> bool:
54
+ def add_task(self, task_definition: 'TaskDefinitionSchema') -> Optional[Task]:
52
55
  """
53
- Adds a single new task to the board.
56
+ Creates a single new task from a definition, adds it to the plan, and returns it.
54
57
  """
55
58
  raise NotImplementedError
56
59
 
@@ -64,7 +67,7 @@ class BaseTaskBoard(ABC, EventEmitter):
64
67
  @abstractmethod
65
68
  def get_status_overview(self) -> Dict[str, Any]:
66
69
  """
67
- Returns a serializable dictionary of the board's current state.
70
+ Returns a serializable dictionary of the plan's current state.
68
71
  """
69
72
  raise NotImplementedError
70
73
 
@@ -2,8 +2,8 @@
2
2
  """
3
3
  Exposes the public converters for the task management module.
4
4
  """
5
- from .task_board_converter import TaskBoardConverter
5
+ from .task_plan_converter import TaskPlanConverter
6
6
 
7
7
  __all__ = [
8
- "TaskBoardConverter",
8
+ "TaskPlanConverter",
9
9
  ]
@@ -1,4 +1,4 @@
1
- # file: autobyteus/autobyteus/task_management/converters/task_board_converter.py
1
+ # file: autobyteus/autobyteus/task_management/converters/task_plan_converter.py
2
2
  """
3
3
  Contains converters for translating internal task management objects into
4
4
  LLM-friendly Pydantic schemas.
@@ -6,35 +6,35 @@ LLM-friendly Pydantic schemas.
6
6
  import logging
7
7
  from typing import Optional
8
8
 
9
- from autobyteus.task_management.base_task_board import BaseTaskBoard
9
+ from autobyteus.task_management.base_task_plan import BaseTaskPlan
10
10
  from autobyteus.task_management.schemas import TaskStatusReportSchema, TaskStatusReportItemSchema
11
11
 
12
12
  logger = logging.getLogger(__name__)
13
13
 
14
- class TaskBoardConverter:
15
- """A converter to transform TaskBoard state into LLM-friendly schemas."""
14
+ class TaskPlanConverter:
15
+ """A converter to transform TaskPlan state into LLM-friendly schemas."""
16
16
 
17
17
  @staticmethod
18
- def to_schema(task_board: BaseTaskBoard) -> Optional[TaskStatusReportSchema]:
18
+ def to_schema(task_plan: BaseTaskPlan) -> Optional[TaskStatusReportSchema]:
19
19
  """
20
- Converts the current state of a TaskBoard into a TaskStatusReportSchema.
20
+ Converts the current state of a TaskPlan into a TaskStatusReportSchema.
21
21
 
22
22
  Args:
23
- task_board: The task board instance to convert.
23
+ task_plan: The task plan instance to convert.
24
24
 
25
25
  Returns:
26
26
  A TaskStatusReportSchema object if there are tasks, otherwise None.
27
27
  """
28
- if not task_board.tasks:
29
- logger.debug(f"TaskBoard for team '{task_board.team_id}' has no tasks. Cannot generate report.")
28
+ if not task_plan.tasks:
29
+ logger.debug(f"TaskPlan for team '{task_plan.team_id}' has no tasks. Cannot generate report.")
30
30
  return None
31
31
 
32
- internal_status = task_board.get_status_overview()
32
+ internal_status = task_plan.get_status_overview()
33
33
 
34
- id_to_name_map = {task.task_id: task.task_name for task in task_board.tasks}
34
+ id_to_name_map = {task.task_id: task.task_name for task in task_plan.tasks}
35
35
 
36
36
  report_items = []
37
- for task in task_board.tasks:
37
+ for task in task_plan.tasks:
38
38
  dep_names = [id_to_name_map.get(dep_id, str(dep_id)) for dep_id in task.dependencies]
39
39
 
40
40
  report_item = TaskStatusReportItemSchema(
@@ -51,5 +51,5 @@ class TaskBoardConverter:
51
51
  tasks=report_items
52
52
  )
53
53
 
54
- logger.debug(f"Successfully converted TaskBoard state to TaskStatusReportSchema for team '{task_board.team_id}'.")
54
+ logger.debug(f"Successfully converted TaskPlan state to TaskStatusReportSchema for team '{task_plan.team_id}'.")
55
55
  return status_report
@@ -1,25 +1,25 @@
1
1
  # file: autobyteus/autobyteus/task_management/events.py
2
2
  """
3
- Defines the Pydantic models for events emitted by a TaskBoard.
3
+ Defines the Pydantic models for events emitted by a TaskPlan.
4
4
  """
5
5
  from typing import List, Optional
6
6
  from pydantic import BaseModel
7
7
 
8
8
  from autobyteus.task_management.task import Task
9
- from autobyteus.task_management.base_task_board import TaskStatus
9
+ from autobyteus.task_management.base_task_plan import TaskStatus
10
10
  from .deliverable import FileDeliverable
11
11
 
12
- class BaseTaskBoardEvent(BaseModel):
13
- """Base class for all task board events."""
12
+ class BaseTaskPlanEvent(BaseModel):
13
+ """Base class for all task plan events."""
14
14
  team_id: str
15
15
 
16
- class TasksAddedEvent(BaseTaskBoardEvent):
16
+ class TasksCreatedEvent(BaseTaskPlanEvent):
17
17
  """
18
- Payload for when one or more tasks are added to the board.
18
+ Payload for when one or more tasks are created in the plan.
19
19
  """
20
20
  tasks: List[Task]
21
21
 
22
- class TaskStatusUpdatedEvent(BaseTaskBoardEvent):
22
+ class TaskStatusUpdatedEvent(BaseTaskPlanEvent):
23
23
  """Payload for when a task's status is updated."""
24
24
  task_id: str
25
25
  new_status: TaskStatus
@@ -1,6 +1,6 @@
1
- # file: autobyteus/autobyteus/task_management/in_memory_task_board.py
1
+ # file: autobyteus/autobyteus/task_management/in_memory_task_plan.py
2
2
  """
3
- An in-memory implementation of the BaseTaskBoard.
3
+ An in-memory implementation of the BaseTaskPlan.
4
4
  It tracks task statuses in a simple dictionary and emits events on state changes.
5
5
  """
6
6
  import logging
@@ -8,50 +8,62 @@ from typing import Optional, List, Dict, Any
8
8
  from enum import Enum
9
9
 
10
10
  from autobyteus.events.event_types import EventType
11
+ from .schemas import TaskDefinitionSchema
11
12
  from .task import Task
12
- from .base_task_board import BaseTaskBoard, TaskStatus
13
- from .events import TasksAddedEvent, TaskStatusUpdatedEvent
13
+ from .base_task_plan import BaseTaskPlan, TaskStatus
14
+ from .events import TasksCreatedEvent, TaskStatusUpdatedEvent
14
15
 
15
16
  logger = logging.getLogger(__name__)
16
17
 
17
- class InMemoryTaskBoard(BaseTaskBoard):
18
+ class InMemoryTaskPlan(BaseTaskPlan):
18
19
  """
19
- An in-memory, dictionary-based implementation of the TaskBoard that emits
20
+ An in-memory, dictionary-based implementation of the TaskPlan that emits
20
21
  events on state changes.
21
22
  """
22
23
  def __init__(self, team_id: str):
23
24
  """
24
- Initializes the InMemoryTaskBoard.
25
+ Initializes the InMemoryTaskPlan.
25
26
  """
26
27
  super().__init__(team_id=team_id)
27
28
  self.task_statuses: Dict[str, TaskStatus] = {}
28
29
  self._task_map: Dict[str, Task] = {}
29
- logger.info(f"InMemoryTaskBoard initialized for team '{self.team_id}'.")
30
+ self._id_counter: int = 0
31
+ logger.info(f"InMemoryTaskPlan initialized for team '{self.team_id}'.")
32
+
33
+ def _generate_next_id(self) -> str:
34
+ self._id_counter += 1
35
+ return f"task_{self._id_counter:04d}"
30
36
 
31
- def add_tasks(self, tasks: List[Task]) -> bool:
37
+ def add_tasks(self, task_definitions: List[TaskDefinitionSchema]) -> List[Task]:
32
38
  """
33
- Adds new tasks to the board. This is an additive-only operation.
39
+ Creates new tasks from definitions, adds them to the plan, and returns the created tasks.
34
40
  """
35
- for task in tasks:
41
+ new_tasks: List[Task] = []
42
+ for task_def in task_definitions:
43
+ new_id = self._generate_next_id()
44
+ task = Task(task_id=new_id, **task_def.model_dump())
45
+
36
46
  self.tasks.append(task)
37
47
  self.task_statuses[task.task_id] = TaskStatus.NOT_STARTED
38
48
  self._task_map[task.task_id] = task
49
+ new_tasks.append(task)
39
50
 
40
51
  self._hydrate_all_dependencies()
41
- logger.info(f"Team '{self.team_id}': Added {len(tasks)} new task(s) to the board. Emitting TasksAddedEvent.")
52
+ logger.info(f"Team '{self.team_id}': Added {len(new_tasks)} new task(s) to the plan. Emitting TasksCreatedEvent.")
42
53
 
43
- event_payload = TasksAddedEvent(
54
+ event_payload = TasksCreatedEvent(
44
55
  team_id=self.team_id,
45
- tasks=tasks,
56
+ tasks=new_tasks,
46
57
  )
47
- self.emit(EventType.TASK_BOARD_TASKS_ADDED, payload=event_payload)
48
- return True
58
+ self.emit(EventType.TASK_PLAN_TASKS_CREATED, payload=event_payload)
59
+ return new_tasks
49
60
 
50
- def add_task(self, task: Task) -> bool:
61
+ def add_task(self, task_definition: TaskDefinitionSchema) -> Optional[Task]:
51
62
  """
52
- Adds a single new task to the board by wrapping it in a list and calling add_tasks.
63
+ Creates a single new task from a definition, adds it to the plan, and returns it.
53
64
  """
54
- return self.add_tasks([task])
65
+ created_tasks = self.add_tasks([task_definition])
66
+ return created_tasks[0] if created_tasks else None
55
67
 
56
68
  def _hydrate_all_dependencies(self):
57
69
  """
@@ -67,7 +79,7 @@ class InMemoryTaskBoard(BaseTaskBoard):
67
79
 
68
80
  resolved_deps = []
69
81
  for dep in task.dependencies:
70
- # Case 1: The dependency is already a valid task_id on the board.
82
+ # Case 1: The dependency is already a valid task_id on the plan.
71
83
  if dep in all_task_ids:
72
84
  resolved_deps.append(dep)
73
85
  # Case 2: The dependency is a task_name that can be resolved.
@@ -103,12 +115,12 @@ class InMemoryTaskBoard(BaseTaskBoard):
103
115
  agent_name=agent_name,
104
116
  deliverables=task_deliverables
105
117
  )
106
- self.emit(EventType.TASK_BOARD_STATUS_UPDATED, payload=event_payload)
118
+ self.emit(EventType.TASK_PLAN_STATUS_UPDATED, payload=event_payload)
107
119
  return True
108
120
 
109
121
  def get_status_overview(self) -> Dict[str, Any]:
110
122
  """
111
- Returns a serializable dictionary of the board's current state.
123
+ Returns a serializable dictionary of the plan's current state.
112
124
  The overall_goal is now fetched from the context via the converter.
113
125
  """
114
126
  return {
@@ -5,6 +5,7 @@ Exposes the public schema models for the task management module.
5
5
  from .task_definition import TasksDefinitionSchema, TaskDefinitionSchema
6
6
  from .task_status_report import TaskStatusReportSchema, TaskStatusReportItemSchema
7
7
  from .deliverable_schema import FileDeliverableSchema
8
+ from .todo_definition import ToDoDefinitionSchema, ToDosDefinitionSchema
8
9
 
9
10
  __all__ = [
10
11
  "TasksDefinitionSchema",
@@ -12,4 +13,6 @@ __all__ = [
12
13
  "TaskStatusReportSchema",
13
14
  "TaskStatusReportItemSchema",
14
15
  "FileDeliverableSchema",
16
+ "ToDoDefinitionSchema",
17
+ "ToDosDefinitionSchema",
15
18
  ]
@@ -9,7 +9,7 @@ but includes dynamic state information (like task status).
9
9
  from typing import List, Optional
10
10
  from pydantic import BaseModel, Field
11
11
 
12
- from autobyteus.task_management.base_task_board import TaskStatus
12
+ from autobyteus.task_management.base_task_plan import TaskStatus
13
13
  from autobyteus.task_management.deliverable import FileDeliverable
14
14
 
15
15
  class TaskStatusReportItemSchema(BaseModel):
@@ -22,5 +22,5 @@ class TaskStatusReportItemSchema(BaseModel):
22
22
  file_deliverables: List[FileDeliverable] = Field(default_factory=list, description="A list of files submitted as deliverables for this task.")
23
23
 
24
24
  class TaskStatusReportSchema(BaseModel):
25
- """Represents a full task board status report in an LLM-friendly format."""
25
+ """Represents a full task plan status report in an LLM-friendly format."""
26
26
  tasks: List[TaskStatusReportItemSchema] = Field(..., description="The list of tasks and their current statuses.")
@@ -0,0 +1,15 @@
1
+ # file: autobyteus/autobyteus/task_management/schemas/todo_definition.py
2
+ """
3
+ Defines the Pydantic models for ToDo "definitions".
4
+ These models represent the structure an LLM is expected to generate for personal planning.
5
+ """
6
+ from typing import List
7
+ from pydantic import BaseModel, Field
8
+
9
+ class ToDoDefinitionSchema(BaseModel):
10
+ """A Pydantic model representing a single to-do item as defined by an LLM."""
11
+ description: str = Field(..., description="A clear, detailed description of what this to-do item or step entails.")
12
+
13
+ class ToDosDefinitionSchema(BaseModel):
14
+ """A Pydantic model representing a list of to-do items as generated by an LLM."""
15
+ todos: List[ToDoDefinitionSchema] = Field(..., description="The list of to-do items to create.")