deepagents-cli 0.0.3__py3-none-any.whl → 0.0.4__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.
Potentially problematic release.
This version of deepagents-cli might be problematic. Click here for more details.
- deepagents_cli/__init__.py +5 -0
- deepagents_cli/__main__.py +6 -0
- deepagents_cli/agent.py +267 -0
- deepagents_cli/cli.py +13 -0
- deepagents_cli/commands.py +86 -0
- deepagents_cli/config.py +138 -0
- deepagents_cli/execution.py +644 -0
- deepagents_cli/file_ops.py +347 -0
- deepagents_cli/input.py +249 -0
- deepagents_cli/main.py +217 -0
- deepagents_cli/py.typed +0 -0
- deepagents_cli/tools.py +140 -0
- deepagents_cli/ui.py +455 -0
- deepagents_cli-0.0.4.dist-info/METADATA +18 -0
- deepagents_cli-0.0.4.dist-info/RECORD +18 -0
- deepagents_cli-0.0.4.dist-info/entry_points.txt +3 -0
- deepagents_cli-0.0.4.dist-info/top_level.txt +1 -0
- deepagents/__init__.py +0 -7
- deepagents/cli.py +0 -567
- deepagents/default_agent_prompt.md +0 -64
- deepagents/graph.py +0 -144
- deepagents/memory/__init__.py +0 -17
- deepagents/memory/backends/__init__.py +0 -15
- deepagents/memory/backends/composite.py +0 -250
- deepagents/memory/backends/filesystem.py +0 -330
- deepagents/memory/backends/state.py +0 -206
- deepagents/memory/backends/store.py +0 -351
- deepagents/memory/backends/utils.py +0 -319
- deepagents/memory/protocol.py +0 -164
- deepagents/middleware/__init__.py +0 -13
- deepagents/middleware/agent_memory.py +0 -207
- deepagents/middleware/filesystem.py +0 -615
- deepagents/middleware/patch_tool_calls.py +0 -44
- deepagents/middleware/subagents.py +0 -481
- deepagents/pretty_cli.py +0 -289
- deepagents_cli-0.0.3.dist-info/METADATA +0 -551
- deepagents_cli-0.0.3.dist-info/RECORD +0 -24
- deepagents_cli-0.0.3.dist-info/entry_points.txt +0 -2
- deepagents_cli-0.0.3.dist-info/licenses/LICENSE +0 -21
- deepagents_cli-0.0.3.dist-info/top_level.txt +0 -1
- {deepagents_cli-0.0.3.dist-info → deepagents_cli-0.0.4.dist-info}/WHEEL +0 -0
deepagents/pretty_cli.py
DELETED
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Minimalist prompt-toolkit TUI for DeepAgents sandbox chat.
|
|
3
|
-
|
|
4
|
-
Beautiful emerald green theme with streaming responses.
|
|
5
|
-
|
|
6
|
-
Controls:
|
|
7
|
-
- Enter: Submit message
|
|
8
|
-
- Alt-Enter (or Esc then Enter): New line for multiline input
|
|
9
|
-
- Ctrl+C or Ctrl+D: Quit
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
import asyncio
|
|
13
|
-
|
|
14
|
-
from prompt_toolkit import PromptSession
|
|
15
|
-
from prompt_toolkit.key_binding import KeyBindings
|
|
16
|
-
from prompt_toolkit.styles import Style
|
|
17
|
-
from rich.console import Console
|
|
18
|
-
from rich.spinner import Spinner
|
|
19
|
-
|
|
20
|
-
from chat_agent import create_sandbox_chat_agent
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
# ============================================================================
|
|
24
|
-
# CONFIGURATION
|
|
25
|
-
# ============================================================================
|
|
26
|
-
|
|
27
|
-
COLORS = {
|
|
28
|
-
"primary": "#10b981", # Emerald 500
|
|
29
|
-
"dim": "#6b7280", # Gray 500
|
|
30
|
-
"user": "#ffffff", # White
|
|
31
|
-
"agent": "#10b981", # Emerald 500
|
|
32
|
-
"thinking": "#34d399", # Emerald 400
|
|
33
|
-
"tool": "#fbbf24", # Amber 400
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
DEEP_AGENTS_ASCII = """
|
|
37
|
-
██████╗ ███████╗ ███████╗ ██████╗
|
|
38
|
-
██╔══██╗ ██╔════╝ ██╔════╝ ██╔══██╗
|
|
39
|
-
██║ ██║ █████╗ █████╗ ██████╔╝
|
|
40
|
-
██║ ██║ ██╔══╝ ██╔══╝ ██╔═══╝
|
|
41
|
-
██████╔╝ ███████╗ ███████╗ ██║
|
|
42
|
-
╚═════╝ ╚══════╝ ╚══════╝ ╚═╝
|
|
43
|
-
|
|
44
|
-
█████╗ ██████╗ ███████╗ ███╗ ██╗ ████████╗ ███████╗
|
|
45
|
-
██╔══██╗ ██╔════╝ ██╔════╝ ████╗ ██║ ╚══██╔══╝ ██╔════╝
|
|
46
|
-
███████║ ██║ ███╗ █████╗ ██╔██╗ ██║ ██║ ███████╗
|
|
47
|
-
██╔══██║ ██║ ██║ ██╔══╝ ██║╚██╗██║ ██║ ╚════██║
|
|
48
|
-
██║ ██║ ╚██████╔╝ ███████╗ ██║ ╚████║ ██║ ███████║
|
|
49
|
-
╚═╝ ╚═╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═══╝ ╚═╝ ╚══════╝
|
|
50
|
-
"""
|
|
51
|
-
|
|
52
|
-
# ============================================================================
|
|
53
|
-
# GLOBALS
|
|
54
|
-
# ============================================================================
|
|
55
|
-
|
|
56
|
-
console = Console()
|
|
57
|
-
agent = None
|
|
58
|
-
config = {"configurable": {"thread_id": "sandbox-chat"}}
|
|
59
|
-
|
|
60
|
-
# ============================================================================
|
|
61
|
-
# UTILITIES
|
|
62
|
-
# ============================================================================
|
|
63
|
-
|
|
64
|
-
MAX_ARG_LENGTH = 150
|
|
65
|
-
|
|
66
|
-
TOOL_ICONS = {
|
|
67
|
-
"shell": "⚡",
|
|
68
|
-
"write_file": "✏️",
|
|
69
|
-
"read_file": "📖",
|
|
70
|
-
"edit_file": "✂️",
|
|
71
|
-
"ls": "📁",
|
|
72
|
-
"glob": "🔍",
|
|
73
|
-
"grep": "🔎",
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
def truncate(text: str, max_len: int) -> str:
|
|
78
|
-
"""Truncate text with ellipsis."""
|
|
79
|
-
return text[:max_len] + "..." if len(text) > max_len else text
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
# ============================================================================
|
|
83
|
-
# DISPLAY FUNCTIONS
|
|
84
|
-
# ============================================================================
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
def show_welcome():
|
|
88
|
-
"""Display welcome screen and wait for Enter."""
|
|
89
|
-
console.clear()
|
|
90
|
-
console.print(DEEP_AGENTS_ASCII, style=f"bold {COLORS['primary']}")
|
|
91
|
-
console.print("\n")
|
|
92
|
-
console.print("Press Enter to start", style=COLORS["dim"])
|
|
93
|
-
input()
|
|
94
|
-
# Don't clear - keep ASCII art visible!
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
# ============================================================================
|
|
98
|
-
# AGENT INTERACTION
|
|
99
|
-
# ============================================================================
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
async def stream_agent_response(user_input: str):
|
|
103
|
-
"""Stream agent response using async iteration."""
|
|
104
|
-
global agent
|
|
105
|
-
|
|
106
|
-
has_responded = False
|
|
107
|
-
current_text = ""
|
|
108
|
-
|
|
109
|
-
# Start spinner manually so we can stop it when we have content
|
|
110
|
-
status = console.status("[bold #34d399]Agent is thinking...", spinner="dots")
|
|
111
|
-
status.start()
|
|
112
|
-
spinner_active = True
|
|
113
|
-
|
|
114
|
-
async for _, chunk in agent.astream(
|
|
115
|
-
{"messages": [{"role": "user", "content": user_input}]},
|
|
116
|
-
stream_mode="updates",
|
|
117
|
-
subgraphs=True,
|
|
118
|
-
config=config,
|
|
119
|
-
durability="exit",
|
|
120
|
-
):
|
|
121
|
-
chunk_data = list(chunk.values())[0]
|
|
122
|
-
if not chunk_data or "messages" not in chunk_data:
|
|
123
|
-
continue
|
|
124
|
-
|
|
125
|
-
last_message = chunk_data["messages"][-1]
|
|
126
|
-
message_role = getattr(last_message, "type", None)
|
|
127
|
-
message_content = getattr(last_message, "content", None)
|
|
128
|
-
|
|
129
|
-
# Handle tool calls from AI messages (LangChain tool_calls attribute)
|
|
130
|
-
tool_calls = getattr(last_message, "tool_calls", None)
|
|
131
|
-
if tool_calls and message_role == "ai":
|
|
132
|
-
for tool_call in tool_calls:
|
|
133
|
-
tool_name = tool_call.get("name", "unknown")
|
|
134
|
-
tool_args = tool_call.get("args", {})
|
|
135
|
-
|
|
136
|
-
icon = TOOL_ICONS.get(tool_name, "🔧")
|
|
137
|
-
args_str = ", ".join(
|
|
138
|
-
f"{k}={truncate(str(v), 50)}" for k, v in tool_args.items()
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
# Stop spinner temporarily to print tool call
|
|
142
|
-
if spinner_active:
|
|
143
|
-
status.stop()
|
|
144
|
-
console.print(f" {icon} {tool_name}({args_str})", style=f"dim {COLORS['tool']}")
|
|
145
|
-
# Restart spinner for next tool/processing
|
|
146
|
-
if spinner_active:
|
|
147
|
-
status.start()
|
|
148
|
-
|
|
149
|
-
# Skip tool results - they're verbose and the agent will summarize
|
|
150
|
-
if message_role == "tool":
|
|
151
|
-
continue
|
|
152
|
-
|
|
153
|
-
if not message_content:
|
|
154
|
-
continue
|
|
155
|
-
|
|
156
|
-
# Handle tool calls from content blocks (alternative format)
|
|
157
|
-
if message_role == "ai" and isinstance(message_content, list):
|
|
158
|
-
for block in message_content:
|
|
159
|
-
if isinstance(block, dict) and block.get("type") == "tool_use":
|
|
160
|
-
tool_name = block.get("name", "unknown")
|
|
161
|
-
tool_input = block.get("input", {})
|
|
162
|
-
|
|
163
|
-
icon = TOOL_ICONS.get(tool_name, "🔧")
|
|
164
|
-
args = ", ".join(
|
|
165
|
-
f"{k}={truncate(str(v), 50)}" for k, v in tool_input.items()
|
|
166
|
-
)
|
|
167
|
-
|
|
168
|
-
# Stop spinner temporarily to print tool call
|
|
169
|
-
if spinner_active:
|
|
170
|
-
status.stop()
|
|
171
|
-
console.print(f" {icon} {tool_name}({args})", style=f"dim {COLORS['tool']}")
|
|
172
|
-
# Restart spinner for next tool/processing
|
|
173
|
-
if spinner_active:
|
|
174
|
-
status.start()
|
|
175
|
-
|
|
176
|
-
# Handle agent text responses
|
|
177
|
-
if message_role == "ai":
|
|
178
|
-
text_content = ""
|
|
179
|
-
|
|
180
|
-
if isinstance(message_content, str):
|
|
181
|
-
text_content = message_content
|
|
182
|
-
elif isinstance(message_content, list):
|
|
183
|
-
for block in message_content:
|
|
184
|
-
if isinstance(block, dict) and block.get("type") == "text":
|
|
185
|
-
text_content = block.get("text", "")
|
|
186
|
-
break
|
|
187
|
-
|
|
188
|
-
if text_content.strip():
|
|
189
|
-
# Stop spinner when we have actual text to display
|
|
190
|
-
if spinner_active:
|
|
191
|
-
status.stop()
|
|
192
|
-
spinner_active = False
|
|
193
|
-
|
|
194
|
-
# Print prefix on first response
|
|
195
|
-
if not has_responded:
|
|
196
|
-
console.print("... ", style=COLORS["agent"], end="")
|
|
197
|
-
has_responded = True
|
|
198
|
-
|
|
199
|
-
# Stream new content
|
|
200
|
-
if text_content != current_text:
|
|
201
|
-
new_text = text_content[len(current_text) :]
|
|
202
|
-
console.print(new_text, style=COLORS["agent"], end="")
|
|
203
|
-
current_text = text_content
|
|
204
|
-
|
|
205
|
-
# Make sure spinner is stopped (in case loop ended without content)
|
|
206
|
-
if spinner_active:
|
|
207
|
-
status.stop()
|
|
208
|
-
|
|
209
|
-
if has_responded:
|
|
210
|
-
console.print() # Newline
|
|
211
|
-
console.print() # Blank line
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
# ============================================================================
|
|
215
|
-
# MAIN
|
|
216
|
-
# ============================================================================
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
async def main():
|
|
220
|
-
"""Main entry point."""
|
|
221
|
-
global agent
|
|
222
|
-
|
|
223
|
-
# Show welcome
|
|
224
|
-
show_welcome()
|
|
225
|
-
|
|
226
|
-
# Initialize agent
|
|
227
|
-
console.print("\nInitializing agent...", style=COLORS["dim"])
|
|
228
|
-
agent = create_sandbox_chat_agent()
|
|
229
|
-
|
|
230
|
-
# Show ready message
|
|
231
|
-
console.print("\n... Ready to code! What would you like to build?", style=COLORS["agent"])
|
|
232
|
-
console.print()
|
|
233
|
-
|
|
234
|
-
# One-time hint for multiline input
|
|
235
|
-
console.print(" Tip: Alt-Enter for newline, Enter to submit", style=f"dim {COLORS['dim']}")
|
|
236
|
-
|
|
237
|
-
# Setup key bindings for multiline input
|
|
238
|
-
kb = KeyBindings()
|
|
239
|
-
|
|
240
|
-
@kb.add('enter')
|
|
241
|
-
def _(event):
|
|
242
|
-
buffer = event.current_buffer
|
|
243
|
-
if buffer.text.strip(): # Only submit if buffer has content
|
|
244
|
-
buffer.validate_and_handle()
|
|
245
|
-
# else: do nothing - no newline, no submission
|
|
246
|
-
|
|
247
|
-
@kb.add('escape', 'enter') # Alt-Enter (or Esc then Enter) for newline
|
|
248
|
-
def _(event):
|
|
249
|
-
event.current_buffer.insert_text('\n')
|
|
250
|
-
|
|
251
|
-
# Setup prompt session with multiline support
|
|
252
|
-
style = Style.from_dict({"prompt": COLORS["user"]})
|
|
253
|
-
session = PromptSession(
|
|
254
|
-
message="> ",
|
|
255
|
-
style=style,
|
|
256
|
-
multiline=True,
|
|
257
|
-
prompt_continuation=lambda width, line_number, is_soft_wrap: " ",
|
|
258
|
-
key_bindings=kb,
|
|
259
|
-
)
|
|
260
|
-
|
|
261
|
-
# Main chat loop
|
|
262
|
-
while True:
|
|
263
|
-
try:
|
|
264
|
-
# Get user input
|
|
265
|
-
user_input = await session.prompt_async()
|
|
266
|
-
|
|
267
|
-
# Handle quit commands
|
|
268
|
-
if user_input.strip().lower() in ["quit", "exit", "q"]:
|
|
269
|
-
break
|
|
270
|
-
|
|
271
|
-
# Skip empty input
|
|
272
|
-
if not user_input.strip():
|
|
273
|
-
continue
|
|
274
|
-
|
|
275
|
-
# Add spacing
|
|
276
|
-
console.print()
|
|
277
|
-
|
|
278
|
-
# Stream agent response
|
|
279
|
-
await stream_agent_response(user_input)
|
|
280
|
-
|
|
281
|
-
except (KeyboardInterrupt, EOFError):
|
|
282
|
-
break
|
|
283
|
-
|
|
284
|
-
# Goodbye message
|
|
285
|
-
console.print("\nGoodbye!", style=COLORS["primary"])
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
if __name__ == "__main__":
|
|
289
|
-
asyncio.run(main())
|