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,212 @@
1
+ import fcntl
2
+ import json
3
+ import os
4
+ import threading
5
+ import time
6
+ from typing import List, Dict, Any, Optional
7
+ import uuid
8
+ from dolphin.core.logging.logger import get_logger
9
+
10
+ logger = get_logger("utils.cache_kv")
11
+
12
+
13
+ class CacheKV:
14
+ def __init__(
15
+ self, filePath: str, dumpInterval: int = 5, expireTimeByDay: float = 1
16
+ ):
17
+ self.filePath = filePath
18
+ self.cache = {}
19
+ self.lock = threading.Lock()
20
+ self.dumpInterval = dumpInterval
21
+ self.lastDumpSec = 0
22
+ self.expireTimeByDay = expireTimeByDay
23
+ self.loadCache()
24
+
25
+ def loadCache(self):
26
+ if not os.path.exists(self.filePath):
27
+ return # No file, nothing to load
28
+
29
+ try:
30
+ with open(self.filePath, "r", encoding="utf-8") as f:
31
+ fd = f.fileno()
32
+ fcntl.flock(fd, fcntl.LOCK_SH) # Shared lock for reading
33
+ try:
34
+ loaded_cache = json.load(f)
35
+ for key, value in loaded_cache.items():
36
+ if self._cacheItemExpired(value):
37
+ continue
38
+
39
+ if (
40
+ isinstance(value, dict)
41
+ and "value" in value
42
+ and "timestamp" in value
43
+ ):
44
+ self.cache[key] = value
45
+ else:
46
+ # Compatible with old formats
47
+ self.cache[key] = {"value": value, "timestamp": time.time()}
48
+ finally:
49
+ fcntl.flock(fd, fcntl.LOCK_UN)
50
+ except (json.JSONDecodeError, IOError) as e:
51
+ logger.error(
52
+ f"Error loading cache file {self.filePath}: {e} try to backup and reset cache"
53
+ )
54
+ backup_path = self.filePath + ".err"
55
+ self.cache = {}
56
+ try:
57
+ os.rename(self.filePath, backup_path)
58
+ except OSError as rename_err:
59
+ logger.error(f"Failed to backup cache file: {rename_err}")
60
+
61
+ def dumpCache(self):
62
+ curTime = time.time()
63
+ if curTime - self.lastDumpSec < self.dumpInterval:
64
+ return
65
+
66
+ with self.lock:
67
+ # Ensure the directory exists
68
+ os.makedirs(os.path.dirname(self.filePath), exist_ok=True)
69
+ # Clear expired cache
70
+ self.cache = {
71
+ key: value
72
+ for key, value in self.cache.items()
73
+ if not self._cacheItemExpired(value)
74
+ }
75
+
76
+ # Use unique temporary filename (PID + UUID)
77
+ temp_path = f"{self.filePath}.tmp.{os.getpid()}.{uuid.uuid4().hex}"
78
+ try:
79
+ with open(temp_path, "w", encoding="utf-8") as f:
80
+ fd = f.fileno()
81
+ fcntl.flock(fd, fcntl.LOCK_EX) # Exclusive lock for writing
82
+ try:
83
+ json.dump(self.cache, f, ensure_ascii=False)
84
+ f.flush()
85
+ os.fsync(fd) # Ensure data is written to disk
86
+ finally:
87
+ fcntl.flock(fd, fcntl.LOCK_UN)
88
+
89
+ # Atomic rename
90
+ os.rename(temp_path, self.filePath)
91
+ self.lastDumpSec = curTime
92
+ except Exception as e:
93
+ logger.error(f"Error dumping cache to {self.filePath}: {e}")
94
+ if os.path.exists(temp_path):
95
+ try:
96
+ os.remove(temp_path)
97
+ except OSError as remove_err:
98
+ logger.error(
99
+ f"Failed to remove temp file {temp_path}: {remove_err}"
100
+ )
101
+
102
+ def _keyToStr(self, key: List[Dict]) -> str:
103
+ return json.dumps(key, sort_keys=True, ensure_ascii=False)
104
+
105
+ def get(self, key: List[Dict]) -> Optional[Any]:
106
+ keyStr = self._keyToStr(key)
107
+ with self.lock:
108
+ cached_item = self.cache.get(keyStr)
109
+ if cached_item:
110
+ if not self._cacheItemExpired(cached_item):
111
+ return cached_item["value"]
112
+ else:
113
+ del self.cache[keyStr]
114
+ return None
115
+
116
+ def set(self, key: List[Dict], value: Any):
117
+ keyStr = self._keyToStr(key)
118
+ with self.lock:
119
+ self.cache[keyStr] = {"value": value, "timestamp": time.time()}
120
+ self.dumpCache()
121
+
122
+ def remove(self, key: List[Dict]):
123
+ keyStr = self._keyToStr(key)
124
+ with self.lock:
125
+ if keyStr in self.cache:
126
+ del self.cache[keyStr]
127
+ self.dumpCache()
128
+
129
+ def _cacheItemExpired(self, cacheItem: dict) -> bool:
130
+ return time.time() - cacheItem["timestamp"] > self.expireTimeByDay * 86400
131
+
132
+
133
+ class CacheKVMgr:
134
+ FilePrefix = "cache_"
135
+
136
+ def __init__(
137
+ self,
138
+ cacheDir: str,
139
+ category: str,
140
+ dumpInterval: int = 5,
141
+ expireTimeByDay: float = 1,
142
+ ):
143
+ self.prefix = f"{CacheKVMgr.FilePrefix}{category}_"
144
+ self.cacheDir = cacheDir
145
+ self.category = category
146
+ self.dumpInterval = dumpInterval
147
+ self.expireTimeByDay = expireTimeByDay
148
+ self.caches = {}
149
+ self.loadCaches()
150
+
151
+ def loadCaches(self):
152
+ if not os.path.exists(self.cacheDir):
153
+ os.makedirs(self.cacheDir)
154
+
155
+ for fileName in os.listdir(self.cacheDir):
156
+ if fileName.startswith(self.prefix) and fileName.endswith(".json"):
157
+ modelName = fileName[len(self.prefix) : -5]
158
+ filePath = os.path.join(self.cacheDir, fileName)
159
+ try:
160
+ self.caches[modelName] = CacheKV(
161
+ filePath, self.dumpInterval, self.expireTimeByDay
162
+ )
163
+ except Exception as e:
164
+ logger.error(f"Error initializing cache for {modelName}: {e}")
165
+ raise Exception(f"Error initializing cache for {modelName}: {e}")
166
+
167
+ def getCache(self, modelName: str) -> CacheKV:
168
+ return self.caches.get(modelName)
169
+
170
+ def getValue(self, modelName: str, key: List[Dict]) -> Optional[Any]:
171
+ cache = self.getCache(modelName)
172
+ if cache:
173
+ result = cache.get(key)
174
+ if result:
175
+ logger.debug(f"cache hit: {modelName} {key}")
176
+ return result
177
+ return None
178
+
179
+ def setValue(self, modelName: str, key: List[Dict], value: Any):
180
+ cache = self.getCache(modelName)
181
+ if not cache:
182
+ filePath = os.path.join(self.cacheDir, f"{self.prefix}{modelName}.json")
183
+ cache = CacheKV(filePath, self.dumpInterval, self.expireTimeByDay)
184
+ self.caches[modelName] = cache
185
+ cache.set(key, value)
186
+
187
+ def removeValue(self, modelName: str, key: List[Dict]):
188
+ cache = self.getCache(modelName)
189
+ if cache:
190
+ cache.remove(key)
191
+
192
+
193
+ class CacheKVCenter:
194
+ def __init__(self):
195
+ self.repos = {}
196
+
197
+ def getCacheMgr(
198
+ self,
199
+ cacheDir: str,
200
+ category: str,
201
+ dumpInterval: int = 5,
202
+ expireTimeByDay: float = 1,
203
+ ) -> CacheKVMgr:
204
+ key = f"{cacheDir}_{category}"
205
+ if key not in self.repos:
206
+ self.repos[key] = CacheKVMgr(
207
+ cacheDir, category, dumpInterval, expireTimeByDay
208
+ )
209
+ return self.repos[key]
210
+
211
+
212
+ GlobalCacheKVCenter = CacheKVCenter()
@@ -0,0 +1,340 @@
1
+ from typing import Any, Dict, Iterator, List, Optional
2
+ import ast
3
+ import json
4
+
5
+ from dolphin.core.logging.logger import get_logger
6
+
7
+ logger = get_logger("utils.tools")
8
+
9
+
10
+ def safe_json_loads(json_str: str, strict: bool = True) -> Dict[str, Any]:
11
+ """A safe JSON parsing function that supports multiple parsing strategies.
12
+
13
+ Args:
14
+ json_str: The JSON string to be parsed.
15
+ strict: Whether to use strict mode.
16
+
17
+ Returns:
18
+ The parsed dictionary object.
19
+
20
+ Raises:
21
+ ValueError: When all parsing strategies fail.
22
+ """
23
+ if not json_str or not json_str.strip():
24
+ return {}
25
+
26
+ json_str = json_str.strip()
27
+
28
+ # Strategy 1: Use ast.literal_eval for safer parsing
29
+ try:
30
+ value = ast.literal_eval(json_str)
31
+ if isinstance(value, dict) or isinstance(value, list):
32
+ return value
33
+ except Exception:
34
+ pass
35
+
36
+ # Strategy 2: Use standard json.loads with strict mode
37
+ try:
38
+ return json.loads(json_str, strict=strict)
39
+ except Exception:
40
+ pass
41
+
42
+ # Strategy 3: Replace single quotes with double quotes then parse
43
+ try:
44
+ normalized_content = json_str.replace("'", '"')
45
+ return json.loads(normalized_content, strict=strict)
46
+ except Exception:
47
+ pass
48
+
49
+ # Strategy 4: Try non-strict mode if we were in strict mode
50
+ if strict:
51
+ try:
52
+ return json.loads(json_str, strict=False)
53
+ except Exception:
54
+ pass
55
+
56
+ # Strategy 6: Advanced string cleaning
57
+ try:
58
+ # Clean up common formatting issues to improve fault tolerance
59
+ if json_str.startswith('{\\"'):
60
+ cleaned = json_str.replace('\\"', '"')
61
+ return json.loads(cleaned, strict=False)
62
+ except Exception:
63
+ pass
64
+
65
+ # Strategy 7: Replace newlines with spaces
66
+ try:
67
+ cleaned = json_str.replace("\n", " ")
68
+ return json.loads(cleaned, strict=False)
69
+ except Exception:
70
+ pass
71
+
72
+ # Strategy 8: Append missing closing brace if exactly one more open brace
73
+ try:
74
+ open_brace = json_str.count("{")
75
+ close_brace = json_str.count("}")
76
+ if open_brace == close_brace + 1:
77
+ appended = json_str + "}"
78
+ return json.loads(appended, strict=False)
79
+ except Exception:
80
+ pass
81
+
82
+ # Strategy 9: Handle malformed empty object like '{"}' -> treat as {}
83
+ try:
84
+ stripped = json_str.strip()
85
+ if stripped == '{"}':
86
+ return {}
87
+ except Exception:
88
+ pass
89
+
90
+ raise ValueError(f"Failed to parse JSON: {json_str}")
91
+
92
+
93
+ def safe_jsonl_loads(jsonl_str: str) -> List[Dict[str, Any]]:
94
+ """Safe JSONL parsing function
95
+
96
+ Args:
97
+ jsonl_str: JSONL string to be parsed
98
+
99
+ Returns:
100
+ List of parsed dictionaries
101
+
102
+ Raises:
103
+ ValueError: If parsing fails
104
+ """
105
+ jsonl_str = jsonl_str.strip()
106
+ if not jsonl_str:
107
+ return []
108
+
109
+ results = []
110
+ try:
111
+ results = json.loads(jsonl_str, strict=False)
112
+ except Exception:
113
+ try:
114
+ results = ast.literal_eval(jsonl_str)
115
+ if isinstance(results, list):
116
+ return results
117
+ except Exception:
118
+ pass
119
+
120
+ if results:
121
+ if isinstance(results, list):
122
+ return results
123
+ if isinstance(results, dict):
124
+ for key, value in results.items():
125
+ if isinstance(value, list):
126
+ return value
127
+
128
+ results = []
129
+ for line_num, line in enumerate(jsonl_str.split("\n"), 1):
130
+ line = line.strip()
131
+ if not line:
132
+ continue
133
+
134
+ try:
135
+ obj = safe_json_loads(line, strict=False)
136
+ results.append(obj)
137
+ except ValueError as e:
138
+ logger.error(f"Failed to parse JSONL line {line_num}: {e}")
139
+ logger.error(f"Line content: {line}")
140
+ raise ValueError(f"Invalid JSON format in JSONL line {line_num}: {e}")
141
+
142
+ return results
143
+
144
+
145
+ def extract_json_from_response(response_str: str) -> str:
146
+ """Extract JSON content from response string (handling code block markers)
147
+
148
+ Args:
149
+ response_str: Original response string
150
+
151
+ Returns:
152
+ Extracted JSON string
153
+ """
154
+ response_str = response_str.strip()
155
+
156
+ # Process ```json code block
157
+ if "```json" in response_str:
158
+ start = response_str.find("```json") + 7
159
+ end = response_str.find("```", start)
160
+ if end != -1:
161
+ return response_str[start:end].strip()
162
+
163
+ # Process generic code blocks
164
+ elif response_str.startswith("```") and response_str.endswith("```"):
165
+ lines = response_str.split("\n")
166
+ if len(lines) > 2:
167
+ return "\n".join(lines[1:-1])
168
+
169
+ elif response_str.startswith("{"):
170
+ # Find the matching } considering nested braces
171
+ start = 0
172
+ count = 1
173
+ end = -1
174
+ for i in range(1, len(response_str)):
175
+ if response_str[i] == "{":
176
+ count += 1
177
+ elif response_str[i] == "}":
178
+ count -= 1
179
+ if count == 0:
180
+ end = i
181
+ break
182
+ if end != -1:
183
+ return response_str[start : end + 1].strip()
184
+
185
+ return response_str
186
+
187
+
188
+ def extract_jsonl_from_response(response_str: str) -> str:
189
+ """Extract JSONL content from response string (handling code block markers)
190
+
191
+ Args:
192
+ response_str: Original response string
193
+
194
+ Returns:
195
+ Extracted JSONL string
196
+ """
197
+ response_str = response_str.strip()
198
+
199
+ # Handle ```jsonl or ```json code blocks
200
+ start_markers = ["```jsonl", "```json"]
201
+ for marker in start_markers:
202
+ if marker in response_str:
203
+ start = response_str.find(marker) + len(marker)
204
+ end = response_str.find("```", start)
205
+ if end != -1:
206
+ return response_str[start:end].strip()
207
+ break
208
+
209
+ # Process generic code blocks
210
+ if response_str.startswith("```") and response_str.endswith("```"):
211
+ lines = response_str.split("\n")
212
+ if len(lines) > 2:
213
+ return "\n".join(lines[1:-1])
214
+
215
+ elif response_str.startswith("["):
216
+ # Find the matching ] considering nested braces
217
+ start = 0
218
+ count = 1
219
+ end = -1
220
+ for i in range(1, len(response_str)):
221
+ if response_str[i] == "[":
222
+ count += 1
223
+ elif response_str[i] == "]":
224
+ count -= 1
225
+ if count == 0:
226
+ end = i
227
+ break
228
+ if end != -1:
229
+ return response_str[start : end + 1].strip()
230
+
231
+ return response_str
232
+
233
+
234
+ def extract_json(content: str) -> Dict[str, Any]:
235
+ """Extract JSON content from response string (handling code block markers)
236
+
237
+ Args:
238
+ content: Original response string
239
+ """
240
+ content = extract_json_from_response(content)
241
+ result = safe_json_loads(content)
242
+ if isinstance(result, dict) or isinstance(result, list):
243
+ return result
244
+ else:
245
+ raise ValueError(f"Invalid JSON format: {content}")
246
+
247
+
248
+ def extract_jsonl(content: str) -> List[Dict[str, Any]]:
249
+ """Extract JSONL content from response string (handling code block markers)
250
+
251
+ Args:
252
+ content: Original response string
253
+ """
254
+ content = extract_jsonl_from_response(content)
255
+ result = safe_jsonl_loads(content)
256
+ if isinstance(result, list):
257
+ return result
258
+ else:
259
+ raise ValueError(f"Invalid JSONL format: {content}")
260
+
261
+
262
+ class Tool:
263
+ # The unique name of the tool that clearly communicates its purpose
264
+ name: str
265
+ # Tool description, explaining the functions of the tool, facilitating the selection and invocation of LLM
266
+ description: str
267
+ # Tool type, eg: flow, component, api, etc
268
+ # type: str
269
+ # Input parameters of the tool
270
+ inputs: Dict
271
+ # Output format of the tool
272
+ outputs: Dict
273
+
274
+ result_process_strategy_cfg: list[Dict[str, str]] = None
275
+
276
+ def __init__(
277
+ self,
278
+ name: str,
279
+ description: str,
280
+ inputs: Dict,
281
+ outputs: Dict,
282
+ props: Optional[dict] = None,
283
+ result_process_strategy_cfg: list[Dict[str, str]] = None,
284
+ ):
285
+ self.name = name
286
+ self.description = description
287
+ self.inputs = inputs
288
+ self.outputs = outputs
289
+ self.props = props
290
+ self.intervention = props.get("intervention", False)
291
+ self.result_process_strategy_cfg = result_process_strategy_cfg
292
+
293
+ def tool_info(self) -> dict:
294
+ """The tool's information."""
295
+ return {
296
+ "name": self.name,
297
+ "description": self.description,
298
+ "inputs": self.inputs,
299
+ "outputs": self.outputs,
300
+ }
301
+
302
+ def run(self, **kwargs) -> Any:
303
+ """
304
+ Run the tool
305
+ """
306
+ raise NotImplementedError
307
+
308
+ async def arun(self, **kwargs) -> Any:
309
+ """
310
+ Run the tool asynchronously.
311
+ """
312
+ raise NotImplementedError
313
+
314
+ def run_stream(self, **kwargs) -> Iterator[Any]:
315
+ """
316
+ Run the tool with streaming output.
317
+ """
318
+ raise NotImplementedError
319
+
320
+ async def arun_stream(self, **kwargs) -> Iterator[Any]:
321
+ """
322
+ Run the tool with streaming output asynchronously.
323
+ """
324
+ raise NotImplementedError
325
+
326
+
327
+ class ToolInterrupt(Exception):
328
+ """Exception raised when the tool is interrupted."""
329
+
330
+ def __init__(
331
+ self,
332
+ message="The tool was interrupted.",
333
+ tool_name: str = None,
334
+ tool_args: List[Dict] = None,
335
+ *args,
336
+ **kwargs,
337
+ ):
338
+ super().__init__(message, *args, **kwargs)
339
+ self.tool_name = tool_name if tool_name else ""
340
+ self.tool_args = tool_args if tool_args else []
@@ -0,0 +1,93 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Dolphin Lib - 标准库和工具集(用户态)
4
+
5
+ 职责:
6
+ - 内置 Skillkits(search、sql、memory、mcp 等)
7
+ - Ontology 管理系统
8
+ - VM 虚拟机(可选执行后端)
9
+ - Memory 内存管理(知识管理)
10
+ - 工具函数库
11
+ - 调试可视化工具
12
+
13
+ 依赖规则:
14
+ - dolphin.lib → 依赖 dolphin.core
15
+ """
16
+
17
+ from typing import TYPE_CHECKING
18
+
19
+ if TYPE_CHECKING:
20
+ # Skillkits
21
+ from dolphin.lib.skillkits import (
22
+ SearchSkillkit,
23
+ SQLSkillkit,
24
+ MemorySkillkit,
25
+ MCPSkillkit,
26
+ OntologySkillkit,
27
+ PlanActSkillkit,
28
+ CognitiveSkillkit,
29
+ VMSkillkit,
30
+ NoopSkillkit,
31
+ ResourceSkillkit,
32
+ SystemFunctionsSkillKit,
33
+ AgentSkillKit,
34
+ )
35
+ # Ontology
36
+ from dolphin.lib.ontology import (
37
+ Ontology,
38
+ OntologyManager,
39
+ OntologyContext,
40
+ )
41
+ # VM
42
+ from dolphin.lib.vm import (
43
+ VM,
44
+ PythonSessionManager,
45
+ )
46
+ # Memory
47
+ from dolphin.lib.memory import (
48
+ MemoryManager,
49
+ )
50
+ # Skill Results
51
+ from dolphin.lib.skill_results import (
52
+ CacheBackend,
53
+ ResultProcessor,
54
+ ResultReference,
55
+ )
56
+
57
+ _module_lookup = {
58
+ # Skillkits
59
+ "SearchSkillkit": "dolphin.lib.skillkits",
60
+ "SQLSkillkit": "dolphin.lib.skillkits",
61
+ "MemorySkillkit": "dolphin.lib.skillkits",
62
+ "MCPSkillkit": "dolphin.lib.skillkits",
63
+ "OntologySkillkit": "dolphin.lib.skillkits",
64
+ "PlanActSkillkit": "dolphin.lib.skillkits",
65
+ "CognitiveSkillkit": "dolphin.lib.skillkits",
66
+ "VMSkillkit": "dolphin.lib.skillkits",
67
+ "NoopSkillkit": "dolphin.lib.skillkits",
68
+ "ResourceSkillkit": "dolphin.lib.skillkits",
69
+ "SystemFunctionsSkillKit": "dolphin.lib.skillkits",
70
+ "AgentSkillKit": "dolphin.lib.skillkits",
71
+ # Ontology
72
+ "Ontology": "dolphin.lib.ontology",
73
+ "OntologyManager": "dolphin.lib.ontology",
74
+ "OntologyContext": "dolphin.lib.ontology",
75
+ # VM
76
+ "VM": "dolphin.lib.vm",
77
+ "PythonSessionManager": "dolphin.lib.vm",
78
+ # Memory
79
+ "MemoryManager": "dolphin.lib.memory",
80
+ # Skill Results
81
+ "CacheBackend": "dolphin.lib.skill_results",
82
+ "ResultProcessor": "dolphin.lib.skill_results",
83
+ "ResultReference": "dolphin.lib.skill_results",
84
+ }
85
+
86
+ def __getattr__(name):
87
+ if name in _module_lookup:
88
+ import importlib
89
+ module = importlib.import_module(_module_lookup[name])
90
+ return getattr(module, name)
91
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
92
+
93
+ __all__ = list(_module_lookup.keys())
@@ -0,0 +1,8 @@
1
+ # -*- coding: utf-8 -*-
2
+ """Debug 模块 - 调试工具"""
3
+
4
+ from dolphin.lib.debug.visualizer import TraceVisualizer
5
+
6
+ __all__ = [
7
+ "TraceVisualizer",
8
+ ]