autobyteus 1.1.9__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 (126) 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/clients/__init__.py +10 -0
  22. autobyteus/clients/autobyteus_client.py +318 -0
  23. autobyteus/clients/cert_utils.py +105 -0
  24. autobyteus/clients/certificates/cert.pem +34 -0
  25. autobyteus/events/event_types.py +4 -3
  26. autobyteus/llm/api/autobyteus_llm.py +1 -1
  27. autobyteus/llm/api/zhipu_llm.py +26 -0
  28. autobyteus/llm/autobyteus_provider.py +1 -1
  29. autobyteus/llm/llm_factory.py +23 -0
  30. autobyteus/llm/ollama_provider_resolver.py +1 -0
  31. autobyteus/llm/providers.py +1 -0
  32. autobyteus/llm/token_counter/token_counter_factory.py +3 -0
  33. autobyteus/llm/token_counter/zhipu_token_counter.py +24 -0
  34. autobyteus/multimedia/audio/api/__init__.py +3 -2
  35. autobyteus/multimedia/audio/api/autobyteus_audio_client.py +1 -1
  36. autobyteus/multimedia/audio/api/openai_audio_client.py +112 -0
  37. autobyteus/multimedia/audio/audio_client_factory.py +37 -0
  38. autobyteus/multimedia/audio/autobyteus_audio_provider.py +1 -1
  39. autobyteus/multimedia/image/api/autobyteus_image_client.py +1 -1
  40. autobyteus/multimedia/image/autobyteus_image_provider.py +1 -1
  41. autobyteus/multimedia/image/image_client_factory.py +1 -1
  42. autobyteus/task_management/__init__.py +44 -20
  43. autobyteus/task_management/{base_task_board.py → base_task_plan.py} +16 -13
  44. autobyteus/task_management/converters/__init__.py +2 -2
  45. autobyteus/task_management/converters/{task_board_converter.py → task_plan_converter.py} +13 -13
  46. autobyteus/task_management/events.py +7 -7
  47. autobyteus/task_management/{in_memory_task_board.py → in_memory_task_plan.py} +34 -22
  48. autobyteus/task_management/schemas/__init__.py +3 -0
  49. autobyteus/task_management/schemas/task_definition.py +1 -1
  50. autobyteus/task_management/schemas/task_status_report.py +3 -3
  51. autobyteus/task_management/schemas/todo_definition.py +15 -0
  52. autobyteus/task_management/todo.py +29 -0
  53. autobyteus/task_management/todo_list.py +75 -0
  54. autobyteus/task_management/tools/__init__.py +25 -7
  55. autobyteus/task_management/tools/task_tools/__init__.py +19 -0
  56. autobyteus/task_management/tools/task_tools/assign_task_to.py +125 -0
  57. autobyteus/task_management/tools/{publish_task.py → task_tools/create_task.py} +16 -18
  58. autobyteus/task_management/tools/{publish_tasks.py → task_tools/create_tasks.py} +19 -19
  59. autobyteus/task_management/tools/{get_my_tasks.py → task_tools/get_my_tasks.py} +15 -15
  60. autobyteus/task_management/tools/{get_task_board_status.py → task_tools/get_task_plan_status.py} +16 -16
  61. autobyteus/task_management/tools/{update_task_status.py → task_tools/update_task_status.py} +16 -16
  62. autobyteus/task_management/tools/todo_tools/__init__.py +18 -0
  63. autobyteus/task_management/tools/todo_tools/add_todo.py +78 -0
  64. autobyteus/task_management/tools/todo_tools/create_todo_list.py +79 -0
  65. autobyteus/task_management/tools/todo_tools/get_todo_list.py +55 -0
  66. autobyteus/task_management/tools/todo_tools/update_todo_status.py +85 -0
  67. autobyteus/tools/__init__.py +61 -21
  68. autobyteus/tools/bash/bash_executor.py +3 -3
  69. autobyteus/tools/browser/session_aware/browser_session_aware_navigate_to.py +5 -5
  70. autobyteus/tools/browser/session_aware/browser_session_aware_web_element_trigger.py +4 -4
  71. autobyteus/tools/browser/session_aware/browser_session_aware_webpage_reader.py +3 -3
  72. autobyteus/tools/browser/session_aware/browser_session_aware_webpage_screenshot_taker.py +3 -3
  73. autobyteus/tools/browser/standalone/navigate_to.py +13 -9
  74. autobyteus/tools/browser/standalone/web_page_pdf_generator.py +9 -5
  75. autobyteus/tools/browser/standalone/webpage_image_downloader.py +10 -6
  76. autobyteus/tools/browser/standalone/webpage_reader.py +13 -9
  77. autobyteus/tools/browser/standalone/webpage_screenshot_taker.py +9 -5
  78. autobyteus/tools/file/__init__.py +13 -0
  79. autobyteus/tools/file/edit_file.py +200 -0
  80. autobyteus/tools/file/list_directory.py +168 -0
  81. autobyteus/tools/file/{file_reader.py → read_file.py} +3 -3
  82. autobyteus/tools/file/search_files.py +188 -0
  83. autobyteus/tools/file/{file_writer.py → write_file.py} +3 -3
  84. autobyteus/tools/functional_tool.py +10 -8
  85. autobyteus/tools/mcp/tool.py +3 -3
  86. autobyteus/tools/mcp/tool_registrar.py +5 -2
  87. autobyteus/tools/multimedia/__init__.py +2 -1
  88. autobyteus/tools/multimedia/audio_tools.py +2 -2
  89. autobyteus/tools/multimedia/download_media_tool.py +136 -0
  90. autobyteus/tools/multimedia/image_tools.py +4 -4
  91. autobyteus/tools/multimedia/media_reader_tool.py +1 -1
  92. autobyteus/tools/registry/tool_definition.py +66 -13
  93. autobyteus/tools/registry/tool_registry.py +29 -0
  94. autobyteus/tools/search/__init__.py +17 -0
  95. autobyteus/tools/search/base_strategy.py +35 -0
  96. autobyteus/tools/search/client.py +24 -0
  97. autobyteus/tools/search/factory.py +81 -0
  98. autobyteus/tools/search/google_cse_strategy.py +68 -0
  99. autobyteus/tools/search/providers.py +10 -0
  100. autobyteus/tools/search/serpapi_strategy.py +65 -0
  101. autobyteus/tools/search/serper_strategy.py +87 -0
  102. autobyteus/tools/search_tool.py +83 -0
  103. autobyteus/tools/timer.py +4 -0
  104. autobyteus/tools/tool_meta.py +4 -24
  105. autobyteus/tools/usage/parsers/_string_decoders.py +18 -0
  106. autobyteus/tools/usage/parsers/default_json_tool_usage_parser.py +9 -1
  107. autobyteus/tools/usage/parsers/default_xml_tool_usage_parser.py +15 -1
  108. autobyteus/tools/usage/parsers/gemini_json_tool_usage_parser.py +4 -1
  109. autobyteus/tools/usage/parsers/openai_json_tool_usage_parser.py +4 -1
  110. autobyteus/workflow/bootstrap_steps/coordinator_prompt_preparation_step.py +1 -2
  111. {autobyteus-1.1.9.dist-info → autobyteus-1.2.1.dist-info}/METADATA +7 -6
  112. {autobyteus-1.1.9.dist-info → autobyteus-1.2.1.dist-info}/RECORD +117 -94
  113. examples/run_agentic_software_engineer.py +239 -0
  114. examples/run_poem_writer.py +3 -3
  115. autobyteus/person/__init__.py +0 -0
  116. autobyteus/person/examples/__init__.py +0 -0
  117. autobyteus/person/examples/sample_persons.py +0 -14
  118. autobyteus/person/examples/sample_roles.py +0 -14
  119. autobyteus/person/person.py +0 -29
  120. autobyteus/person/role.py +0 -14
  121. autobyteus/tools/google_search.py +0 -149
  122. autobyteus/tools/image_downloader.py +0 -99
  123. autobyteus/tools/pdf_downloader.py +0 -89
  124. {autobyteus-1.1.9.dist-info → autobyteus-1.2.1.dist-info}/WHEEL +0 -0
  125. {autobyteus-1.1.9.dist-info → autobyteus-1.2.1.dist-info}/licenses/LICENSE +0 -0
  126. {autobyteus-1.1.9.dist-info → autobyteus-1.2.1.dist-info}/top_level.txt +0 -0
@@ -12,6 +12,7 @@ from autobyteus.agent.workspace.base_workspace import BaseAgentWorkspace
12
12
  from autobyteus.agent.tool_invocation import ToolInvocation
13
13
  # LLMConfig is no longer needed here
14
14
  # from autobyteus.llm.utils.llm_config import LLMConfig
15
+ from autobyteus.task_management.todo_list import ToDoList
15
16
 
16
17
  if TYPE_CHECKING:
17
18
  from autobyteus.agent.phases import AgentPhaseManager
@@ -52,6 +53,9 @@ class AgentRuntimeState:
52
53
  # NEW: State for multi-tool call invocation turns, with a very explicit name.
53
54
  self.active_multi_tool_call_turn: Optional['ToolInvocationTurn'] = None
54
55
 
56
+ # NEW: State for the agent's personal ToDoList
57
+ self.todo_list: Optional[ToDoList] = None
58
+
55
59
  self.processed_system_prompt: Optional[str] = None
56
60
  # self.final_llm_config_for_creation removed
57
61
 
@@ -1,6 +1,6 @@
1
1
  # file: autobyteus/autobyteus/agent/events/notifiers.py
2
2
  import logging
3
- from typing import Optional, Dict, Any, TYPE_CHECKING
3
+ from typing import Optional, Dict, Any, TYPE_CHECKING, List
4
4
 
5
5
  from autobyteus.events.event_emitter import EventEmitter
6
6
  from autobyteus.events.event_types import EventType
@@ -117,6 +117,10 @@ class AgentExternalEventNotifier(EventEmitter):
117
117
  """Notifies that the agent has received a system-generated task notification."""
118
118
  self._emit_event(EventType.AGENT_DATA_SYSTEM_TASK_NOTIFICATION_RECEIVED, payload_content=notification_data)
119
119
 
120
+ def notify_agent_data_todo_list_updated(self, todo_list: List[Dict[str, Any]]):
121
+ """Notifies that the agent's ToDo list has been updated."""
122
+ self._emit_event(EventType.AGENT_DATA_TODO_LIST_UPDATED, payload_content={"todos": todo_list})
123
+
120
124
  def notify_agent_error_output_generation(self, error_source: str, error_message: str, error_details: Optional[str] = None):
121
125
  payload_dict = {
122
126
  "source": error_source,
@@ -21,7 +21,7 @@ class SendMessageTo(BaseTool):
21
21
  This tool dynamically retrieves the team communication channel from the
22
22
  agent's context at runtime.
23
23
  """
24
- TOOL_NAME = "SendMessageTo"
24
+ TOOL_NAME = "send_message_to"
25
25
  CATEGORY = ToolCategory.AGENT_COMMUNICATION
26
26
 
27
27
  def __init__(self, config: Optional[ToolConfig] = None):
@@ -30,7 +30,7 @@ class SendMessageTo(BaseTool):
30
30
  """
31
31
  super().__init__(config=config)
32
32
  # The TeamManager is no longer stored as an instance variable.
33
- logger.debug("SendMessageTo tool initialized (stateless).")
33
+ logger.debug("%s tool initialized (stateless).", self.get_name())
34
34
 
35
35
  # The set_team_manager method has been removed.
36
36
 
@@ -81,7 +81,8 @@ class SendMessageTo(BaseTool):
81
81
  # --- NEW: Retrieve TeamManager dynamically from context ---
82
82
  team_context: Optional['AgentTeamContext'] = context.custom_data.get("team_context")
83
83
  if not team_context:
84
- error_msg = "Critical error: SendMessageTo tool is not configured for team communication. It can only be used within a managed AgentTeam."
84
+ error_msg = (f"Critical error: {self.get_name()} tool is not configured for team communication. "
85
+ "It can only be used within a managed AgentTeam.")
85
86
  logger.error(f"Agent '{context.agent_id}': {error_msg}")
86
87
  return f"Error: {error_msg}"
87
88
 
@@ -122,4 +123,4 @@ class SendMessageTo(BaseTool):
122
123
 
123
124
  success_msg = f"Message dispatch for recipient '{recipient_name}' has been successfully requested."
124
125
  logger.info(f"Tool '{self.get_name()}': {success_msg}")
125
- return success_msg
126
+ return success_msg
@@ -17,6 +17,7 @@ from autobyteus.agent.streaming.stream_event_payloads import (
17
17
  create_tool_invocation_approval_requested_data,
18
18
  create_tool_invocation_auto_executing_data,
19
19
  create_system_task_notification_data, # NEW
20
+ create_todo_list_update_data,
20
21
  AssistantChunkData,
21
22
  AssistantCompleteResponseData,
22
23
  ToolInteractionLogEntryData,
@@ -25,6 +26,7 @@ from autobyteus.agent.streaming.stream_event_payloads import (
25
26
  ToolInvocationAutoExecutingData,
26
27
  ErrorEventData,
27
28
  SystemTaskNotificationData, # NEW
29
+ ToDoListUpdateData,
28
30
  EmptyData,
29
31
  StreamDataPayload,
30
32
  )
@@ -107,6 +109,9 @@ class AgentEventStream(EventEmitter):
107
109
  elif event_type == EventType.AGENT_DATA_SYSTEM_TASK_NOTIFICATION_RECEIVED:
108
110
  typed_payload_for_stream_event = create_system_task_notification_data(payload)
109
111
  stream_event_type_for_generic_stream = StreamEventType.SYSTEM_TASK_NOTIFICATION
112
+ elif event_type == EventType.AGENT_DATA_TODO_LIST_UPDATED:
113
+ typed_payload_for_stream_event = create_todo_list_update_data(payload)
114
+ stream_event_type_for_generic_stream = StreamEventType.AGENT_TODO_LIST_UPDATE
110
115
 
111
116
  elif event_type in [EventType.AGENT_DATA_ASSISTANT_CHUNK_STREAM_END, EventType.AGENT_DATA_TOOL_LOG_STREAM_END]:
112
117
  pass
@@ -66,6 +66,14 @@ class SystemTaskNotificationData(BaseStreamPayload):
66
66
  sender_id: str
67
67
  content: str
68
68
 
69
+ class ToDoItemData(BaseStreamPayload):
70
+ description: str
71
+ todo_id: str
72
+ status: str
73
+
74
+ class ToDoListUpdateData(BaseStreamPayload):
75
+ todos: List[ToDoItemData]
76
+
69
77
  class EmptyData(BaseStreamPayload):
70
78
  pass
71
79
 
@@ -79,6 +87,7 @@ StreamDataPayload = Union[
79
87
  ToolInvocationApprovalRequestedData,
80
88
  ToolInvocationAutoExecutingData,
81
89
  SystemTaskNotificationData, # NEW
90
+ ToDoListUpdateData,
82
91
  EmptyData
83
92
  ]
84
93
 
@@ -196,3 +205,19 @@ def create_system_task_notification_data(notification_data_dict: Any) -> SystemT
196
205
  return SystemTaskNotificationData(**notification_data_dict)
197
206
  raise ValueError(f"Cannot create SystemTaskNotificationData from {type(notification_data_dict)}")
198
207
 
208
+ def create_todo_list_update_data(todo_data_dict: Any) -> ToDoListUpdateData:
209
+ if isinstance(todo_data_dict, dict):
210
+ todos_payload = todo_data_dict.get('todos', [])
211
+ if not isinstance(todos_payload, list):
212
+ raise ValueError("Expected 'todos' to be a list when creating ToDoListUpdateData.")
213
+ todo_items = []
214
+ for todo_entry in todos_payload:
215
+ if not isinstance(todo_entry, dict):
216
+ logger.warning(f"Skipping non-dict todo entry when creating ToDoListUpdateData: {todo_entry!r}")
217
+ continue
218
+ try:
219
+ todo_items.append(ToDoItemData(**todo_entry))
220
+ except Exception as exc:
221
+ logger.warning(f"Failed to parse todo entry into ToDoItemData: {todo_entry!r}; error: {exc}")
222
+ return ToDoListUpdateData(todos=todo_items)
223
+ raise ValueError(f"Cannot create ToDoListUpdateData from {type(todo_data_dict)}")
@@ -17,7 +17,17 @@ from .stream_event_payloads import (
17
17
  ToolInvocationApprovalRequestedData,
18
18
  ToolInvocationAutoExecutingData,
19
19
  SystemTaskNotificationData, # NEW
20
- EmptyData
20
+ ToDoListUpdateData,
21
+ EmptyData,
22
+ create_assistant_chunk_data,
23
+ create_assistant_complete_response_data,
24
+ create_tool_interaction_log_entry_data,
25
+ create_agent_operational_phase_transition_data,
26
+ create_error_event_data,
27
+ create_tool_invocation_approval_requested_data,
28
+ create_tool_invocation_auto_executing_data,
29
+ create_system_task_notification_data, # NEW
30
+ create_todo_list_update_data,
21
31
  )
22
32
 
23
33
  logger = logging.getLogger(__name__)
@@ -35,6 +45,7 @@ class StreamEventType(str, Enum):
35
45
  TOOL_INVOCATION_APPROVAL_REQUESTED = "tool_invocation_approval_requested"
36
46
  TOOL_INVOCATION_AUTO_EXECUTING = "tool_invocation_auto_executing"
37
47
  SYSTEM_TASK_NOTIFICATION = "system_task_notification" # NEW
48
+ AGENT_TODO_LIST_UPDATE = "agent_todo_list_updated"
38
49
  AGENT_IDLE = "agent_idle"
39
50
 
40
51
 
@@ -47,6 +58,7 @@ _STREAM_EVENT_TYPE_TO_PAYLOAD_CLASS: Dict[StreamEventType, Type[BaseModel]] = {
47
58
  StreamEventType.TOOL_INVOCATION_APPROVAL_REQUESTED: ToolInvocationApprovalRequestedData,
48
59
  StreamEventType.TOOL_INVOCATION_AUTO_EXECUTING: ToolInvocationAutoExecutingData,
49
60
  StreamEventType.SYSTEM_TASK_NOTIFICATION: SystemTaskNotificationData, # NEW
61
+ StreamEventType.AGENT_TODO_LIST_UPDATE: ToDoListUpdateData,
50
62
  StreamEventType.AGENT_IDLE: AgentOperationalPhaseTransitionData,
51
63
  }
52
64
 
@@ -27,9 +27,9 @@ class TaskNotifierInitializationStep(BaseAgentTeamBootstrapStep):
27
27
 
28
28
  logger.info(f"Team '{team_id}': Mode is SYSTEM_EVENT_DRIVEN. Initializing and activating task notifier.")
29
29
  try:
30
- task_board = context.state.task_board
31
- if not task_board:
32
- logger.error(f"Team '{team_id}': TaskBoard not found. Cannot initialize task notifier. This step should run after TeamContextInitializationStep.")
30
+ task_plan = context.state.task_plan
31
+ if not task_plan:
32
+ logger.error(f"Team '{team_id}': TaskPlan not found. Cannot initialize task notifier. This step should run after TeamContextInitializationStep.")
33
33
  return False
34
34
 
35
35
  team_manager = context.team_manager
@@ -38,7 +38,7 @@ class TaskNotifierInitializationStep(BaseAgentTeamBootstrapStep):
38
38
  return False
39
39
 
40
40
  notifier = SystemEventDrivenAgentTaskNotifier(
41
- task_board=task_board,
41
+ task_plan=task_plan,
42
42
  team_manager=team_manager
43
43
  )
44
44
  notifier.start_monitoring()
@@ -3,7 +3,7 @@ import logging
3
3
  from typing import TYPE_CHECKING
4
4
 
5
5
  from autobyteus.agent_team.bootstrap_steps.base_agent_team_bootstrap_step import BaseAgentTeamBootstrapStep
6
- from autobyteus.task_management import TaskBoard
6
+ from autobyteus.task_management import TaskPlan
7
7
  from autobyteus.events.event_types import EventType
8
8
 
9
9
  if TYPE_CHECKING:
@@ -15,29 +15,29 @@ logger = logging.getLogger(__name__)
15
15
  class TeamContextInitializationStep(BaseAgentTeamBootstrapStep):
16
16
  """
17
17
  Bootstrap step to initialize shared team context components, such as the
18
- TaskBoard, and bridges its events to the team's notifier.
18
+ TaskPlan, and bridges its events to the team's notifier.
19
19
  """
20
20
  async def execute(self, context: 'AgentTeamContext', phase_manager: 'AgentTeamPhaseManager') -> bool:
21
21
  team_id = context.team_id
22
22
  logger.info(f"Team '{team_id}': Executing TeamContextInitializationStep.")
23
23
  try:
24
- if context.state.task_board is None:
25
- task_board = TaskBoard(team_id=team_id)
26
- context.state.task_board = task_board
27
- logger.info(f"Team '{team_id}': TaskBoard initialized and attached to team state.")
24
+ if context.state.task_plan is None:
25
+ task_plan = TaskPlan(team_id=team_id)
26
+ context.state.task_plan = task_plan
27
+ logger.info(f"Team '{team_id}': TaskPlan initialized and attached to team state.")
28
28
 
29
29
  notifier = phase_manager.notifier
30
30
  if notifier:
31
31
  # The notifier, a long-lived component, subscribes to events
32
- # from the task_board, another long-lived component.
33
- notifier.subscribe_from(sender=task_board, event=EventType.TASK_BOARD_TASKS_ADDED, listener=notifier.handle_and_publish_task_board_event)
34
- notifier.subscribe_from(sender=task_board, event=EventType.TASK_BOARD_STATUS_UPDATED, listener=notifier.handle_and_publish_task_board_event)
35
- logger.info(f"Team '{team_id}': Successfully bridged TaskBoard events to the team notifier.")
32
+ # from the task_plan, another long-lived component.
33
+ notifier.subscribe_from(sender=task_plan, event=EventType.TASK_PLAN_TASKS_CREATED, listener=notifier.handle_and_publish_task_plan_event)
34
+ notifier.subscribe_from(sender=task_plan, event=EventType.TASK_PLAN_STATUS_UPDATED, listener=notifier.handle_and_publish_task_plan_event)
35
+ logger.info(f"Team '{team_id}': Successfully bridged TaskPlan events to the team notifier.")
36
36
  else:
37
- logger.warning(f"Team '{team_id}': Notifier not found in PhaseManager. Cannot bridge TaskBoard events.")
37
+ logger.warning(f"Team '{team_id}': Notifier not found in PhaseManager. Cannot bridge TaskPlan events.")
38
38
 
39
39
  else:
40
- logger.warning(f"Team '{team_id}': TaskBoard already exists. Skipping initialization.")
40
+ logger.warning(f"Team '{team_id}': TaskPlan already exists. Skipping initialization.")
41
41
 
42
42
  return True
43
43
  except Exception as e:
@@ -13,7 +13,7 @@ if TYPE_CHECKING:
13
13
  from autobyteus.agent_team.context.team_node_config import TeamNodeConfig
14
14
  from autobyteus.agent_team.context.team_manager import TeamManager
15
15
  from autobyteus.agent_team.streaming.agent_event_multiplexer import AgentEventMultiplexer
16
- from autobyteus.task_management.base_task_board import BaseTaskBoard
16
+ from autobyteus.task_management.base_task_plan import BaseTaskPlan
17
17
  from autobyteus.agent_team.task_notification.system_event_driven_agent_task_notifier import SystemEventDrivenAgentTaskNotifier
18
18
 
19
19
  logger = logging.getLogger(__name__)
@@ -38,7 +38,7 @@ class AgentTeamRuntimeState:
38
38
  multiplexer_ref: Optional['AgentEventMultiplexer'] = None
39
39
 
40
40
  # Dynamic planning and artifact state
41
- task_board: Optional['BaseTaskBoard'] = None
41
+ task_plan: Optional['BaseTaskPlan'] = None
42
42
 
43
43
  def __post_init__(self):
44
44
  if not self.team_id or not isinstance(self.team_id, str):
@@ -7,7 +7,7 @@ from autobyteus.events.event_types import EventType
7
7
  from autobyteus.agent_team.phases.agent_team_operational_phase import AgentTeamOperationalPhase
8
8
  from autobyteus.agent.streaming.stream_events import StreamEvent as AgentStreamEvent
9
9
  from .agent_team_stream_events import AgentTeamStreamEvent, AgentEventRebroadcastPayload, AgentTeamPhaseTransitionData, SubTeamEventRebroadcastPayload
10
- from autobyteus.task_management.events import BaseTaskBoardEvent
10
+ from autobyteus.task_management.events import BaseTaskPlanEvent
11
11
 
12
12
  if TYPE_CHECKING:
13
13
  from autobyteus.agent_team.runtime.agent_team_runtime import AgentTeamRuntime
@@ -56,9 +56,9 @@ class AgentTeamExternalEventNotifier(EventEmitter):
56
56
  event = AgentTeamStreamEvent(team_id=self.team_id, event_source_type="SUB_TEAM", data=SubTeamEventRebroadcastPayload(sub_team_node_name=sub_team_node_name, sub_team_event=sub_team_event))
57
57
  self._emit_event(event)
58
58
 
59
- def handle_and_publish_task_board_event(self, payload: BaseTaskBoardEvent, **kwargs):
59
+ def handle_and_publish_task_plan_event(self, payload: BaseTaskPlanEvent, **kwargs):
60
60
  """
61
- Listener for TaskBoard events. It wraps the event and publishes it on the main team stream.
61
+ Listener for TaskPlan events. It wraps the event and publishes it on the main team stream.
62
62
  """
63
- event = AgentTeamStreamEvent(team_id=self.team_id, event_source_type="TASK_BOARD", data=payload)
63
+ event = AgentTeamStreamEvent(team_id=self.team_id, event_source_type="TASK_PLAN", data=payload)
64
64
  self._emit_event(event)
@@ -3,7 +3,7 @@ from typing import Optional, Any
3
3
  from pydantic import BaseModel, Field
4
4
  from autobyteus.agent_team.phases.agent_team_operational_phase import AgentTeamOperationalPhase
5
5
  from autobyteus.agent.streaming.stream_events import StreamEvent as AgentStreamEvent
6
- from autobyteus.task_management.events import TasksAddedEvent, TaskStatusUpdatedEvent
6
+ from autobyteus.task_management.events import TasksCreatedEvent, TaskStatusUpdatedEvent
7
7
  # Need to use a forward reference string to avoid circular import at runtime
8
8
  from typing import TYPE_CHECKING, Union
9
9
  if TYPE_CHECKING:
@@ -28,5 +28,5 @@ class SubTeamEventRebroadcastPayload(BaseModel):
28
28
  sub_team_node_name: str # The friendly name of the sub-team node
29
29
  sub_team_event: "AgentTeamStreamEvent" = Field(..., description="The original, unmodified event from the sub-team's stream")
30
30
 
31
- # --- Payload for events originating from the "TASK_BOARD" source ---
32
- TaskBoardEventPayload = Union[TasksAddedEvent, TaskStatusUpdatedEvent]
31
+ # --- Payload for events originating from the "TASK_PLAN" source ---
32
+ TaskPlanEventPayload = Union[TasksCreatedEvent, TaskStatusUpdatedEvent]
@@ -6,21 +6,21 @@ from pydantic import BaseModel, Field, model_validator
6
6
 
7
7
  from .agent_team_stream_event_payloads import (
8
8
  AgentTeamPhaseTransitionData, AgentEventRebroadcastPayload,
9
- SubTeamEventRebroadcastPayload, TaskBoardEventPayload
9
+ SubTeamEventRebroadcastPayload, TaskPlanEventPayload
10
10
  )
11
- from autobyteus.task_management.events import BaseTaskBoardEvent
11
+ from autobyteus.task_management.events import BaseTaskPlanEvent
12
12
 
13
13
  # A union of all possible payloads for a "TEAM" sourced event.
14
14
  TeamSpecificPayload = Union[AgentTeamPhaseTransitionData]
15
15
 
16
16
  # The top-level discriminated union for the main event stream's payload.
17
- AgentTeamStreamDataPayload = Union[TeamSpecificPayload, AgentEventRebroadcastPayload, SubTeamEventRebroadcastPayload, TaskBoardEventPayload]
17
+ AgentTeamStreamDataPayload = Union[TeamSpecificPayload, AgentEventRebroadcastPayload, SubTeamEventRebroadcastPayload, TaskPlanEventPayload]
18
18
 
19
19
  class AgentTeamStreamEvent(BaseModel):
20
20
  event_id: str = Field(default_factory=lambda: str(uuid.uuid4()))
21
21
  timestamp: datetime.datetime = Field(default_factory=datetime.datetime.utcnow)
22
22
  team_id: str
23
- event_source_type: Literal["TEAM", "AGENT", "SUB_TEAM", "TASK_BOARD"]
23
+ event_source_type: Literal["TEAM", "AGENT", "SUB_TEAM", "TASK_PLAN"]
24
24
  data: AgentTeamStreamDataPayload
25
25
 
26
26
  @model_validator(mode='after')
@@ -34,8 +34,8 @@ class AgentTeamStreamEvent(BaseModel):
34
34
  is_team_event = self.event_source_type == "TEAM"
35
35
  is_team_payload = isinstance(self.data, AgentTeamPhaseTransitionData)
36
36
 
37
- is_task_board_event = self.event_source_type == "TASK_BOARD"
38
- is_task_board_payload = isinstance(self.data, BaseTaskBoardEvent)
37
+ is_task_plan_event = self.event_source_type == "TASK_PLAN"
38
+ is_task_plan_payload = isinstance(self.data, BaseTaskPlanEvent)
39
39
 
40
40
  if is_agent_event and not is_agent_payload:
41
41
  raise ValueError("event_source_type is 'AGENT' but data is not an AgentEventRebroadcastPayload")
@@ -46,8 +46,8 @@ class AgentTeamStreamEvent(BaseModel):
46
46
  if is_team_event and not is_team_payload:
47
47
  raise ValueError("event_source_type is 'TEAM' but data is not a valid team-specific payload")
48
48
 
49
- if is_task_board_event and not is_task_board_payload:
50
- raise ValueError("event_source_type is 'TASK_BOARD' but data is not a TaskBoardEventPayload")
49
+ if is_task_plan_event and not is_task_plan_payload:
50
+ raise ValueError("event_source_type is 'TASK_PLAN' but data is not a BaseTaskPlanEvent instance")
51
51
 
52
52
  return self
53
53
 
@@ -31,7 +31,7 @@ class ActivationPolicy:
31
31
  def reset(self):
32
32
  """
33
33
  Resets the activation state. This should be called when a new batch of
34
- tasks is published to the task board, signifying a new plan or a
34
+ tasks is published to the task plan, signifying a new plan or a
35
35
  significant change in scope.
36
36
  """
37
37
  logger.info(f"Team '{self._team_id}': ActivationPolicy state has been reset. All agents are now considered inactive.")
@@ -3,39 +3,39 @@ import logging
3
3
  from typing import Union, TYPE_CHECKING
4
4
 
5
5
  from autobyteus.events.event_types import EventType
6
- from autobyteus.task_management.events import TasksAddedEvent, TaskStatusUpdatedEvent
7
- from autobyteus.task_management.base_task_board import TaskStatus
6
+ from autobyteus.task_management.events import TasksCreatedEvent, TaskStatusUpdatedEvent
7
+ from autobyteus.task_management.base_task_plan import TaskStatus
8
8
 
9
9
  # Import the new, separated components
10
10
  from .activation_policy import ActivationPolicy
11
11
  from .task_activator import TaskActivator
12
12
 
13
13
  if TYPE_CHECKING:
14
- from autobyteus.task_management.base_task_board import BaseTaskBoard
14
+ from autobyteus.task_management.base_task_plan import BaseTaskPlan
15
15
  from autobyteus.agent_team.context.team_manager import TeamManager
16
16
 
17
17
  logger = logging.getLogger(__name__)
18
18
 
19
19
  class SystemEventDrivenAgentTaskNotifier:
20
20
  """
21
- An internal component that monitors a TaskBoard and orchestrates agent
21
+ An internal component that monitors a TaskPlan and orchestrates agent
22
22
  activation based on task runnability.
23
23
 
24
24
  This class acts as a conductor, delegating the logic for *when* to activate
25
25
  to an ActivationPolicy and the action of *how* to activate to a TaskActivator.
26
26
  """
27
- def __init__(self, task_board: 'BaseTaskBoard', team_manager: 'TeamManager'):
27
+ def __init__(self, task_plan: 'BaseTaskPlan', team_manager: 'TeamManager'):
28
28
  """
29
29
  Initializes the SystemEventDrivenAgentTaskNotifier.
30
30
 
31
31
  Args:
32
- task_board: The team's shared task board instance.
32
+ task_plan: The team's shared task plan instance.
33
33
  team_manager: The team's manager for activating agents.
34
34
  """
35
- if not task_board or not team_manager:
36
- raise ValueError("TaskBoard and TeamManager are required for the notifier.")
35
+ if not task_plan or not team_manager:
36
+ raise ValueError("TaskPlan and TeamManager are required for the notifier.")
37
37
 
38
- self._task_board = task_board
38
+ self._task_plan = task_plan
39
39
  self._team_manager = team_manager
40
40
 
41
41
  # Instantiate the components that hold the actual logic and action
@@ -46,27 +46,27 @@ class SystemEventDrivenAgentTaskNotifier:
46
46
 
47
47
  def start_monitoring(self):
48
48
  """
49
- Subscribes to task board events to begin monitoring for runnable tasks.
49
+ Subscribes to task plan events to begin monitoring for runnable tasks.
50
50
  """
51
- self._task_board.subscribe(EventType.TASK_BOARD_TASKS_ADDED, self._handle_tasks_changed)
52
- self._task_board.subscribe(EventType.TASK_BOARD_STATUS_UPDATED, self._handle_tasks_changed)
53
- logger.info(f"Team '{self._team_manager.team_id}': Task notifier orchestrator is now monitoring TaskBoard events.")
51
+ self._task_plan.subscribe(EventType.TASK_PLAN_TASKS_CREATED, self._handle_tasks_changed)
52
+ self._task_plan.subscribe(EventType.TASK_PLAN_STATUS_UPDATED, self._handle_tasks_changed)
53
+ logger.info(f"Team '{self._team_manager.team_id}': Task notifier orchestrator is now monitoring TaskPlan events.")
54
54
 
55
- async def _handle_tasks_changed(self, payload: Union[TasksAddedEvent, TaskStatusUpdatedEvent], **kwargs):
55
+ async def _handle_tasks_changed(self, payload: Union[TasksCreatedEvent, TaskStatusUpdatedEvent], **kwargs):
56
56
  """
57
- Orchestrates the agent activation workflow upon any change to the task board.
57
+ Orchestrates the agent activation workflow upon any change to the task plan.
58
58
  """
59
59
  team_id = self._team_manager.team_id
60
- logger.info(f"Team '{team_id}': Task board changed ({type(payload).__name__}). Orchestrating activation check.")
60
+ logger.info(f"Team '{team_id}': Task plan changed ({type(payload).__name__}). Orchestrating activation check.")
61
61
 
62
62
  # If a new batch of tasks was added, it's a new "wave" of work.
63
63
  # We must reset the policy's memory of who has been activated.
64
- if isinstance(payload, TasksAddedEvent):
65
- logger.info(f"Team '{team_id}': New tasks added. Resetting activation policy.")
64
+ if isinstance(payload, TasksCreatedEvent):
65
+ logger.info(f"Team '{team_id}': New tasks created. Resetting activation policy.")
66
66
  self._policy.reset()
67
67
 
68
- # 1. DATA FETCHING: Get the current state of runnable tasks from the board.
69
- runnable_tasks = self._task_board.get_next_runnable_tasks()
68
+ # 1. DATA FETCHING: Get the current state of runnable tasks from the plan.
69
+ runnable_tasks = self._task_plan.get_next_runnable_tasks()
70
70
 
71
71
  if not runnable_tasks:
72
72
  logger.debug(f"Team '{team_id}': No runnable tasks found after change. No action needed.")
@@ -87,8 +87,8 @@ class SystemEventDrivenAgentTaskNotifier:
87
87
  agent_runnable_tasks = [t for t in runnable_tasks if t.assignee_name == agent_name]
88
88
  for task in agent_runnable_tasks:
89
89
  # We only need to queue tasks that are NOT_STARTED.
90
- if self._task_board.task_statuses.get(task.task_id) == TaskStatus.NOT_STARTED:
91
- self._task_board.update_task_status(
90
+ if self._task_plan.task_statuses.get(task.task_id) == TaskStatus.NOT_STARTED:
91
+ self._task_plan.update_task_status(
92
92
  task_id=task.task_id,
93
93
  status=TaskStatus.QUEUED,
94
94
  agent_name="SystemTaskNotifier"
@@ -16,7 +16,7 @@ class TaskNotificationMode(str, Enum):
16
16
 
17
17
  SYSTEM_EVENT_DRIVEN = "system_event_driven"
18
18
  """
19
- In this mode, the agent team framework automatically monitors the TaskBoard
19
+ In this mode, the agent team framework automatically monitors the TaskPlan
20
20
  and sends notifications to agents when their assigned tasks become runnable.
21
21
  """
22
22
 
@@ -141,8 +141,8 @@ class AgentTeamApp(App):
141
141
  focused_data = self.focused_node_data
142
142
  if focused_data and focused_data.get("type") in ['team', 'subteam']:
143
143
  node_name = focused_data['name']
144
- task_plan = self.store.get_task_board_plan(node_name)
145
- task_statuses = self.store.get_task_board_statuses(node_name)
144
+ task_plan = self.store.get_task_plan_tasks(node_name)
145
+ task_statuses = self.store.get_task_plan_statuses(node_name)
146
146
  await focus_pane.update_content(
147
147
  node_data=focused_data,
148
148
  history=[], # No history for teams
@@ -169,8 +169,8 @@ class AgentTeamApp(App):
169
169
  task_plan = None
170
170
  task_statuses = None
171
171
  if node_type in ['team', 'subteam']:
172
- task_plan = self.store.get_task_board_plan(node_name)
173
- task_statuses = self.store.get_task_board_statuses(node_name)
172
+ task_plan = self.store.get_task_plan_tasks(node_name)
173
+ task_statuses = self.store.get_task_plan_statuses(node_name)
174
174
 
175
175
  sidebar = self.query_one(AgentListSidebar)
176
176
  focus_pane = self.query_one(FocusPane)
@@ -17,8 +17,8 @@ from autobyteus.agent.streaming.stream_event_payloads import (
17
17
  from autobyteus.agent_team.streaming.agent_team_stream_events import AgentTeamStreamEvent
18
18
  from autobyteus.agent_team.streaming.agent_team_stream_event_payloads import AgentEventRebroadcastPayload, SubTeamEventRebroadcastPayload, AgentTeamPhaseTransitionData
19
19
  from autobyteus.task_management.task import Task
20
- from autobyteus.task_management.events import TasksAddedEvent, TaskStatusUpdatedEvent
21
- from autobyteus.task_management.base_task_board import TaskStatus
20
+ from autobyteus.task_management.events import TasksCreatedEvent, TaskStatusUpdatedEvent
21
+ from autobyteus.task_management.base_task_plan import TaskStatus
22
22
 
23
23
  logger = logging.getLogger(__name__)
24
24
 
@@ -46,7 +46,7 @@ class TUIStateStore:
46
46
  self._pending_approvals: Dict[str, ToolInvocationApprovalRequestedData] = {}
47
47
  self._speaking_agents: Dict[str, bool] = {}
48
48
 
49
- # State for task boards
49
+ # State for task plans
50
50
  self._task_plans: Dict[str, List[Task]] = {} # team_name -> List[Task]
51
51
  self._task_statuses: Dict[str, Dict[str, TaskStatus]] = {} # team_name -> {task_id: status}
52
52
 
@@ -85,15 +85,15 @@ class TUIStateStore:
85
85
  self._team_event_history[parent_name] = []
86
86
  self._team_event_history[parent_name].append(event)
87
87
 
88
- if event.event_source_type == "TASK_BOARD":
88
+ if event.event_source_type == "TASK_PLAN":
89
89
  team_name_key = parent_name
90
- if isinstance(event.data, TasksAddedEvent):
90
+ if isinstance(event.data, TasksCreatedEvent):
91
91
  if team_name_key not in self._task_plans: self._task_plans[team_name_key] = []
92
92
  if team_name_key not in self._task_statuses: self._task_statuses[team_name_key] = {}
93
93
  self._task_plans[team_name_key].extend(event.data.tasks)
94
94
  for task in event.data.tasks:
95
95
  self._task_statuses[team_name_key][task.task_id] = TaskStatus.NOT_STARTED
96
- logger.debug(f"TUI State: Added {len(event.data.tasks)} tasks to board for '{team_name_key}'.")
96
+ logger.debug(f"TUI State: Created {len(event.data.tasks)} tasks in plan for '{team_name_key}'.")
97
97
 
98
98
  elif isinstance(event.data, TaskStatusUpdatedEvent):
99
99
  if team_name_key not in self._task_statuses: self._task_statuses[team_name_key] = {}
@@ -164,10 +164,10 @@ class TUIStateStore:
164
164
  def get_pending_approval_for_agent(self, agent_name: str) -> Optional[ToolInvocationApprovalRequestedData]:
165
165
  return self._pending_approvals.get(agent_name)
166
166
 
167
- def get_task_board_plan(self, team_name: str) -> Optional[List[Task]]:
167
+ def get_task_plan_tasks(self, team_name: str) -> Optional[List[Task]]:
168
168
  return self._task_plans.get(team_name)
169
169
 
170
- def get_task_board_statuses(self, team_name: str) -> Optional[Dict[str, TaskStatus]]:
170
+ def get_task_plan_statuses(self, team_name: str) -> Optional[Dict[str, TaskStatus]]:
171
171
  return self._task_statuses.get(team_name)
172
172
 
173
173
  def clear_pending_approval(self, agent_name: str):
@@ -14,7 +14,7 @@ from textual.containers import VerticalScroll, Horizontal
14
14
 
15
15
  from autobyteus.agent.phases import AgentOperationalPhase
16
16
  from autobyteus.agent_team.phases import AgentTeamOperationalPhase
17
- from autobyteus.task_management.base_task_board import TaskStatus
17
+ from autobyteus.task_management.base_task_plan import TaskStatus
18
18
  from autobyteus.task_management.task import Task
19
19
  from autobyteus.agent.streaming.stream_events import StreamEvent as AgentStreamEvent, StreamEventType as AgentStreamEventType
20
20
  from autobyteus.agent.streaming.stream_event_payloads import (
@@ -27,7 +27,7 @@ from .shared import (
27
27
  USER_ICON, ASSISTANT_ICON, TEAM_ICON, AGENT_ICON, SYSTEM_TASK_ICON
28
28
  )
29
29
  from . import renderables
30
- from .task_board_panel import TaskBoardPanel
30
+ from .task_plan_panel import TaskPlanPanel
31
31
 
32
32
  logger = logging.getLogger(__name__)
33
33
 
@@ -211,7 +211,7 @@ class FocusPane(Static):
211
211
  info_text.append(f"Status: {phase_icon} {phase.value}")
212
212
  await log_container.mount(Static(Panel(info_text, title="Team Info", border_style="green", title_align="left")))
213
213
 
214
- await log_container.mount(TaskBoardPanel(tasks=task_plan, statuses=task_statuses, team_name=node_data['name']))
214
+ await log_container.mount(TaskPlanPanel(tasks=task_plan, statuses=task_statuses, team_name=node_data['name']))
215
215
 
216
216
  children_data = node_data.get("children", {})
217
217
  if children_data:
@@ -4,7 +4,7 @@ Shared constants and data for TUI widgets.
4
4
  from typing import Dict
5
5
  from autobyteus.agent.phases import AgentOperationalPhase
6
6
  from autobyteus.agent_team.phases import AgentTeamOperationalPhase
7
- from autobyteus.task_management.base_task_board import TaskStatus
7
+ from autobyteus.task_management.base_task_plan import TaskStatus
8
8
 
9
9
  AGENT_PHASE_ICONS: Dict[AgentOperationalPhase, str] = {
10
10
  AgentOperationalPhase.UNINITIALIZED: "⚪",
@@ -7,13 +7,13 @@ from rich.text import Text
7
7
  from textual.widgets import Static
8
8
 
9
9
  from autobyteus.task_management.task import Task
10
- from autobyteus.task_management.base_task_board import TaskStatus
10
+ from autobyteus.task_management.base_task_plan import TaskStatus
11
11
  from .shared import TASK_STATUS_ICONS, LOG_ICON
12
12
 
13
13
  logger = logging.getLogger(__name__)
14
14
 
15
- class TaskBoardPanel(Static):
16
- """A widget to display the team's task board."""
15
+ class TaskPlanPanel(Static):
16
+ """A widget to display the team's task plan."""
17
17
 
18
18
  def __init__(self, tasks: Optional[List[Task]], statuses: Dict[str, TaskStatus], team_name: str, **kwargs) -> None:
19
19
  super().__init__(**kwargs)
@@ -23,7 +23,7 @@ class TaskBoardPanel(Static):
23
23
 
24
24
  def compose(self) -> None:
25
25
  if not self.tasks:
26
- yield Static(Panel("No task plan has been published yet.", title="Task Board", border_style="yellow", title_align="left"))
26
+ yield Static(Panel("No task plan has been published yet.", title="Task Plan", border_style="yellow", title_align="left"))
27
27
  return
28
28
 
29
29
  table = Table(
@@ -79,4 +79,4 @@ class TaskBoardPanel(Static):
79
79
  ", ".join(dep_names)
80
80
  )
81
81
 
82
- yield Static(Panel(table, title="Task Board", border_style="blue", title_align="left"))
82
+ yield Static(Panel(table, title="Task Plan", border_style="blue", title_align="left"))
@@ -0,0 +1,10 @@
1
+ """
2
+ Client utilities for communicating with the Autobyteus LLM server.
3
+
4
+ Consolidates the previously standalone autobyteus-llm-client package so the
5
+ HTTP client can evolve alongside the rest of the framework.
6
+ """
7
+
8
+ from .autobyteus_client import AutobyteusClient, CertificateError
9
+
10
+ __all__ = ["AutobyteusClient", "CertificateError"]