agentcrew-ai 0.8.1__py3-none-any.whl → 0.8.2__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.
AgentCrew/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.8.1"
1
+ __version__ = "0.8.2"
@@ -41,7 +41,7 @@ class BrowserAutomationService:
41
41
 
42
42
  self.debug_port = debug_port
43
43
  self.chrome_manager = ChromeManager(debug_port=debug_port)
44
- self.chrome_interface: Optional[Any] = None
44
+ self.chrome_interface: Optional[PyChromeDevTools.ChromeInterface] = None
45
45
  self._is_initialized = False
46
46
  # UUID to XPath mapping for element identification
47
47
  self.uuid_to_xpath_mapping: Dict[str, str] = {}
@@ -51,6 +51,9 @@ class BrowserAutomationService:
51
51
  """Ensure Chrome browser is running and connected."""
52
52
  if not self._is_initialized:
53
53
  self._initialize_chrome(profile)
54
+ # Always get active content tabs
55
+ if self.chrome_interface:
56
+ self.chrome_interface.connect()
54
57
 
55
58
  def _initialize_chrome(self, profile: str = "Default"):
56
59
  """Initialize Chrome browser and DevTools connection."""
@@ -471,7 +474,11 @@ class BrowserAutomationService:
471
474
  if style:
472
475
  # Remove spaces and check for display:none
473
476
  style_clean = re.sub(r"\s+", "", style.lower())
474
- if "display:none" in style_clean or "display=none" in style_clean:
477
+ if (
478
+ "display:none" in style_clean
479
+ or "display=none" in style_clean
480
+ or "visibility:hidden" in style_clean
481
+ ):
475
482
  should_hide = True
476
483
 
477
484
  # Check for aria-hidden="true"
@@ -27,7 +27,7 @@ def get_browser_navigate_tool_definition(provider="claude") -> Dict[str, Any]:
27
27
 
28
28
  if provider == "claude":
29
29
  return {
30
- "name": "browser_navigate",
30
+ "name": "navigate_url",
31
31
  "description": tool_description,
32
32
  "input_schema": {
33
33
  "type": "object",
@@ -39,7 +39,7 @@ def get_browser_navigate_tool_definition(provider="claude") -> Dict[str, Any]:
39
39
  return {
40
40
  "type": "function",
41
41
  "function": {
42
- "name": "browser_navigate",
42
+ "name": "navigate_url",
43
43
  "description": tool_description,
44
44
  "parameters": {
45
45
  "type": "object",
@@ -65,7 +65,7 @@ def get_browser_click_tool_definition(provider="claude") -> Dict[str, Any]:
65
65
 
66
66
  if provider == "claude":
67
67
  return {
68
- "name": "browser_click",
68
+ "name": "click_browser_element",
69
69
  "description": tool_description,
70
70
  "input_schema": {
71
71
  "type": "object",
@@ -77,7 +77,7 @@ def get_browser_click_tool_definition(provider="claude") -> Dict[str, Any]:
77
77
  return {
78
78
  "type": "function",
79
79
  "function": {
80
- "name": "browser_click",
80
+ "name": "click_browser_element",
81
81
  "description": tool_description,
82
82
  "parameters": {
83
83
  "type": "object",
@@ -115,7 +115,7 @@ def get_browser_scroll_tool_definition(provider="claude") -> Dict[str, Any]:
115
115
 
116
116
  if provider == "claude":
117
117
  return {
118
- "name": "browser_scroll",
118
+ "name": "scroll_browser",
119
119
  "description": tool_description,
120
120
  "input_schema": {
121
121
  "type": "object",
@@ -127,7 +127,7 @@ def get_browser_scroll_tool_definition(provider="claude") -> Dict[str, Any]:
127
127
  return {
128
128
  "type": "function",
129
129
  "function": {
130
- "name": "browser_scroll",
130
+ "name": "scroll_browser",
131
131
  "description": tool_description,
132
132
  "parameters": {
133
133
  "type": "object",
@@ -149,7 +149,7 @@ def get_browser_get_content_tool_definition(provider="claude") -> Dict[str, Any]
149
149
 
150
150
  if provider == "claude":
151
151
  return {
152
- "name": "browser_get_content",
152
+ "name": "get_browser_content",
153
153
  "description": tool_description,
154
154
  "input_schema": {
155
155
  "type": "object",
@@ -161,7 +161,7 @@ def get_browser_get_content_tool_definition(provider="claude") -> Dict[str, Any]
161
161
  return {
162
162
  "type": "function",
163
163
  "function": {
164
- "name": "browser_get_content",
164
+ "name": "get_browser_content",
165
165
  "description": tool_description,
166
166
  "parameters": {
167
167
  "type": "object",
@@ -301,7 +301,7 @@ def get_browser_input_tool_definition(provider="claude") -> Dict[str, Any]:
301
301
 
302
302
  if provider == "claude":
303
303
  return {
304
- "name": "browser_input",
304
+ "name": "input_browser_field",
305
305
  "description": tool_description,
306
306
  "input_schema": {
307
307
  "type": "object",
@@ -313,7 +313,7 @@ def get_browser_input_tool_definition(provider="claude") -> Dict[str, Any]:
313
313
  return {
314
314
  "type": "function",
315
315
  "function": {
316
- "name": "browser_input",
316
+ "name": "input_browser_field",
317
317
  "description": tool_description,
318
318
  "parameters": {
319
319
  "type": "object",
@@ -367,7 +367,7 @@ def get_browser_get_elements_by_text_tool_definition(
367
367
 
368
368
  if provider == "claude":
369
369
  return {
370
- "name": "browser_get_elements_by_text",
370
+ "name": "get_browser_elements_by_text",
371
371
  "description": tool_description,
372
372
  "input_schema": {
373
373
  "type": "object",
@@ -379,7 +379,7 @@ def get_browser_get_elements_by_text_tool_definition(
379
379
  return {
380
380
  "type": "function",
381
381
  "function": {
382
- "name": "browser_get_elements_by_text",
382
+ "name": "get_browser_elements_by_text",
383
383
  "description": tool_description,
384
384
  "parameters": {
385
385
  "type": "object",
@@ -446,7 +446,7 @@ def get_browser_capture_screenshot_tool_definition(provider="claude") -> Dict[st
446
446
 
447
447
  if provider == "claude":
448
448
  return {
449
- "name": "browser_capture_screenshot",
449
+ "name": "capture_browser_screenshot",
450
450
  "description": tool_description,
451
451
  "input_schema": {
452
452
  "type": "object",
@@ -458,7 +458,7 @@ def get_browser_capture_screenshot_tool_definition(provider="claude") -> Dict[st
458
458
  return {
459
459
  "type": "function",
460
460
  "function": {
461
- "name": "browser_capture_screenshot",
461
+ "name": "capture_browser_screenshot",
462
462
  "description": tool_description,
463
463
  "parameters": {
464
464
  "type": "object",
@@ -572,7 +572,7 @@ def get_browser_send_key_tool_definition(provider="claude") -> Dict[str, Any]:
572
572
 
573
573
  if provider == "claude":
574
574
  return {
575
- "name": "browser_send_key",
575
+ "name": "send_browser_key",
576
576
  "description": tool_description,
577
577
  "input_schema": {
578
578
  "type": "object",
@@ -584,7 +584,7 @@ def get_browser_send_key_tool_definition(provider="claude") -> Dict[str, Any]:
584
584
  return {
585
585
  "type": "function",
586
586
  "function": {
587
- "name": "browser_send_key",
587
+ "name": "send_browser_key",
588
588
  "description": tool_description,
589
589
  "parameters": {
590
590
  "type": "object",
@@ -376,10 +376,26 @@ class CommandProcessor:
376
376
  self.message_handler.last_assisstant_response_idx = len(
377
377
  self.message_handler.streamline_messages
378
378
  )
379
+ if isinstance(selected_message.get("content"), list):
380
+ selected_content = next(
381
+ (
382
+ c.get("text", "")
383
+ for c in selected_message.get("content", [])
384
+ if c.get("type", "") == "text"
385
+ ),
386
+ "",
387
+ )
388
+
389
+ else:
390
+ selected_content = selected_message.get("content", "")
379
391
 
380
392
  self.message_handler._notify(
381
393
  "jump_performed",
382
- {"turn_number": turn_number, "preview": selected_turn.get_preview(100)},
394
+ {
395
+ "turn_number": turn_number,
396
+ "preview": selected_turn.get_preview(100),
397
+ "message": selected_content,
398
+ },
383
399
  )
384
400
 
385
401
  return True
@@ -17,7 +17,7 @@ def get_clipboard_read_tool_definition(provider="claude") -> Dict[str, Any]:
17
17
  tool_required = []
18
18
  if provider == "claude":
19
19
  return {
20
- "name": "clipboard_read",
20
+ "name": "read_clipboard",
21
21
  "description": tool_description,
22
22
  "input_schema": {
23
23
  "type": "object",
@@ -29,7 +29,7 @@ def get_clipboard_read_tool_definition(provider="claude") -> Dict[str, Any]:
29
29
  return {
30
30
  "type": "function",
31
31
  "function": {
32
- "name": "clipboard_read",
32
+ "name": "read_clipboard",
33
33
  "description": tool_description,
34
34
  "parameters": {
35
35
  "type": "object",
@@ -191,6 +191,7 @@ class ConsoleUI(Observer):
191
191
 
192
192
  self.display_handlers.display_message(jump_text)
193
193
  self.display_handlers.display_message(preview_text)
194
+ self.input_handler.set_current_buffer(data["message"])
194
195
  elif event == "thinking_completed":
195
196
  self.display_handlers.display_divider()
196
197
  elif event == "file_processing":
@@ -287,7 +288,7 @@ class ConsoleUI(Observer):
287
288
  import os
288
289
  import time
289
290
 
290
- if self.input_handler.is_message_processing and self._is_resizing:
291
+ if self.input_handler.is_message_processing or self._is_resizing:
291
292
  return # Ignore resize during message processing
292
293
  self._is_resizing = True
293
294
  time.sleep(0.5) # brief pause to allow resize to complete
@@ -55,6 +55,7 @@ class InputHandler:
55
55
  self._last_ctrl_c_time = 0
56
56
  self.is_message_processing = False
57
57
  self.swap_enter = swap_enter
58
+ self._jumped_user_message = ""
58
59
 
59
60
  # Set up key bindings
60
61
  self.kb = self._setup_key_bindings()
@@ -263,6 +264,11 @@ class InputHandler:
263
264
  def clear_buffer(self):
264
265
  if self._current_prompt_session:
265
266
  self._current_prompt_session.app.current_buffer.reset()
267
+ if self._jumped_user_message:
268
+ self._current_prompt_session.app.current_buffer.insert_text(
269
+ self._jumped_user_message
270
+ )
271
+ self._jumped_user_message = ""
266
272
  if not self.is_message_processing:
267
273
  self.display_handlers.print_divider("👤 YOU: ", with_time=True)
268
274
  self._current_prompt_session.message = HTML(PROMPT_CHAR)
@@ -329,12 +335,14 @@ class InputHandler:
329
335
  )
330
336
  user_input = session.prompt(prompt_text)
331
337
 
338
+ if not user_input:
339
+ continue
340
+
332
341
  user_input = user_input.replace(f"\n{PROMPT_CHAR}", "\n")
333
342
 
334
343
  self.message_handler.history_manager.reset_position()
335
344
 
336
345
  self._input_queue.put(user_input)
337
- self.is_message_processing = True
338
346
 
339
347
  except KeyboardInterrupt:
340
348
  # Handle Ctrl+C in input thread
@@ -382,6 +390,9 @@ class InputHandler:
382
390
  pass
383
391
  self._input_thread.join(timeout=1.0)
384
392
 
393
+ def set_current_buffer(self, content: str):
394
+ self._jumped_user_message = content
395
+
385
396
  def get_user_input(self):
386
397
  """
387
398
  Get multiline input from the user with support for command history.
@@ -415,6 +426,7 @@ class InputHandler:
415
426
  # Add None check here
416
427
  if user_input is None:
417
428
  continue
429
+ self.is_message_processing = True
418
430
 
419
431
  self.display_handlers.print_divider()
420
432
 
@@ -107,6 +107,8 @@ class UIEffects:
107
107
  self.live = Live(
108
108
  live_panel,
109
109
  console=self.console,
110
+ auto_refresh=True,
111
+ refresh_per_second=8,
110
112
  vertical_overflow="crop",
111
113
  )
112
114
  self.live.start()
@@ -119,7 +121,8 @@ class UIEffects:
119
121
  self._visible_buffer = max(0, self._visible_buffer - speed)
120
122
  elif direction == "down":
121
123
  self._visible_buffer += speed
122
- self.update_live_display(self.updated_text)
124
+ if self.live:
125
+ self.update_live_display(self.updated_text)
123
126
 
124
127
  def update_live_display(self, chunk: str):
125
128
  """Update the live display with a new chunk of the response."""
@@ -131,12 +134,14 @@ class UIEffects:
131
134
 
132
135
  # Only show the last part that fits in the console
133
136
  lines = self.updated_text.split("\n")
134
- height_limit = (
135
- self.console.size.height - 10
136
- ) # leave some space for other elements
137
+ height_limit = int(self.console.size.height * 0.9)
137
138
  if len(lines) > height_limit:
138
- self.tracking_buffer = len(lines) - height_limit
139
- if self._visible_buffer == -1:
139
+ if (
140
+ self._visible_buffer == -1
141
+ or self._visible_buffer > len(lines) - height_limit
142
+ ):
143
+ self._tracking_buffer = len(lines) - height_limit
144
+ self._visible_buffer = -1
140
145
  lines = lines[-height_limit:]
141
146
  else:
142
147
  lines = lines[
@@ -161,6 +166,8 @@ class UIEffects:
161
166
  box=HORIZONTALS,
162
167
  subtitle=subtitle,
163
168
  title_align="left",
169
+ expand=False,
170
+ height=height_limit if len(lines) >= height_limit - 10 else None,
164
171
  border_style=RICH_STYLE_GREEN,
165
172
  )
166
173
  self.live.update(live_panel)
@@ -64,7 +64,7 @@ Auto syntax check (30+ langs) with rollback on error
64
64
 
65
65
  if provider == "claude":
66
66
  return {
67
- "name": "file_write_or_edit",
67
+ "name": "write_or_edit_file",
68
68
  "description": tool_description,
69
69
  "input_schema": {
70
70
  "type": "object",
@@ -76,7 +76,7 @@ Auto syntax check (30+ langs) with rollback on error
76
76
  return {
77
77
  "type": "function",
78
78
  "function": {
79
- "name": "file_write_or_edit",
79
+ "name": "write_or_edit_file",
80
80
  "description": tool_description,
81
81
  "parameters": {
82
82
  "type": "object",
@@ -444,7 +444,7 @@ class MCPService:
444
444
  Formatted tool definition
445
445
  """
446
446
  # Create namespaced tool name
447
- namespaced_name = f"{server_id}_{tool.name}"
447
+ namespaced_name = f"{server_id}__{tool.name}"
448
448
 
449
449
  from jsonref import replace_refs
450
450
  import json
@@ -87,6 +87,25 @@ class BaseMemoryService(ABC):
87
87
  """
88
88
  pass
89
89
 
90
+ @abstractmethod
91
+ def list_memory_ids(
92
+ self,
93
+ from_date: Optional[int] = None,
94
+ to_date: Optional[int] = None,
95
+ agent_name: str = "None",
96
+ ) -> List[str]:
97
+ """
98
+ List all memory IDs within an optional date range.
99
+
100
+ Args:
101
+ from_date: Optional start date (timestamp) to filter memories
102
+ to_date: Optional end date (timestamp) to filter memories
103
+
104
+ Returns:
105
+ List of memory IDs
106
+ """
107
+ pass
108
+
90
109
  @abstractmethod
91
110
  def cleanup_old_memories(self, months: int = 1) -> int:
92
111
  """
@@ -425,6 +425,35 @@ class ChromaMemoryService(BaseMemoryService):
425
425
  else:
426
426
  return input
427
427
 
428
+ def list_memory_ids(
429
+ self,
430
+ from_date: Optional[int] = None,
431
+ to_date: Optional[int] = None,
432
+ agent_name: str = "None",
433
+ ) -> List[str]:
434
+ collection = self._initialize_collection()
435
+
436
+ and_conditions: List[Dict[str, Any]] = []
437
+
438
+ if self.session_id.strip():
439
+ and_conditions.append({"session_id": {"$ne": self.session_id}})
440
+ if agent_name.strip():
441
+ and_conditions.append({"agent": agent_name})
442
+ if from_date:
443
+ and_conditions.append({"date": {"$gte": from_date}})
444
+ if to_date:
445
+ and_conditions.append({"date": {"$lte": to_date}})
446
+
447
+ list_memory = collection.get(
448
+ where={"$and": and_conditions}
449
+ if len(and_conditions) >= 2
450
+ else and_conditions[0]
451
+ if and_conditions
452
+ else None,
453
+ include=[],
454
+ )
455
+ return list_memory["ids"]
456
+
428
457
  def retrieve_memory(
429
458
  self,
430
459
  keywords: str,
@@ -451,7 +480,6 @@ class ChromaMemoryService(BaseMemoryService):
451
480
  and_conditions.append({"session_id": {"$ne": self.session_id}})
452
481
  if agent_name.strip():
453
482
  and_conditions.append({"agent": agent_name})
454
-
455
483
  if from_date:
456
484
  and_conditions.append({"date": {"$gte": from_date}})
457
485
  if to_date:
@@ -329,7 +329,9 @@ class ContextPersistenceService:
329
329
  # listdir raises OSError if the directory is invalid
330
330
  filenames = os.listdir(self.conversations_dir)
331
331
  for filename in filenames:
332
- if filename.endswith(".json"):
332
+ if filename.endswith(".json") and not filename.endswith(
333
+ ".metadata.json"
334
+ ):
333
335
  conversation_id = filename[:-5] # Remove .json extension
334
336
  file_path = os.path.join(self.conversations_dir, filename)
335
337
  try:
@@ -8,31 +8,21 @@ from .base_service import BaseMemoryService
8
8
  def get_memory_forget_tool_definition(provider="claude") -> Dict[str, Any]:
9
9
  """Optimized memory forgetting tool definition."""
10
10
 
11
- tool_description = """Removes memories related to specific topics or IDs from storage.
11
+ tool_description = """Removes memories using IDs from memory bank.
12
12
 
13
13
  Use for clearing outdated information, removing sensitive data, resolving conflicting memories, or correcting errors.
14
14
 
15
- Be specific with topics to avoid over-deletion. Use IDs for precise removal when available.
16
- Use date filters to limit scope whenever posible, Eg: yesterday: from_date = current_date - 1"""
15
+ Search for memories need to remote, use date filters to limit scope whenever posible, Eg: yesterday: from_date = current_date - 1 and use IDs for precise removal."""
17
16
 
18
17
  tool_arguments = {
19
- "topic": {
20
- "type": "string",
18
+ "ids": {
19
+ "type": "array",
21
20
  "description": "Keywords describing what to forget. Use specific terms like 'project alpha 2024 credentials' or 'outdated api documentation v1'. Avoid broad terms like 'user' or 'project'.",
22
- },
23
- "from_date": {
24
- "type": "string",
25
- "format": "date",
26
- "description": "Filter removing memories from this date (YYYY-MM-DD). Optional.",
27
- },
28
- "to_date": {
29
- "type": "string",
30
- "format": "date",
31
- "description": "Filter removing memories til this date (YYYY-MM-DD). Optional.",
21
+ "items": {"type": "string"},
32
22
  },
33
23
  }
34
24
 
35
- tool_required = ["topic"]
25
+ tool_required = ["ids"]
36
26
 
37
27
  if provider == "claude":
38
28
  return {
@@ -63,41 +53,21 @@ def get_memory_forget_tool_handler(memory_service: BaseMemoryService) -> Callabl
63
53
  """Optimized memory forgetting handler with concise feedback."""
64
54
 
65
55
  def handle_memory_forget(**params) -> str:
66
- topic = params.get("topic", "").strip()
67
-
68
- from_date = params.get("from_date", None)
69
- to_date = params.get("to_date", None)
56
+ ids = params.get("ids", "").strip()
70
57
 
71
58
  # Use provided agent_name or fallback to current agent
72
59
  current_agent = AgentManager.get_instance().get_current_agent()
73
60
  agent_name = current_agent.name if current_agent else "None"
74
61
 
75
- # Topic-based removal
76
- if not topic:
77
- return "❌ Topic required for memory removal."
78
-
79
- # Prevent overly broad deletion
80
- risky_terms = ["all", "everything", "user", "conversation", "memory"]
81
- if topic.lower() in risky_terms:
82
- return f"⚠️ '{topic}' too broad. Use specific terms to avoid over-deletion."
83
-
84
62
  try:
85
- if from_date:
86
- from_date = int(dt.strptime(from_date, "%Y-%m-%d").timestamp())
87
- if to_date:
88
- to_date = int(dt.strptime(to_date, "%Y-%m-%d").timestamp())
89
- if from_date and to_date and from_date >= to_date:
90
- raise ValueError(
91
- "from_date must be earlier than and not equal to to_date."
92
- )
93
- result = memory_service.forget_topic(topic, from_date, to_date, agent_name)
63
+ result = memory_service.forget_ids(ids, agent_name)
94
64
  return (
95
- f"✅ Removed memories for '{topic}': {result.get('message', 'Success')}"
65
+ f"✅ Removed memories: {result.get('message', 'Success')}"
96
66
  if result.get("success")
97
67
  else f"⚠️ Removal incomplete: {result.get('message', 'Not found')}"
98
68
  )
99
69
  except Exception as e:
100
- return f"❌ Topic removal failed: {str(e)}"
70
+ return f"❌ Memories removal failed: {str(e)}"
101
71
 
102
72
  return handle_memory_forget
103
73
 
@@ -105,15 +75,15 @@ def get_memory_forget_tool_handler(memory_service: BaseMemoryService) -> Callabl
105
75
  def get_memory_retrieve_tool_definition(provider="claude") -> Dict[str, Any]:
106
76
  """Optimized memory retrieval tool definition."""
107
77
 
108
- tool_description = """Retrieves relevant information from conversation history using semantic search.
78
+ tool_description = """Search relevant information from conversation history using semantic search.
109
79
  Use for gathering context, accessing user preferences, finding similar problems, and maintaining conversation continuity.
110
- Search with specific, descriptive keywords for better results.
80
+ Search with specific, descriptive queries for better results.
111
81
  Use from_date and to_date to filter memories by time whenever posible, Eg: yesterday: from_date = current_date - 1"""
112
82
 
113
83
  tool_arguments = {
114
- "phrases": {
84
+ "query": {
115
85
  "type": "string",
116
- "description": "Search a phrases for finding relevant memories. Use specific semantic phrases like 'project alpha database issues' or 'user preferences communication style' rather than single words.",
86
+ "description": "A searching query for finding relevant memories. Use specific semantic phrases like 'project alpha database issues' or 'user preferences communication style' rather than keywords.",
117
87
  },
118
88
  "from_date": {
119
89
  "type": "string",
@@ -127,11 +97,11 @@ Use from_date and to_date to filter memories by time whenever posible, Eg: yeste
127
97
  },
128
98
  }
129
99
 
130
- tool_required = ["phrases"]
100
+ tool_required = ["query"]
131
101
 
132
102
  if provider == "claude":
133
103
  return {
134
- "name": "retrieve_memory",
104
+ "name": "search_memory",
135
105
  "description": tool_description,
136
106
  "input_schema": {
137
107
  "type": "object",
@@ -143,7 +113,7 @@ Use from_date and to_date to filter memories by time whenever posible, Eg: yeste
143
113
  return {
144
114
  "type": "function",
145
115
  "function": {
146
- "name": "retrieve_memory",
116
+ "name": "search_memory",
147
117
  "description": tool_description,
148
118
  "parameters": {
149
119
  "type": "object",
@@ -159,16 +129,16 @@ def memory_instruction_prompt():
159
129
  return """<Memory_System>
160
130
  <Purpose>
161
131
  Extremely useful for gathering context through intelligent storage and retrieval of relevant information.
162
- Call retrieve_memory when on of retrieval triggers occur to provide better responses.
132
+ Call search_memory when one of <Memory_Triggers> occur to provide better responses.
163
133
  </Purpose>
164
134
  <Usage_Guidelines>
165
- <Retrieval_Triggers>
135
+ <Memory_Triggers>
166
136
  - When start a new conversation - gather relevant context from user request
167
137
  - When current topic changes - Get new topic-related memories context for better responses
168
138
  - When User references to past interactions
169
- </Retrieval_Triggers>
139
+ </Memory_Triggers>
170
140
  <Search_Strategy>
171
- - Use specific, descriptive phrases
141
+ - Use specific, descriptive queries
172
142
  - Combine related concepts with spaces
173
143
  - Include temporal indicators when relevant
174
144
  - Include time filters when applicable
@@ -177,8 +147,7 @@ def memory_instruction_prompt():
177
147
  <Memory_Management>
178
148
  - Remove outdated/conflicting information when corrected
179
149
  - Clear sensitive data when requested
180
- - Use precise topic phrases to avoid over-deletion
181
- - Prefer ID-based removal for surgical precision
150
+ - Search and Use ID-based removal for surgical precision
182
151
  </Memory_Management>
183
152
  </Usage_Guidelines>
184
153
  </Memory_System>"""
@@ -188,16 +157,16 @@ def get_memory_retrieve_tool_handler(memory_service: BaseMemoryService) -> Calla
188
157
  """Optimized memory retrieval handler with concise feedback."""
189
158
 
190
159
  def handle_memory_retrieve(**params) -> str:
191
- phrases = params.get("phrases", "").strip()
160
+ query = params.get("query", "").strip()
192
161
  from_date = params.get("from_date", None)
193
162
  to_date = params.get("to_date", None)
194
163
 
195
- if not phrases:
164
+ if not query:
196
165
  raise ValueError("❌ Phrases required for memory search. Try again.")
197
166
 
198
- if len(phrases) < 3:
167
+ if len(query) < 3:
199
168
  raise ValueError(
200
- f"⚠️ Search term '{phrases}' too short. Try again with more semantica and descriptive phrases."
169
+ f"⚠️ Search term '{query}' too short. Try again with more semantica and descriptive phrases."
201
170
  )
202
171
 
203
172
  # Use provided agent_name or fallback to current agent
@@ -215,11 +184,11 @@ def get_memory_retrieve_tool_handler(memory_service: BaseMemoryService) -> Calla
215
184
  )
216
185
 
217
186
  result = memory_service.retrieve_memory(
218
- phrases, from_date, to_date, agent_name
187
+ query, from_date, to_date, agent_name
219
188
  )
220
189
 
221
190
  if not result or result.strip() == "":
222
- return f"📝 No memories found for '{phrases}'. Try broader phrases or related terms."
191
+ return f"📝 No memories found for '{query}'. Try broader phrases or related terms."
223
192
 
224
193
  # Count memories for user feedback
225
194
  return f"📚 Found relevant memories:\n\n{result}"
@@ -260,7 +229,7 @@ All behaviors must follow 'when..., [action]...' format for automatic activation
260
229
 
261
230
  if provider == "claude":
262
231
  return {
263
- "name": "adapt",
232
+ "name": "adapt_behavior",
264
233
  "description": tool_description,
265
234
  "input_schema": {
266
235
  "type": "object",
@@ -272,7 +241,7 @@ All behaviors must follow 'when..., [action]...' format for automatic activation
272
241
  return {
273
242
  "type": "function",
274
243
  "function": {
275
- "name": "adapt",
244
+ "name": "adapt_behavior",
276
245
  "description": tool_description,
277
246
  "parameters": {
278
247
  "type": "object",
@@ -35,7 +35,7 @@ def get_web_search_tool_definition(provider="claude"):
35
35
  tool_required = ["query", "search_depth", "topic"]
36
36
  if provider == "claude":
37
37
  return {
38
- "name": "web_search",
38
+ "name": "search_web",
39
39
  "description": tool_description,
40
40
  "input_schema": {
41
41
  "type": "object",
@@ -47,7 +47,7 @@ def get_web_search_tool_definition(provider="claude"):
47
47
  return {
48
48
  "type": "function",
49
49
  "function": {
50
- "name": "web_search",
50
+ "name": "search_web",
51
51
  "description": tool_description,
52
52
  "parameters": {
53
53
  "type": "object",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentcrew-ai
3
- Version: 0.8.1
3
+ Version: 0.8.2
4
4
  Summary: Multi-Agents Interactive Chat Tool
5
5
  Author-email: Quy Truong <quy.truong@saigontechnology.com>
6
6
  License-Expression: Apache-2.0
@@ -1,4 +1,4 @@
1
- AgentCrew/__init__.py,sha256=Ocl79hbbH8_jdr5dGC90VR1cAvZc05Rc0tkZttUnMjo,22
1
+ AgentCrew/__init__.py,sha256=B7GiO0rd49YwtLYjvPg4lmCZEDlMTonslQKdSImaMJk,22
2
2
  AgentCrew/app.py,sha256=dXjwoHLKf1tSOq1Vc-9wsF1dpjS5CaGqdiFSksKKwKA,36584
3
3
  AgentCrew/main.py,sha256=oU49LxetLP7GNeCvrK_VeBtz0AbrNJTUKvm0GWHboDE,11170
4
4
  AgentCrew/main_docker.py,sha256=1jpB-XOm-t3GWTKYidGHHkCSzJ-p39ua0E6-_Nj8_9Y,5472
@@ -34,8 +34,8 @@ AgentCrew/modules/browser_automation/__init__.py,sha256=1Qq6Rqz4Mv4arPKWKSDgIOV-
34
34
  AgentCrew/modules/browser_automation/chrome_manager.py,sha256=iBFcImVoeUF5qc8eRzSsihuBSiPhDF0DOSYfda7OHas,11901
35
35
  AgentCrew/modules/browser_automation/element_extractor.py,sha256=5gIoOahm9V7tL28GZ2fCbahxSlYzujW2EQpP70INUTM,15822
36
36
  AgentCrew/modules/browser_automation/js_loader.py,sha256=dQZxVymTPNOmf0_S5OJAHbyxMyf3D__A-XcnLCTcODo,7588
37
- AgentCrew/modules/browser_automation/service.py,sha256=pRBiVeB1oFLKGTdgxIF5nNMM8n5xvZUMNsVylcf-vyY,36145
38
- AgentCrew/modules/browser_automation/tool.py,sha256=RL59WqcXaLY0MJpT-nzQPrUDMVlkGxsie9Ta2YY5Q90,23799
37
+ AgentCrew/modules/browser_automation/service.py,sha256=FktcyBTq1oU9dQ3g6WDlF7wThCvi9bmUkNBTMMlgrOI,36427
38
+ AgentCrew/modules/browser_automation/tool.py,sha256=t2W2sjBT-xsFFT1hOsqfBZALzWehStJnW8GP_ZHUxTM,23819
39
39
  AgentCrew/modules/browser_automation/js/click_element.js,sha256=eNkbPX9wXyj9mPnfNILJjtbiPF0iKCT52bfTFQRhT1Y,1652
40
40
  AgentCrew/modules/browser_automation/js/extract_clickable_elements.js,sha256=kH2nF17hlrgKFZoglbFMUa7yD0u_dR2mLEnkgsT9-bM,5030
41
41
  AgentCrew/modules/browser_automation/js/extract_elements_by_text.js,sha256=HdGmCzYkqO0-6SqwmKsN0EBW9YfBgnMYYC8InVUmkWs,3263
@@ -51,13 +51,13 @@ AgentCrew/modules/chat/history.py,sha256=I7q1_s16h975uAtq6fxC4UcS9iuk1aUpKkMMYCc
51
51
  AgentCrew/modules/chat/message_handler.py,sha256=A8DfuIPjW0R7s3a0P8VzNa2PF6HgXcRt8CEm2nL8fEE,306
52
52
  AgentCrew/modules/chat/message/__init__.py,sha256=SllV6nacLgBSTwkUhI7VbEW-7gwQxQh6cCjRtbU02O8,146
53
53
  AgentCrew/modules/chat/message/base.py,sha256=Xnes4tQCfMfWShSHG8f3ZZ5y5Q0wTWy5g0EwnNmflK0,1016
54
- AgentCrew/modules/chat/message/command_processor.py,sha256=XCnDgK8gOyEFg7_W9kisZChA68Uj2yRDswWJZ0KZCa4,32656
54
+ AgentCrew/modules/chat/message/command_processor.py,sha256=YvXHEJs7tFUMze3uOKrlqZ6A-SC4u85Z759hTXEQ3BY,33214
55
55
  AgentCrew/modules/chat/message/conversation.py,sha256=-R2oIjstFBJS7xqP_9gVMAfiIcLOv7up1ZyL-ezLgRg,10741
56
56
  AgentCrew/modules/chat/message/handler.py,sha256=NOvOcS93WMf7ioeO1-8epqd2YMmaDNVOSPlnCO-CzGk,23606
57
57
  AgentCrew/modules/chat/message/tool_manager.py,sha256=JZTmAQ08MMO42t9FeSKYzuSunkaBVJaragDfZBnIEkM,12852
58
58
  AgentCrew/modules/clipboard/__init__.py,sha256=Xb0wwQ-9dwwLT3R3TYB87pwtDTNX5HAzhkr8iuR6mBc,77
59
59
  AgentCrew/modules/clipboard/service.py,sha256=FCo3zSJH0zDdvW73u4D_ty9fTMsXmOeVsAIOfyJ54Ws,6246
60
- AgentCrew/modules/clipboard/tool.py,sha256=ooyjVAZZ4_nHP11hjirQVehOMaEP_QvKqmC_fPc-1ss,5474
60
+ AgentCrew/modules/clipboard/tool.py,sha256=RMu6Cr5wP79SvfOqojAbu6g1WxBw6EUS4Mdfdr9VEuY,5474
61
61
  AgentCrew/modules/code_analysis/__init__.py,sha256=veGcJQiv2eR2YNRWM1xNhA0WkmEkkL3OLst1uSM-OyM,83
62
62
  AgentCrew/modules/code_analysis/service.py,sha256=macEJDRI1umacpxyf6PbI9fAYKTvhPC6_1hAabWL_sI,62047
63
63
  AgentCrew/modules/code_analysis/tool.py,sha256=Vc33YMBAuZkghw6My-2ZwsRmuNo7v-nr1RnatVEVSGo,6234
@@ -73,13 +73,13 @@ AgentCrew/modules/console/__init__.py,sha256=nO53lUaMEAshdIqDEmgNZ_r35jyg6CuMa7T
73
73
  AgentCrew/modules/console/command_handlers.py,sha256=fkc5mUm6Etw93InaF55kfmBrdDfPDsPloZKMrIABQEw,9675
74
74
  AgentCrew/modules/console/completers.py,sha256=0iYfNv0MmlqXmGOgQfOIp5drGjAZNbPVimR4MdZE5U4,14866
75
75
  AgentCrew/modules/console/confirmation_handler.py,sha256=8xY_hdCqQ7DDrnPSU9rIPJ7AeM6Th2qlrOIZjSWVZPI,8406
76
- AgentCrew/modules/console/console_ui.py,sha256=A6aZfL-9GSbEQjWASeKgkUfbpy5sAVM0EVPbKglSbsE,26775
76
+ AgentCrew/modules/console/console_ui.py,sha256=mk0_n33gxK8f2tnHoSyrGateqxme8pKemfs_7VqLfhY,26841
77
77
  AgentCrew/modules/console/constants.py,sha256=fwLj52O96_t6m1qb0SOiaotM2dMLwXH83KAERm9ltLA,704
78
78
  AgentCrew/modules/console/conversation_handler.py,sha256=vVtGxQJ4sEZJ77svBFJMIGiWiEfE47yDxvt7gZ9bRCA,3632
79
79
  AgentCrew/modules/console/display_handlers.py,sha256=c3P65klqwtVXgjIhaAVUxPnTT1rEby2wyEHhaaPhVCw,17018
80
- AgentCrew/modules/console/input_handler.py,sha256=H2L4GEVpXyZE6ki8yHPXbNbUziA1bTn1uFa4WT9l4zI,17650
80
+ AgentCrew/modules/console/input_handler.py,sha256=N3FVZ7ToJpvyfPYLUhXeRN4bZu4KIf8lV_He8nVxY5w,18077
81
81
  AgentCrew/modules/console/tool_display.py,sha256=qMdtc7zIOTPEDwuia8um8fxtVyGxjwBTQMVsKSGRUB8,6107
82
- AgentCrew/modules/console/ui_effects.py,sha256=iOH1obwcA7yBylIieK07m_vZp74WMindBbQsnYtkaCw,7190
82
+ AgentCrew/modules/console/ui_effects.py,sha256=wnVP3OUVaJuJzH6c3y7ne8LHLIv53ik9hNQQfg7WaCY,7483
83
83
  AgentCrew/modules/console/utils.py,sha256=TFIyyYVFlWMB0FCAq4H09Yp6UCezUEHg3HNEZXuVmiA,273
84
84
  AgentCrew/modules/custom_llm/__init__.py,sha256=NvgE3c6rYd52SmRITqGeHqaGOnHrK9vU8RBqD9_6Mdo,337
85
85
  AgentCrew/modules/custom_llm/copilot_response_service.py,sha256=tySzxnLMzMt3WjwhvBegtDP7Qk43D2Wc5bxZAi0Z3sA,4605
@@ -90,7 +90,7 @@ AgentCrew/modules/file_editing/__init__.py,sha256=Q6oDyP3bHslFpmxHdrCCLVx1M_awaH
90
90
  AgentCrew/modules/file_editing/safety_validator.py,sha256=lLNb_GpIIX2QtN86U2NKbM-b3VYW3b6jNkXL5hKPlok,5575
91
91
  AgentCrew/modules/file_editing/search_replace_engine.py,sha256=i8e18VIvxOwCazjnfrmLp637laDCsJSpZs5YsW9Ic-Y,10751
92
92
  AgentCrew/modules/file_editing/service.py,sha256=bFpjUJgBO1dxZTidwNptv6o1U2oBg0lB50PHJA8-Jyo,9589
93
- AgentCrew/modules/file_editing/tool.py,sha256=xEw7vUn4ikdWfgaN86zG-WXQ7SdIjH7KHLv6vxkoolo,6165
93
+ AgentCrew/modules/file_editing/tool.py,sha256=DTYzAyA50VDBoZI58DWj50RrO-zbA18R8iBZP2qG9Aw,6165
94
94
  AgentCrew/modules/file_editing/tree_sitter_checker.py,sha256=riTzdwgvZ1Kp6gs0lVZNGD6LeN93bddO3obdXYh2iSE,5606
95
95
  AgentCrew/modules/google/__init__.py,sha256=gJoUxCrHb0QJ0S-HWxXJVfDUhgdaoiJ-eYMSzDndur4,143
96
96
  AgentCrew/modules/google/native_service.py,sha256=MSeukYxWVmn0V_MKzLzdcrhOU4COAt4TE9wtmm4W_OU,26744
@@ -154,15 +154,15 @@ AgentCrew/modules/mcpclient/__init__.py,sha256=Gd1y0YVgET37kQVo2HFfNzYRt_GnqCnQH
154
154
  AgentCrew/modules/mcpclient/auth.py,sha256=jxndVHc7oI_LaI0ckifFBLfpl_eJJBxu_UPC4OrGld0,15348
155
155
  AgentCrew/modules/mcpclient/config.py,sha256=9_Awetmzw2BO-0BAqZtPw35gDMpnVTVEs3wTesWMIPk,3193
156
156
  AgentCrew/modules/mcpclient/manager.py,sha256=mjdlr_cMXwjXsFOhMwHSF_K833hLXXCcvkTGOpe1YMI,7259
157
- AgentCrew/modules/mcpclient/service.py,sha256=7wBTc4fvgtpbzfccHwLYe-CAnbfgtEB38dzxkn75k58,33906
157
+ AgentCrew/modules/mcpclient/service.py,sha256=qNM2dBADzhffMvkzqamukQjl4xSGwP-IMN6wYe1E8Ek,33907
158
158
  AgentCrew/modules/mcpclient/tool.py,sha256=6VrwvZOvyVzvfsMYGvrHl8DmLzbjhLQ3q2KmtpbQE-I,805
159
159
  AgentCrew/modules/memory/__init__.py,sha256=1tdK0sybmY2c6y_rWFs2eF0Zy7vcEbGlwtIoF8BF0K4,251
160
- AgentCrew/modules/memory/base_service.py,sha256=FSzq4ZQ6f7l0ewot-teTptyaKjNJSUSLCYJwr2D0qDw,3617
161
- AgentCrew/modules/memory/chroma_service.py,sha256=IRSKOTl1dxe6B6kmYb646AgjLdVZa7RRZCuKQcvQh1o,26905
162
- AgentCrew/modules/memory/context_persistent.py,sha256=HbFnYSZuy5klOkzaCyFF0L2ypNJNV-iL_kRCnkPAEv4,22617
160
+ AgentCrew/modules/memory/base_service.py,sha256=BLp6QuJFu0hatPvEDcrwWwYvSVA8noe_xZk2onqcoXU,4115
161
+ AgentCrew/modules/memory/chroma_service.py,sha256=4ISlSz7tiHF6i78F0T0P7xj2AhTE1NvjjbNr8eONx7U,27829
162
+ AgentCrew/modules/memory/context_persistent.py,sha256=0BrxRY0O_9bEnTY3GQL3E2WedOiEDKZnoQJB5IieMbA,22699
163
163
  AgentCrew/modules/memory/github_copilot_ef.py,sha256=NGIKG8G602cF1nR9QRHgGUwCToyKcx6Aw5I_YVRX7VI,9522
164
164
  AgentCrew/modules/memory/google_genai_ef.py,sha256=8_c9MOR3HNJ-m-KT35eOUGHsN_wswPvjcpRhxFRgE1s,5124
165
- AgentCrew/modules/memory/tool.py,sha256=JQ2RVVwknIdopL9iISPONxnGs5cJpKyCAnj3gg02T40,14561
165
+ AgentCrew/modules/memory/tool.py,sha256=7b6KWpY24e8ei2SNSdCRW2CAPcyZR_j0vrbjO0bcyYU,13211
166
166
  AgentCrew/modules/memory/voyageai_ef.py,sha256=X9znUSfT9Ozd-l1Ak9ulBAZzfGu9G9W18V8XKdIytWk,4508
167
167
  AgentCrew/modules/openai/__init__.py,sha256=w5Ytp3ckIsrcrkyaQl0OWWTHlulqBT7sYEYhxkYaOmE,141
168
168
  AgentCrew/modules/openai/response_service.py,sha256=hBzMfBr9GAMwgbYwH1s6Z-WiqY_wtfhnfeRHhmw2h0Y,24696
@@ -180,10 +180,10 @@ AgentCrew/modules/voice/elevenlabs_service.py,sha256=kjeE_yDcogTLsmsDqYcAPu20e7e
180
180
  AgentCrew/modules/voice/text_cleaner.py,sha256=NgAVBPkP2hFI330nJOyMK_oqP3R2AGZ2299u2f8TQww,3601
181
181
  AgentCrew/modules/web_search/__init__.py,sha256=sVf_z6nH2JghK46pG92PUtDghPIkceiX1F0Ul30euXU,111
182
182
  AgentCrew/modules/web_search/service.py,sha256=DKcOdRSHB5AEvbK8pvTXdffSnk6rFRTzaM1FXf2B70E,4006
183
- AgentCrew/modules/web_search/tool.py,sha256=UVM_h3o1ybNIO64-S8W77TdFF--vLhnYVynbwdffQvU,6655
184
- agentcrew_ai-0.8.1.dist-info/licenses/LICENSE,sha256=O51CIaOUcxVLNf0_PE_a8ap5bf3iXe4SrWN_5NO1PSU,11348
185
- agentcrew_ai-0.8.1.dist-info/METADATA,sha256=nqKg4XGapDJH2FMe8QxljqPpAu-fZucfoOw4dAyijII,18056
186
- agentcrew_ai-0.8.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
187
- agentcrew_ai-0.8.1.dist-info/entry_points.txt,sha256=N9R5jslrBYA8dTaNMRJ_JdSosJ6jkpGEtnJFzlcZD6k,54
188
- agentcrew_ai-0.8.1.dist-info/top_level.txt,sha256=bSsmhCOn6g-JytoVMpxB_QAnCgb7lV56fcnxUhbfrvg,10
189
- agentcrew_ai-0.8.1.dist-info/RECORD,,
183
+ AgentCrew/modules/web_search/tool.py,sha256=GV4xleVFs0UwiPS9toSzPzZei3ehsDZWxTQCJCRaEs8,6655
184
+ agentcrew_ai-0.8.2.dist-info/licenses/LICENSE,sha256=O51CIaOUcxVLNf0_PE_a8ap5bf3iXe4SrWN_5NO1PSU,11348
185
+ agentcrew_ai-0.8.2.dist-info/METADATA,sha256=c7mf6hUjmyfldtqMv1mwwXi4hPoceV9XkEChEZkCCtI,18056
186
+ agentcrew_ai-0.8.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
187
+ agentcrew_ai-0.8.2.dist-info/entry_points.txt,sha256=N9R5jslrBYA8dTaNMRJ_JdSosJ6jkpGEtnJFzlcZD6k,54
188
+ agentcrew_ai-0.8.2.dist-info/top_level.txt,sha256=bSsmhCOn6g-JytoVMpxB_QAnCgb7lV56fcnxUhbfrvg,10
189
+ agentcrew_ai-0.8.2.dist-info/RECORD,,