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.
- DolphinLanguageSDK/__init__.py +58 -0
- dolphin/__init__.py +62 -0
- dolphin/cli/__init__.py +20 -0
- dolphin/cli/args/__init__.py +9 -0
- dolphin/cli/args/parser.py +567 -0
- dolphin/cli/builtin_agents/__init__.py +22 -0
- dolphin/cli/commands/__init__.py +4 -0
- dolphin/cli/interrupt/__init__.py +8 -0
- dolphin/cli/interrupt/handler.py +205 -0
- dolphin/cli/interrupt/keyboard.py +82 -0
- dolphin/cli/main.py +49 -0
- dolphin/cli/multimodal/__init__.py +34 -0
- dolphin/cli/multimodal/clipboard.py +327 -0
- dolphin/cli/multimodal/handler.py +249 -0
- dolphin/cli/multimodal/image_processor.py +214 -0
- dolphin/cli/multimodal/input_parser.py +149 -0
- dolphin/cli/runner/__init__.py +8 -0
- dolphin/cli/runner/runner.py +989 -0
- dolphin/cli/ui/__init__.py +10 -0
- dolphin/cli/ui/console.py +2795 -0
- dolphin/cli/ui/input.py +340 -0
- dolphin/cli/ui/layout.py +425 -0
- dolphin/cli/ui/stream_renderer.py +302 -0
- dolphin/cli/utils/__init__.py +8 -0
- dolphin/cli/utils/helpers.py +135 -0
- dolphin/cli/utils/version.py +49 -0
- dolphin/core/__init__.py +107 -0
- dolphin/core/agent/__init__.py +10 -0
- dolphin/core/agent/agent_state.py +69 -0
- dolphin/core/agent/base_agent.py +970 -0
- dolphin/core/code_block/__init__.py +0 -0
- dolphin/core/code_block/agent_init_block.py +0 -0
- dolphin/core/code_block/assign_block.py +98 -0
- dolphin/core/code_block/basic_code_block.py +1865 -0
- dolphin/core/code_block/explore_block.py +1327 -0
- dolphin/core/code_block/explore_block_v2.py +712 -0
- dolphin/core/code_block/explore_strategy.py +672 -0
- dolphin/core/code_block/judge_block.py +220 -0
- dolphin/core/code_block/prompt_block.py +32 -0
- dolphin/core/code_block/skill_call_deduplicator.py +291 -0
- dolphin/core/code_block/tool_block.py +129 -0
- dolphin/core/common/__init__.py +17 -0
- dolphin/core/common/constants.py +176 -0
- dolphin/core/common/enums.py +1173 -0
- dolphin/core/common/exceptions.py +133 -0
- dolphin/core/common/multimodal.py +539 -0
- dolphin/core/common/object_type.py +165 -0
- dolphin/core/common/output_format.py +432 -0
- dolphin/core/common/types.py +36 -0
- dolphin/core/config/__init__.py +16 -0
- dolphin/core/config/global_config.py +1289 -0
- dolphin/core/config/ontology_config.py +133 -0
- dolphin/core/context/__init__.py +12 -0
- dolphin/core/context/context.py +1580 -0
- dolphin/core/context/context_manager.py +161 -0
- dolphin/core/context/var_output.py +82 -0
- dolphin/core/context/variable_pool.py +356 -0
- dolphin/core/context_engineer/__init__.py +41 -0
- dolphin/core/context_engineer/config/__init__.py +5 -0
- dolphin/core/context_engineer/config/settings.py +402 -0
- dolphin/core/context_engineer/core/__init__.py +7 -0
- dolphin/core/context_engineer/core/budget_manager.py +327 -0
- dolphin/core/context_engineer/core/context_assembler.py +583 -0
- dolphin/core/context_engineer/core/context_manager.py +637 -0
- dolphin/core/context_engineer/core/tokenizer_service.py +260 -0
- dolphin/core/context_engineer/example/incremental_example.py +267 -0
- dolphin/core/context_engineer/example/traditional_example.py +334 -0
- dolphin/core/context_engineer/services/__init__.py +5 -0
- dolphin/core/context_engineer/services/compressor.py +399 -0
- dolphin/core/context_engineer/utils/__init__.py +6 -0
- dolphin/core/context_engineer/utils/context_utils.py +441 -0
- dolphin/core/context_engineer/utils/message_formatter.py +270 -0
- dolphin/core/context_engineer/utils/token_utils.py +139 -0
- dolphin/core/coroutine/__init__.py +15 -0
- dolphin/core/coroutine/context_snapshot.py +154 -0
- dolphin/core/coroutine/context_snapshot_profile.py +922 -0
- dolphin/core/coroutine/context_snapshot_store.py +268 -0
- dolphin/core/coroutine/execution_frame.py +145 -0
- dolphin/core/coroutine/execution_state_registry.py +161 -0
- dolphin/core/coroutine/resume_handle.py +101 -0
- dolphin/core/coroutine/step_result.py +101 -0
- dolphin/core/executor/__init__.py +18 -0
- dolphin/core/executor/debug_controller.py +630 -0
- dolphin/core/executor/dolphin_executor.py +1063 -0
- dolphin/core/executor/executor.py +624 -0
- dolphin/core/flags/__init__.py +27 -0
- dolphin/core/flags/definitions.py +49 -0
- dolphin/core/flags/manager.py +113 -0
- dolphin/core/hook/__init__.py +95 -0
- dolphin/core/hook/expression_evaluator.py +499 -0
- dolphin/core/hook/hook_dispatcher.py +380 -0
- dolphin/core/hook/hook_types.py +248 -0
- dolphin/core/hook/isolated_variable_pool.py +284 -0
- dolphin/core/interfaces.py +53 -0
- dolphin/core/llm/__init__.py +0 -0
- dolphin/core/llm/llm.py +495 -0
- dolphin/core/llm/llm_call.py +100 -0
- dolphin/core/llm/llm_client.py +1285 -0
- dolphin/core/llm/message_sanitizer.py +120 -0
- dolphin/core/logging/__init__.py +20 -0
- dolphin/core/logging/logger.py +526 -0
- dolphin/core/message/__init__.py +8 -0
- dolphin/core/message/compressor.py +749 -0
- dolphin/core/parser/__init__.py +8 -0
- dolphin/core/parser/parser.py +405 -0
- dolphin/core/runtime/__init__.py +10 -0
- dolphin/core/runtime/runtime_graph.py +926 -0
- dolphin/core/runtime/runtime_instance.py +446 -0
- dolphin/core/skill/__init__.py +14 -0
- dolphin/core/skill/context_retention.py +157 -0
- dolphin/core/skill/skill_function.py +686 -0
- dolphin/core/skill/skill_matcher.py +282 -0
- dolphin/core/skill/skillkit.py +700 -0
- dolphin/core/skill/skillset.py +72 -0
- dolphin/core/trajectory/__init__.py +10 -0
- dolphin/core/trajectory/recorder.py +189 -0
- dolphin/core/trajectory/trajectory.py +522 -0
- dolphin/core/utils/__init__.py +9 -0
- dolphin/core/utils/cache_kv.py +212 -0
- dolphin/core/utils/tools.py +340 -0
- dolphin/lib/__init__.py +93 -0
- dolphin/lib/debug/__init__.py +8 -0
- dolphin/lib/debug/visualizer.py +409 -0
- dolphin/lib/memory/__init__.py +28 -0
- dolphin/lib/memory/async_processor.py +220 -0
- dolphin/lib/memory/llm_calls.py +195 -0
- dolphin/lib/memory/manager.py +78 -0
- dolphin/lib/memory/sandbox.py +46 -0
- dolphin/lib/memory/storage.py +245 -0
- dolphin/lib/memory/utils.py +51 -0
- dolphin/lib/ontology/__init__.py +12 -0
- dolphin/lib/ontology/basic/__init__.py +0 -0
- dolphin/lib/ontology/basic/base.py +102 -0
- dolphin/lib/ontology/basic/concept.py +130 -0
- dolphin/lib/ontology/basic/object.py +11 -0
- dolphin/lib/ontology/basic/relation.py +63 -0
- dolphin/lib/ontology/datasource/__init__.py +27 -0
- dolphin/lib/ontology/datasource/datasource.py +66 -0
- dolphin/lib/ontology/datasource/oracle_datasource.py +338 -0
- dolphin/lib/ontology/datasource/sql.py +845 -0
- dolphin/lib/ontology/mapping.py +177 -0
- dolphin/lib/ontology/ontology.py +733 -0
- dolphin/lib/ontology/ontology_context.py +16 -0
- dolphin/lib/ontology/ontology_manager.py +107 -0
- dolphin/lib/skill_results/__init__.py +31 -0
- dolphin/lib/skill_results/cache_backend.py +559 -0
- dolphin/lib/skill_results/result_processor.py +181 -0
- dolphin/lib/skill_results/result_reference.py +179 -0
- dolphin/lib/skill_results/skillkit_hook.py +324 -0
- dolphin/lib/skill_results/strategies.py +328 -0
- dolphin/lib/skill_results/strategy_registry.py +150 -0
- dolphin/lib/skillkits/__init__.py +44 -0
- dolphin/lib/skillkits/agent_skillkit.py +155 -0
- dolphin/lib/skillkits/cognitive_skillkit.py +82 -0
- dolphin/lib/skillkits/env_skillkit.py +250 -0
- dolphin/lib/skillkits/mcp_adapter.py +616 -0
- dolphin/lib/skillkits/mcp_skillkit.py +771 -0
- dolphin/lib/skillkits/memory_skillkit.py +650 -0
- dolphin/lib/skillkits/noop_skillkit.py +31 -0
- dolphin/lib/skillkits/ontology_skillkit.py +89 -0
- dolphin/lib/skillkits/plan_act_skillkit.py +452 -0
- dolphin/lib/skillkits/resource/__init__.py +52 -0
- dolphin/lib/skillkits/resource/models/__init__.py +6 -0
- dolphin/lib/skillkits/resource/models/skill_config.py +109 -0
- dolphin/lib/skillkits/resource/models/skill_meta.py +127 -0
- dolphin/lib/skillkits/resource/resource_skillkit.py +393 -0
- dolphin/lib/skillkits/resource/skill_cache.py +215 -0
- dolphin/lib/skillkits/resource/skill_loader.py +395 -0
- dolphin/lib/skillkits/resource/skill_validator.py +406 -0
- dolphin/lib/skillkits/resource_skillkit.py +11 -0
- dolphin/lib/skillkits/search_skillkit.py +163 -0
- dolphin/lib/skillkits/sql_skillkit.py +274 -0
- dolphin/lib/skillkits/system_skillkit.py +509 -0
- dolphin/lib/skillkits/vm_skillkit.py +65 -0
- dolphin/lib/utils/__init__.py +9 -0
- dolphin/lib/utils/data_process.py +207 -0
- dolphin/lib/utils/handle_progress.py +178 -0
- dolphin/lib/utils/security.py +139 -0
- dolphin/lib/utils/text_retrieval.py +462 -0
- dolphin/lib/vm/__init__.py +11 -0
- dolphin/lib/vm/env_executor.py +895 -0
- dolphin/lib/vm/python_session_manager.py +453 -0
- dolphin/lib/vm/vm.py +610 -0
- dolphin/sdk/__init__.py +60 -0
- dolphin/sdk/agent/__init__.py +12 -0
- dolphin/sdk/agent/agent_factory.py +236 -0
- dolphin/sdk/agent/dolphin_agent.py +1106 -0
- dolphin/sdk/api/__init__.py +4 -0
- dolphin/sdk/runtime/__init__.py +8 -0
- dolphin/sdk/runtime/env.py +363 -0
- dolphin/sdk/skill/__init__.py +10 -0
- dolphin/sdk/skill/global_skills.py +706 -0
- dolphin/sdk/skill/traditional_toolkit.py +260 -0
- kweaver_dolphin-0.1.0.dist-info/METADATA +521 -0
- kweaver_dolphin-0.1.0.dist-info/RECORD +199 -0
- kweaver_dolphin-0.1.0.dist-info/WHEEL +5 -0
- kweaver_dolphin-0.1.0.dist-info/entry_points.txt +27 -0
- kweaver_dolphin-0.1.0.dist-info/licenses/LICENSE.txt +201 -0
- kweaver_dolphin-0.1.0.dist-info/top_level.txt +2 -0
dolphin/cli/ui/input.py
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Input utilities with auto-completion and interrupt support.
|
|
3
|
+
|
|
4
|
+
Provides enhanced input prompts with:
|
|
5
|
+
- Tab/arrow-key completion for debug commands
|
|
6
|
+
- ESC key interrupt handling for agent execution
|
|
7
|
+
- Slash command shortcuts for conversation mode
|
|
8
|
+
- Multimodal input processing (@paste, @image:, @url: markers)
|
|
9
|
+
|
|
10
|
+
Type Annotations:
|
|
11
|
+
All public functions use proper type hints with forward references
|
|
12
|
+
for InterruptToken (via TYPE_CHECKING) to avoid circular imports.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from typing import List, Optional, TYPE_CHECKING, Union, Dict, Any
|
|
16
|
+
from prompt_toolkit.shortcuts import PromptSession
|
|
17
|
+
from prompt_toolkit.completion import Completer, Completion
|
|
18
|
+
from prompt_toolkit.history import InMemoryHistory
|
|
19
|
+
from prompt_toolkit.key_binding import KeyBindings
|
|
20
|
+
from prompt_toolkit.keys import Keys
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from dolphin.cli.interrupt.handler import InterruptToken
|
|
24
|
+
|
|
25
|
+
# Type aliases for better clarity
|
|
26
|
+
MultimodalContentBlock = Dict[str, Any]
|
|
27
|
+
MultimodalInput = Union[str, List[MultimodalContentBlock]]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# Debug command definitions for auto-completion
|
|
31
|
+
DEBUG_COMMANDS = [
|
|
32
|
+
# Execution control
|
|
33
|
+
("step", "单步执行下一个 block"),
|
|
34
|
+
("next", "单步执行下一个 block (同 step)"),
|
|
35
|
+
("continue", "继续执行到下一个断点"),
|
|
36
|
+
("run", "运行到结束(忽略所有断点)"),
|
|
37
|
+
("until", "运行到指定 block: until <n>"),
|
|
38
|
+
("quit", "退出调试模式"),
|
|
39
|
+
# Breakpoint management
|
|
40
|
+
("break", "设置断点: break <n>"),
|
|
41
|
+
("delete", "删除断点: delete <n>"),
|
|
42
|
+
("list", "显示所有断点"),
|
|
43
|
+
# Variable inspection
|
|
44
|
+
("vars", "显示所有变量"),
|
|
45
|
+
("var", "显示特定变量: var <name>"),
|
|
46
|
+
("progress", "显示执行进度信息"),
|
|
47
|
+
("trace", "显示执行轨迹 - trace [brief/full] 默认简略"),
|
|
48
|
+
("trace full", "显示执行轨迹 (完整模式 - 不折叠只读消息)"),
|
|
49
|
+
# Snapshot
|
|
50
|
+
("snapshot", "显示快照分析"),
|
|
51
|
+
# Help
|
|
52
|
+
("help", "显示帮助信息"),
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
# Slash command shortcuts (for conversation mode)
|
|
56
|
+
# These are quick inspection commands - user types / and gets completions
|
|
57
|
+
# /debug enters interactive debug REPL, others execute once and return to conversation
|
|
58
|
+
SLASH_COMMANDS = [
|
|
59
|
+
("/debug", "进入实时调试交互模式 (REPL)"),
|
|
60
|
+
("/trace", "查看执行轨迹 默认简略"),
|
|
61
|
+
("/trace full", "查看执行轨迹 (完整模式 - 不折叠只读消息)"),
|
|
62
|
+
("/snapshot", "查看快照分析"),
|
|
63
|
+
("/vars", "查看所有变量"),
|
|
64
|
+
("/var", "查看特定变量: /var <name>"),
|
|
65
|
+
("/progress", "查看执行进度"),
|
|
66
|
+
("/help", "查看调试命令帮助"),
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class DebugCommandCompleter(Completer):
|
|
71
|
+
"""Completer for debug commands.
|
|
72
|
+
|
|
73
|
+
Supports both direct input (e.g., 'vars') and slash-prefixed input (e.g., '/vars').
|
|
74
|
+
When user types '/', completions are shown but the actual command is without slash.
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
def __init__(self, commands: List[tuple]):
|
|
78
|
+
"""
|
|
79
|
+
Args:
|
|
80
|
+
commands: List of (command, description) tuples
|
|
81
|
+
"""
|
|
82
|
+
self.commands = commands
|
|
83
|
+
|
|
84
|
+
def get_completions(self, document, complete_event):
|
|
85
|
+
text = document.text_before_cursor.lower()
|
|
86
|
+
|
|
87
|
+
# Handle slash prefix: "/va" -> complete to "vars" (strip the slash)
|
|
88
|
+
has_slash = text.startswith("/")
|
|
89
|
+
search_text = text[1:] if has_slash else text
|
|
90
|
+
|
|
91
|
+
for cmd, desc in self.commands:
|
|
92
|
+
cmd_lower = cmd.lower()
|
|
93
|
+
|
|
94
|
+
if cmd_lower.startswith(search_text):
|
|
95
|
+
# Always complete to command without slash (debug mode uses bare commands)
|
|
96
|
+
yield Completion(
|
|
97
|
+
cmd_lower,
|
|
98
|
+
start_position=-len(document.text_before_cursor),
|
|
99
|
+
display_meta=desc,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class ConversationCompleter(Completer):
|
|
104
|
+
"""Completer that only activates for slash commands in conversation mode."""
|
|
105
|
+
|
|
106
|
+
def __init__(self):
|
|
107
|
+
self.slash_commands = SLASH_COMMANDS
|
|
108
|
+
|
|
109
|
+
def get_completions(self, document, complete_event):
|
|
110
|
+
text = document.text_before_cursor
|
|
111
|
+
|
|
112
|
+
# Only show completions when text starts with "/"
|
|
113
|
+
if not text.startswith("/"):
|
|
114
|
+
return
|
|
115
|
+
|
|
116
|
+
text_lower = text.lower()
|
|
117
|
+
for cmd, desc in self.slash_commands:
|
|
118
|
+
if cmd.startswith(text_lower):
|
|
119
|
+
yield Completion(
|
|
120
|
+
cmd,
|
|
121
|
+
start_position=-len(text),
|
|
122
|
+
display_meta=desc,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# Shared PromptSession instances
|
|
127
|
+
_debug_session = PromptSession(history=InMemoryHistory())
|
|
128
|
+
_conversation_session = PromptSession(history=InMemoryHistory())
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
async def prompt_debug_command(prompt_text: str = "Debug > ", allow_execution_control: bool = True) -> str:
|
|
132
|
+
"""
|
|
133
|
+
Prompt for debug command with auto-completion (async version).
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
prompt_text: The prompt string to display
|
|
137
|
+
allow_execution_control: If False, exclude execution control commands from completion
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
User input string
|
|
141
|
+
"""
|
|
142
|
+
commands = DEBUG_COMMANDS
|
|
143
|
+
if not allow_execution_control:
|
|
144
|
+
# Filter out execution control commands for live debug / post-mortem
|
|
145
|
+
execution_cmds = {"step", "next", "continue", "run", "until"}
|
|
146
|
+
commands = [(cmd, desc) for cmd, desc in commands if cmd not in execution_cmds]
|
|
147
|
+
|
|
148
|
+
completer = DebugCommandCompleter(commands)
|
|
149
|
+
|
|
150
|
+
try:
|
|
151
|
+
return (await _debug_session.prompt_async(
|
|
152
|
+
prompt_text,
|
|
153
|
+
completer=completer,
|
|
154
|
+
complete_while_typing=True,
|
|
155
|
+
)).strip()
|
|
156
|
+
except (EOFError, KeyboardInterrupt):
|
|
157
|
+
raise
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
async def prompt_conversation(prompt_text: str = "\n> ") -> str:
|
|
161
|
+
"""
|
|
162
|
+
Prompt for user input in conversation mode with slash-command completion (async version).
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
prompt_text: The prompt string to display
|
|
166
|
+
|
|
167
|
+
Returns:
|
|
168
|
+
User input string
|
|
169
|
+
"""
|
|
170
|
+
completer = ConversationCompleter()
|
|
171
|
+
|
|
172
|
+
try:
|
|
173
|
+
return (await _conversation_session.prompt_async(
|
|
174
|
+
prompt_text,
|
|
175
|
+
completer=completer,
|
|
176
|
+
complete_while_typing=True,
|
|
177
|
+
)).strip()
|
|
178
|
+
except (EOFError, KeyboardInterrupt):
|
|
179
|
+
raise
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class EscapeInterrupt(Exception):
|
|
183
|
+
"""Exception raised when ESC key is pressed during prompt."""
|
|
184
|
+
pass
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def create_interrupt_key_bindings(
|
|
188
|
+
interrupt_token: Optional["InterruptToken"] = None
|
|
189
|
+
) -> KeyBindings:
|
|
190
|
+
"""Create key bindings that handle ESC for interrupt.
|
|
191
|
+
|
|
192
|
+
Args:
|
|
193
|
+
interrupt_token: Optional InterruptToken to trigger on ESC
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
KeyBindings with ESC handler
|
|
197
|
+
"""
|
|
198
|
+
kb = KeyBindings()
|
|
199
|
+
|
|
200
|
+
@kb.add(Keys.Escape)
|
|
201
|
+
def handle_escape(event):
|
|
202
|
+
"""Handle ESC key press to trigger interrupt."""
|
|
203
|
+
if interrupt_token:
|
|
204
|
+
interrupt_token.trigger_interrupt()
|
|
205
|
+
# Use app.exit with exception - the proper way to exit prompt_toolkit
|
|
206
|
+
event.app.exit(exception=EscapeInterrupt())
|
|
207
|
+
|
|
208
|
+
return kb
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
# Session for interrupt-aware prompts
|
|
212
|
+
_interrupt_session: Optional[PromptSession] = None
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def _get_interrupt_session() -> PromptSession:
|
|
216
|
+
"""Get or create the interrupt-aware prompt session."""
|
|
217
|
+
global _interrupt_session
|
|
218
|
+
if _interrupt_session is None:
|
|
219
|
+
_interrupt_session = PromptSession(history=InMemoryHistory())
|
|
220
|
+
return _interrupt_session
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
async def prompt_with_interrupt(
|
|
224
|
+
prompt_text: str = "> ",
|
|
225
|
+
interrupt_token: Optional["InterruptToken"] = None,
|
|
226
|
+
completer: Optional[Completer] = None,
|
|
227
|
+
default_text: str = ""
|
|
228
|
+
) -> str:
|
|
229
|
+
"""
|
|
230
|
+
Prompt for user input with ESC key interrupt support.
|
|
231
|
+
|
|
232
|
+
When ESC is pressed, the interrupt_token is triggered and EscapeInterrupt
|
|
233
|
+
is raised. The caller should catch this and handle the interrupt appropriately.
|
|
234
|
+
|
|
235
|
+
Args:
|
|
236
|
+
prompt_text: The prompt string to display
|
|
237
|
+
interrupt_token: InterruptToken to trigger on ESC press
|
|
238
|
+
completer: Optional completer for auto-completion
|
|
239
|
+
default_text: Initial text to pre-fill the input buffer
|
|
240
|
+
|
|
241
|
+
Returns:
|
|
242
|
+
User input string
|
|
243
|
+
|
|
244
|
+
Raises:
|
|
245
|
+
EscapeInterrupt: When ESC key is pressed
|
|
246
|
+
EOFError: When Ctrl+D is pressed
|
|
247
|
+
KeyboardInterrupt: When Ctrl+C is pressed
|
|
248
|
+
"""
|
|
249
|
+
session = _get_interrupt_session()
|
|
250
|
+
key_bindings = create_interrupt_key_bindings(interrupt_token)
|
|
251
|
+
|
|
252
|
+
# Use ConversationCompleter if no completer provided
|
|
253
|
+
if completer is None:
|
|
254
|
+
completer = ConversationCompleter()
|
|
255
|
+
|
|
256
|
+
try:
|
|
257
|
+
return (await session.prompt_async(
|
|
258
|
+
prompt_text,
|
|
259
|
+
key_bindings=key_bindings,
|
|
260
|
+
completer=completer,
|
|
261
|
+
complete_while_typing=True,
|
|
262
|
+
default=default_text,
|
|
263
|
+
)).strip()
|
|
264
|
+
except EscapeInterrupt:
|
|
265
|
+
raise
|
|
266
|
+
except (EOFError, KeyboardInterrupt):
|
|
267
|
+
raise
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
async def prompt_interrupt_input(prompt_text: str = "💬 New instructions (Enter to continue): ") -> str:
|
|
271
|
+
"""
|
|
272
|
+
Prompt for user input after an interrupt.
|
|
273
|
+
|
|
274
|
+
This is a simplified prompt without ESC handling, used after execution
|
|
275
|
+
has been interrupted to get the user's new instructions.
|
|
276
|
+
|
|
277
|
+
Args:
|
|
278
|
+
prompt_text: The prompt string to display
|
|
279
|
+
|
|
280
|
+
Returns:
|
|
281
|
+
User input string (may be empty if user just pressed Enter)
|
|
282
|
+
"""
|
|
283
|
+
session = PromptSession()
|
|
284
|
+
|
|
285
|
+
try:
|
|
286
|
+
return (await session.prompt_async(prompt_text)).strip()
|
|
287
|
+
except (EOFError, KeyboardInterrupt):
|
|
288
|
+
return ""
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
async def prompt_conversation_with_multimodal(
|
|
292
|
+
prompt_text: str = "> ",
|
|
293
|
+
interrupt_token: Optional["InterruptToken"] = None,
|
|
294
|
+
verbose: bool = False
|
|
295
|
+
) -> MultimodalInput:
|
|
296
|
+
"""
|
|
297
|
+
Prompt for user input with ESC interrupt support and multimodal marker processing.
|
|
298
|
+
|
|
299
|
+
Supports the following multimodal markers:
|
|
300
|
+
- @paste: Read image from clipboard
|
|
301
|
+
- @image:<path>: Read image from file path
|
|
302
|
+
- @url:<url>: Reference image by URL
|
|
303
|
+
|
|
304
|
+
Args:
|
|
305
|
+
prompt_text: The prompt string to display
|
|
306
|
+
interrupt_token: InterruptToken to trigger on ESC press
|
|
307
|
+
verbose: If True, print image processing status messages
|
|
308
|
+
|
|
309
|
+
Returns:
|
|
310
|
+
str: Plain text input if no multimodal markers
|
|
311
|
+
List[MultimodalContentBlock]: Multimodal content blocks if markers are present
|
|
312
|
+
|
|
313
|
+
Raises:
|
|
314
|
+
EscapeInterrupt: When ESC key is pressed
|
|
315
|
+
EOFError: When Ctrl+D is pressed
|
|
316
|
+
KeyboardInterrupt: When Ctrl+C is pressed
|
|
317
|
+
"""
|
|
318
|
+
from dolphin.cli.multimodal import process_multimodal_input
|
|
319
|
+
|
|
320
|
+
# Get raw input using interrupt-aware prompt
|
|
321
|
+
raw_input = await prompt_with_interrupt(
|
|
322
|
+
prompt_text=prompt_text,
|
|
323
|
+
interrupt_token=interrupt_token,
|
|
324
|
+
completer=ConversationCompleter()
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
# Process multimodal markers
|
|
328
|
+
try:
|
|
329
|
+
return process_multimodal_input(raw_input, verbose=verbose)
|
|
330
|
+
except (ValueError, IOError, FileNotFoundError) as e:
|
|
331
|
+
# Expected errors during multimodal processing (invalid path, clipboard error, etc.)
|
|
332
|
+
# Always notify user of multimodal processing failure
|
|
333
|
+
print(f"⚠️ Multimodal processing failed: {e}")
|
|
334
|
+
if verbose:
|
|
335
|
+
import traceback
|
|
336
|
+
traceback.print_exc()
|
|
337
|
+
# Fallback to raw text input
|
|
338
|
+
return raw_input
|
|
339
|
+
|
|
340
|
+
|