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,328 @@
1
+ """Strategy Module
2
+ Provides an abstract interface and concrete implementations for data processing strategies (a unified model based on category)
3
+ """
4
+
5
+ import json
6
+ from abc import ABC, abstractmethod
7
+ from typing import Any, Dict, List, TYPE_CHECKING
8
+
9
+ if TYPE_CHECKING:
10
+ from dolphin.lib.skill_results.result_reference import ResultReference
11
+
12
+ from dolphin.core.logging.logger import get_logger
13
+
14
+ logger = get_logger("skill_results")
15
+
16
+
17
+ class BaseStrategy(ABC):
18
+ """Base class for unified strategies.
19
+
20
+ - Use category to distinguish usage scenarios (e.g., 'llm', 'app', 'export', etc.)
21
+ - Subclasses must set the class attribute category and implement process()
22
+ """
23
+
24
+ # Subclasses should override to specify a concrete category, such as 'llm' or 'app'
25
+ category: str = "generic"
26
+
27
+ def get_category(self) -> str:
28
+ return getattr(self, "category", "generic")
29
+
30
+ def supports(self, category: str) -> bool:
31
+ return self.get_category() == category
32
+
33
+ @abstractmethod
34
+ def process(self, result_reference: "ResultReference", **kwargs) -> Any:
35
+ """Execute strategy processing and return final data (different categories may return different structures)"""
36
+ raise NotImplementedError
37
+
38
+
39
+ # ======================== LLM Category Strategy (category='llm') ========================
40
+
41
+
42
+ class BaseLLMStrategy(BaseStrategy):
43
+ """Base class for LLM strategies, providing general data transformation methods"""
44
+
45
+ category = "llm"
46
+
47
+ def _convert_to_string(self, data: Any) -> str:
48
+ """Convert data to string format"""
49
+ if isinstance(data, str):
50
+ return data
51
+ elif isinstance(data, (dict, list)):
52
+ return json.dumps(data, ensure_ascii=False, indent=2)
53
+ else:
54
+ return str(data)
55
+
56
+
57
+ class DefaultLLMStrategy(BaseLLMStrategy):
58
+
59
+ def process(self, result_reference: "ResultReference", **kwargs) -> str:
60
+ try:
61
+ full_result = result_reference.get_full_result()
62
+ if full_result is None:
63
+ return "数据不存在"
64
+
65
+ return self._convert_to_string(full_result)
66
+ except Exception as e:
67
+ logger.error(f"默认LLM策略处理failed: {e}")
68
+ return f"数据处理failed: {str(e)}"
69
+
70
+
71
+ class SummaryLLMStrategy(BaseLLMStrategy):
72
+
73
+ def process(self, result_reference: "ResultReference", **kwargs) -> str:
74
+ try:
75
+ full_result = result_reference.get_full_result()
76
+ if full_result is None:
77
+ return "数据不存在"
78
+
79
+ max_tokens = kwargs.get("max_tokens", 2000)
80
+ max_chars = max_tokens * 4
81
+
82
+ result_str = self._convert_to_string(full_result)
83
+ if len(result_str) <= max_chars:
84
+ return result_str
85
+
86
+ return self._generate_summary(result_str, max_chars)
87
+ except Exception as e:
88
+ logger.error(f"摘要LLM策略处理failed: {e}")
89
+ return f"摘要生成failed: {str(e)}"
90
+
91
+ def _generate_summary(self, text: str, max_chars: int) -> str:
92
+ if len(text) <= max_chars:
93
+ return text
94
+ start_chars = int(max_chars * 0.6)
95
+ end_chars = int(max_chars * 0.2)
96
+ start_part = text[:start_chars]
97
+ end_part = text[-end_chars:] if end_chars > 0 else ""
98
+
99
+ return f"{start_part}\n\n... (内容已截断) ...\n\n{end_part}"
100
+
101
+
102
+ class TruncateLLMStrategy(BaseLLMStrategy):
103
+
104
+ def process(self, result_reference: "ResultReference", **kwargs) -> str:
105
+ try:
106
+ full_result = result_reference.get_full_result()
107
+ if full_result is None:
108
+ return "数据不存在"
109
+
110
+ max_tokens = kwargs.get("max_tokens", 2000)
111
+ max_chars = max_tokens * 4
112
+
113
+ result_str = self._convert_to_string(full_result)
114
+ if len(result_str) <= max_chars:
115
+ return result_str
116
+
117
+ truncated = result_str[:max_chars]
118
+ return (
119
+ f"{truncated}\n\n... (内容已截断,总长度: {len(result_str)} 字符) ..."
120
+ )
121
+ except Exception as e:
122
+ logger.error(f"截取LLM策略处理failed: {e}")
123
+ return f"数据截取failed: {str(e)}"
124
+
125
+
126
+ # ====================== APP Category Strategy (category='app') ======================
127
+
128
+
129
+ class DefaultAppStrategy(BaseStrategy):
130
+ category = "app"
131
+
132
+ def process(self, result_reference: "ResultReference", **kwargs) -> Dict[str, Any]:
133
+ try:
134
+ full_result = result_reference.get_full_result()
135
+ return full_result
136
+ except Exception as e:
137
+ logger.error(f"默认APP策略处理failed: {e}")
138
+ return {
139
+ "error": f"数据处理failed: {str(e)}",
140
+ "reference_id": result_reference.reference_id,
141
+ }
142
+
143
+
144
+ class PaginationAppStrategy(BaseStrategy):
145
+ category = "app"
146
+
147
+ def process(self, result_reference: "ResultReference", **kwargs) -> Dict[str, Any]:
148
+ try:
149
+ full_result = result_reference.get_full_result()
150
+ metadata = result_reference.get_metadata()
151
+ if full_result is None:
152
+ return {
153
+ "error": "数据不存在",
154
+ "reference_id": result_reference.reference_id,
155
+ }
156
+
157
+ page = kwargs.get("page", 1)
158
+ page_size = kwargs.get("page_size", 20)
159
+
160
+ if isinstance(full_result, list):
161
+ return self._paginate_list(
162
+ full_result,
163
+ page,
164
+ page_size,
165
+ metadata,
166
+ result_reference.reference_id,
167
+ )
168
+ elif isinstance(full_result, dict):
169
+ return self._paginate_dict(
170
+ full_result,
171
+ page,
172
+ page_size,
173
+ metadata,
174
+ result_reference.reference_id,
175
+ )
176
+ else:
177
+ return {
178
+ "data": full_result,
179
+ "metadata": metadata,
180
+ "reference_id": result_reference.reference_id,
181
+ "strategy": "pagination",
182
+ "pagination": {
183
+ "page": 1,
184
+ "page_size": 1,
185
+ "total_pages": 1,
186
+ "total_items": 1,
187
+ },
188
+ }
189
+ except Exception as e:
190
+ logger.error(f"分页APP策略处理failed: {e}")
191
+ return {
192
+ "error": f"分页处理failed: {str(e)}",
193
+ "reference_id": result_reference.reference_id,
194
+ }
195
+
196
+ def _paginate_list(
197
+ self,
198
+ data: List[Any],
199
+ page: int,
200
+ page_size: int,
201
+ metadata: Dict[str, Any],
202
+ reference_id: str,
203
+ ) -> Dict[str, Any]:
204
+ total_items = len(data)
205
+ total_pages = (total_items + page_size - 1) // page_size
206
+ page = max(1, min(page, total_pages))
207
+ start_idx = (page - 1) * page_size
208
+ end_idx = start_idx + page_size
209
+ page_data = data[start_idx:end_idx]
210
+ return {
211
+ "data": page_data,
212
+ "metadata": metadata,
213
+ "reference_id": reference_id,
214
+ "strategy": "pagination",
215
+ "pagination": {
216
+ "page": page,
217
+ "page_size": page_size,
218
+ "total_pages": total_pages,
219
+ "total_items": total_items,
220
+ "has_next": page < total_pages,
221
+ "has_prev": page > 1,
222
+ },
223
+ }
224
+
225
+ def _paginate_dict(
226
+ self,
227
+ data: Dict[str, Any],
228
+ page: int,
229
+ page_size: int,
230
+ metadata: Dict[str, Any],
231
+ reference_id: str,
232
+ ) -> Dict[str, Any]:
233
+ items = list(data.items())
234
+ total_items = len(items)
235
+ total_pages = (total_items + page_size - 1) // page_size
236
+ page = max(1, min(page, total_pages))
237
+ start_idx = (page - 1) * page_size
238
+ end_idx = start_idx + page_size
239
+ page_items = items[start_idx:end_idx]
240
+ page_data = dict(page_items)
241
+ return {
242
+ "data": page_data,
243
+ "metadata": metadata,
244
+ "reference_id": reference_id,
245
+ "strategy": "pagination",
246
+ "pagination": {
247
+ "page": page,
248
+ "page_size": page_size,
249
+ "total_pages": total_pages,
250
+ "total_items": total_items,
251
+ "has_next": page < total_pages,
252
+ "has_prev": page > 1,
253
+ },
254
+ }
255
+
256
+
257
+ class PreviewAppStrategy(BaseStrategy):
258
+ category = "app"
259
+
260
+ def process(self, result_reference: "ResultReference", **kwargs) -> Dict[str, Any]:
261
+ try:
262
+ full_result = result_reference.get_full_result()
263
+ metadata = result_reference.get_metadata()
264
+ if full_result is None:
265
+ return {
266
+ "error": "数据不存在",
267
+ "reference_id": result_reference.reference_id,
268
+ }
269
+
270
+ max_size = kwargs.get("max_size", 1000)
271
+ max_items = kwargs.get("max_items", 10)
272
+
273
+ preview_data = self._generate_preview(full_result, max_size, max_items)
274
+ return {
275
+ "preview": preview_data,
276
+ "metadata": metadata,
277
+ "reference_id": result_reference.reference_id,
278
+ "strategy": "preview",
279
+ "type": type(full_result).__name__,
280
+ "truncated": self._is_truncated(full_result, preview_data, max_size),
281
+ }
282
+ except Exception as e:
283
+ logger.error(f"预览APP策略处理failed: {e}")
284
+ return {
285
+ "error": f"预览处理failed: {str(e)}",
286
+ "reference_id": result_reference.reference_id,
287
+ }
288
+
289
+ def _generate_preview(self, data: Any, max_size: int, max_items: int) -> Any:
290
+ """Generate preview data"""
291
+ if isinstance(data, str):
292
+ if len(data) <= max_size:
293
+ return data
294
+ return data[:max_size] + "..."
295
+
296
+ elif isinstance(data, list):
297
+ if len(data) <= max_items:
298
+ return data
299
+ return data[:max_items] + ["..."]
300
+
301
+ elif isinstance(data, dict):
302
+ items = list(data.items())
303
+ if len(items) <= max_items:
304
+ return data
305
+ preview_dict = dict(items[:max_items])
306
+ preview_dict["..."] = f"还有 {len(items) - max_items} 项"
307
+ return preview_dict
308
+
309
+ else:
310
+ result_str = str(data)
311
+ if len(result_str) <= max_size:
312
+ return data
313
+ return self._truncate_preview(data, max_size)
314
+
315
+ def _is_truncated(self, original: Any, preview: Any, max_size: int) -> bool:
316
+ """Determine if truncated"""
317
+ if isinstance(original, str):
318
+ return len(original) > max_size
319
+ elif isinstance(original, (list, dict)):
320
+ return len(str(original)) > max_size
321
+ return False
322
+
323
+ def _truncate_preview(self, data: Any, max_size: int) -> str:
324
+ """Truncate Preview"""
325
+ result_str = str(data)
326
+ if len(result_str) <= max_size:
327
+ return result_str
328
+ return result_str[:max_size] + "..."
@@ -0,0 +1,150 @@
1
+ """Strategy Registrator
2
+ Provides registration, lookup, and management functions for strategies
3
+ """
4
+
5
+ from typing import Dict, Optional, List, TYPE_CHECKING
6
+
7
+ from .strategies import (
8
+ BaseStrategy,
9
+ DefaultLLMStrategy,
10
+ SummaryLLMStrategy,
11
+ TruncateLLMStrategy,
12
+ DefaultAppStrategy,
13
+ PaginationAppStrategy,
14
+ PreviewAppStrategy,
15
+ )
16
+
17
+ if TYPE_CHECKING:
18
+ pass
19
+
20
+ from dolphin.core.logging.logger import get_logger
21
+
22
+ logger = get_logger("skill_results")
23
+
24
+
25
+ class StrategyRegistry:
26
+ """Strategy Registrator
27
+ - Default support category: 'llm', 'app', and other categories can be extended
28
+ - Multiple named strategies can exist under each category
29
+ - Supports registration, lookup, execution, and other operations
30
+ """
31
+
32
+ def __init__(self):
33
+ # Strategies organized by category
34
+ self._strategies: Dict[str, Dict[str, BaseStrategy]] = {}
35
+ self._default_strategies: Dict[str, str] = {}
36
+
37
+ # Register default policy
38
+ self._register_default_strategies()
39
+
40
+ def _register_default_strategies(self):
41
+ """Register default strategy"""
42
+ # LLM
43
+ self.register("default", DefaultLLMStrategy(), category="llm")
44
+ self.register("summary", SummaryLLMStrategy(), category="llm")
45
+ self.register("truncate", TruncateLLMStrategy(), category="llm")
46
+
47
+ # App
48
+ self.register("default", DefaultAppStrategy(), category="app")
49
+ self.register("pagination", PaginationAppStrategy(), category="app")
50
+ self.register("preview", PreviewAppStrategy(), category="app")
51
+
52
+ # Set default policy
53
+ self._default_strategies = {
54
+ "llm": "default",
55
+ "app": "default",
56
+ }
57
+
58
+ def register(
59
+ self, name: str, strategy: BaseStrategy, category: Optional[str] = None
60
+ ) -> None:
61
+ """Register strategy
62
+ - name: Strategy name
63
+ - strategy: Strategy instance
64
+ - category: Strategy category, if None then use the strategy's own category
65
+ """
66
+ if category is None:
67
+ category = strategy.get_category()
68
+
69
+ if category not in self._strategies:
70
+ self._strategies[category] = {}
71
+
72
+ self._strategies[category][name] = strategy
73
+ logger.debug(f"注册策略: {category}:{name} -> {strategy.__class__.__name__}")
74
+
75
+ def get_strategy(self, name: str, category: str) -> Optional[BaseStrategy]:
76
+ """Get strategy
77
+ - name: Strategy name, supports 'llm:summary' / 'app/pagination' format
78
+ - category: Strategy category
79
+ """
80
+ # Parse the category information in name
81
+ if ":" in name:
82
+ category, name = name.split(":", 1)
83
+ elif "/" in name:
84
+ category, name = name.split("/", 1)
85
+
86
+ # If category is a wildcard, try all supported categories
87
+ if category == "*":
88
+ for k in ("llm", "app"):
89
+ if k in self._strategies and name in self._strategies[k]:
90
+ return self._strategies[k][name]
91
+ return None
92
+
93
+ # If category is a list, try each category
94
+ if isinstance(category, (list, tuple)):
95
+ for k in category:
96
+ if k in self._strategies and name in self._strategies[k]:
97
+ return self._strategies[k][name]
98
+ return None
99
+
100
+ # If category is a wildcard, try all supported categories
101
+ # if category in ("llm", "app"):
102
+ if category in self._strategies and name in self._strategies[category]:
103
+ return self._strategies[category][name]
104
+
105
+ return None
106
+
107
+ def get_default_strategy(self, category: str) -> Optional[BaseStrategy]:
108
+ """Get default policy"""
109
+ if category not in self._default_strategies:
110
+ return None
111
+
112
+ default_name = self._default_strategies[category]
113
+ return self.get_strategy(default_name, category)
114
+
115
+ def list_strategies(self, category: Optional[str] = None) -> Dict[str, List[str]]:
116
+ """List all strategies"""
117
+ if category is None:
118
+ return {
119
+ cat: list(strategies.keys())
120
+ for cat, strategies in self._strategies.items()
121
+ }
122
+ elif category in self._strategies:
123
+ return {category: list(self._strategies[category].keys())}
124
+ else:
125
+ return {}
126
+
127
+ def has_strategy(self, name: str, category: str) -> bool:
128
+ """Check if the specified policy exists"""
129
+ return self.get_strategy(name, category) is not None
130
+
131
+ def remove_strategy(self, name: str, category: str) -> bool:
132
+ """Remove Strategy"""
133
+ if category in self._strategies and name in self._strategies[category]:
134
+ del self._strategies[category][name]
135
+ logger.debug(f"移除策略: {category}:{name}")
136
+ return True
137
+ return False
138
+
139
+ def clear(self) -> None:
140
+ """Clear all strategies"""
141
+ self._strategies.clear()
142
+ self._default_strategies.clear()
143
+ logger.debug("清空所有策略")
144
+
145
+ def __len__(self) -> int:
146
+ """Return total number of strategies"""
147
+ return sum(len(strategies) for strategies in self._strategies.values())
148
+
149
+ def __repr__(self) -> str:
150
+ return f"StrategyRegistry(strategies={len(self)}, categories={list(self._strategies.keys())})"
@@ -0,0 +1,44 @@
1
+ # -*- coding: utf-8 -*-
2
+ """Skillkits 模块 - 内置 Skillkits"""
3
+
4
+ from typing import TYPE_CHECKING
5
+
6
+ if TYPE_CHECKING:
7
+ from dolphin.lib.skillkits.search_skillkit import SearchSkillkit
8
+ from dolphin.lib.skillkits.sql_skillkit import SQLSkillkit
9
+ from dolphin.lib.skillkits.memory_skillkit import MemorySkillkit
10
+ from dolphin.lib.skillkits.mcp_skillkit import MCPSkillkit
11
+ from dolphin.lib.skillkits.ontology_skillkit import OntologySkillkit
12
+ from dolphin.lib.skillkits.plan_act_skillkit import PlanActSkillkit
13
+ from dolphin.lib.skillkits.cognitive_skillkit import CognitiveSkillkit
14
+ from dolphin.lib.skillkits.vm_skillkit import VMSkillkit
15
+ from dolphin.lib.skillkits.noop_skillkit import NoopSkillkit
16
+ from dolphin.lib.skillkits.resource_skillkit import ResourceSkillkit
17
+ from dolphin.lib.skillkits.system_skillkit import SystemFunctionsSkillKit
18
+ from dolphin.lib.skillkits.agent_skillkit import AgentSkillKit
19
+ from dolphin.lib.skillkits.env_skillkit import EnvSkillkit
20
+
21
+ _module_lookup = {
22
+ "SearchSkillkit": "dolphin.lib.skillkits.search_skillkit",
23
+ "SQLSkillkit": "dolphin.lib.skillkits.sql_skillkit",
24
+ "MemorySkillkit": "dolphin.lib.skillkits.memory_skillkit",
25
+ "MCPSkillkit": "dolphin.lib.skillkits.mcp_skillkit",
26
+ "OntologySkillkit": "dolphin.lib.skillkits.ontology_skillkit",
27
+ "PlanActSkillkit": "dolphin.lib.skillkits.plan_act_skillkit",
28
+ "CognitiveSkillkit": "dolphin.lib.skillkits.cognitive_skillkit",
29
+ "VMSkillkit": "dolphin.lib.skillkits.vm_skillkit",
30
+ "NoopSkillkit": "dolphin.lib.skillkits.noop_skillkit",
31
+ "ResourceSkillkit": "dolphin.lib.skillkits.resource_skillkit",
32
+ "SystemFunctionsSkillKit": "dolphin.lib.skillkits.system_skillkit",
33
+ "AgentSkillKit": "dolphin.lib.skillkits.agent_skillkit",
34
+ "EnvSkillkit": "dolphin.lib.skillkits.env_skillkit",
35
+ }
36
+
37
+ def __getattr__(name):
38
+ if name in _module_lookup:
39
+ import importlib
40
+ module = importlib.import_module(_module_lookup[name])
41
+ return getattr(module, name)
42
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
43
+
44
+ __all__ = list(_module_lookup.keys())
@@ -0,0 +1,155 @@
1
+ from typing import List, Any
2
+
3
+ from dolphin.core.skill.skillkit import Skillkit
4
+ from dolphin.core.skill.skill_function import SkillFunction
5
+ from dolphin.core.agent.base_agent import BaseAgent
6
+
7
+
8
+ class AgentSkillKit(Skillkit):
9
+ """
10
+ AgentSkillKit acts as a bridge between Agent and Skill system
11
+ Converts a single Agent into a callable skill
12
+ """
13
+
14
+ def __init__(self, agent: BaseAgent, agentName: str = None):
15
+ """
16
+ Initialize AgentSkillKit with an agent
17
+
18
+ Args:
19
+ agent (BaseAgent): BaseAgent instance to wrap as a skill
20
+ agentName (str, optional): Name for the agent skill. If None, uses agent.get_name()
21
+ """
22
+ super().__init__()
23
+ self.agent = agent
24
+ self.agentName = agentName or agent.get_name()
25
+
26
+ # Create the agent execution functions
27
+ self._createAgentSkills()
28
+
29
+ def set_context(self, context):
30
+ self.agent.set_context(context)
31
+
32
+ def _createAgentSkills(self):
33
+ """
34
+ Create OpenAI functions for agent execution
35
+ """
36
+ # Get agent description for function documentation
37
+ agentDesc = self.agent.get_description()
38
+
39
+ # Create async execution function
40
+ async def arunAgent(query_str: str = None, **kwargs) -> Any:
41
+ """
42
+ Execute the agent asynchronously
43
+
44
+ Args:
45
+ query_str (str, optional): Query or task description to pass to the agent
46
+ **kwargs: Additional arguments to pass to the agent
47
+
48
+ Returns:
49
+ Agent execution result
50
+ """
51
+ lastResult = None
52
+ # Use query_str if provided, otherwise use query, with query_str taking priority
53
+ queryParam = query_str
54
+
55
+ # Prepare arguments for agent.arun()
56
+ agentArgs = kwargs.copy()
57
+ if queryParam is not None:
58
+ agentArgs["query"] = queryParam
59
+
60
+ await self.agent.initialize()
61
+ async for result in self.agent.arun(**agentArgs):
62
+ lastResult = result
63
+
64
+ #return variables and last stage answer
65
+ result = {}
66
+ if isinstance(lastResult, dict):
67
+ for k, v in lastResult.items():
68
+ if not k.startswith("_"):
69
+ result[k] = v
70
+ elif k == "_progress":
71
+ if len(v) > 1:
72
+ result.update(v[-1])
73
+ return result
74
+
75
+ # Update function names and docstrings dynamically
76
+ arunAgent.__name__ = f"{self.agentName}"
77
+
78
+ # Use agent description if available, otherwise use default description
79
+ if agentDesc:
80
+ arunAgent.__doc__ = f"""
81
+ {agentDesc}
82
+
83
+ Args:
84
+ query_str (str, optional): Query or task description to pass to the agent
85
+ query (str, optional): Alternative parameter name for backward compatibility
86
+ **kwargs: Additional arguments to pass to the agent
87
+
88
+ Returns:
89
+ Agent execution result
90
+ """
91
+ else:
92
+ arunAgent.__doc__ = f"""
93
+ Execute agent '{self.agentName}' asynchronously
94
+
95
+ Args:
96
+ query_str (str, optional): Query or task description to pass to the agent
97
+ query (str, optional): Alternative parameter name for backward compatibility
98
+ **kwargs: Additional arguments to pass to the agent
99
+
100
+ Returns:
101
+ Agent execution result
102
+ """
103
+
104
+ # Store function references
105
+ self.arunAgentFunc = arunAgent
106
+
107
+ def getName(self) -> str:
108
+ """
109
+ Get the skillkit name
110
+
111
+ Returns:
112
+ Skillkit name
113
+ """
114
+ return f"agent_skillkit_{self.agentName}"
115
+
116
+ def _createSkills(self) -> List[SkillFunction]:
117
+ """
118
+ Create the skills (OpenAI functions) for this agent
119
+
120
+ Returns:
121
+ List of SkillFunction objects
122
+ """
123
+ skills = []
124
+
125
+ # Add async execution function (with arun_ prefix for backward compatibility)
126
+ skills.append(SkillFunction(self.arunAgentFunc))
127
+
128
+ return skills
129
+
130
+ def getAgent(self) -> BaseAgent:
131
+ """
132
+ Get the wrapped agent
133
+
134
+ Returns:
135
+ BaseAgent instance
136
+ """
137
+ return self.agent
138
+
139
+ def getAgentName(self) -> str:
140
+ """
141
+ Get the agent name
142
+
143
+ Returns:
144
+ Agent name string
145
+ """
146
+ return self.agentName
147
+
148
+ def __str__(self) -> str:
149
+ """
150
+ String representation of the AgentSkillKit
151
+
152
+ Returns:
153
+ Description string
154
+ """
155
+ return f"AgentSkillKit(agent={self.agentName})"