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.

Files changed (41) hide show
  1. deepagents_cli/__init__.py +5 -0
  2. deepagents_cli/__main__.py +6 -0
  3. deepagents_cli/agent.py +267 -0
  4. deepagents_cli/cli.py +13 -0
  5. deepagents_cli/commands.py +86 -0
  6. deepagents_cli/config.py +138 -0
  7. deepagents_cli/execution.py +644 -0
  8. deepagents_cli/file_ops.py +347 -0
  9. deepagents_cli/input.py +249 -0
  10. deepagents_cli/main.py +217 -0
  11. deepagents_cli/py.typed +0 -0
  12. deepagents_cli/tools.py +140 -0
  13. deepagents_cli/ui.py +455 -0
  14. deepagents_cli-0.0.4.dist-info/METADATA +18 -0
  15. deepagents_cli-0.0.4.dist-info/RECORD +18 -0
  16. deepagents_cli-0.0.4.dist-info/entry_points.txt +3 -0
  17. deepagents_cli-0.0.4.dist-info/top_level.txt +1 -0
  18. deepagents/__init__.py +0 -7
  19. deepagents/cli.py +0 -567
  20. deepagents/default_agent_prompt.md +0 -64
  21. deepagents/graph.py +0 -144
  22. deepagents/memory/__init__.py +0 -17
  23. deepagents/memory/backends/__init__.py +0 -15
  24. deepagents/memory/backends/composite.py +0 -250
  25. deepagents/memory/backends/filesystem.py +0 -330
  26. deepagents/memory/backends/state.py +0 -206
  27. deepagents/memory/backends/store.py +0 -351
  28. deepagents/memory/backends/utils.py +0 -319
  29. deepagents/memory/protocol.py +0 -164
  30. deepagents/middleware/__init__.py +0 -13
  31. deepagents/middleware/agent_memory.py +0 -207
  32. deepagents/middleware/filesystem.py +0 -615
  33. deepagents/middleware/patch_tool_calls.py +0 -44
  34. deepagents/middleware/subagents.py +0 -481
  35. deepagents/pretty_cli.py +0 -289
  36. deepagents_cli-0.0.3.dist-info/METADATA +0 -551
  37. deepagents_cli-0.0.3.dist-info/RECORD +0 -24
  38. deepagents_cli-0.0.3.dist-info/entry_points.txt +0 -2
  39. deepagents_cli-0.0.3.dist-info/licenses/LICENSE +0 -21
  40. deepagents_cli-0.0.3.dist-info/top_level.txt +0 -1
  41. {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())