kweaver-dolphin 0.1.0__py3-none-any.whl → 0.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 (38) hide show
  1. dolphin/cli/runner/runner.py +20 -0
  2. dolphin/cli/ui/console.py +35 -17
  3. dolphin/cli/utils/helpers.py +4 -4
  4. dolphin/core/agent/base_agent.py +70 -7
  5. dolphin/core/code_block/basic_code_block.py +162 -26
  6. dolphin/core/code_block/explore_block.py +438 -35
  7. dolphin/core/code_block/explore_block_v2.py +105 -16
  8. dolphin/core/code_block/explore_strategy.py +3 -1
  9. dolphin/core/code_block/judge_block.py +41 -8
  10. dolphin/core/code_block/skill_call_deduplicator.py +32 -10
  11. dolphin/core/code_block/tool_block.py +69 -23
  12. dolphin/core/common/constants.py +25 -1
  13. dolphin/core/config/global_config.py +35 -0
  14. dolphin/core/context/context.py +175 -9
  15. dolphin/core/context/cow_context.py +392 -0
  16. dolphin/core/executor/dolphin_executor.py +9 -0
  17. dolphin/core/flags/definitions.py +2 -2
  18. dolphin/core/llm/llm.py +2 -3
  19. dolphin/core/llm/llm_client.py +1 -0
  20. dolphin/core/runtime/runtime_instance.py +31 -0
  21. dolphin/core/skill/context_retention.py +3 -3
  22. dolphin/core/task_registry.py +404 -0
  23. dolphin/core/utils/cache_kv.py +70 -8
  24. dolphin/core/utils/tools.py +2 -0
  25. dolphin/lib/__init__.py +0 -2
  26. dolphin/lib/skillkits/__init__.py +2 -2
  27. dolphin/lib/skillkits/plan_skillkit.py +756 -0
  28. dolphin/lib/skillkits/system_skillkit.py +103 -30
  29. dolphin/sdk/skill/global_skills.py +43 -3
  30. dolphin/sdk/skill/traditional_toolkit.py +4 -0
  31. {kweaver_dolphin-0.1.0.dist-info → kweaver_dolphin-0.2.1.dist-info}/METADATA +1 -1
  32. {kweaver_dolphin-0.1.0.dist-info → kweaver_dolphin-0.2.1.dist-info}/RECORD +36 -34
  33. {kweaver_dolphin-0.1.0.dist-info → kweaver_dolphin-0.2.1.dist-info}/WHEEL +1 -1
  34. kweaver_dolphin-0.2.1.dist-info/entry_points.txt +15 -0
  35. dolphin/lib/skillkits/plan_act_skillkit.py +0 -452
  36. kweaver_dolphin-0.1.0.dist-info/entry_points.txt +0 -27
  37. {kweaver_dolphin-0.1.0.dist-info → kweaver_dolphin-0.2.1.dist-info}/licenses/LICENSE.txt +0 -0
  38. {kweaver_dolphin-0.1.0.dist-info → kweaver_dolphin-0.2.1.dist-info}/top_level.txt +0 -0
@@ -1,452 +0,0 @@
1
- from typing import List, Optional, Any
2
- from dolphin.core.skill.skill_function import SkillFunction
3
- from dolphin.core.skill.skillkit import Skillkit
4
-
5
- # Lazy import to avoid circular dependencies
6
- _console_ui = None
7
- _live_plan_card = None
8
-
9
- def _get_console_ui():
10
- """Lazy loader for ConsoleUI to avoid circular imports."""
11
- global _console_ui
12
- if _console_ui is None:
13
- try:
14
- from dolphin.cli.ui.console import get_console_ui
15
- _console_ui = get_console_ui()
16
- except ImportError:
17
- _console_ui = None
18
- return _console_ui
19
-
20
- def _get_live_plan_card():
21
- """Lazy loader for LivePlanCard."""
22
- global _live_plan_card
23
- if _live_plan_card is None:
24
- try:
25
- from dolphin.cli.ui.console import LivePlanCard
26
- _live_plan_card = LivePlanCard()
27
- except ImportError:
28
- _live_plan_card = None
29
- return _live_plan_card
30
-
31
-
32
- class PlanActSkillkit(Skillkit):
33
- """Plan execution skill suite, providing task planning, status tracking, and execution progress management.
34
-
35
- Features:
36
- - Task list planning and generation
37
- - Task status tracking and updating
38
- - Execution progress display (with custom Plan Card UI)
39
- - Multiple task format recognition
40
- - Custom UI rendering protocol implementation
41
- - **Live animated spinner during task execution**
42
- """
43
-
44
- def __init__(self, verbose: bool = True, ui_style: str = "codex"):
45
- super().__init__()
46
- self.globalContext = None
47
- self.current_task_list: str = ""
48
- self.task_states = {} # Store task status {task_list_key: {task_id: status}}\\
49
-
50
- # UI rendering options
51
- self.verbose = verbose # Whether to render to terminal
52
- self.ui_style = ui_style # 'codex' for checkbox style, 'emoji' for emoji style
53
-
54
- # Store last execution context for UI rendering
55
- self._last_params: dict = {}
56
- self._last_tasks: List[dict] = []
57
- self._live_card_active: bool = False
58
-
59
- def getName(self) -> str:
60
- return "plan_act_skillkit"
61
-
62
- # ─────────────────────────────────────────────────────────────
63
- # Custom UI Rendering Protocol Implementation
64
- # ─────────────────────────────────────────────────────────────
65
-
66
- def has_custom_ui(self, skill_name: str) -> bool:
67
- """PlanActSkillkit uses custom Plan Card UI instead of generic skill box."""
68
- return skill_name == "_plan_act" and self.verbose
69
-
70
- def render_skill_start(
71
- self,
72
- skill_name: str,
73
- params: dict,
74
- verbose: bool = True
75
- ) -> None:
76
- """Start the live Plan Card animation with spinning indicator."""
77
- # Store params for later rendering
78
- self._last_params = params
79
-
80
- if not verbose or not self.verbose:
81
- return
82
-
83
- # If we have existing tasks, start the live card animation
84
- if self._last_tasks:
85
- live_card = _get_live_plan_card()
86
- if live_card:
87
- task_status = params.get("taskStatus", "")
88
- current_task_id = params.get("currentTaskId", 0)
89
-
90
- task_content = None
91
- if current_task_id > 0 and current_task_id <= len(self._last_tasks):
92
- task_content = self._last_tasks[current_task_id - 1].get("content", "")
93
-
94
- current_action = task_status if task_status in ("start", "done", "pause", "skip") else None
95
-
96
- # Start live animation
97
- live_card.start(
98
- tasks=self._last_tasks,
99
- current_task_id=current_task_id if current_task_id > 0 else None,
100
- current_action=current_action,
101
- current_task_content=task_content
102
- )
103
- self._live_card_active = True
104
-
105
- def render_skill_end(
106
- self,
107
- skill_name: str,
108
- params: dict,
109
- result: Any,
110
- success: bool = True,
111
- duration_ms: float = 0,
112
- verbose: bool = True
113
- ) -> None:
114
- """Stop the live animation and render final Plan Card state."""
115
- if not verbose or not self.verbose:
116
- return
117
-
118
- # Stop live card if it was active
119
- live_card = _get_live_plan_card()
120
- if live_card and self._live_card_active:
121
- live_card.stop()
122
- self._live_card_active = False
123
-
124
- ui = _get_console_ui()
125
- if not ui:
126
- return
127
-
128
- # Use stored tasks from last _plan_act call
129
- if not self._last_tasks:
130
- return
131
-
132
- # Extract action info from params
133
- task_status = params.get("taskStatus", "")
134
- current_task_id = params.get("currentTaskId", 0)
135
- conclusions = params.get("conclusions", "")
136
-
137
- # Get task content if task_id is valid
138
- task_content = None
139
- if current_task_id > 0 and current_task_id <= len(self._last_tasks):
140
- task_content = self._last_tasks[current_task_id - 1].get("content", "")
141
-
142
- # Determine action type
143
- current_action = task_status if task_status in ("start", "done", "pause", "skip") else None
144
-
145
- # Render the final plan card (static)
146
-
147
- ui.plan_update(
148
- tasks=self._last_tasks,
149
- current_action=current_action,
150
- current_task_id=current_task_id if current_task_id > 0 else None,
151
- current_task_content=task_content,
152
- conclusions=conclusions if conclusions else None,
153
- verbose=True
154
- )
155
-
156
- def _plan_act(
157
- self,
158
- planningMode: str = "update",
159
- taskList: str = "",
160
- currentTaskId: int = 0,
161
- taskStatus: str = "",
162
- conclusions: str = "",
163
- **kwargs,
164
- ) -> str:
165
- """Intelligent planning execution tool, supporting task list planning, status tracking, and execution progress management.
166
- Function description: Task list planning; track task progress; status updates and execution monitoring
167
-
168
- Args:
169
- planningMode (str): Planning mode configuration: "create"(create), "update"(update), "extend"(extend)
170
- currentTaskId (int): Target task ID for status updates and operations. 0 means show all task statuses, >0 specifies a particular task number
171
- taskStatus (str): Task status update operation: "plan"(plan), "start"(start), "done"(done), "pause"(pause), "skip"(skip), "review"(review)
172
- taskList (str, optional): Task list description, supports numbered lists, symbol lists, plain text, and other formats with status markers. If empty, use the currently stored task list
173
- conclusions (str, optional): Summary of the current step of the task, must be set only when taskStatus is "done"
174
- **kwargs: Extended parameters, support setting other task attributes
175
-
176
- Returns:
177
- str:
178
- Formatted task management report, containing:
179
- - 📋 Task list and current status
180
- - 📊 Progress statistics and completion rate
181
- - 🎯 Feedback on current operation result
182
- - 💡 Next action suggestions
183
- - 📝 Important notes and reminders
184
- """
185
-
186
- # Process task list input
187
- if taskList:
188
- self.current_task_list = taskList
189
-
190
- # If there is no current task list, return a prompt message
191
- if not self.current_task_list.strip():
192
- return "📋 暂无任务列表,请先创建任务列表"
193
-
194
- # Ensure that the current task list has status records
195
- if self.current_task_list not in self.task_states:
196
- self.task_states[self.current_task_list] = {}
197
- stored_states = self.task_states[self.current_task_list]
198
-
199
- # Intelligent Parsing Task List
200
- tasks = self._parse_task_list(self.current_task_list, stored_states)
201
-
202
- # Processing Planning Patterns
203
- if taskStatus == "plan":
204
- return self._handle_planning_mode(
205
- tasks, planningMode, conclusions, **kwargs
206
- )
207
-
208
- # Process task status updates
209
- if currentTaskId > 0 and taskStatus and currentTaskId <= len(tasks):
210
- tasks = self._update_task_status(
211
- tasks, currentTaskId, taskStatus, stored_states, conclusions
212
- )
213
- elif currentTaskId > 0 and taskStatus and currentTaskId > len(tasks):
214
- # If the task ID is out of range, return an error message.
215
- return f"❌ 错误:任务ID {currentTaskId} 超出范围,当前任务列表只有 {len(tasks)} 个任务"
216
-
217
- # Generate Task Management Report
218
- return self._generate_task_report(
219
- tasks, currentTaskId, taskStatus, conclusions, **kwargs
220
- )
221
-
222
- def _parse_task_list(self, task_list: str, stored_states: dict) -> List[dict]:
223
- """Intelligent parsing task list, supporting multiple formats and status tags"""
224
- lines = [line.strip() for line in task_list.split("\n") if line.strip()]
225
- tasks = []
226
-
227
- for i, line in enumerate(lines, 1):
228
- content = line
229
-
230
- # Get task status from storage state (highest priority)
231
- status = stored_states.get(i, "pending")
232
-
233
- # Parse state markers in the text
234
- if "✅" in line or "(completed)" in line.lower() or "完成" in line:
235
- status = "completed"
236
- elif "🔄" in line or "(in progress)" in line.lower() or "进行中" in line:
237
- status = "in_progress"
238
- elif "⏸️" in line or "(paused)" in line.lower() or "暂停" in line:
239
- status = "paused"
240
- elif (
241
- "❌" in line
242
- or "(cancelled)" in line.lower()
243
- or "(skip)" in line.lower()
244
- ):
245
- status = "cancelled"
246
-
247
- # Clean up task content
248
- content = self._clean_task_content(content)
249
-
250
- if content:
251
- tasks.append(
252
- {
253
- "id": i,
254
- "content": content,
255
- "status": status,
256
- "original_line": line,
257
- }
258
- )
259
-
260
- return tasks
261
-
262
- def _clean_task_content(self, content: str) -> str:
263
- """Clean up task content by removing status markers and formatting symbols"""
264
- # Remove status emoji and markers
265
- status_markers = [
266
- "✅",
267
- "🔄",
268
- "⏸️",
269
- "❌",
270
- "⏳",
271
- "(completed)",
272
- "(in progress)",
273
- "(paused)",
274
- "(cancelled)",
275
- "(skip)",
276
- "完成",
277
- "进行中",
278
- "暂停",
279
- ]
280
-
281
- for marker in status_markers:
282
- content = content.replace(marker, "").strip()
283
-
284
- # Remove list formatting symbols
285
- if content.startswith(("-", "*", "•")):
286
- content = content[1:].strip()
287
- elif "." in content and content.split(".")[0].isdigit():
288
- content = ".".join(content.split(".")[1:]).strip()
289
-
290
- return content
291
-
292
- def _handle_planning_mode(
293
- self, tasks: List[dict], planning_mode: str, conclusions: str, **kwargs
294
- ) -> str:
295
- """Logic for processing planning patterns"""
296
- if planning_mode == "create":
297
- return self._create_planning_suggestions(tasks, conclusions)
298
- elif planning_mode == "extend":
299
- return self._extend_task_list(tasks, conclusions)
300
- else: # update
301
- return self._update_planning(tasks, conclusions)
302
-
303
- def _create_planning_suggestions(self, tasks: List[dict], conclusions: str) -> str:
304
- """Create Task Planning Suggestions"""
305
- if len(tasks) == 1 and tasks[0]["content"]:
306
- goal = tasks[0]["content"]
307
- """🎯 Goal: {goal}
308
-
309
- Suggested breakdown:
310
- 1. Requirements analysis
311
- 2. Solution design
312
- 3. Feature development
313
- 4. Testing verification
314
- 5. Deployment and launch
315
-
316
- 💡 Break the big goal into specific, executable sub-tasks
317
- {f"📝 {conclusions}" if conclusions else ""}
318
- """
319
- return suggestions
320
- else:
321
- return self._generate_task_report(tasks, 0, "plan", conclusions)
322
-
323
- def _extend_task_list(self, tasks: List[dict], conclusions: str) -> str:
324
- """Extend the existing task list"""
325
- total_tasks = len(tasks)
326
- completed = sum(1 for t in tasks if t["status"] == "completed")
327
-
328
- extend_suggestions = f"📈 当前进度: {completed}/{total_tasks} ({completed / total_tasks * 100:.0f}%)\n\n"
329
-
330
- if completed / total_tasks > 0.5:
331
- extend_suggestions += (
332
- "💡 建议补充:\n- 质量保证和测试\n- 文档完善\n- 性能优化\n- 用户培训"
333
- )
334
- else:
335
- extend_suggestions += (
336
- "🔧 建议补充:\n- 风险评估\n- 依赖项检查\n- 里程碑设置\n- 团队协作"
337
- )
338
-
339
- if conclusions:
340
- extend_suggestions += f"\n\n📝 {conclusions}"
341
-
342
- return extend_suggestions
343
-
344
- def _update_planning(self, tasks: List[dict], conclusions: str) -> str:
345
- """Update existing task planning"""
346
- if not tasks:
347
- return "📋 暂无任务列表"
348
-
349
- total_tasks = len(tasks)
350
- completed = sum(1 for t in tasks if t["status"] == "completed")
351
- in_progress = sum(1 for t in tasks if t["status"] == "in_progress")
352
- paused = sum(1 for t in tasks if t["status"] == "paused")
353
- pending = sum(1 for t in tasks if t["status"] == "pending")
354
-
355
- update_report = f"🔄 进度: {completed}/{total_tasks} ({completed / total_tasks * 100:.0f}%)\n"
356
- update_report += (
357
- f"状态: ✅{completed} 🔄{in_progress} ⏸️{paused} ⏳{pending}\n\n"
358
- )
359
-
360
- # Provide simplified suggestions based on the current state
361
- if paused > 0:
362
- update_report += f"⚠️ 有 {paused} 个暂停任务需处理\n"
363
- if in_progress > 3:
364
- update_report += "⚡ 同时进行任务过多,建议聚焦\n"
365
- elif in_progress == 0 and pending > 0:
366
- update_report += "🚀 建议开始下一个任务\n"
367
-
368
- if conclusions:
369
- update_report += f"\n📝 {conclusions}"
370
-
371
- return update_report
372
-
373
- def _update_task_status(
374
- self,
375
- tasks: List[dict],
376
- task_id: int,
377
- status: str,
378
- stored_states: dict,
379
- conclusions: str,
380
- ) -> List[dict]:
381
- """Update task status"""
382
- status_mapping = {
383
- "start": "in_progress",
384
- "done": "completed",
385
- "pause": "paused",
386
- "skip": "cancelled",
387
- "review": "review",
388
- }
389
-
390
- if status in status_mapping:
391
- new_status = status_mapping[status]
392
- tasks[task_id - 1]["status"] = new_status
393
- stored_states[task_id] = new_status
394
-
395
- return tasks
396
-
397
- def _generate_task_report(
398
- self,
399
- tasks: List[dict],
400
- current_task_id: int,
401
- task_status: str,
402
- conclusions: str,
403
- **kwargs,
404
- ) -> str:
405
- """Generate concise task management reports.
406
-
407
- Note: UI rendering is handled by render_skill_end() via the custom UI protocol.
408
- This method only generates the text report for LLM consumption.
409
- """
410
- if not tasks:
411
- return "📋 暂无任务列表"
412
-
413
- total = len(tasks)
414
- completed = sum(1 for t in tasks if t["status"] == "completed")
415
- in_progress = sum(1 for t in tasks if t["status"] == "in_progress")
416
- pending = sum(1 for t in tasks if t["status"] == "pending")
417
-
418
- # ─────────────────────────────────────────────────────────────
419
- # Store tasks for custom UI rendering (via render_skill_end)
420
- # ─────────────────────────────────────────────────────────────
421
- self._last_tasks = [
422
- {"content": t["content"], "status": t["status"]}
423
- for t in tasks
424
- ]
425
-
426
- # ─────────────────────────────────────────────────────────────
427
- # Text Report (Return Value for LLM)
428
- # ─────────────────────────────────────────────────────────────
429
-
430
- # Return compact summary (UI rendering is handled separately by render_skill_end)
431
- percentage = completed / total * 100 if total > 0 else 0
432
- summary = f"进度: {completed}/{total} ({percentage:.0f}%)"
433
-
434
- if current_task_id > 0 and task_status and current_task_id <= len(tasks):
435
- action_text = {"start": "开始", "done": "完成", "pause": "暂停", "skip": "跳过"}.get(task_status, "")
436
- if action_text:
437
- summary += f" | {action_text}: 任务{current_task_id}"
438
- if conclusions:
439
- summary += f" - {conclusions}"
440
-
441
- if completed == total:
442
- summary += " | 🎉 全部完成!"
443
- elif in_progress == 0 and pending > 0:
444
- next_task = next((t for t in tasks if t["status"] == "pending"), None)
445
- if next_task:
446
- summary += f" | 下一步: 任务{next_task['id']}"
447
-
448
- return summary
449
-
450
- def _createSkills(self) -> List[SkillFunction]:
451
- return [SkillFunction(self._plan_act)]
452
-
@@ -1,27 +0,0 @@
1
- [DolphinLanguageSDK.skillkits]
2
- cognitive = DolphinLanguageSDK.skill.installed.cognitive_skillkit:CognitiveSkillkit
3
- mcp = DolphinLanguageSDK.skill.installed.mcp_skillkit:MCPSkillkit
4
- memory = DolphinLanguageSDK.skill.installed.memory_skillkit:MemorySkillkit
5
- noop = DolphinLanguageSDK.skill.installed.noop_skillkit:NoopSkillkit
6
- ontology = DolphinLanguageSDK.skill.installed.ontology_skillkit:OntologySkillkit
7
- plan_act = DolphinLanguageSDK.skill.installed.plan_act_skillkit:PlanActSkillkit
8
- resource_skillkit = DolphinLanguageSDK.skill.installed.resource_skillkit:ResourceSkillkit
9
- search = DolphinLanguageSDK.skill.installed.search_skillkit:SearchSkillkit
10
- sql = DolphinLanguageSDK.skill.installed.sql_skillkit:SQLSkillkit
11
- vm = DolphinLanguageSDK.skill.installed.vm_skillkit:VMSkillkit
12
-
13
- [console_scripts]
14
- dolphin = dolphin.cli:main
15
-
16
- [dolphin.skillkits]
17
- cognitive = dolphin.lib.skillkits.cognitive_skillkit:CognitiveSkillkit
18
- env_skillkit = dolphin.lib.skillkits.env_skillkit:EnvSkillkit
19
- mcp = dolphin.lib.skillkits.mcp_skillkit:MCPSkillkit
20
- memory = dolphin.lib.skillkits.memory_skillkit:MemorySkillkit
21
- noop = dolphin.lib.skillkits.noop_skillkit:NoopSkillkit
22
- ontology = dolphin.lib.skillkits.ontology_skillkit:OntologySkillkit
23
- plan_act = dolphin.lib.skillkits.plan_act_skillkit:PlanActSkillkit
24
- resource = dolphin.lib.skillkits.resource_skillkit:ResourceSkillkit
25
- search = dolphin.lib.skillkits.search_skillkit:SearchSkillkit
26
- sql = dolphin.lib.skillkits.sql_skillkit:SQLSkillkit
27
- vm = dolphin.lib.skillkits.vm_skillkit:VMSkillkit