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,274 @@
1
+ from typing import List, Optional
2
+ import re
3
+ from dolphin.core.skill.skill_function import SkillFunction
4
+ from dolphin.core.skill.skillkit import Skillkit
5
+
6
+ from dolphin.lib.ontology.ontology_context import OntologyContext
7
+
8
+
9
+ class SQLSkillkit(Skillkit):
10
+ def __init__(self, ontologyContext: Optional[OntologyContext] = None):
11
+ super().__init__()
12
+ self.ontologyContext = ontologyContext
13
+
14
+ def getName(self) -> str:
15
+ return "sql_skillkit"
16
+
17
+ def setGlobalConfig(self, globalConfig):
18
+ super().setGlobalConfig(globalConfig)
19
+ if (
20
+ self.ontologyContext is None
21
+ and self.globalConfig.ontology_config is not None
22
+ ):
23
+ self.ontologyContext = OntologyContext.loadOntologyContext(
24
+ self.globalConfig.ontology_config
25
+ )
26
+
27
+ def executeSQL(
28
+ self, datasource: str, sql: str, dialect: str = "mysql", **kwargs
29
+ ) -> str:
30
+ """Execute an SQL statement in the specified data source and return the result.
31
+
32
+ Args:
33
+ datasource (str): Name or concept name of the data source
34
+ sql (str): A valid SQL statement starting with SELECT
35
+ dialect (str): SQL dialect, default is 'mysql', supports 'oracle', 'mysql', 'postgres', etc.
36
+ **kwargs: Other parameters
37
+ """
38
+ # Extract valid SQL from input string using regex
39
+ cleanedSQL = self._extractSQL(sql)
40
+ if not cleanedSQL:
41
+ return "无法从输入中提取有效的SQL语句"
42
+
43
+ # Apply dialect-specific preprocessing
44
+ processedSQL = self._preprocessSQL(cleanedSQL, dialect)
45
+
46
+ if self.ontologyContext is None:
47
+ return "Ontology context is not initialized"
48
+
49
+ ontology = self.ontologyContext.getOntology()
50
+ if ontology is None:
51
+ return "Ontology is not available"
52
+
53
+ theDataSource = ontology.getDataSource(datasource)
54
+ if theDataSource is None:
55
+ return f"数据源或概念 {datasource} 不存在"
56
+
57
+ try:
58
+ result = theDataSource.executeQuery(processedSQL)
59
+ return str(result)
60
+ except Exception as e:
61
+ # Enhanced error handling with dialect-specific suggestions
62
+ return self._handleSQLError(e, processedSQL, dialect)
63
+
64
+ def _extractSQL(self, inputStr: str) -> str:
65
+ if not inputStr:
66
+ return ""
67
+
68
+ content = inputStr.strip()
69
+
70
+ if content.startswith("```") and content.endswith("```"):
71
+ content = content[3:-3].strip()
72
+ if content.lower().startswith("sql"):
73
+ content = content[3:].strip()
74
+
75
+ while True:
76
+ if (
77
+ (content.startswith('"') and content.endswith('"'))
78
+ or (content.startswith("'") and content.endswith("'"))
79
+ or (content.startswith("`") and content.endswith("`"))
80
+ ):
81
+ content = content[1:-1].strip()
82
+ else:
83
+ break
84
+
85
+ lines = content.split("\n")
86
+ sql_lines = []
87
+ in_sql_block = False
88
+ sql_keywords = [
89
+ "SELECT",
90
+ "INSERT",
91
+ "UPDATE",
92
+ "DELETE",
93
+ "CREATE",
94
+ "DROP",
95
+ "ALTER",
96
+ "WITH",
97
+ ]
98
+
99
+ for line in lines:
100
+ stripped_line = line.strip()
101
+
102
+ if not in_sql_block:
103
+ for keyword in sql_keywords:
104
+ if stripped_line.upper().startswith(keyword):
105
+ in_sql_block = True
106
+ break
107
+
108
+ if in_sql_block:
109
+ if not stripped_line:
110
+ break
111
+ sql_lines.append(line)
112
+ if stripped_line.endswith(";"):
113
+ break
114
+
115
+ if sql_lines:
116
+ return "\n".join(sql_lines).strip()
117
+
118
+ return content.strip()
119
+
120
+ def _extractSQLFromMixedContent(self, text: str) -> str:
121
+ return self._extractSQL(text) # Just reuse the main logic
122
+
123
+ def _normalizeWhitespace(self, sql: str) -> str:
124
+ return sql.strip()
125
+
126
+ def _validateSQLCompleteness(self, sql: str) -> bool:
127
+ if not sql:
128
+ return False
129
+
130
+ text = sql
131
+
132
+ # Remove string literals and comments to avoid interfering with structural validation
133
+ def _strip_literals_and_comments(s: str) -> str:
134
+ # Remove -- line comments
135
+ s = re.sub(r"--.*?$", "", s, flags=re.MULTILINE)
136
+ # Remove /* ... */ block comments
137
+ s = re.sub(r"/\*.*?\*/", "", s, flags=re.DOTALL)
138
+ # Remove the content within single and double quotation marks (preserve structure outside quotes)
139
+ s = re.sub(r"'(?:''|[^'])*'", "''", s)
140
+ s = re.sub(r'"(?:""|[^"])*"', '""', s)
141
+ return s
142
+
143
+ cleaned = _strip_literals_and_comments(text)
144
+
145
+ # Bracket Matching
146
+ open_parens = cleaned.count("(")
147
+ close_parens = cleaned.count(")")
148
+ if open_parens != close_parens:
149
+ return False
150
+
151
+ sql_upper = cleaned.upper().strip()
152
+
153
+ # Basic Structure Judgment
154
+ if sql_upper.startswith("SELECT"):
155
+ # Allow FROM across newlines/indentation by using word-boundary match
156
+ if not re.search(r"\bFROM\b", sql_upper):
157
+ return False
158
+ # Avoid false positives like identifiers ending with these keywords (e.g., SORT_ORDER)
159
+ if re.search(
160
+ r"\b(AND|OR|WHERE|FROM|JOIN|ON|GROUP|ORDER|HAVING|UNION|INTERSECT|EXCEPT)\s*$",
161
+ sql_upper,
162
+ ):
163
+ return False
164
+ elif sql_upper.startswith("WITH"):
165
+ if "SELECT" not in sql_upper:
166
+ return False
167
+
168
+ if text.strip().endswith(","):
169
+ return False
170
+
171
+ # CASE/END Pairing (matched by word boundaries to avoid miscounting)
172
+ case_count = len(re.findall(r"\bCASE\b", cleaned, flags=re.IGNORECASE))
173
+ end_count = len(re.findall(r"\bEND\b", cleaned, flags=re.IGNORECASE))
174
+ if case_count != end_count:
175
+ return False
176
+
177
+ return True
178
+
179
+ def _extractSQLConservatively(self, text: str) -> str:
180
+ return self._extractSQL(text)
181
+
182
+ def _preprocessSQL(self, sql: str, dialect: str) -> str:
183
+ if dialect.lower() == "oracle":
184
+ return self._preprocessOracleSQL(sql)
185
+ elif dialect.lower() == "mysql":
186
+ return self._preprocessMySQLSQL(sql)
187
+ else:
188
+ return sql
189
+
190
+ def _preprocessOracleSQL(self, sql: str) -> str:
191
+ # Simplified replacements to avoid complex regex issues
192
+ # 1. Fix DATE() function -> TO_DATE(), but avoid replacing TO_DATE()
193
+ sql = re.sub(
194
+ r"(?<!TO_)DATE\s*\(\s*'(.*?)'\s*\)",
195
+ r"TO_DATE('\1', 'YYYY-MM-DD')",
196
+ sql,
197
+ flags=re.IGNORECASE,
198
+ )
199
+
200
+ # 2. Convert LIMIT -> FETCH FIRST
201
+ limit_match = re.search(r"LIMIT\s+(\d+)\s*$", sql, re.IGNORECASE)
202
+ if limit_match:
203
+ num = limit_match.group(1)
204
+ sql = re.sub(
205
+ r"LIMIT\s+\d+\s*$",
206
+ f"FETCH FIRST {num} ROWS ONLY",
207
+ sql,
208
+ flags=re.IGNORECASE,
209
+ )
210
+
211
+ # 3. Handle date strings -> TO_DATE(), but DO NOT alter ANSI DATE literals
212
+ # i.e., keep: DATE 'YYYY-MM-DD' as-is, and avoid nesting when already inside TO_DATE(
213
+ def _replace_plain_date_literals(text: str) -> str:
214
+ pattern = re.compile(r"'(\d{4}-\d{2}-\d{2})'")
215
+
216
+ def repl(m: re.Match) -> str:
217
+ start = m.start()
218
+ before = text[:start]
219
+ # Ignore if immediately preceded by DATE (ANSI literal)
220
+ if re.search(r"(?i)DATE\s*$", before.rstrip()[-10:]):
221
+ return m.group(0)
222
+ # Ignore if inside a TO_DATE( ... ) argument beginning
223
+ if re.search(r"(?i)TO_DATE\s*\($", before.rstrip()[-15:]):
224
+ return m.group(0)
225
+ value = m.group(1)
226
+ return f"TO_DATE('{value}', 'YYYY-MM-DD')"
227
+
228
+ return pattern.sub(repl, text)
229
+
230
+ sql = _replace_plain_date_literals(sql)
231
+
232
+ # 4. Ensure string literals use single quotes (preserve '=')
233
+ sql = re.sub(r'="([^"]*)"', r"='\1'", sql)
234
+
235
+ return sql
236
+
237
+ def _preprocessMySQLSQL(self, sql: str) -> str:
238
+ return sql
239
+
240
+ def _handleSQLError(self, error: Exception, sql: str, dialect: str) -> str:
241
+ error_str = str(error).upper()
242
+ if dialect.lower() == "oracle":
243
+ return self._handleOracleError(error_str, sql)
244
+ else:
245
+ return f"执行SQL语句failed: {error}"
246
+
247
+ def _handleOracleError(self, error_str: str, sql: str) -> str:
248
+ suggestions = []
249
+ if "ORA-00904" in error_str:
250
+ suggestions.append("字段不存在或无效。请检查字段名拼写和表别名。")
251
+ elif "ORA-00942" in error_str:
252
+ suggestions.append("表或视图不存在。请检查table name和用户权限。")
253
+ elif "ORA-01843" in error_str:
254
+ suggestions.append(
255
+ "日期格式无效。请使用 TO_DATE('YYYY-MM-DD', 'YYYY-MM-DD') 格式。"
256
+ )
257
+ elif "ORA-00933" in error_str:
258
+ suggestions.append("SQL命令未正确结束。请检查语法和括号匹配。")
259
+ elif "ORA-00936" in error_str:
260
+ suggestions.append("缺少表达式。请检查SELECT子句是否完整。")
261
+
262
+ if suggestions:
263
+ suggestion_text = "\n".join([f" - {s}" for s in suggestions])
264
+ return f"执行SQL语句failed: {error_str}\n\n建议修复方案:\n{suggestion_text}"
265
+ else:
266
+ return f"执行SQL语句failed: {error_str}"
267
+
268
+ def _createSkills(self) -> List[SkillFunction]:
269
+ return [
270
+ SkillFunction(self.executeSQL, block_as_parameter=("sql", "sql")),
271
+ ]
272
+
273
+ def getTools(self) -> List[SkillFunction]:
274
+ return self.getSkills() # Uses base class getSkills() with caching