jupyter-agent 2025.6.100__py3-none-any.whl → 2025.6.101__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 (35) hide show
  1. jupyter_agent/__init__.py +0 -0
  2. jupyter_agent/bot_agents/__init__.py +42 -0
  3. jupyter_agent/bot_agents/base.py +324 -0
  4. jupyter_agent/bot_agents/master_planner.py +45 -0
  5. jupyter_agent/bot_agents/output_task_result.py +29 -0
  6. jupyter_agent/bot_agents/task_code_executor.py +53 -0
  7. jupyter_agent/bot_agents/task_coder.py +71 -0
  8. jupyter_agent/bot_agents/task_debuger.py +69 -0
  9. jupyter_agent/bot_agents/task_planner_v1.py +158 -0
  10. jupyter_agent/bot_agents/task_planner_v2.py +172 -0
  11. jupyter_agent/bot_agents/task_planner_v3.py +189 -0
  12. jupyter_agent/bot_agents/task_reasoner.py +61 -0
  13. jupyter_agent/bot_agents/task_structrue_reasoner.py +106 -0
  14. jupyter_agent/bot_agents/task_structrue_summarier.py +123 -0
  15. jupyter_agent/bot_agents/task_summarier.py +76 -0
  16. jupyter_agent/bot_agents/task_verifier.py +99 -0
  17. jupyter_agent/bot_agents/task_verify_summarier.py +134 -0
  18. jupyter_agent/bot_chat.py +218 -0
  19. jupyter_agent/bot_contexts.py +466 -0
  20. jupyter_agent/bot_flows/__init__.py +20 -0
  21. jupyter_agent/bot_flows/base.py +209 -0
  22. jupyter_agent/bot_flows/master_planner.py +16 -0
  23. jupyter_agent/bot_flows/task_executor_v1.py +86 -0
  24. jupyter_agent/bot_flows/task_executor_v2.py +84 -0
  25. jupyter_agent/bot_flows/task_executor_v3.py +89 -0
  26. jupyter_agent/bot_magics.py +127 -0
  27. jupyter_agent/bot_outputs.py +480 -0
  28. jupyter_agent/utils.py +138 -0
  29. {jupyter_agent-2025.6.100.dist-info → jupyter_agent-2025.6.101.dist-info}/METADATA +13 -7
  30. jupyter_agent-2025.6.101.dist-info/RECORD +33 -0
  31. jupyter_agent-2025.6.101.dist-info/top_level.txt +1 -0
  32. jupyter_agent-2025.6.100.dist-info/RECORD +0 -5
  33. jupyter_agent-2025.6.100.dist-info/top_level.txt +0 -1
  34. {jupyter_agent-2025.6.100.dist-info → jupyter_agent-2025.6.101.dist-info}/WHEEL +0 -0
  35. {jupyter_agent-2025.6.100.dist-info → jupyter_agent-2025.6.101.dist-info}/licenses/LICENSE +0 -0
File without changes
@@ -0,0 +1,42 @@
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
+ from .base import BaseChatAgent, AgentFactory
9
+ from .master_planner import MasterPlannerAgent
10
+ from .output_task_result import OutputTaskResult
11
+ from .task_code_executor import CodeExecutor
12
+ from .task_planner_v1 import TaskPlannerAgentV1
13
+ from .task_planner_v2 import TaskPlannerAgentV2
14
+ from .task_planner_v3 import TaskPlannerAgentV3
15
+ from .task_coder import TaskCodingAgent
16
+ from .task_debuger import CodeDebugerAgent
17
+ from .task_verifier import TaskVerifyAgent, TaskVerifyState
18
+ from .task_summarier import TaskSummaryAgent
19
+ from .task_verify_summarier import TaskVerifySummaryAgent
20
+ from .task_structrue_summarier import TaskStructureSummaryAgent
21
+ from .task_reasoner import TaskReasoningAgent
22
+ from .task_structrue_reasoner import TaskStructureReasoningAgent
23
+
24
+ __all__ = [
25
+ "AgentFactory",
26
+ "BaseChatAgent",
27
+ "CodeDebugerAgent",
28
+ "CodeExecutor",
29
+ "MasterPlannerAgent",
30
+ "TaskCodingAgent",
31
+ "TaskPlannerAgentV1",
32
+ "TaskPlannerAgentV2",
33
+ "TaskPlannerAgentV3",
34
+ "TaskReasoningAgent",
35
+ "TaskStructureReasoningAgent",
36
+ "TaskStructureSummaryAgent",
37
+ "TaskSummaryAgent",
38
+ "TaskVerifyAgent",
39
+ "TaskVerifyState",
40
+ "TaskVerifySummaryAgent",
41
+ "OutputTaskResult",
42
+ ]
@@ -0,0 +1,324 @@
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 json
9
+ import importlib
10
+
11
+ from typing import Tuple, Any
12
+ from enum import Enum, unique
13
+ from IPython.display import Markdown
14
+ from ..bot_outputs import _C, flush_output
15
+ from ..bot_chat import BotChat
16
+ from ..utils import no_indent
17
+
18
+ _TASK_CONTEXTS = no_indent(
19
+ """
20
+ **全局任务规划及子任务完成情况**:
21
+
22
+ {% for cell in cells %}
23
+ {% if cell.type == "planning" and cell.source.strip() %}
24
+ {{ cell.source }}
25
+ {{ cell.result }}
26
+ {% elif cell.type == "task" and cell.subject.strip() %}
27
+ ## 子任务[{{ cell.task_id }}] - {{ '已完成' if cell.result else '未完成' }}
28
+
29
+ ### 任务目标
30
+
31
+ {{ cell.subject }}
32
+
33
+ ### 任务结果
34
+
35
+ {{ cell.result }}
36
+
37
+ {% if cell.important_infos %}
38
+ ### 任务结论中的重要信息(Important Infos)
39
+
40
+ ```json
41
+ {{ cell.important_infos | json }}
42
+ ```
43
+ {%+ endif %}
44
+ {% elif cell.is_task_context and cell.source.strip() %}
45
+ {{ cell.source }}
46
+ {% endif %}
47
+ {% endfor %}
48
+ """
49
+ )
50
+
51
+
52
+ _CODE_CONTEXTS = no_indent(
53
+ """
54
+ **已执行的代码**:
55
+
56
+ ```python
57
+ {% for cell in cells +%}
58
+ {% if cell.type == "task" and cell.source.strip() %}
59
+ ######## Cell[{{ cell.cell_idx }}] for Task[{{ cell.task_id }}] ########
60
+
61
+ {{ cell.source }}
62
+ {% elif cell.is_code_context and cell.source.strip() %}
63
+ ######## Cell[{{ cell.cell_idx }}] ########
64
+
65
+ {{ cell.source }}
66
+ {% endif %}
67
+ {%+ endfor %}
68
+ ```
69
+ """
70
+ )
71
+
72
+ _TASK_OUTPUT_FORMAT = """
73
+ {% if OUTPUT_FORMAT == "code" %}
74
+ **输出格式**:
75
+
76
+ 输出{{ OUTPUT_CODE_LANG }}代码块,以Markdown格式显示,使用```{{ OUTPUT_CODE_LANG }}...```包裹。
77
+
78
+ 示例代码:
79
+
80
+ ```python
81
+ def xxx(xxx):
82
+ ...
83
+ return xxx
84
+
85
+ xxx(...)
86
+ ```
87
+
88
+ {% elif OUTPUT_FORMAT == "json" %}
89
+ **输出格式**:
90
+
91
+ 输出JSON格式数据,以Markdown格式显示,使用```json...```包裹。
92
+
93
+ 数据符合JSON Schema:
94
+
95
+ ```json
96
+ {{ OUTPUT_JSON_SCHEMA }}
97
+ ```
98
+
99
+ 数据示例:
100
+
101
+ ```json
102
+ {{ OUTPUT_JSON_EXAMPLE }}
103
+ ```
104
+
105
+ {% endif %}
106
+ """
107
+
108
+ PREDEFINE_PROMPT_BLOCKS = {
109
+ "TASK_CONTEXTS": _TASK_CONTEXTS,
110
+ "CODE_CONTEXTS": _CODE_CONTEXTS,
111
+ "TASK_OUTPUT_FORMAT": _TASK_OUTPUT_FORMAT,
112
+ }
113
+
114
+
115
+ @unique
116
+ class AgentOutputFormat(str, Enum):
117
+ RAW = "raw"
118
+ TEXT = "text"
119
+ CODE = "code"
120
+ JSON = "json"
121
+
122
+
123
+ @unique
124
+ class AgentCombineReply(str, Enum):
125
+ FIRST = "first"
126
+ LAST = "last"
127
+ LIST = "list"
128
+ MERGE = "merge"
129
+
130
+
131
+ @unique
132
+ class AgentModelType(str, Enum):
133
+ DEFAULT = "default"
134
+ PLANNER = "planner"
135
+ CODING = "coding"
136
+ REASONING = "reasoning"
137
+
138
+
139
+ class BaseAgent:
140
+ """基础代理类"""
141
+
142
+ def __init__(self, notebook_context):
143
+ self.notebook_context = notebook_context
144
+
145
+ @property
146
+ def task(self):
147
+ return self.notebook_context.cur_task
148
+
149
+ @property
150
+ def cells(self):
151
+ return self.notebook_context.cells
152
+
153
+
154
+ class BaseChatAgent(BotChat, BaseAgent):
155
+ """基础聊天代理类"""
156
+
157
+ PROMPT = "You are a helpful assistant. {{ prompt }}\n\nAnswer:"
158
+ OUTPUT_FORMAT = AgentOutputFormat.RAW
159
+ OUTPUT_CODE_LANG = "python"
160
+ OUTPUT_JSON_SCHEMA = None # Pydantic Model
161
+ DISPLAY_REPLY = True
162
+ COMBINE_REPLY = AgentCombineReply.MERGE
163
+ ACCEPT_EMPYT_REPLY = False
164
+ MODEL_TYPE = AgentModelType.REASONING
165
+
166
+ def __init__(self, notebook_context, base_url, api_key, model_name, **chat_kwargs):
167
+ """初始化基础任务代理"""
168
+ BaseAgent.__init__(self, notebook_context)
169
+ BotChat.__init__(self, base_url, api_key, model_name, **chat_kwargs)
170
+
171
+ def prepare_contexts(self, **kwargs):
172
+ contexts = {
173
+ "cells": self.cells,
174
+ "task": self.task,
175
+ "OUTPUT_FORMAT": self.OUTPUT_FORMAT,
176
+ "OUTPUT_CODE_LANG": self.OUTPUT_CODE_LANG,
177
+ }
178
+ if self.OUTPUT_JSON_SCHEMA:
179
+ json_schema = self.OUTPUT_JSON_SCHEMA.model_json_schema()
180
+ model_fields = getattr(self.OUTPUT_JSON_SCHEMA, "model_fields", None)
181
+ if model_fields and hasattr(model_fields, "items"):
182
+ json_example = {
183
+ name: field.examples[0] if getattr(field, "examples", None) else getattr(field, "default", None)
184
+ for name, field in model_fields.items()
185
+ }
186
+ else:
187
+ json_example = {}
188
+ contexts["OUTPUT_JSON_SCHEMA"] = json.dumps(json_schema, indent=2, ensure_ascii=False)
189
+ contexts["OUTPUT_JSON_EXAMPLE"] = json.dumps(json_example, indent=2, ensure_ascii=False)
190
+ contexts.update(kwargs)
191
+ return contexts
192
+
193
+ def create_messages(self, contexts):
194
+ messages = super().create_messages(contexts, templates=PREDEFINE_PROMPT_BLOCKS)
195
+ messages.add(self.PROMPT)
196
+ return messages
197
+
198
+ def combine_raw_replies(self, replies):
199
+ if self.COMBINE_REPLY == AgentCombineReply.FIRST:
200
+ return replies[0]["raw"]
201
+ elif self.COMBINE_REPLY == AgentCombineReply.LAST:
202
+ return replies[-1]["raw"]
203
+ elif self.COMBINE_REPLY == AgentCombineReply.MERGE:
204
+ return "".join([reply["raw"] for reply in replies])
205
+ else:
206
+ raise ValueError("Unsupported combine_reply: {} for raw output".format(self.COMBINE_REPLY))
207
+
208
+ def combine_code_replies(self, replies):
209
+ code_replies = [
210
+ reply for reply in replies if reply["type"] == "code" and reply["lang"] == self.OUTPUT_CODE_LANG
211
+ ]
212
+ if self.COMBINE_REPLY == AgentCombineReply.FIRST:
213
+ return code_replies[0]["content"]
214
+ elif self.COMBINE_REPLY == AgentCombineReply.LAST:
215
+ return code_replies[-1]["content"]
216
+ elif self.COMBINE_REPLY == AgentCombineReply.MERGE:
217
+ return "\n".join([reply["content"] for reply in code_replies])
218
+ else:
219
+ raise ValueError("Unsupported combine_reply: {} for code output".format(self.COMBINE_REPLY))
220
+
221
+ def combine_json_replies(self, replies):
222
+ json_replies = [reply for reply in replies if reply["type"] == "code" and reply["lang"] == "json"]
223
+ if self.COMBINE_REPLY == AgentCombineReply.FIRST:
224
+ json_obj = json.loads(json_replies[0]["content"])
225
+ if self.OUTPUT_JSON_SCHEMA:
226
+ json_obj = self.OUTPUT_JSON_SCHEMA(**json_obj)
227
+ return json_obj
228
+ elif self.COMBINE_REPLY == AgentCombineReply.LAST:
229
+ json_obj = json.loads(json_replies[-1]["content"])
230
+ if self.OUTPUT_JSON_SCHEMA:
231
+ json_obj = self.OUTPUT_JSON_SCHEMA(**json_obj)
232
+ return json_obj
233
+ elif self.COMBINE_REPLY == AgentCombineReply.LIST:
234
+ json_objs = [json.loads(reply["content"]) for reply in json_replies]
235
+ if self.OUTPUT_JSON_SCHEMA:
236
+ json_objs = [self.OUTPUT_JSON_SCHEMA(**json_obj) for json_obj in json_objs]
237
+ return json_objs
238
+ elif self.COMBINE_REPLY == AgentCombineReply.MERGE:
239
+ json_obj = {}
240
+ for json_reply in json_replies:
241
+ json_obj.update(json.loads(json_reply["content"]))
242
+ if self.OUTPUT_JSON_SCHEMA:
243
+ json_obj = self.OUTPUT_JSON_SCHEMA(**json_obj)
244
+ return json_obj
245
+ else:
246
+ raise ValueError("Unsupported combine_reply: {} for json output".format(self.COMBINE_REPLY))
247
+
248
+ def combine_text_replies(self, replies):
249
+ text_replies = [reply for reply in replies if reply["type"] == "text"]
250
+ if self.COMBINE_REPLY == AgentCombineReply.FIRST:
251
+ return text_replies[0]["content"]
252
+ elif self.COMBINE_REPLY == AgentCombineReply.LAST:
253
+ return text_replies[-1]["content"]
254
+ elif self.COMBINE_REPLY == AgentCombineReply.MERGE:
255
+ return "".join([reply["content"] for reply in text_replies])
256
+ else:
257
+ raise ValueError("Unsupported combine_reply: {} for text output".format(self.COMBINE_REPLY))
258
+
259
+ def combine_replies(self, replies):
260
+ if self.OUTPUT_FORMAT == AgentOutputFormat.RAW:
261
+ return self.combine_raw_replies(replies).strip()
262
+ elif self.OUTPUT_FORMAT == AgentOutputFormat.TEXT:
263
+ return self.combine_text_replies(replies).strip()
264
+ elif self.OUTPUT_FORMAT == AgentOutputFormat.CODE:
265
+ return self.combine_code_replies(replies).strip()
266
+ elif self.OUTPUT_FORMAT == AgentOutputFormat.JSON:
267
+ return self.combine_json_replies(replies)
268
+ else:
269
+ raise ValueError("Unsupported output format: {}".format(self.OUTPUT_FORMAT))
270
+
271
+ def on_reply(self, reply) -> Tuple[bool, Any] | Any:
272
+ _C(Markdown(reply))
273
+
274
+ def __call__(self, **kwargs) -> Tuple[bool, Any]:
275
+ contexts = self.prepare_contexts(**kwargs)
276
+ messages = self.create_messages(contexts)
277
+ replies = self.chat(messages.get(), display_reply=self.DISPLAY_REPLY)
278
+ reply = self.combine_replies(replies)
279
+ if not self.ACCEPT_EMPYT_REPLY and not reply:
280
+ raise ValueError("Reply is empty")
281
+ result = self.on_reply(reply)
282
+ flush_output()
283
+ if not isinstance(result, tuple):
284
+ return False, result
285
+ else:
286
+ return result
287
+
288
+
289
+ class AgentFactory:
290
+
291
+ def __init__(self, notebook_context, **chat_kwargs):
292
+ self.notebook_context = notebook_context
293
+ self.chat_kwargs = chat_kwargs
294
+ self.models = {AgentModelType.DEFAULT: {"api_url": None, "api_key": None, "model": None}}
295
+
296
+ def config_model(self, agent_model, api_url, api_key, model_name):
297
+ self.models[agent_model] = {
298
+ "api_url": api_url,
299
+ "api_key": api_key,
300
+ "model": model_name,
301
+ }
302
+
303
+ def __call__(self, agent_class):
304
+
305
+ if isinstance(agent_class, str):
306
+ bot_agents = importlib.import_module("..bot_agents", __package__)
307
+ agent_class = getattr(bot_agents, agent_class)
308
+
309
+ if issubclass(agent_class, BaseChatAgent):
310
+ agent_model = agent_class.MODEL_TYPE if hasattr(agent_class, "MODEL_TYPE") else AgentModelType.DEFAULT
311
+ return agent_class(
312
+ notebook_context=self.notebook_context,
313
+ base_url=self.models.get(agent_model, {}).get("api_url")
314
+ or self.models[AgentModelType.DEFAULT]["api_url"],
315
+ api_key=self.models.get(agent_model, {}).get("api_key")
316
+ or self.models[AgentModelType.DEFAULT]["api_key"],
317
+ model_name=self.models.get(agent_model, {}).get("model")
318
+ or self.models[AgentModelType.DEFAULT]["model"],
319
+ **self.chat_kwargs,
320
+ )
321
+ elif issubclass(agent_class, BaseAgent):
322
+ return agent_class(notebook_context=self.notebook_context)
323
+ else:
324
+ raise ValueError("Unsupported agent class: {}".format(agent_class))
@@ -0,0 +1,45 @@
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
+ from IPython.display import Markdown
9
+ from .base import BaseChatAgent, AgentModelType
10
+ from ..bot_outputs import _C, ReplyType
11
+
12
+ MASTER_PLANNER_PROMPT = """\
13
+ **角色定义**:
14
+
15
+ 你是一个高级分析规划专家,擅长将自然语言任务拆解为可执行的Jupyter Notebook分析流程。
16
+
17
+ **任务要求**:
18
+
19
+ - 解析用户输入的自然语言指令(目标Prompt),提取核心需求(如数据来源、分析目标、输出格式等)
20
+ - 将核心需求转化为可执行的Jupyter Notebook分析流程
21
+ - 流程的每个环节应尽量简单明确
22
+ - 生成**目标规划说明**,包含:
23
+ 1. 需要执行的子任务列表(按逻辑顺序排列)
24
+ 3. 每个子任务的输入/输出依赖关系
25
+ 4. 预期的最终输出形式(文字/图表/表格等)
26
+
27
+ **用户需求**:
28
+
29
+ {{ task.source }}
30
+
31
+ ---
32
+
33
+ 请根据上述信息为用户规划全局执行计划:
34
+ """
35
+
36
+
37
+ class MasterPlannerAgent(BaseChatAgent):
38
+ """全局规划器代理类"""
39
+
40
+ PROMPT = MASTER_PLANNER_PROMPT
41
+ DISPLAY_REPLY = False
42
+ MODEL_TYPE = AgentModelType.PLANNER
43
+
44
+ def on_reply(self, reply):
45
+ _C(Markdown(reply), reply_type=ReplyType.TASK_RESULT)
@@ -0,0 +1,29 @@
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 json
9
+
10
+ from IPython.display import Markdown
11
+ from .base import BaseAgent
12
+ from ..bot_outputs import _D, _I, _W, _E, _F, _M, _B, _C, _O, ReplyType, markdown_block
13
+
14
+
15
+ class OutputTaskResult(BaseAgent):
16
+
17
+ def __call__(self):
18
+ """执行代码逻辑"""
19
+ if self.task.result:
20
+ _O(Markdown("### 任务结果\n\n"))
21
+ _C(Markdown(self.task.result), reply_type=ReplyType.TASK_RESULT)
22
+ if self.task.important_infos:
23
+ _O(
24
+ markdown_block(
25
+ f"```json\n{json.dumps(self.task.important_infos, indent=4, ensure_ascii=False)}\n```",
26
+ title="重要信息",
27
+ )
28
+ )
29
+ return False, None
@@ -0,0 +1,53 @@
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 re
9
+
10
+ from IPython.core.getipython import get_ipython
11
+ from IPython.display import Markdown, clear_output
12
+ from .base import BaseAgent
13
+ from ..utils import TeeOutputCapture
14
+ from ..bot_outputs import _D, _I, _W, _E, _F, _M, _B, _C, ReplyType
15
+
16
+
17
+ class CodeExecutor(BaseAgent):
18
+
19
+ def __call__(self):
20
+ """执行代码逻辑"""
21
+ _D(f"执行代码: {repr(self.task.source)[:80]}")
22
+ ipython = get_ipython()
23
+ exec_failed = False
24
+ with TeeOutputCapture() as captured:
25
+ if ipython is None:
26
+ exec_failed = True
27
+ self.task.cell_error = "IPython environment not found."
28
+ _E("执行失败: IPython environment not found.")
29
+ result = None
30
+ else:
31
+ result = ipython.run_cell(self.task.source)
32
+ if result.success:
33
+ self.task.cell_result = "{}".format(result.result)
34
+ _D(f"执行结果: {repr(self.task.cell_result)[:80]}")
35
+ else:
36
+ exec_failed = True
37
+ exc_info = ipython._format_exception_for_storage(result.error_before_exec or result.error_in_exec)
38
+ ansi_escape = re.compile(r"\x1b\[[0-9;]*m")
39
+ clean_traceback = "\n".join(ansi_escape.sub("", line) for line in exc_info["traceback"])
40
+ self.task.cell_error = clean_traceback
41
+ _E(f"执行失败: {clean_traceback}")
42
+ self.task.cell_output = ""
43
+ if captured.stdout:
44
+ self.task.cell_output += "Stdout:\n" + captured.stdout + "\n"
45
+ if captured.stderr:
46
+ self.task.cell_output += "Stderr:\n" + captured.stderr + "\n"
47
+ if captured.outputs:
48
+ self.task.cell_output += "Outputs:\n"
49
+ for output in captured.outputs:
50
+ output_content = output.data.get("text/markdown", "") or output.data.get("text/plain", "")
51
+ self.task.cell_output += output_content
52
+ self.task.cell_output += "\n"
53
+ return exec_failed, not exec_failed
@@ -0,0 +1,71 @@
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 .base import BaseChatAgent, AgentOutputFormat, AgentModelType
11
+
12
+
13
+ TASK_CODING_PROMPT = """\
14
+ **角色定义**:
15
+
16
+ 你是一个代码生成器,能够将自然语言描述转化为可执行的Jupyter Notebook代码。
17
+
18
+ **任务要求**:
19
+
20
+ - 根据子任务Prompt生成**Python代码**(需包含必要的依赖导入)
21
+ - 代码需严格遵守以下原则:
22
+ - 使用已存在的变量(如`cleaned_sales_df`)
23
+ - 新生成的变量需命名清晰(如`growth_rates_df`)
24
+ - 发生错误时,直接抛出异常,不需要进行任何错误处理,以便于执行器发现问题
25
+ - 代码在Jupyter环境中执行,但也应考虑通用性,尽量封装为函数或类
26
+ - 执行结果应保存在变量中,同时打印输出(或做为cell的返回值输出)
27
+ - 代码中应保含必要的文档注释
28
+ - 避免生成重复的代码
29
+
30
+ {% include "TASK_OUTPUT_FORMAT" %}
31
+
32
+ ---
33
+
34
+ {% include "TASK_CONTEXTS" %}
35
+
36
+ ---
37
+
38
+ {% include "CODE_CONTEXTS" %}
39
+
40
+ ---
41
+
42
+ **当前子任务信息**:
43
+
44
+ ### 当前子任务目标:
45
+ {{ task.subject }}
46
+
47
+ ### 当前子任务代码需求:
48
+ {{ task.coding_prompt }}
49
+
50
+ {% if task.issue %}
51
+ ### 尽量避免的问题:
52
+ {{ task.issue }}
53
+ {% endif %}
54
+
55
+ ---
56
+
57
+ 请按要求生成任务代码:
58
+ """
59
+
60
+
61
+ class TaskCodingAgent(BaseChatAgent):
62
+
63
+ PROMPT = TASK_CODING_PROMPT
64
+ OUTPUT_FORMAT = AgentOutputFormat.CODE
65
+ OUTPUT_CODE_LANG = "python"
66
+ MODEL_TYPE = AgentModelType.CODING
67
+
68
+ def on_reply(self, reply: str):
69
+ generated_code = "# Generated by Jupyter Agent (Coder) {}\n".format(time.strftime("%Y-%m-%d %H:%M:%S"))
70
+ generated_code += reply
71
+ self.task.source = generated_code
@@ -0,0 +1,69 @@
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 .base import BaseChatAgent, AgentOutputFormat, AgentModelType
11
+
12
+ TASK_DEBUGGER_PROMPT = """\
13
+ **角色定义**:
14
+
15
+ 你是一个代码调试专家,擅长定位并修复Jupyter Notebook中的错误。
16
+
17
+ **任务要求**:
18
+
19
+ - 分析执行失败的代码和错误信息,提出修复方案
20
+ - 修复方案需包含错误原因分析(语法错误/逻辑错误/依赖缺失等)
21
+
22
+ {% include "TASK_OUTPUT_FORMAT" %}
23
+
24
+ ---
25
+
26
+ {% include "TASK_CONTEXTS" %}
27
+
28
+ ---
29
+
30
+ {% include "CODE_CONTEXTS" %}
31
+
32
+ ---
33
+
34
+ **当前子任务信息**:
35
+
36
+ ### 当前子任务目标:
37
+ {{ task.subject }}
38
+
39
+ ### 当前子任务代码需求:
40
+ {{ task.coding_prompt }}
41
+
42
+ ### 当前代码:
43
+ ```python
44
+ {{ task.source }}
45
+ ```
46
+
47
+ ### 当前输出:
48
+ {{ task.cell_output }}
49
+
50
+ ### 当前错误:
51
+ {{ task.cell_error }}
52
+
53
+ ---
54
+
55
+ 请输出修复后的代码:
56
+ """
57
+
58
+
59
+ class CodeDebugerAgent(BaseChatAgent):
60
+
61
+ PROMPT = TASK_DEBUGGER_PROMPT
62
+ OUTPUT_FORMAT = AgentOutputFormat.CODE
63
+ OUTPUT_CODE_LANG = "python"
64
+ MODEL_TYPE = AgentModelType.CODING
65
+
66
+ def on_reply(self, reply: str):
67
+ generated_code = "# Generated by Jupyter Agent (Debugger) {}\n".format(time.strftime("%Y-%m-%d %H:%M:%S"))
68
+ generated_code += reply
69
+ self.task.source = generated_code