jupyter-agent 2025.6.104__py3-none-any.whl → 2025.7.100__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 (43) hide show
  1. jupyter_agent/bot_actions.py +270 -0
  2. jupyter_agent/bot_agents/__init__.py +0 -42
  3. jupyter_agent/bot_agents/base.py +89 -45
  4. jupyter_agent/bot_agents/master_planner.py +1 -0
  5. jupyter_agent/bot_agents/output_task_result.py +6 -7
  6. jupyter_agent/bot_agents/prepare_next_cell.py +52 -0
  7. jupyter_agent/bot_agents/request_user_supply.py +186 -0
  8. jupyter_agent/bot_agents/task_code_executor.py +3 -2
  9. jupyter_agent/bot_agents/task_planner_v3.py +16 -13
  10. jupyter_agent/bot_agents/task_reasoner.py +3 -2
  11. jupyter_agent/bot_agents/task_structrue_reasoner.py +22 -12
  12. jupyter_agent/bot_agents/task_structrue_summarier.py +22 -18
  13. jupyter_agent/bot_agents/task_summarier.py +3 -2
  14. jupyter_agent/bot_agents/task_verifier.py +2 -1
  15. jupyter_agent/bot_agents/task_verify_summarier.py +6 -6
  16. jupyter_agent/bot_chat.py +2 -2
  17. jupyter_agent/bot_contexts.py +37 -29
  18. jupyter_agent/bot_evaluation.py +262 -143
  19. jupyter_agent/bot_evaluators/__init__.py +0 -0
  20. jupyter_agent/bot_evaluators/base.py +42 -0
  21. jupyter_agent/bot_evaluators/dummy_flow.py +20 -0
  22. jupyter_agent/bot_evaluators/dummy_global.py +20 -0
  23. jupyter_agent/bot_evaluators/dummy_task.py +20 -0
  24. jupyter_agent/bot_evaluators/flow_global_planning.py +88 -0
  25. jupyter_agent/bot_evaluators/flow_task_executor.py +152 -0
  26. jupyter_agent/bot_flows/__init__.py +0 -4
  27. jupyter_agent/bot_flows/base.py +120 -41
  28. jupyter_agent/bot_flows/master_planner.py +15 -4
  29. jupyter_agent/bot_flows/task_executor_v3.py +57 -38
  30. jupyter_agent/bot_magics.py +119 -69
  31. jupyter_agent/bot_outputs.py +37 -43
  32. jupyter_agent/utils.py +20 -31
  33. {jupyter_agent-2025.6.104.dist-info → jupyter_agent-2025.7.100.dist-info}/METADATA +56 -4
  34. jupyter_agent-2025.7.100.dist-info/RECORD +41 -0
  35. jupyter_agent/bot_agents/task_planner_v1.py +0 -158
  36. jupyter_agent/bot_agents/task_planner_v2.py +0 -172
  37. jupyter_agent/bot_flows/task_executor_v1.py +0 -86
  38. jupyter_agent/bot_flows/task_executor_v2.py +0 -84
  39. jupyter_agent-2025.6.104.dist-info/RECORD +0 -35
  40. {jupyter_agent-2025.6.104.dist-info → jupyter_agent-2025.7.100.dist-info}/WHEEL +0 -0
  41. {jupyter_agent-2025.6.104.dist-info → jupyter_agent-2025.7.100.dist-info}/entry_points.txt +0 -0
  42. {jupyter_agent-2025.6.104.dist-info → jupyter_agent-2025.7.100.dist-info}/licenses/LICENSE +0 -0
  43. {jupyter_agent-2025.6.104.dist-info → jupyter_agent-2025.7.100.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,152 @@
1
+ """
2
+ Copyright (c) 2025 viewstar000
3
+
4
+ This software is released under the MIT License.
5
+ https://opensource.org/licenses/MIT
6
+ """
7
+
8
+ import time
9
+
10
+ from enum import Enum
11
+ from typing import Optional, List
12
+ from pydantic import BaseModel, Field
13
+ from IPython.display import Markdown
14
+ from .base import BaseEvaluator
15
+ from ..bot_outputs import _D, _I, _W, _E, _F, _A, _O, _C, _M, _B
16
+ from ..bot_evaluation import FlowEvaluationRecord
17
+
18
+
19
+ FLOW_TASK_EXEC_EVAL_PROMPT = """\
20
+ **角色定义**:
21
+
22
+ 你是一个任务规划评估专家,负责对任务规划的结果进行评估。
23
+
24
+ **任务要求**:
25
+
26
+ 请你根据任务规划的结果,评估任务规划的质量和准确性,并给出相应的评分和反馈。
27
+
28
+ {% include "TASK_OUTPUT_FORMAT" %}
29
+
30
+ ---
31
+
32
+ {% include "TASK_CONTEXTS" %}
33
+
34
+ ---
35
+
36
+ {% include "CODE_CONTEXTS" %}
37
+
38
+ ---
39
+
40
+ **当前子任务规划信息**:
41
+
42
+ ### 当前子任务规划目标:
43
+
44
+ {{ task.subject }}
45
+
46
+ {% if task.coding_prompt %}
47
+ ### 当前子任务代码需求:
48
+
49
+ {{ task.coding_prompt }}
50
+
51
+ ### 当前子任务生成的代码:
52
+
53
+ ```python
54
+ {{ task.source }}
55
+ ```
56
+
57
+ ### 当前代码执行的输出与结果:
58
+
59
+ {{ task.output }}
60
+ {% endif %}
61
+
62
+ ### 当前子任务总结要求:
63
+
64
+ {{ task.summary_prompt }}
65
+
66
+
67
+ ### 当前子任务输出的分析总结后的最终结果:
68
+
69
+ ```markdown
70
+ {{ task.result }}
71
+ ```
72
+
73
+ {% if task.important_infos %}
74
+ ### 当前子任务输出的重要信息:
75
+
76
+ ```json
77
+ {{ task.important_infos | json }}
78
+ ```
79
+ {% endif %}
80
+
81
+ {% if task.request_below_supply_infos %}
82
+ ### 当前子任务输出的请求用户补充确认的信息:
83
+
84
+ ```json
85
+ {{ task.request_below_supply_infos | json }}
86
+ ```
87
+ {% endif %}
88
+
89
+ ---
90
+
91
+ 请按要求给出当前子任务规划的评估结果:
92
+ """
93
+
94
+
95
+ class FlowTaskExecEvalResult(BaseModel):
96
+ """
97
+ 任务规划评估结果
98
+ """
99
+
100
+ is_correct: bool = Field(description="最终结果是否符合当前子任务的目标", examples=[True, False])
101
+ correct_score: float = Field(
102
+ description="最终结果符合当前子任务目标的分数,范围0-1,>=0.5表示符合目标,<0.5表示不符合目标",
103
+ examples=[0.95, 0.3],
104
+ )
105
+ planning_score: float = Field(
106
+ description="当前子任务的目标规划、代码生成、总结是否符合全局目标规划要求,范围0-1,>=0.5表示符合要求,<0.5表示不符合要求",
107
+ examples=[0.85, 0.25],
108
+ )
109
+ reasoning_score: float = Field(
110
+ description="当前子任务的推理过程是否合理,是否存在逻辑错误,是否存在与前置子任务相冲突的情况,"
111
+ "范围0-1,>=0.5表示合理、正确、无冲突,<0.5表示不合理",
112
+ examples=[0.9, 0.4],
113
+ )
114
+ coding_score: float = Field(
115
+ description="代码生成的质量评分,代码逻辑是否符合规划要求,是否存在逻辑错误,是否存在冗余、抽象不合理等情况,"
116
+ "范围0-1,>=0.5表示代码质量较高,<0.5表示代码质量较低",
117
+ examples=[0.75, 0.2],
118
+ )
119
+ important_info_score: float = Field(
120
+ description="重要信息分数,当前子任务的规划、代码生成、总结是否充分考虑了前置任务生成的重要信息,"
121
+ "以及当前子任务的重要信息是否完整、准确、无误导、无冲突,"
122
+ "范围0-1,>=0.5表示重要信息完整、准确,<0.5表示重要信息不完整或不准确",
123
+ examples=[0.9, 0.4],
124
+ )
125
+ user_supply_info_score: float = Field(
126
+ description="用户补充信息分数,当前子任务的规划、代码生成、总结是否充分考虑了用户补充的信息,"
127
+ "范围0-1,>=0.5表示充分考虑,<0.5表示未充分考虑",
128
+ examples=[0.8, 0.3],
129
+ )
130
+ feedback: Optional[str] = Field(default=None, description="评估反馈")
131
+
132
+
133
+ class FlowTaskExecEvaluator(BaseEvaluator):
134
+ """
135
+ 任务规划评估器
136
+ """
137
+
138
+ PROMPT = FLOW_TASK_EXEC_EVAL_PROMPT
139
+ OUTPUT_JSON_SCHEMA = FlowTaskExecEvalResult
140
+
141
+ def on_reply(self, reply):
142
+ reply = super().on_reply(reply)
143
+ return FlowEvaluationRecord(
144
+ timestamp=time.time(),
145
+ evaluator="flow_task_executor",
146
+ correct_score=reply.correct_score,
147
+ planning_score=reply.planning_score,
148
+ reasoning_score=reply.reasoning_score,
149
+ coding_score=reply.coding_score,
150
+ important_score=reply.important_info_score,
151
+ user_supply_score=reply.user_supply_info_score,
152
+ )
@@ -7,14 +7,10 @@ https://opensource.org/licenses/MIT
7
7
 
8
8
  from .base import BaseTaskFlow
9
9
  from .master_planner import MasterPlannerFlow
10
- from .task_executor_v1 import TaskExecutorFlowV1
11
- from .task_executor_v2 import TaskExecutorFlowV2
12
10
  from .task_executor_v3 import TaskExecutorFlowV3
13
11
 
14
12
  __all__ = [
15
13
  "BaseTaskFlow",
16
14
  "MasterPlannerFlow",
17
- "TaskExecutorFlowV1",
18
- "TaskExecutorFlowV2",
19
15
  "TaskExecutorFlowV3",
20
16
  ]
@@ -13,9 +13,12 @@ from enum import Enum
13
13
  from typing import List, Dict, Optional, Type
14
14
  from IPython.display import Markdown
15
15
  from ..bot_agents.base import BaseAgent
16
+ from ..bot_evaluators.base import BaseEvaluator
17
+ from ..bot_evaluators.dummy_global import DummyGlobalEvaluator
18
+ from ..bot_evaluators.flow_task_executor import FlowTaskExecEvaluator
16
19
  from ..bot_outputs import _D, _I, _W, _E, _F, _M, _B
17
20
  from ..bot_outputs import set_stage, flush_output, output_evaluation
18
- from ..bot_outputs import FlowEvalutionRecord, StageEvalutionRecord, NotebookEvalutionRecord
21
+ from ..bot_evaluation import FlowEvaluationRecord, StageEvaluationRecord, NotebookEvaluationRecord
19
22
 
20
23
  TASK_AGENT_STATE_ERROR = "_AGENT_STATE_ERROR_32534526_"
21
24
  TASK_STAGE_START = "start"
@@ -37,9 +40,10 @@ class StageNext[ST](BaseModel):
37
40
  message: str = ""
38
41
 
39
42
 
40
- class StageTransition[ST, AS](BaseModel):
43
+ class StageNode[ST, AS](BaseModel):
41
44
  stage: ST | str
42
- agent: Type[BaseAgent] | str
45
+ agents: Type[BaseAgent] | List[Type[BaseAgent]]
46
+ evaluators: Optional[Type[BaseEvaluator] | List[Type[BaseEvaluator]]] = None
43
47
  states: Dict[AS | str, StageNext[ST] | List[StageNext[ST]] | Dict[TaskAction, StageNext[ST]] | ST | str] = {}
44
48
  next_stage: Optional[StageNext[ST] | List[StageNext[ST]] | Dict[TaskAction, StageNext[ST]] | ST | str] = None
45
49
 
@@ -49,15 +53,18 @@ class BaseTaskFlow:
49
53
  基础任务流程
50
54
  """
51
55
 
52
- STAGE_TRANSITIONS: List[StageTransition] = []
56
+ STAGE_NODES: List[StageNode] = []
53
57
  START_STAGE = TASK_STAGE_START
54
58
  STOP_STAGES = [TASK_STAGE_COMPLETED, TASK_STAGE_GLOBAL_FINISHED]
59
+ FLOW_EVALUATOR = FlowTaskExecEvaluator
60
+ GLOBAL_EVALUATOR = DummyGlobalEvaluator
55
61
 
56
- def __init__(self, notebook_context, agent_factory):
62
+ def __init__(self, notebook_context, agent_factory, evaluator_factory=None):
57
63
  self.notebook_context = notebook_context
58
64
  self.agent_factory = agent_factory
59
- self.stage_transitions = {}
60
- self.prepare_stage_transitions()
65
+ self.evaluator_factory = evaluator_factory
66
+ self.stage_nodes = {}
67
+ self.prepare_stage_nodes()
61
68
 
62
69
  @property
63
70
  def task(self):
@@ -67,10 +74,10 @@ class BaseTaskFlow:
67
74
  def cells(self):
68
75
  return self.notebook_context.cells
69
76
 
70
- def prepare_stage_transitions(self):
71
- for st in self.STAGE_TRANSITIONS:
77
+ def prepare_stage_nodes(self):
78
+ for st in self.STAGE_NODES:
72
79
  assert not (st.next_stage and st.states), "next_stage and states are mutually exclusive"
73
- self.stage_transitions[st.stage] = st
80
+ self.stage_nodes[st.stage] = st
74
81
  if st.next_stage:
75
82
  st.states[TaskAction.DEFAULT] = st.next_stage
76
83
  st.next_stage = None
@@ -99,15 +106,29 @@ class BaseTaskFlow:
99
106
  if TASK_AGENT_STATE_ERROR not in st.states:
100
107
  st.states[TASK_AGENT_STATE_ERROR] = {"*": StageNext(stage=st.stage)}
101
108
 
102
- def get_stage_agent(self, stage):
103
- for t in self.STAGE_TRANSITIONS:
109
+ def get_stage_agents(self, stage) -> List[BaseAgent]:
110
+ for t in self.STAGE_NODES:
104
111
  if t.stage == stage:
105
- return self.agent_factory(t.agent)
112
+ if isinstance(t.agents, list):
113
+ return [self.agent_factory(a) for a in t.agents]
114
+ else:
115
+ return [self.agent_factory(t.agents)]
106
116
  raise ValueError(f"No agent for stage `{stage}`")
107
117
 
118
+ def get_stage_evaluators(self, stage) -> List[BaseEvaluator]:
119
+ if self.evaluator_factory is None:
120
+ return []
121
+ for t in self.STAGE_NODES:
122
+ if t.stage == stage:
123
+ if isinstance(t.evaluators, list):
124
+ return [self.evaluator_factory(e) for e in t.evaluators]
125
+ else:
126
+ return [self.evaluator_factory(t.evaluators)]
127
+ return []
128
+
108
129
  def _get_next_stage_trans(self, stage, state, action=TaskAction.CONTINUE):
109
130
 
110
- st = self.stage_transitions.get(stage)
131
+ st = self.stage_nodes.get(stage)
111
132
  if st:
112
133
  state_ns = st.states.get(state) or st.states.get("*")
113
134
  assert state_ns, f"No next stage for stage `{stage}` and state `{state}`"
@@ -157,16 +178,19 @@ class BaseTaskFlow:
157
178
  stage_count = 0
158
179
  # Initialize the task stage
159
180
  stage = stage or self.START_STAGE
181
+ agent = None
160
182
  while n_tries <= max_tries:
161
183
  stage_st = time.time()
162
184
  try:
163
185
  stage_name = stage.value if isinstance(stage, Enum) else stage
164
186
  stage_name = stage_name.replace(".", "-").capitalize()
165
187
  set_stage(stage_name)
166
- agent = self.get_stage_agent(stage)
167
- _M(f"**Executing** stage `{stage}` with agent `{type(agent).__name__}` ...")
168
- failed, state = agent()
188
+ agents = self.get_stage_agents(stage)
189
+ for agent in agents:
190
+ _I(f"Executing stage `{stage}` with agent `{type(agent).__name__}` ...")
191
+ failed, state = agent()
169
192
  except Exception as e:
193
+ _W(f"Error during task execution stage `{stage}`: `{type(e)}`: `{e}`")
170
194
  _M(f"**Error** during task execution stage `{stage}`: `{type(e)}`: `{e}`")
171
195
  _M(f"```python\n{traceback.format_exc()}\n```")
172
196
  state = TASK_AGENT_STATE_ERROR
@@ -174,16 +198,39 @@ class BaseTaskFlow:
174
198
  stage_count += 1
175
199
  stage_duration = time.time() - stage_st
176
200
  flow_duration += stage_duration
177
- _M(f"Stage `{stage}` completed in {stage_duration:.2f} seconds with state `{state}` and failed `{failed}`")
178
- output_evaluation(
179
- StageEvalutionRecord(
180
- cell_index=self.task.cell_idx,
181
- flow=type(self).__name__,
182
- stage=str(stage),
183
- execution_duration=stage_duration,
184
- is_success=not failed,
201
+ _I(f"Stage `{stage}` completed in {stage_duration:.2f} seconds with state `{state}` and failed `{failed}`")
202
+ if evaluators := self.get_stage_evaluators(stage):
203
+ for evaluator in evaluators:
204
+ # If the agent has evaluators, run them
205
+ try:
206
+ _I(f"Evaluating stage `{stage}` with evaluator `{type(evaluator).__name__}` ...")
207
+ evaluation_result = evaluator()
208
+ evaluation_result.timestamp = evaluation_result.timestamp or time.time()
209
+ evaluation_result.evaluator = evaluation_result.evaluator or type(evaluator).__name__
210
+ evaluation_result.cell_index = self.task.cell_idx
211
+ evaluation_result.flow = type(self).__name__
212
+ evaluation_result.stage = str(stage)
213
+ evaluation_result.agent = type(agent).__name__
214
+ evaluation_result.execution_duration = stage_duration
215
+ evaluation_result.is_success = not failed
216
+ output_evaluation(evaluation_result)
217
+ except Exception as e:
218
+ _W(f"Error during task evaluation stage `{stage}`: `{type(e)}`: `{e}`")
219
+ _M(f"**Error** during task evaluation stage `{stage}`: `{type(e)}`: `{e}`")
220
+ _M(f"```python\n{traceback.format_exc()}\n```")
221
+ else:
222
+ output_evaluation(
223
+ StageEvaluationRecord(
224
+ timestamp=time.time(),
225
+ evaluator="default",
226
+ cell_index=self.task.cell_idx,
227
+ flow=type(self).__name__,
228
+ stage=str(stage),
229
+ agent=type(agent).__name__,
230
+ execution_duration=stage_duration,
231
+ is_success=not failed,
232
+ )
185
233
  )
186
- )
187
234
 
188
235
  if state != TASK_AGENT_STATE_ERROR:
189
236
  # Agent did not fail, check if we have reached the final stage
@@ -191,7 +238,7 @@ class BaseTaskFlow:
191
238
  self.task.agent_stage = next_stage
192
239
  self.task.update_cell()
193
240
  if next_stage in self.STOP_STAGES:
194
- _M(f"Task execution **Stopped** at stage `{next_stage}`")
241
+ _I(f"Task execution **Stopped** at stage `{next_stage}`")
195
242
  stage = next_stage
196
243
  break
197
244
 
@@ -212,37 +259,69 @@ class BaseTaskFlow:
212
259
  self.task.agent_stage = next_stage
213
260
  self.task.update_cell()
214
261
  if action == TaskAction.STOP:
215
- _M(f"Task execution **Stopped**, and set next stage to `{next_stage}`")
262
+ _I(f"Task execution **Stopped**, and set next stage to `{next_stage}`")
216
263
  stage = next_stage
217
264
  break
218
265
  else:
219
- _M(f"**Action**: `{action}` transits stage to `{next_stage}`")
266
+ _I(f"Action: `{action}` transits stage to `{next_stage}`")
220
267
  stage = next_stage
221
268
  else:
222
269
  # transit to the next stage without confirmation
223
270
  next_stage = self.get_next_stage(stage, state, TaskAction.CONTINUE)
224
271
  self.task.agent_stage = next_stage
225
272
  self.task.update_cell()
226
- _M(f"**Transits** stage to `{next_stage}`")
273
+ _I(f"Transits stage to `{next_stage}`")
227
274
  stage = next_stage
228
-
229
275
  if not stage_continue:
230
276
  break
231
277
  # Finalize the task execution
232
278
  stage_name = stage.value if isinstance(stage, Enum) else stage
233
279
  if stage_name == TASK_STAGE_GLOBAL_FINISHED:
234
280
  _M("Task execution **finished** globally.")
235
- output_evaluation(NotebookEvalutionRecord(cell_index=self.task.cell_idx, is_success=True))
281
+ if self.evaluator_factory is not None and hasattr(self, "GLOBAL_EVALUATOR") and self.GLOBAL_EVALUATOR:
282
+ evaluator = self.evaluator_factory(self.GLOBAL_EVALUATOR)
283
+ _I(f"Evaluating notebook with evaluator `{type(evaluator).__name__}` ...")
284
+ evaluation_result = evaluator()
285
+ evaluation_result.timestamp = evaluation_result.timestamp or time.time()
286
+ evaluation_result.evaluator = evaluation_result.evaluator or type(evaluator).__name__
287
+ evaluation_result.cell_index = self.task.cell_idx
288
+ evaluation_result.is_success = True
289
+ output_evaluation(evaluation_result)
290
+ else:
291
+ output_evaluation(
292
+ NotebookEvaluationRecord(
293
+ timestamp=time.time(),
294
+ evaluator="default",
295
+ cell_index=self.task.cell_idx,
296
+ is_success=True,
297
+ )
298
+ )
236
299
  elif stage_name == TASK_STAGE_COMPLETED:
237
- _M(f"Task execution **completed** in {flow_duration:.2f} seconds with {stage_count} stages.")
238
- output_evaluation(
239
- FlowEvalutionRecord(
240
- cell_index=self.task.cell_idx,
241
- flow=type(self).__name__,
242
- stage_count=stage_count,
243
- execution_duration=flow_duration,
244
- is_success=True,
300
+ _I(f"Task execution **completed** in {flow_duration:.2f} seconds with {stage_count} stages.")
301
+ if self.evaluator_factory is not None and hasattr(self, "FLOW_EVALUATOR") and self.FLOW_EVALUATOR:
302
+ evaluator = self.evaluator_factory(self.FLOW_EVALUATOR)
303
+ _I(f"Evaluating flow `{type(self).__name__}` with evaluator `{type(evaluator).__name__}` ...")
304
+ evaluation_result = evaluator()
305
+ evaluation_result.timestamp = evaluation_result.timestamp or time.time()
306
+ evaluation_result.evaluator = evaluation_result.evaluator or type(evaluator).__name__
307
+ evaluation_result.cell_index = self.task.cell_idx
308
+ evaluation_result.flow = type(self).__name__
309
+ evaluation_result.stage_count = stage_count
310
+ evaluation_result.execution_duration = flow_duration
311
+ evaluation_result.is_success = True
312
+ output_evaluation(evaluation_result)
313
+ else:
314
+ # If no evaluator, just output the evaluation record
315
+ output_evaluation(
316
+ FlowEvaluationRecord(
317
+ timestamp=time.time(),
318
+ evaluator="default",
319
+ cell_index=self.task.cell_idx,
320
+ flow=type(self).__name__,
321
+ stage_count=stage_count,
322
+ execution_duration=flow_duration,
323
+ is_success=True,
324
+ )
245
325
  )
246
- )
247
326
  flush_output()
248
327
  return stage
@@ -5,13 +5,24 @@ This software is released under the MIT License.
5
5
  https://opensource.org/licenses/MIT
6
6
  """
7
7
 
8
- from .base import BaseTaskFlow, StageTransition, TASK_STAGE_START, TASK_STAGE_COMPLETED
8
+ from .base import BaseTaskFlow, StageNode, TASK_STAGE_START, TASK_STAGE_COMPLETED
9
+ from ..bot_evaluators.flow_global_planning import FlowGlobalPlanningEvaluator
10
+ from ..bot_agents.master_planner import MasterPlannerAgent
11
+ from ..bot_agents.output_task_result import OutputTaskResult
12
+ from ..bot_agents.prepare_next_cell import PrepareNextCell
13
+ from ..bot_evaluators.dummy_task import DummyTaskEvaluator
9
14
 
10
15
 
11
16
  class MasterPlannerFlow(BaseTaskFlow):
12
17
 
13
- STAGE_TRANSITIONS = [
14
- StageTransition(stage=TASK_STAGE_START, agent="MasterPlannerAgent", next_stage=TASK_STAGE_COMPLETED),
15
- StageTransition(stage=TASK_STAGE_COMPLETED, agent="OutputTaskResult", next_stage=TASK_STAGE_COMPLETED),
18
+ STAGE_NODES = [
19
+ StageNode(
20
+ stage=TASK_STAGE_START,
21
+ agents=MasterPlannerAgent,
22
+ evaluators=DummyTaskEvaluator,
23
+ next_stage=TASK_STAGE_COMPLETED,
24
+ ),
25
+ StageNode(stage=TASK_STAGE_COMPLETED, agents=OutputTaskResult, next_stage=TASK_STAGE_COMPLETED),
16
26
  ]
17
27
  STOP_STAGES = [TASK_STAGE_COMPLETED]
28
+ FLOW_EVALUATOR = FlowGlobalPlanningEvaluator
@@ -8,32 +8,34 @@ https://opensource.org/licenses/MIT
8
8
  from enum import Enum
9
9
  from .base import (
10
10
  BaseTaskFlow,
11
- StageTransition,
11
+ StageNode,
12
12
  StageNext,
13
13
  TaskAction,
14
14
  TASK_STAGE_COMPLETED,
15
15
  TASK_STAGE_GLOBAL_FINISHED,
16
16
  )
17
- from ..bot_agents import (
18
- TaskPlannerAgentV3,
19
- TaskCodingAgent,
20
- CodeDebugerAgent,
21
- CodeExecutor,
22
- TaskStructureSummaryAgent,
23
- TaskStructureReasoningAgent,
24
- OutputTaskResult,
25
- )
26
- from ..bot_agents.task_planner_v3 import TaskPlannerState
17
+ from ..bot_agents.task_planner_v3 import TaskPlannerAgentV3, TaskPlannerState
18
+ from ..bot_agents.task_coder import TaskCodingAgent
19
+ from ..bot_agents.task_debuger import CodeDebugerAgent
20
+ from ..bot_agents.task_code_executor import CodeExecutor
21
+ from ..bot_agents.task_structrue_summarier import TaskStructureSummaryAgent, TaskStructureSummaryState
22
+ from ..bot_agents.task_structrue_reasoner import TaskStructureReasoningAgent, TaskStructureReasonState
23
+ from ..bot_agents.output_task_result import OutputTaskResult
24
+ from ..bot_agents.request_user_supply import RequestAboveUserSupplyAgent, RequestBelowUserSupplyAgent
25
+ from ..bot_agents.prepare_next_cell import PrepareNextCell
27
26
 
28
27
 
29
28
  class TaskStage(str, Enum):
30
29
  PLANNING = "planning"
31
30
  PLANNING_PAUSED = "planning_paused"
31
+ REQUEST_INFO_ABOVE = "request_info_above"
32
+ REQUEST_INFO_BELOW = "request_info_below"
32
33
  CODING = "coding"
33
34
  EXECUTING = "executing"
34
35
  DEBUGGING = "debugging"
35
36
  REASONING = "reasoning"
36
37
  SUMMARY = "summary"
38
+ PREPARE_NEXT = "prepare_next"
37
39
  OUTPUT_RESULT = "output_result"
38
40
  COMPLETED = TASK_STAGE_COMPLETED
39
41
  GLOBAL_FINISHED = TASK_STAGE_GLOBAL_FINISHED
@@ -43,20 +45,25 @@ class TaskExecutorFlowV3(BaseTaskFlow):
43
45
 
44
46
  START_STAGE = TaskStage.PLANNING
45
47
  STOP_STAGES = [TaskStage.COMPLETED, TaskStage.PLANNING_PAUSED, TaskStage.GLOBAL_FINISHED]
46
- STAGE_TRANSITIONS = [
47
- StageTransition[TaskStage, TaskPlannerState](
48
+ STAGE_NODES = [
49
+ StageNode[TaskStage, TaskPlannerState](
48
50
  stage=TaskStage.PLANNING,
49
- agent=TaskPlannerAgentV3,
51
+ agents=TaskPlannerAgentV3,
50
52
  states={
51
53
  TaskPlannerState.CODING_PLANNED: TaskStage.CODING,
52
54
  TaskPlannerState.REASONING_PLANNED: TaskStage.REASONING,
53
- TaskPlannerState.REQUEST_INFO: TaskStage.PLANNING_PAUSED,
55
+ TaskPlannerState.REQUEST_INFO: TaskStage.REQUEST_INFO_ABOVE,
54
56
  TaskPlannerState.GLOBAL_FINISHED: TaskStage.GLOBAL_FINISHED,
55
57
  },
56
58
  ),
57
- StageTransition[TaskStage, TaskPlannerState](
59
+ StageNode[TaskStage, None](
60
+ stage=TaskStage.REQUEST_INFO_ABOVE,
61
+ agents=RequestAboveUserSupplyAgent,
62
+ next_stage=TaskStage.PLANNING_PAUSED,
63
+ ),
64
+ StageNode[TaskStage, TaskPlannerState](
58
65
  stage=TaskStage.PLANNING_PAUSED,
59
- agent=TaskPlannerAgentV3,
66
+ agents=TaskPlannerAgentV3,
60
67
  states={
61
68
  TaskPlannerState.CODING_PLANNED: TaskStage.CODING,
62
69
  TaskPlannerState.REASONING_PLANNED: TaskStage.REASONING,
@@ -64,37 +71,49 @@ class TaskExecutorFlowV3(BaseTaskFlow):
64
71
  TaskPlannerState.GLOBAL_FINISHED: TaskStage.COMPLETED,
65
72
  },
66
73
  ),
67
- StageTransition[TaskStage, None](
68
- stage=TaskStage.CODING, agent=TaskCodingAgent, next_stage=TaskStage.EXECUTING
69
- ),
70
- StageTransition[TaskStage, bool](
74
+ StageNode[TaskStage, None](stage=TaskStage.CODING, agents=TaskCodingAgent, next_stage=TaskStage.EXECUTING),
75
+ StageNode[TaskStage, bool](
71
76
  stage=TaskStage.EXECUTING,
72
- agent=CodeExecutor,
77
+ agents=CodeExecutor,
73
78
  states={True: TaskStage.SUMMARY, False: TaskStage.DEBUGGING},
74
79
  ),
75
- StageTransition[TaskStage, None](
76
- stage=TaskStage.DEBUGGING, agent=CodeDebugerAgent, next_stage=TaskStage.EXECUTING
77
- ),
78
- StageTransition[TaskStage, None](
79
- stage=TaskStage.REASONING, agent=TaskStructureReasoningAgent, next_stage=TaskStage.COMPLETED
80
+ StageNode[TaskStage, None](stage=TaskStage.DEBUGGING, agents=CodeDebugerAgent, next_stage=TaskStage.EXECUTING),
81
+ StageNode[TaskStage, TaskStructureReasonState](
82
+ stage=TaskStage.REASONING,
83
+ agents=TaskStructureReasoningAgent,
84
+ states={
85
+ TaskStructureReasonState.DONE: TaskStage.COMPLETED,
86
+ TaskStructureReasonState.REQUEST_INFO: TaskStage.REQUEST_INFO_BELOW,
87
+ },
80
88
  ),
81
- StageTransition[TaskStage, None](
89
+ StageNode[TaskStage, TaskStructureSummaryState](
82
90
  stage=TaskStage.SUMMARY,
83
- agent=TaskStructureSummaryAgent,
84
- next_stage={
85
- TaskAction.DEFAULT: StageNext(stage=TaskStage.COMPLETED),
86
- TaskAction.STOP: StageNext(stage=TaskStage.EXECUTING),
91
+ agents=TaskStructureSummaryAgent,
92
+ states={
93
+ TaskStructureSummaryState.DONE: {
94
+ TaskAction.DEFAULT: StageNext(stage=TaskStage.PREPARE_NEXT),
95
+ TaskAction.STOP: StageNext(stage=TaskStage.EXECUTING),
96
+ },
97
+ TaskStructureSummaryState.REQUEST_INFO: TaskStage.REQUEST_INFO_BELOW,
87
98
  },
88
99
  ),
89
- StageTransition[TaskStage, bool](
100
+ StageNode[TaskStage, None](
101
+ stage=TaskStage.PREPARE_NEXT, agents=PrepareNextCell, next_stage=TaskStage.COMPLETED
102
+ ),
103
+ StageNode[TaskStage, None](
104
+ stage=TaskStage.REQUEST_INFO_BELOW,
105
+ agents=[PrepareNextCell, RequestBelowUserSupplyAgent],
106
+ next_stage=TaskStage.COMPLETED,
107
+ ),
108
+ StageNode[TaskStage, bool](
90
109
  stage=TaskStage.COMPLETED,
91
- agent=CodeExecutor,
110
+ agents=CodeExecutor,
92
111
  states={True: TaskStage.OUTPUT_RESULT, False: TaskStage.DEBUGGING},
93
112
  ),
94
- StageTransition[TaskStage, None](
95
- stage=TaskStage.OUTPUT_RESULT, agent=OutputTaskResult, next_stage=TaskStage.COMPLETED
113
+ StageNode[TaskStage, None](
114
+ stage=TaskStage.OUTPUT_RESULT, agents=OutputTaskResult, next_stage=TaskStage.COMPLETED
96
115
  ),
97
- StageTransition[TaskStage, None](
98
- stage=TaskStage.GLOBAL_FINISHED, agent=OutputTaskResult, next_stage=TaskStage.GLOBAL_FINISHED
116
+ StageNode[TaskStage, None](
117
+ stage=TaskStage.GLOBAL_FINISHED, agents=OutputTaskResult, next_stage=TaskStage.GLOBAL_FINISHED
99
118
  ),
100
119
  ]