kweaver-dolphin 0.1.0__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 (199) hide show
  1. DolphinLanguageSDK/__init__.py +58 -0
  2. dolphin/__init__.py +62 -0
  3. dolphin/cli/__init__.py +20 -0
  4. dolphin/cli/args/__init__.py +9 -0
  5. dolphin/cli/args/parser.py +567 -0
  6. dolphin/cli/builtin_agents/__init__.py +22 -0
  7. dolphin/cli/commands/__init__.py +4 -0
  8. dolphin/cli/interrupt/__init__.py +8 -0
  9. dolphin/cli/interrupt/handler.py +205 -0
  10. dolphin/cli/interrupt/keyboard.py +82 -0
  11. dolphin/cli/main.py +49 -0
  12. dolphin/cli/multimodal/__init__.py +34 -0
  13. dolphin/cli/multimodal/clipboard.py +327 -0
  14. dolphin/cli/multimodal/handler.py +249 -0
  15. dolphin/cli/multimodal/image_processor.py +214 -0
  16. dolphin/cli/multimodal/input_parser.py +149 -0
  17. dolphin/cli/runner/__init__.py +8 -0
  18. dolphin/cli/runner/runner.py +989 -0
  19. dolphin/cli/ui/__init__.py +10 -0
  20. dolphin/cli/ui/console.py +2795 -0
  21. dolphin/cli/ui/input.py +340 -0
  22. dolphin/cli/ui/layout.py +425 -0
  23. dolphin/cli/ui/stream_renderer.py +302 -0
  24. dolphin/cli/utils/__init__.py +8 -0
  25. dolphin/cli/utils/helpers.py +135 -0
  26. dolphin/cli/utils/version.py +49 -0
  27. dolphin/core/__init__.py +107 -0
  28. dolphin/core/agent/__init__.py +10 -0
  29. dolphin/core/agent/agent_state.py +69 -0
  30. dolphin/core/agent/base_agent.py +970 -0
  31. dolphin/core/code_block/__init__.py +0 -0
  32. dolphin/core/code_block/agent_init_block.py +0 -0
  33. dolphin/core/code_block/assign_block.py +98 -0
  34. dolphin/core/code_block/basic_code_block.py +1865 -0
  35. dolphin/core/code_block/explore_block.py +1327 -0
  36. dolphin/core/code_block/explore_block_v2.py +712 -0
  37. dolphin/core/code_block/explore_strategy.py +672 -0
  38. dolphin/core/code_block/judge_block.py +220 -0
  39. dolphin/core/code_block/prompt_block.py +32 -0
  40. dolphin/core/code_block/skill_call_deduplicator.py +291 -0
  41. dolphin/core/code_block/tool_block.py +129 -0
  42. dolphin/core/common/__init__.py +17 -0
  43. dolphin/core/common/constants.py +176 -0
  44. dolphin/core/common/enums.py +1173 -0
  45. dolphin/core/common/exceptions.py +133 -0
  46. dolphin/core/common/multimodal.py +539 -0
  47. dolphin/core/common/object_type.py +165 -0
  48. dolphin/core/common/output_format.py +432 -0
  49. dolphin/core/common/types.py +36 -0
  50. dolphin/core/config/__init__.py +16 -0
  51. dolphin/core/config/global_config.py +1289 -0
  52. dolphin/core/config/ontology_config.py +133 -0
  53. dolphin/core/context/__init__.py +12 -0
  54. dolphin/core/context/context.py +1580 -0
  55. dolphin/core/context/context_manager.py +161 -0
  56. dolphin/core/context/var_output.py +82 -0
  57. dolphin/core/context/variable_pool.py +356 -0
  58. dolphin/core/context_engineer/__init__.py +41 -0
  59. dolphin/core/context_engineer/config/__init__.py +5 -0
  60. dolphin/core/context_engineer/config/settings.py +402 -0
  61. dolphin/core/context_engineer/core/__init__.py +7 -0
  62. dolphin/core/context_engineer/core/budget_manager.py +327 -0
  63. dolphin/core/context_engineer/core/context_assembler.py +583 -0
  64. dolphin/core/context_engineer/core/context_manager.py +637 -0
  65. dolphin/core/context_engineer/core/tokenizer_service.py +260 -0
  66. dolphin/core/context_engineer/example/incremental_example.py +267 -0
  67. dolphin/core/context_engineer/example/traditional_example.py +334 -0
  68. dolphin/core/context_engineer/services/__init__.py +5 -0
  69. dolphin/core/context_engineer/services/compressor.py +399 -0
  70. dolphin/core/context_engineer/utils/__init__.py +6 -0
  71. dolphin/core/context_engineer/utils/context_utils.py +441 -0
  72. dolphin/core/context_engineer/utils/message_formatter.py +270 -0
  73. dolphin/core/context_engineer/utils/token_utils.py +139 -0
  74. dolphin/core/coroutine/__init__.py +15 -0
  75. dolphin/core/coroutine/context_snapshot.py +154 -0
  76. dolphin/core/coroutine/context_snapshot_profile.py +922 -0
  77. dolphin/core/coroutine/context_snapshot_store.py +268 -0
  78. dolphin/core/coroutine/execution_frame.py +145 -0
  79. dolphin/core/coroutine/execution_state_registry.py +161 -0
  80. dolphin/core/coroutine/resume_handle.py +101 -0
  81. dolphin/core/coroutine/step_result.py +101 -0
  82. dolphin/core/executor/__init__.py +18 -0
  83. dolphin/core/executor/debug_controller.py +630 -0
  84. dolphin/core/executor/dolphin_executor.py +1063 -0
  85. dolphin/core/executor/executor.py +624 -0
  86. dolphin/core/flags/__init__.py +27 -0
  87. dolphin/core/flags/definitions.py +49 -0
  88. dolphin/core/flags/manager.py +113 -0
  89. dolphin/core/hook/__init__.py +95 -0
  90. dolphin/core/hook/expression_evaluator.py +499 -0
  91. dolphin/core/hook/hook_dispatcher.py +380 -0
  92. dolphin/core/hook/hook_types.py +248 -0
  93. dolphin/core/hook/isolated_variable_pool.py +284 -0
  94. dolphin/core/interfaces.py +53 -0
  95. dolphin/core/llm/__init__.py +0 -0
  96. dolphin/core/llm/llm.py +495 -0
  97. dolphin/core/llm/llm_call.py +100 -0
  98. dolphin/core/llm/llm_client.py +1285 -0
  99. dolphin/core/llm/message_sanitizer.py +120 -0
  100. dolphin/core/logging/__init__.py +20 -0
  101. dolphin/core/logging/logger.py +526 -0
  102. dolphin/core/message/__init__.py +8 -0
  103. dolphin/core/message/compressor.py +749 -0
  104. dolphin/core/parser/__init__.py +8 -0
  105. dolphin/core/parser/parser.py +405 -0
  106. dolphin/core/runtime/__init__.py +10 -0
  107. dolphin/core/runtime/runtime_graph.py +926 -0
  108. dolphin/core/runtime/runtime_instance.py +446 -0
  109. dolphin/core/skill/__init__.py +14 -0
  110. dolphin/core/skill/context_retention.py +157 -0
  111. dolphin/core/skill/skill_function.py +686 -0
  112. dolphin/core/skill/skill_matcher.py +282 -0
  113. dolphin/core/skill/skillkit.py +700 -0
  114. dolphin/core/skill/skillset.py +72 -0
  115. dolphin/core/trajectory/__init__.py +10 -0
  116. dolphin/core/trajectory/recorder.py +189 -0
  117. dolphin/core/trajectory/trajectory.py +522 -0
  118. dolphin/core/utils/__init__.py +9 -0
  119. dolphin/core/utils/cache_kv.py +212 -0
  120. dolphin/core/utils/tools.py +340 -0
  121. dolphin/lib/__init__.py +93 -0
  122. dolphin/lib/debug/__init__.py +8 -0
  123. dolphin/lib/debug/visualizer.py +409 -0
  124. dolphin/lib/memory/__init__.py +28 -0
  125. dolphin/lib/memory/async_processor.py +220 -0
  126. dolphin/lib/memory/llm_calls.py +195 -0
  127. dolphin/lib/memory/manager.py +78 -0
  128. dolphin/lib/memory/sandbox.py +46 -0
  129. dolphin/lib/memory/storage.py +245 -0
  130. dolphin/lib/memory/utils.py +51 -0
  131. dolphin/lib/ontology/__init__.py +12 -0
  132. dolphin/lib/ontology/basic/__init__.py +0 -0
  133. dolphin/lib/ontology/basic/base.py +102 -0
  134. dolphin/lib/ontology/basic/concept.py +130 -0
  135. dolphin/lib/ontology/basic/object.py +11 -0
  136. dolphin/lib/ontology/basic/relation.py +63 -0
  137. dolphin/lib/ontology/datasource/__init__.py +27 -0
  138. dolphin/lib/ontology/datasource/datasource.py +66 -0
  139. dolphin/lib/ontology/datasource/oracle_datasource.py +338 -0
  140. dolphin/lib/ontology/datasource/sql.py +845 -0
  141. dolphin/lib/ontology/mapping.py +177 -0
  142. dolphin/lib/ontology/ontology.py +733 -0
  143. dolphin/lib/ontology/ontology_context.py +16 -0
  144. dolphin/lib/ontology/ontology_manager.py +107 -0
  145. dolphin/lib/skill_results/__init__.py +31 -0
  146. dolphin/lib/skill_results/cache_backend.py +559 -0
  147. dolphin/lib/skill_results/result_processor.py +181 -0
  148. dolphin/lib/skill_results/result_reference.py +179 -0
  149. dolphin/lib/skill_results/skillkit_hook.py +324 -0
  150. dolphin/lib/skill_results/strategies.py +328 -0
  151. dolphin/lib/skill_results/strategy_registry.py +150 -0
  152. dolphin/lib/skillkits/__init__.py +44 -0
  153. dolphin/lib/skillkits/agent_skillkit.py +155 -0
  154. dolphin/lib/skillkits/cognitive_skillkit.py +82 -0
  155. dolphin/lib/skillkits/env_skillkit.py +250 -0
  156. dolphin/lib/skillkits/mcp_adapter.py +616 -0
  157. dolphin/lib/skillkits/mcp_skillkit.py +771 -0
  158. dolphin/lib/skillkits/memory_skillkit.py +650 -0
  159. dolphin/lib/skillkits/noop_skillkit.py +31 -0
  160. dolphin/lib/skillkits/ontology_skillkit.py +89 -0
  161. dolphin/lib/skillkits/plan_act_skillkit.py +452 -0
  162. dolphin/lib/skillkits/resource/__init__.py +52 -0
  163. dolphin/lib/skillkits/resource/models/__init__.py +6 -0
  164. dolphin/lib/skillkits/resource/models/skill_config.py +109 -0
  165. dolphin/lib/skillkits/resource/models/skill_meta.py +127 -0
  166. dolphin/lib/skillkits/resource/resource_skillkit.py +393 -0
  167. dolphin/lib/skillkits/resource/skill_cache.py +215 -0
  168. dolphin/lib/skillkits/resource/skill_loader.py +395 -0
  169. dolphin/lib/skillkits/resource/skill_validator.py +406 -0
  170. dolphin/lib/skillkits/resource_skillkit.py +11 -0
  171. dolphin/lib/skillkits/search_skillkit.py +163 -0
  172. dolphin/lib/skillkits/sql_skillkit.py +274 -0
  173. dolphin/lib/skillkits/system_skillkit.py +509 -0
  174. dolphin/lib/skillkits/vm_skillkit.py +65 -0
  175. dolphin/lib/utils/__init__.py +9 -0
  176. dolphin/lib/utils/data_process.py +207 -0
  177. dolphin/lib/utils/handle_progress.py +178 -0
  178. dolphin/lib/utils/security.py +139 -0
  179. dolphin/lib/utils/text_retrieval.py +462 -0
  180. dolphin/lib/vm/__init__.py +11 -0
  181. dolphin/lib/vm/env_executor.py +895 -0
  182. dolphin/lib/vm/python_session_manager.py +453 -0
  183. dolphin/lib/vm/vm.py +610 -0
  184. dolphin/sdk/__init__.py +60 -0
  185. dolphin/sdk/agent/__init__.py +12 -0
  186. dolphin/sdk/agent/agent_factory.py +236 -0
  187. dolphin/sdk/agent/dolphin_agent.py +1106 -0
  188. dolphin/sdk/api/__init__.py +4 -0
  189. dolphin/sdk/runtime/__init__.py +8 -0
  190. dolphin/sdk/runtime/env.py +363 -0
  191. dolphin/sdk/skill/__init__.py +10 -0
  192. dolphin/sdk/skill/global_skills.py +706 -0
  193. dolphin/sdk/skill/traditional_toolkit.py +260 -0
  194. kweaver_dolphin-0.1.0.dist-info/METADATA +521 -0
  195. kweaver_dolphin-0.1.0.dist-info/RECORD +199 -0
  196. kweaver_dolphin-0.1.0.dist-info/WHEEL +5 -0
  197. kweaver_dolphin-0.1.0.dist-info/entry_points.txt +27 -0
  198. kweaver_dolphin-0.1.0.dist-info/licenses/LICENSE.txt +201 -0
  199. kweaver_dolphin-0.1.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,89 @@
1
+ from typing import List, Optional
2
+
3
+ from dolphin.core.skill.skill_function import SkillFunction
4
+ from dolphin.core.skill.skillkit import Skillkit
5
+ from dolphin.lib.ontology.ontology_context import OntologyContext
6
+
7
+
8
+ class OntologySkillkit(Skillkit):
9
+ def __init__(self, ontologyContext: Optional[OntologyContext] = None):
10
+ super().__init__()
11
+ self.ontologyContext = ontologyContext
12
+
13
+ def setGlobalConfig(self, globalConfig):
14
+ super().setGlobalConfig(globalConfig)
15
+ if (
16
+ self.ontologyContext is None
17
+ and self.globalConfig.ontology_config is not None
18
+ ):
19
+ self.ontologyContext = OntologyContext.loadOntologyContext(
20
+ self.globalConfig.ontology_config
21
+ )
22
+
23
+ def getName(self) -> str:
24
+ return "ontology_skillkit"
25
+
26
+ def getDesc(self) -> str:
27
+ return "Ontology"
28
+
29
+ def getAllConcepts(self, **kwargs) -> str:
30
+ """Get the descriptions of all concepts in the ontology model
31
+
32
+ Args:
33
+ None
34
+
35
+ Returns:
36
+ str: The descriptions of all concepts in the ontology model
37
+ """
38
+ return self.ontologyContext.getOntology().getAllConceptsDescription()
39
+
40
+ def getSampleData(self, conceptNames: List[str], **kwargs) -> str:
41
+ """Get sample data for a specified concept in the ontology model
42
+
43
+ Args:
44
+ conceptNames (List[str]): List of concept names
45
+
46
+ Returns:
47
+ str: Sample data for the specified concept in the ontology model
48
+ """
49
+ return self.ontologyContext.getOntology().sampleData(conceptNames)
50
+
51
+ def getDataSourceSchemas(self, conceptNames: List[str], **kwargs) -> str:
52
+ """Get the schema of data sources for specified concepts in the ontology model
53
+
54
+ Args:
55
+ conceptNames (List[str]): List of concept names
56
+ """
57
+ dataSourceSchemas = []
58
+ for conceptName in conceptNames:
59
+ concept = self.ontologyContext.getOntology().getConcept(conceptName)
60
+ if not concept:
61
+ continue
62
+ dataSourceSchemas.append(concept.getDataSourceSchemas())
63
+ return dataSourceSchemas
64
+
65
+ def getDataSourcesFromConcepts(self, conceptNames: List[str], **kwargs) -> str:
66
+ """Get the schema of the data source for the specified concept in the ontology model
67
+
68
+ Args:
69
+ conceptNames (List[str]): List of concept names
70
+
71
+ Returns:
72
+ str: The schema of the data source for the specified concept in the ontology model
73
+ """
74
+ result = self.ontologyContext.getOntology().getDataSourcesFromConcepts(
75
+ conceptNames
76
+ )
77
+ return str(result)
78
+
79
+ def _createSkills(self) -> List[SkillFunction]:
80
+ return [
81
+ SkillFunction(self.getAllConcepts),
82
+ SkillFunction(self.getSampleData),
83
+ SkillFunction(self.getDataSourceSchemas),
84
+ SkillFunction(self.getDataSourcesFromConcepts),
85
+ ]
86
+
87
+ # Add alias method to support getTools
88
+ def getTools(self) -> List[SkillFunction]:
89
+ return self.getSkills()
@@ -0,0 +1,452 @@
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
+
@@ -0,0 +1,52 @@
1
+ """ResourceSkillkit - Claude Skill format support for Dolphin.
2
+
3
+ This package provides ResourceSkillkit, a Skillkit type that supports
4
+ resource/guidance skills in Claude Skill format (SKILL.md).
5
+
6
+ Example usage:
7
+ ```python
8
+ from dolphin.lib.skillkits.resource import (
9
+ ResourceSkillkit,
10
+ ResourceSkillConfig,
11
+ )
12
+
13
+ config = ResourceSkillConfig(
14
+ directories=["./skills", "~/.dolphin/skills"]
15
+ )
16
+ skillkit = ResourceSkillkit(config)
17
+ skillkit.initialize()
18
+
19
+ # Get metadata prompt for system injection (Level 1)
20
+ metadata_prompt = skillkit.get_metadata_prompt()
21
+
22
+ # Load full skill content (Level 2)
23
+ content = skillkit.load_skill("data-pipeline")
24
+ ```
25
+ """
26
+
27
+ from .resource_skillkit import ResourceSkillkit
28
+ from .models.skill_config import ResourceSkillConfig
29
+ from .models.skill_meta import SkillMeta, SkillContent
30
+ from .skill_loader import SkillLoader, SkillLoaderError
31
+ from .skill_validator import SkillValidator, ValidationResult
32
+ from .skill_cache import SkillMetaCache, SkillContentCache, TTLLRUCache
33
+
34
+ __all__ = [
35
+ # Main class
36
+ "ResourceSkillkit",
37
+ # Configuration
38
+ "ResourceSkillConfig",
39
+ # Data models
40
+ "SkillMeta",
41
+ "SkillContent",
42
+ # Loader
43
+ "SkillLoader",
44
+ "SkillLoaderError",
45
+ # Validator
46
+ "SkillValidator",
47
+ "ValidationResult",
48
+ # Cache
49
+ "SkillMetaCache",
50
+ "SkillContentCache",
51
+ "TTLLRUCache",
52
+ ]
@@ -0,0 +1,6 @@
1
+ """Data models for ResourceSkillkit."""
2
+
3
+ from .skill_meta import SkillMeta, SkillContent
4
+ from .skill_config import ResourceSkillConfig
5
+
6
+ __all__ = ["SkillMeta", "SkillContent", "ResourceSkillConfig"]