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,302 @@
1
+ """
2
+ Stream Renderer - CLI Layer for Live Markdown Rendering
3
+
4
+ This module provides the CLI-layer rendering logic for LLM streaming output.
5
+ It is completely separate from the SDK core, allowing the SDK to remain
6
+ agnostic to terminal rendering concerns.
7
+
8
+ Usage:
9
+ renderer = LiveStreamRenderer()
10
+ renderer.start()
11
+ async for item in llm_chat_stream(..., on_stream_chunk=renderer.on_chunk):
12
+ ...
13
+ renderer.stop()
14
+ """
15
+
16
+ from typing import Optional, Callable
17
+
18
+
19
+ def _is_fixed_layout_active() -> bool:
20
+ """Check if we're using the fixed bottom layout (scroll region is active).
21
+
22
+ When fixed layout is active, Rich Live is incompatible and should be disabled.
23
+ """
24
+ try:
25
+ from dolphin.cli.ui.console import _active_status_bar
26
+ # If there's an active status bar with a fixed_row, we're in fixed layout mode
27
+ if _active_status_bar and hasattr(_active_status_bar, 'fixed_row'):
28
+ return _active_status_bar.fixed_row is not None
29
+ except ImportError:
30
+ pass
31
+ return False
32
+
33
+
34
+ class LiveStreamRenderer:
35
+ """
36
+ Live Markdown renderer for LLM streaming output.
37
+
38
+ This class manages Rich's Live component to provide real-time
39
+ Markdown rendering of LLM responses. If Rich is not available,
40
+ or if fixed layout mode is active, it falls back to simple console output.
41
+
42
+ IMPORTANT: Rich Live is DISABLED when fixed bottom layout is active,
43
+ because Rich Live and ANSI scroll regions are fundamentally incompatible.
44
+ Rich Live takes over terminal control and breaks our scroll region setup.
45
+ """
46
+
47
+ def __init__(self, verbose: bool = True):
48
+ self._live = None
49
+ self._Markdown = None
50
+ self._verbose = verbose
51
+ self._started = False
52
+ self._rich_available = False
53
+ self._use_simple_mode = False # True when Rich Live is disabled
54
+ self._paused_status_bar = None # Track paused status bar for resume
55
+ self._has_output = False # Track if we've actually output something
56
+
57
+ def start(self) -> "LiveStreamRenderer":
58
+ """
59
+ Start the Live renderer context.
60
+
61
+ Returns self for method chaining:
62
+ renderer = LiveStreamRenderer().start()
63
+ """
64
+ if not self._verbose:
65
+ return self
66
+
67
+ # Pause the status bar to avoid conflicts with streaming output
68
+ try:
69
+ from dolphin.cli.ui.console import _pause_active_status_bar
70
+ self._paused_status_bar = _pause_active_status_bar()
71
+ except ImportError:
72
+ self._paused_status_bar = None
73
+
74
+ # ALWAYS use simple mode in CLI
75
+ # Rich Live is INCOMPATIBLE with scroll regions and terminal layouts
76
+ # because it takes over terminal control and breaks cursor positioning
77
+ import sys
78
+ if sys.stdout.isatty():
79
+ self._use_simple_mode = True
80
+ self._started = True
81
+ return self
82
+
83
+ # Non-TTY fallback: try Rich Live (for notebooks, etc.)
84
+ try:
85
+ from rich.live import Live
86
+ from rich.markdown import Markdown
87
+
88
+ self._Markdown = Markdown
89
+ self._live = Live(
90
+ Markdown(""),
91
+ auto_refresh=True,
92
+ refresh_per_second=10,
93
+ vertical_overflow="visible",
94
+ )
95
+ self._live.start()
96
+ self._rich_available = True
97
+ self._started = True
98
+ except ImportError:
99
+ self._rich_available = False
100
+ self._started = True
101
+
102
+ return self
103
+
104
+ def on_chunk(self, chunk_text: str, full_text: str, is_final: bool = False) -> None:
105
+ """
106
+ Callback for each streaming chunk.
107
+
108
+ Args:
109
+ chunk_text: The new text in this chunk (delta)
110
+ full_text: The complete accumulated text so far
111
+ is_final: Whether this is the final chunk
112
+ """
113
+ if not self._verbose:
114
+ return
115
+
116
+ if self._use_simple_mode:
117
+ # Line-buffered output with manual ANSI highlighting
118
+ # This provides basic Markdown formatting without Rich Live
119
+ if not hasattr(self, '_line_buffer'):
120
+ self._line_buffer = ""
121
+
122
+ self._line_buffer += chunk_text
123
+
124
+ # Process complete lines
125
+ while '\n' in self._line_buffer:
126
+ line, self._line_buffer = self._line_buffer.split('\n', 1)
127
+ self._print_highlighted_line(line)
128
+ self._has_output = True # Track that we've output something
129
+
130
+ elif self._rich_available and self._live and self._Markdown:
131
+ # Rich Live mode: update with full Markdown
132
+ self._live.update(self._Markdown(full_text))
133
+ else:
134
+ # Fallback: print incremental text
135
+ print(chunk_text, end="", flush=True)
136
+
137
+ def _print_highlighted_line(self, line: str) -> None:
138
+ """Print a line with simple ANSI Markdown highlighting."""
139
+ # ANSI codes
140
+ BOLD = "\033[1m"
141
+ RESET = "\033[0m"
142
+ CYAN = "\033[36m"
143
+ GREEN = "\033[32m"
144
+ YELLOW = "\033[33m"
145
+ MAGENTA = "\033[35m"
146
+ BLUE = "\033[34m"
147
+ WHITE = "\033[37m"
148
+ DIM = "\033[2m"
149
+ BG_GRAY = "\033[48;5;236m" # Dark gray background for code
150
+
151
+ stripped = line.lstrip()
152
+ indent = line[:len(line) - len(stripped)]
153
+
154
+ # Track code block state
155
+ if not hasattr(self, '_in_code_block'):
156
+ self._in_code_block = False
157
+ self._code_lang = ""
158
+
159
+ # Code block start/end markers
160
+ if stripped.startswith('```'):
161
+ if not self._in_code_block:
162
+ # Starting a code block
163
+ self._in_code_block = True
164
+ self._code_lang = stripped[3:].strip()
165
+ lang_display = f" {self._code_lang}" if self._code_lang else ""
166
+ print(f"{indent}{DIM}╭───{lang_display}{'─' * max(0, 40 - len(lang_display))}╮{RESET}")
167
+ else:
168
+ # Ending a code block
169
+ self._in_code_block = False
170
+ self._code_lang = ""
171
+ print(f"{indent}{DIM}╰{'─' * 44}╯{RESET}")
172
+ return
173
+
174
+ # Inside code block - render code with special formatting
175
+ if self._in_code_block:
176
+ print(f"{indent}{DIM}│{RESET} {GREEN}{stripped}{RESET}")
177
+ return
178
+
179
+ # Headers (H1-H6) - check longer prefixes first, remove # prefix for cleaner output
180
+ if stripped.startswith('###### '):
181
+ title = stripped[7:] # Remove '###### '
182
+ print(f"{indent}{DIM}{title}{RESET}")
183
+ elif stripped.startswith('##### '):
184
+ title = stripped[6:] # Remove '##### '
185
+ print(f"{indent}{WHITE}{title}{RESET}")
186
+ elif stripped.startswith('#### '):
187
+ title = stripped[5:] # Remove '#### '
188
+ print(f"{indent}{BLUE}{BOLD}{title}{RESET}")
189
+ elif stripped.startswith('### '):
190
+ title = stripped[4:] # Remove '### '
191
+ print(f"{indent}{MAGENTA}{BOLD}{title}{RESET}")
192
+ elif stripped.startswith('## '):
193
+ title = stripped[3:] # Remove '## '
194
+ print(f"{indent}{CYAN}{BOLD}{title}{RESET}")
195
+ elif stripped.startswith('# '):
196
+ title = stripped[2:] # Remove '# '
197
+ print(f"{indent}{YELLOW}{BOLD}{title}{RESET}")
198
+ # Markdown tables - detect lines with | delimiters
199
+ elif stripped.startswith('|') and stripped.endswith('|'):
200
+ # Check if it's a separator row (|---|---|)
201
+ inner = stripped[1:-1]
202
+ if all(c in '-|: ' for c in inner):
203
+ # Table separator row - render as horizontal line
204
+ cells = inner.split('|')
205
+ rendered_cells = [DIM + '─' * max(3, len(cell.strip())) + RESET for cell in cells]
206
+ print(f"{indent}{DIM}├{'┼'.join(rendered_cells)}┤{RESET}")
207
+ else:
208
+ # Table data row - render with nice borders
209
+ cells = inner.split('|')
210
+ rendered_cells = [self._highlight_inline(cell.strip()) for cell in cells]
211
+ print(f"{indent}{DIM}│{RESET} {f' {DIM}│{RESET} '.join(rendered_cells)} {DIM}│{RESET}")
212
+ # Lists
213
+ elif stripped.startswith('- ') or stripped.startswith('* '):
214
+ bullet = stripped[0]
215
+ content = stripped[2:]
216
+ # Handle inline formatting in content
217
+ content = self._highlight_inline(content)
218
+ print(f"{indent}{GREEN}•{RESET} {content}")
219
+ # Numbered lists
220
+ elif len(stripped) > 2 and stripped[0].isdigit() and stripped[1] in '.:)':
221
+ num = stripped[0]
222
+ content = stripped[2:].lstrip()
223
+ content = self._highlight_inline(content)
224
+ print(f"{indent}{GREEN}{num}.{RESET} {content}")
225
+ # Regular text with inline formatting
226
+ else:
227
+ print(f"{indent}{self._highlight_inline(stripped)}")
228
+
229
+ def _highlight_inline(self, text: str) -> str:
230
+ """Highlight inline Markdown: **bold**, `code`, etc."""
231
+ import re
232
+ BOLD = "\033[1m"
233
+ RESET = "\033[0m"
234
+ CYAN = "\033[36m"
235
+ DIM = "\033[2m"
236
+
237
+ # Replace **text** with bold
238
+ text = re.sub(r'\*\*(.+?)\*\*', f'{BOLD}\\1{RESET}', text)
239
+ # Replace `code` with cyan
240
+ text = re.sub(r'`([^`]+)`', f'{CYAN}\\1{RESET}', text)
241
+ return text
242
+
243
+ def _highlight_inline_bold(self, text: str) -> str:
244
+ """Highlight **bold** text with ANSI codes. (Legacy, use _highlight_inline instead)"""
245
+ return self._highlight_inline(text)
246
+
247
+ def stop(self) -> None:
248
+ """Stop the Live renderer and clean up."""
249
+ # Flush any remaining buffer in simple mode
250
+ if self._use_simple_mode and self._started:
251
+ if hasattr(self, '_line_buffer') and self._line_buffer:
252
+ # Print remaining content (may not end with newline)
253
+ self._print_highlighted_line(self._line_buffer)
254
+ self._line_buffer = ""
255
+ # Only add newline if we actually output something
256
+ elif hasattr(self, '_has_output') and self._has_output:
257
+ print() # End the streaming output with a newline
258
+
259
+ if self._live and self._started and not self._use_simple_mode:
260
+ try:
261
+ self._live.stop()
262
+ except Exception:
263
+ pass
264
+ self._started = False
265
+ self._use_simple_mode = False
266
+ self._has_output = False # Reset for next use
267
+
268
+ # Resume the status bar that was paused during streaming
269
+ if hasattr(self, '_paused_status_bar') and self._paused_status_bar:
270
+ try:
271
+ from dolphin.cli.ui.console import _resume_status_bar
272
+ _resume_status_bar(self._paused_status_bar)
273
+ except ImportError:
274
+ pass
275
+ self._paused_status_bar = None
276
+
277
+ def __enter__(self) -> "LiveStreamRenderer":
278
+ """Context manager support."""
279
+ return self.start()
280
+
281
+ def __exit__(self, exc_type, exc_val, exc_tb) -> None:
282
+ """Context manager cleanup."""
283
+ self.stop()
284
+
285
+
286
+ # Convenience function for getting a renderer callback
287
+ def create_stream_renderer(verbose: bool = True) -> tuple:
288
+ """
289
+ Create a stream renderer and return (renderer, callback).
290
+
291
+ Usage:
292
+ renderer, on_chunk = create_stream_renderer()
293
+ renderer.start()
294
+ async for item in llm_chat_stream(..., on_stream_chunk=on_chunk):
295
+ ...
296
+ renderer.stop()
297
+
298
+ Returns:
299
+ Tuple of (LiveStreamRenderer instance, on_chunk callback)
300
+ """
301
+ renderer = LiveStreamRenderer(verbose=verbose)
302
+ return renderer, renderer.on_chunk
@@ -0,0 +1,8 @@
1
+ # -*- coding: utf-8 -*-
2
+ """Utils 模块 - CLI 工具"""
3
+
4
+ from dolphin.cli.utils.version import getVersion
5
+
6
+ __all__ = [
7
+ "getVersion",
8
+ ]
@@ -0,0 +1,135 @@
1
+ """
2
+ Utility functions for Dolphin CLI
3
+
4
+ This module contains helper functions used by the CLI.
5
+ """
6
+
7
+ import json
8
+ import sys
9
+ from typing import Any, Dict, List
10
+
11
+ from dolphin.core.common.constants import (
12
+ DOLPHIN_VARIABLES_OUTPUT_START,
13
+ DOLPHIN_VARIABLES_OUTPUT_END,
14
+ )
15
+ from dolphin.core.logging.logger import console
16
+
17
+ from dolphin.cli.args.parser import Args
18
+
19
+
20
+ def readFile(filePath: str) -> str:
21
+ """Read content from file
22
+
23
+ Args:
24
+ filePath: Path to the file
25
+
26
+ Returns:
27
+ File content as string
28
+ """
29
+ try:
30
+ with open(filePath, "r", encoding="utf-8") as file:
31
+ return file.read()
32
+ except FileNotFoundError:
33
+ console(f"Error: File not found: {filePath}")
34
+ sys.exit(1)
35
+ except Exception as e:
36
+ console(f"Error reading file {filePath}: {e}")
37
+ sys.exit(1)
38
+
39
+
40
+ def buildVariables(args: Args) -> Dict[str, Any]:
41
+ """Build variables dictionary from arguments
42
+
43
+ Args:
44
+ args: Parsed CLI arguments
45
+
46
+ Returns:
47
+ Dictionary of variables to pass to the agent
48
+ """
49
+ variables = {}
50
+
51
+ if args.query is not None:
52
+ variables["query"] = args.query
53
+
54
+ if args.userId is not None:
55
+ variables["user_id"] = args.userId
56
+
57
+ if args.runArgs:
58
+ variables.update(args.runArgs)
59
+
60
+ return variables
61
+
62
+
63
+ def outputVariablesToJson(context, variableNames: List[str]) -> None:
64
+ """Output specified variables in JSON format
65
+
66
+ Args:
67
+ context: Dolphin context object
68
+ variableNames: List of variable names to output (empty = all)
69
+ """
70
+ if not variableNames:
71
+ allVariables = context.get_all_variables_values()
72
+ else:
73
+ allVariables = {}
74
+ for varName in variableNames:
75
+ try:
76
+ varValue = context.get_var_path_value(varName)
77
+ if varValue is not None:
78
+ allVariables[varName] = varValue
79
+ except Exception:
80
+ allVariables[varName] = None
81
+
82
+ if "_all_stages" not in allVariables:
83
+ allVariables["_all_stages"] = context.get_runtime_graph().get_all_stages()
84
+
85
+ variablesJson = json.dumps(
86
+ allVariables, ensure_ascii=False, default=str, indent=2
87
+ )
88
+ console(f"\n{DOLPHIN_VARIABLES_OUTPUT_START}")
89
+ console(variablesJson)
90
+ console(f"{DOLPHIN_VARIABLES_OUTPUT_END}\n")
91
+
92
+
93
+ def validateArgs(args: Args) -> None:
94
+ """Validate CLI arguments before execution
95
+
96
+ Args:
97
+ args: Parsed CLI arguments
98
+
99
+ Raises:
100
+ SystemExit: If validation fails
101
+ """
102
+ import os
103
+
104
+ if args.folder and not os.path.exists(args.folder):
105
+ console(f"Error: Folder not found: {args.folder}")
106
+ sys.exit(1)
107
+
108
+ if args.skillFolder and not os.path.exists(args.skillFolder):
109
+ console(f"Error: Skill folder not found: {args.skillFolder}")
110
+ sys.exit(1)
111
+
112
+
113
+ def setupFlagsFromArgs(args: Args) -> None:
114
+ """Set feature flags from CLI arguments
115
+
116
+ Args:
117
+ args: Parsed CLI arguments
118
+ """
119
+ from dolphin.core import flags
120
+
121
+ if not args.flagsOverrides:
122
+ return
123
+
124
+ for flagName, flagValue in args.flagsOverrides.items():
125
+ # Convert string "true"/"false" to boolean, handle boolean directly
126
+ if isinstance(flagValue, str):
127
+ boolValue = flagValue.lower() in ('true', '1', 'yes', 'on', 'True')
128
+ else:
129
+ boolValue = bool(flagValue)
130
+
131
+ flags.set_flag(flagName, boolValue)
132
+ # Cleaner flag output
133
+ state = "Enabled" if boolValue else "Disabled"
134
+ console(f"[Flag] {flagName}: {state}")
135
+
@@ -0,0 +1,49 @@
1
+ """
2
+ Version management for Dolphin CLI
3
+
4
+ Reads version from VERSION file to avoid hardcoding.
5
+ """
6
+
7
+ import os
8
+ from functools import lru_cache
9
+
10
+
11
+ @lru_cache(maxsize=1)
12
+ def getVersion() -> str:
13
+ """
14
+ Get version from VERSION file.
15
+
16
+ Returns:
17
+ Version string (e.g., "0.3.3")
18
+ """
19
+ # Try multiple paths to find VERSION file
20
+ possiblePaths = [
21
+ # When running from project root
22
+ os.path.join(os.getcwd(), "VERSION"),
23
+ # When running from bin/
24
+ os.path.join(os.path.dirname(__file__), "..", "..", "..", "..", "VERSION"),
25
+ # Fallback: relative to this file
26
+ os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", "..", "VERSION"),
27
+ ]
28
+
29
+ for versionPath in possiblePaths:
30
+ normalizedPath = os.path.normpath(versionPath)
31
+ if os.path.exists(normalizedPath):
32
+ try:
33
+ with open(normalizedPath, "r", encoding="utf-8") as f:
34
+ return f.read().strip()
35
+ except Exception:
36
+ continue
37
+
38
+ return "unknown"
39
+
40
+
41
+ def getFullVersion() -> str:
42
+ """
43
+ Get full version string for display.
44
+
45
+ Returns:
46
+ Full version string (e.g., "Dolphin Language v0.3.3")
47
+ """
48
+ return f"Dolphin Language v{getVersion()}"
49
+
@@ -0,0 +1,107 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Dolphin Core - 核心运行时引擎(内核态)
4
+
5
+ 职责:
6
+ - 执行引擎(Executor)
7
+ - 上下文管理(Context)
8
+ - 上下文工程(Context Engineer)
9
+ - 消息压缩(Message Compressor)
10
+ - 变量池(Variable Pool)
11
+ - 语法解析器(Parser)
12
+ - 协程调度(Coroutine)
13
+ - 代码块执行(Code Block)
14
+ - LLM 调用抽象层
15
+ - Skill 核心(Skillkit、skill_function、skill_matcher)
16
+ - 轨迹记录(Trajectory)
17
+ - Agent 核心定义(BaseAgent、AgentState)
18
+ - Runtime 核心(RuntimeInstance、RuntimeGraph)
19
+
20
+ 依赖规则:
21
+ - dolphin.core 无内部依赖(仅依赖第三方库)
22
+ """
23
+
24
+ # Context
25
+ from dolphin.core.context.context import Context
26
+ from dolphin.core.context_engineer.core.context_manager import ContextManager
27
+ from dolphin.core.context.variable_pool import VariablePool
28
+
29
+ # Executor
30
+ from dolphin.core.executor.executor import Executor
31
+ # DolphinExecutor is available via lazy import from dolphin.core.executor
32
+ from dolphin.core.executor.debug_controller import DebugController
33
+
34
+ # Runtime
35
+ from dolphin.core.runtime.runtime_instance import RuntimeInstance
36
+ from dolphin.core.runtime.runtime_graph import RuntimeGraph
37
+
38
+ # Agent
39
+ from dolphin.core.agent.base_agent import BaseAgent
40
+ from dolphin.core.agent.agent_state import AgentState
41
+
42
+ # Skill
43
+ from dolphin.core.skill.skillkit import Skillkit
44
+ from dolphin.core.skill.skillset import Skillset
45
+ from dolphin.core.skill.skill_function import SkillFunction
46
+ from dolphin.core.skill.skill_matcher import SkillMatcher
47
+
48
+ # LLM
49
+ from dolphin.core.llm.llm import LLM
50
+ from dolphin.core.llm.llm_client import LLMClient
51
+ from dolphin.core.llm.llm_call import LLMCall
52
+
53
+ # Config
54
+ from dolphin.core.config.global_config import GlobalConfig
55
+
56
+ # Common
57
+ from dolphin.core.common.enums import MessageRole, SkillType
58
+ from dolphin.core.common.exceptions import DolphinException
59
+
60
+ # Logging
61
+ from dolphin.core.logging.logger import get_logger
62
+
63
+ # Trajectory
64
+ from dolphin.core.trajectory.trajectory import Trajectory
65
+ from dolphin.core.trajectory.recorder import Recorder
66
+
67
+ # Interfaces
68
+ from dolphin.core.interfaces import IMemoryManager
69
+
70
+ __all__ = [
71
+ # Context
72
+ "Context",
73
+ "ContextManager",
74
+ "VariablePool",
75
+ # Executor
76
+ "Executor",
77
+ # DolphinExecutor is available via lazy import
78
+ "DebugController",
79
+ # Runtime
80
+ "RuntimeInstance",
81
+ "RuntimeGraph",
82
+ # Agent
83
+ "BaseAgent",
84
+ "AgentState",
85
+ # Skill
86
+ "Skillkit",
87
+ "Skillset",
88
+ "SkillFunction",
89
+ "SkillMatcher",
90
+ # LLM
91
+ "LLM",
92
+ "LLMClient",
93
+ "LLMCall",
94
+ # Config
95
+ "GlobalConfig",
96
+ # Common
97
+ "MessageRole",
98
+ "SkillType",
99
+ "DolphinException",
100
+ # Logging
101
+ "get_logger",
102
+ # Trajectory
103
+ "Trajectory",
104
+ "Recorder",
105
+ # Interfaces
106
+ "IMemoryManager",
107
+ ]
@@ -0,0 +1,10 @@
1
+ # -*- coding: utf-8 -*-
2
+ """Agent 模块 - Agent 核心定义"""
3
+
4
+ from dolphin.core.agent.base_agent import BaseAgent
5
+ from dolphin.core.agent.agent_state import AgentState
6
+
7
+ __all__ = [
8
+ "BaseAgent",
9
+ "AgentState",
10
+ ]
@@ -0,0 +1,69 @@
1
+ """Agent state enumeration definition"""
2
+
3
+ from datetime import datetime
4
+ from enum import Enum
5
+ from typing import Any
6
+
7
+
8
+ class AgentState(Enum):
9
+ """Agent State Enumeration"""
10
+
11
+ CREATED = "created" # Created, not initialized
12
+ INITIALIZED = "initialized" # Initialized
13
+ RUNNING = "running" # Running
14
+ PAUSED = "paused" # Paused
15
+ COMPLETED = "completed" # Completed
16
+ TERMINATED = "terminated" # Terminated
17
+ ERROR = "error" # Error State
18
+
19
+
20
+ class PauseType(Enum):
21
+ """Type of pause that caused agent to enter PAUSED state.
22
+
23
+ Values:
24
+ MANUAL: User explicitly called pause()
25
+ TOOL_INTERRUPT: Tool requested user input (ToolInterrupt)
26
+ USER_INTERRUPT: User actively interrupted execution (UserInterrupt)
27
+ """
28
+ MANUAL = "manual"
29
+ TOOL_INTERRUPT = "tool_interrupt"
30
+ USER_INTERRUPT = "user_interrupt"
31
+
32
+
33
+ class AgentEvent(Enum):
34
+ """Agent Event Enumeration"""
35
+
36
+ INIT = "init" # Initialize event
37
+ START = "start" # Start executing event
38
+ PAUSE = "pause" # Pause Event
39
+ RESUME = "resume" # Recover event
40
+ TERMINATE = "terminate" # Termination Event
41
+ COMPLETE = "complete" # Completion Event
42
+ ERROR = "error" # Error Event
43
+
44
+
45
+ class AgentStatus:
46
+ """Agent State Information Container"""
47
+
48
+ def __init__(
49
+ self,
50
+ state: AgentState = AgentState.CREATED,
51
+ message: str = "",
52
+ data: Any = None,
53
+ ):
54
+ self.state = state
55
+ self.message = message
56
+ self.data = data
57
+ self.timestamp: datetime = datetime.now()
58
+
59
+ def to_dict(self) -> dict:
60
+ """Convert to dictionary format"""
61
+ return {
62
+ "state": self.state.value,
63
+ "message": self.message,
64
+ "data": self.data,
65
+ "timestamp": self.timestamp.isoformat() if self.timestamp else None,
66
+ }
67
+
68
+ def __str__(self) -> str:
69
+ return f"AgentStatus(state={self.state.value}, message='{self.message}')"