@@ -3,6 +3,7 @@ |
| 3 | 3 | from __future__ import annotations |
| 4 | 4 | |
| 5 | 5 | from ..llm.base import Message, Role |
| 6 | +from ..utils.todos import active_todo_store_path, clear_active_todos |
| 6 | 7 | from .bootstrap import ( |
| 7 | 8 | RuntimeBootstrapSource, |
| 8 | 9 | RuntimeBootstrapView, |
@@ -12,7 +13,7 @@ from .chat_lane import ConversationalTurnRunner |
| 12 | 13 | from .conversation import ConfirmationHandler, ConversationRuntime, EventSink, UserQuestionHandler |
| 13 | 14 | from .decomposition_lane import DecompositionTurnRunner |
| 14 | 15 | from .deliberation import should_decompose |
| 15 | | -from .events import TurnSummary |
| 16 | +from .events import AgentEvent, TurnSummary |
| 16 | 17 | from .explore import ExploreRuntime |
| 17 | 18 | from .task_classification import is_conversational |
| 18 | 19 | from .workflow import WorkflowMode |
@@ -48,8 +49,7 @@ class RuntimeLauncher: |
| 48 | 49 | if is_conversational(user_message): |
| 49 | 50 | return await self.run_conversational(user_message, emit) |
| 50 | 51 | |
| 51 | | - if self.source.current_task is None: |
| 52 | | - self.source.current_task = user_message |
| 52 | + await self._begin_top_level_task(user_message, emit) |
| 53 | 53 | |
| 54 | 54 | requested_mode = self._requested_workflow_mode(use_plan) |
| 55 | 55 | |
@@ -167,6 +167,20 @@ class RuntimeLauncher: |
| 167 | 167 | return WorkflowMode.PLAN.value |
| 168 | 168 | return None |
| 169 | 169 | |
| 170 | + async def _begin_top_level_task(self, user_message: str, emit: EventSink) -> None: |
| 171 | + """Reset task-scoped state before a new top-level task starts.""" |
| 172 | + |
| 173 | + previous_task = self.source.current_task |
| 174 | + had_active_todos = active_todo_store_path(self.source.project_root).exists() |
| 175 | + self.source.current_task = user_message |
| 176 | + |
| 177 | + if previous_task == user_message: |
| 178 | + return |
| 179 | + |
| 180 | + clear_active_todos(self.source.project_root) |
| 181 | + if previous_task is not None or had_active_todos: |
| 182 | + await emit(AgentEvent(type="todo_update", todo_items=[])) |
| 183 | + |
| 170 | 184 | |
| 171 | 185 | def build_runtime_launcher(source: RuntimeBootstrapSource) -> RuntimeLauncher: |
| 172 | 186 | """Build a public runtime launcher from the shared bootstrap source.""" |