Skip to content

Commit bb72327

Browse files
authored
Revert "fix(cli): Abort functionality, autocomplete, and fixed memory prompts…" (#248)
This reverts commit 681e184.
1 parent 681e184 commit bb72327

File tree

10 files changed

+212
-629
lines changed

10 files changed

+212
-629
lines changed

libs/deepagents-cli/deepagents_cli/agent.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,14 @@ def format_edit_file_description(tool_call: dict) -> str:
199199
f"Snippet delta: {delta:+} characters"
200200
)
201201

202+
def format_web_search_description(tool_call: dict) -> str:
203+
"""Format web_search tool call for approval prompt."""
204+
args = tool_call.get("args", {})
205+
query = args.get("query", "unknown")
206+
max_results = args.get("max_results", 5)
207+
208+
return f"Query: {query}\nMax results: {max_results}\n\n⚠️ This will use Tavily API credits"
209+
202210
def format_task_description(tool_call: dict) -> str:
203211
"""Format task (subagent) tool call for approval prompt."""
204212
args = tool_call.get("args", {})
@@ -240,6 +248,11 @@ def format_task_description(tool_call: dict) -> str:
240248
"description": lambda tool_call, state, runtime: format_edit_file_description(tool_call),
241249
}
242250

251+
web_search_interrupt_config: InterruptOnConfig = {
252+
"allowed_decisions": ["approve", "reject"],
253+
"description": lambda tool_call, state, runtime: format_web_search_description(tool_call),
254+
}
255+
243256
task_interrupt_config: InterruptOnConfig = {
244257
"allowed_decisions": ["approve", "reject"],
245258
"description": lambda tool_call, state, runtime: format_task_description(tool_call),
@@ -255,9 +268,8 @@ def format_task_description(tool_call: dict) -> str:
255268
"shell": shell_interrupt_config,
256269
"write_file": write_file_interrupt_config,
257270
"edit_file": edit_file_interrupt_config,
271+
"web_search": web_search_interrupt_config,
258272
"task": task_interrupt_config,
259-
# Note: web_search is NOT here - it's a read-only tool like http_request
260-
# and should execute automatically without requiring approval
261273
},
262274
).with_config(config)
263275

Lines changed: 16 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
"""Command handlers for slash commands and bash execution."""
22

3-
import os
4-
import signal
53
import subprocess
64
from pathlib import Path
75

@@ -59,92 +57,33 @@ def execute_bash_command(command: str) -> bool:
5957
if not cmd:
6058
return True
6159

62-
process = None
63-
interrupted = False
64-
original_handler = None
65-
66-
def sigint_handler(signum, frame):
67-
"""Custom SIGINT handler - kills subprocess immediately and sets flag."""
68-
nonlocal interrupted, process
69-
interrupted = True
70-
71-
# Kill subprocess immediately when Ctrl+C is pressed
72-
if process and process.poll() is None:
73-
try:
74-
if hasattr(os, "killpg"):
75-
os.killpg(os.getpgid(process.pid), signal.SIGINT)
76-
else:
77-
process.send_signal(signal.SIGINT)
78-
except (ProcessLookupError, OSError):
79-
pass
80-
8160
try:
82-
# Install our signal handler (temporarily overrides asyncio's handler)
83-
original_handler = signal.signal(signal.SIGINT, sigint_handler)
84-
8561
console.print()
8662
console.print(f"[dim]$ {cmd}[/dim]")
8763

88-
# Create subprocess in new session (process group) to isolate from parent's signals
89-
process = subprocess.Popen(
90-
cmd,
91-
shell=True,
92-
text=True,
93-
stdin=subprocess.DEVNULL, # Close stdin to prevent interactive commands from hanging
94-
stdout=subprocess.PIPE,
95-
stderr=subprocess.PIPE,
96-
start_new_session=True, # Isolate subprocess in its own process group
97-
cwd=Path.cwd(),
64+
# Execute the command
65+
result = subprocess.run(
66+
cmd, check=False, shell=True, capture_output=True, text=True, timeout=30, cwd=Path.cwd()
9867
)
9968

100-
try:
101-
# Wait for command to complete with timeout
102-
stdout, stderr = process.communicate(timeout=30)
103-
104-
# Display output
105-
if stdout:
106-
console.print(stdout, style=COLORS["dim"], markup=False)
107-
if stderr:
108-
console.print(stderr, style="red", markup=False)
109-
110-
# Check if interrupted via our flag
111-
if interrupted:
112-
console.print("\n[yellow]Command interrupted by user[/yellow]\n")
113-
elif process.returncode != 0:
114-
# Exit code 130 = 128 + SIGINT (2) - command was interrupted
115-
# Exit code -2 also indicates interrupt in some shells
116-
if process.returncode == 130 or process.returncode == -2:
117-
console.print("[yellow]Command interrupted[/yellow]")
118-
else:
119-
console.print(f"[dim]Exit code: {process.returncode}[/dim]")
120-
121-
except subprocess.TimeoutExpired:
122-
# Timeout - kill the process group
123-
if hasattr(os, "killpg"):
124-
try:
125-
os.killpg(os.getpgid(process.pid), signal.SIGKILL)
126-
except (ProcessLookupError, OSError):
127-
pass
128-
else:
129-
process.kill()
130-
131-
# Clean up zombie process
132-
try:
133-
process.wait(timeout=1)
134-
except subprocess.TimeoutExpired:
135-
pass
136-
137-
console.print("[red]Command timed out after 30 seconds[/red]")
69+
# Display output
70+
if result.stdout:
71+
console.print(result.stdout, style=COLORS["dim"], markup=False)
72+
if result.stderr:
73+
console.print(result.stderr, style="red", markup=False)
74+
75+
# Show return code if non-zero
76+
if result.returncode != 0:
77+
console.print(f"[dim]Exit code: {result.returncode}[/dim]")
13878

13979
console.print()
14080
return True
14181

82+
except subprocess.TimeoutExpired:
83+
console.print("[red]Command timed out after 30 seconds[/red]")
84+
console.print()
85+
return True
14286
except Exception as e:
14387
console.print(f"[red]Error executing command: {e}[/red]")
14488
console.print()
14589
return True
146-
147-
finally:
148-
# CRITICAL: Always restore original signal handler so asyncio can handle Ctrl+C at prompt
149-
if original_handler is not None:
150-
signal.signal(signal.SIGINT, original_handler)

libs/deepagents-cli/deepagents_cli/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
# Common bash commands for autocomplete
4949
COMMON_BASH_COMMANDS = {
5050
"ls": "List directory contents",
51+
"ls -la": "List all files with details",
5152
"cd": "Change directory",
5253
"pwd": "Print working directory",
5354
"cat": "Display file contents",

libs/deepagents-cli/deepagents_cli/default_agent_prompt.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@ You are an AI assistant that helps users with various tasks including coding, re
33
# Core Role
44
Your core role and behavior may be updated based on user feedback and instructions. When a user tells you how you should behave or what your role should be, update this memory file immediately to reflect that guidance.
55

6-
## Memory System
7-
You have access to persistent memory in `/memories/`.
6+
## Memory-First Protocol
7+
You have access to a persistent memory system. ALWAYS follow this protocol:
88

9-
**When answering questions:**
10-
- If asked "what do you know about X?" or similar questions about specific topics → Check `/memories/` for relevant knowledge
11-
- If you recall working on or saving information about the current topic → Read those memory files
9+
**At session start:**
10+
- Check `ls /memories/` to see what knowledge you have stored
11+
- If your role description references specific topics, check /memories/ for relevant guides
12+
13+
**Before answering questions:**
14+
- If asked "what do you know about X?" or "how do I do Y?" → Check `ls /memories/` FIRST
15+
- If relevant memory files exist → Read them and base your answer on saved knowledge
1216
- Prefer saved knowledge over general knowledge when available
1317

1418
**When learning new information:**

0 commit comments

Comments
 (0)