webagents 0.1.13__py3-none-any.whl → 0.2.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.
Files changed (77) hide show
  1. webagents/__init__.py +1 -1
  2. webagents/__main__.py +55 -0
  3. webagents/agents/__init__.py +1 -1
  4. webagents/agents/core/__init__.py +1 -1
  5. webagents/agents/core/base_agent.py +15 -15
  6. webagents/agents/core/handoffs.py +1 -1
  7. webagents/agents/skills/__init__.py +11 -11
  8. webagents/agents/skills/base.py +1 -1
  9. webagents/agents/skills/core/llm/litellm/__init__.py +1 -1
  10. webagents/agents/skills/core/llm/litellm/skill.py +1 -1
  11. webagents/agents/skills/core/mcp/README.md +2 -2
  12. webagents/agents/skills/core/mcp/skill.py +2 -2
  13. webagents/agents/skills/core/memory/long_term_memory/memory_skill.py +14 -14
  14. webagents/agents/skills/core/memory/short_term_memory/__init__.py +1 -1
  15. webagents/agents/skills/core/memory/short_term_memory/skill.py +1 -1
  16. webagents/agents/skills/core/memory/vector_memory/skill.py +6 -6
  17. webagents/agents/skills/core/planning/__init__.py +1 -1
  18. webagents/agents/skills/ecosystem/crewai/__init__.py +3 -1
  19. webagents/agents/skills/ecosystem/crewai/skill.py +158 -0
  20. webagents/agents/skills/ecosystem/database/__init__.py +3 -1
  21. webagents/agents/skills/ecosystem/database/skill.py +522 -0
  22. webagents/agents/skills/ecosystem/google/calendar/skill.py +1 -1
  23. webagents/agents/skills/ecosystem/mongodb/__init__.py +3 -0
  24. webagents/agents/skills/ecosystem/mongodb/skill.py +428 -0
  25. webagents/agents/skills/ecosystem/n8n/README.md +287 -0
  26. webagents/agents/skills/ecosystem/n8n/__init__.py +3 -0
  27. webagents/agents/skills/ecosystem/n8n/skill.py +341 -0
  28. webagents/agents/skills/ecosystem/x_com/README.md +401 -0
  29. webagents/agents/skills/ecosystem/x_com/__init__.py +3 -0
  30. webagents/agents/skills/ecosystem/x_com/skill.py +1048 -0
  31. webagents/agents/skills/ecosystem/zapier/README.md +363 -0
  32. webagents/agents/skills/ecosystem/zapier/__init__.py +3 -0
  33. webagents/agents/skills/ecosystem/zapier/skill.py +337 -0
  34. webagents/agents/skills/robutler/__init__.py +2 -2
  35. webagents/agents/skills/robutler/auth/__init__.py +3 -3
  36. webagents/agents/skills/robutler/auth/skill.py +16 -16
  37. webagents/agents/skills/robutler/crm/__init__.py +2 -2
  38. webagents/agents/skills/robutler/crm/skill.py +5 -5
  39. webagents/agents/skills/robutler/discovery/README.md +5 -5
  40. webagents/agents/skills/robutler/discovery/__init__.py +2 -2
  41. webagents/agents/skills/robutler/discovery/skill.py +21 -21
  42. webagents/agents/skills/robutler/message_history/__init__.py +2 -2
  43. webagents/agents/skills/robutler/message_history/skill.py +5 -5
  44. webagents/agents/skills/robutler/nli/__init__.py +1 -1
  45. webagents/agents/skills/robutler/nli/skill.py +9 -9
  46. webagents/agents/skills/robutler/payments/__init__.py +3 -3
  47. webagents/agents/skills/robutler/payments/exceptions.py +1 -1
  48. webagents/agents/skills/robutler/payments/skill.py +23 -23
  49. webagents/agents/skills/robutler/storage/__init__.py +2 -2
  50. webagents/agents/skills/robutler/storage/files/__init__.py +2 -2
  51. webagents/agents/skills/robutler/storage/files/skill.py +4 -4
  52. webagents/agents/skills/robutler/storage/json/__init__.py +1 -1
  53. webagents/agents/skills/robutler/storage/json/skill.py +3 -3
  54. webagents/agents/skills/robutler/storage/kv/skill.py +3 -3
  55. webagents/agents/skills/robutler/storage.py +6 -6
  56. webagents/agents/tools/decorators.py +12 -12
  57. webagents/server/__init__.py +3 -3
  58. webagents/server/context/context_vars.py +2 -2
  59. webagents/server/core/app.py +13 -13
  60. webagents/server/core/middleware.py +3 -3
  61. webagents/server/core/models.py +1 -1
  62. webagents/server/core/monitoring.py +2 -2
  63. webagents/server/middleware.py +1 -1
  64. webagents/server/models.py +2 -2
  65. webagents/server/monitoring.py +15 -15
  66. webagents/utils/logging.py +20 -20
  67. webagents-0.2.2.dist-info/METADATA +266 -0
  68. webagents-0.2.2.dist-info/RECORD +105 -0
  69. webagents-0.2.2.dist-info/licenses/LICENSE +20 -0
  70. webagents/api/__init__.py +0 -17
  71. webagents/api/client.py +0 -1207
  72. webagents/api/types.py +0 -253
  73. webagents-0.1.13.dist-info/METADATA +0 -32
  74. webagents-0.1.13.dist-info/RECORD +0 -96
  75. webagents-0.1.13.dist-info/licenses/LICENSE +0 -1
  76. {webagents-0.1.13.dist-info → webagents-0.2.2.dist-info}/WHEEL +0 -0
  77. {webagents-0.1.13.dist-info → webagents-0.2.2.dist-info}/entry_points.txt +0 -0
webagents/__init__.py CHANGED
@@ -1,5 +1,5 @@
1
1
  """
2
- Robutler V2.0 - AI Agent Framework
2
+ WebAgents V2.0 - AI Agent Framework
3
3
 
4
4
  A comprehensive framework for building AI agents with skills, tools, handoffs,
5
5
  and seamless integration with LLM providers.
webagents/__main__.py ADDED
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ WebAgents CLI Entry Point
4
+
5
+ Command-line interface for the WebAgents framework.
6
+ """
7
+
8
+ import sys
9
+ import argparse
10
+ from webagents.server.core.app import WebAgentsServer
11
+ from webagents.utils.logging import setup_logging
12
+
13
+
14
+ def main():
15
+ """Main entry point for the webagents CLI."""
16
+ parser = argparse.ArgumentParser(description="WebAgents - AI Agent Framework")
17
+ parser.add_argument(
18
+ "--server",
19
+ action="store_true",
20
+ help="Start the WebAgents server"
21
+ )
22
+ parser.add_argument(
23
+ "--port",
24
+ type=int,
25
+ default=8000,
26
+ help="Port to run the server on (default: 8000)"
27
+ )
28
+ parser.add_argument(
29
+ "--host",
30
+ default="0.0.0.0",
31
+ help="Host to bind the server to (default: 0.0.0.0)"
32
+ )
33
+ parser.add_argument(
34
+ "--debug",
35
+ action="store_true",
36
+ help="Enable debug logging"
37
+ )
38
+
39
+ args = parser.parse_args()
40
+
41
+ # Setup logging
42
+ setup_logging(debug=args.debug)
43
+
44
+ if args.server:
45
+ # Start the server
46
+ server = WebAgentsServer()
47
+ server.run(host=args.host, port=args.port)
48
+ else:
49
+ print("WebAgents - AI Agent Framework")
50
+ print("Use --server to start the server")
51
+ print("Use --help for more options")
52
+
53
+
54
+ if __name__ == "__main__":
55
+ main()
@@ -1,5 +1,5 @@
1
1
  """
2
- Robutler V2.0 Agents Module
2
+ WebAgents V2.0 Agents Module
3
3
 
4
4
  Core agent system including BaseAgent, skills, tools, handoffs, and lifecycle management.
5
5
  """
@@ -1,5 +1,5 @@
1
1
  """
2
- Robutler V2.0 Core Agent Module
2
+ WebAgents V2.0 Core Agent Module
3
3
 
4
4
  Contains the core agent implementation and supporting systems:
5
5
  - BaseAgent: Main agent class with tool/hook/handoff registration
@@ -1,5 +1,5 @@
1
1
  """
2
- BaseAgent - Robutler V2.0 Core Agent Implementation
2
+ BaseAgent - WebAgents V2.0 Core Agent Implementation
3
3
 
4
4
  Central agent implementation with automatic decorator registration,
5
5
  unified context management, and comprehensive tool/hook/handoff execution.
@@ -158,7 +158,7 @@ class BaseAgent:
158
158
  level = getattr(logging, log_level, logging.INFO)
159
159
  # If using a LoggerAdapter (e.g., AgentContextAdapter), operate on the underlying logger
160
160
  base_logger = self.logger.logger if isinstance(self.logger, logging.LoggerAdapter) else self.logger
161
- # Set desired level and let it propagate to 'robutler' logger configured by setup_logging
161
+ # Set desired level and let it propagate to 'webagents' logger configured by setup_logging
162
162
  base_logger.setLevel(level)
163
163
  base_logger.propagate = True
164
164
 
@@ -218,7 +218,7 @@ class BaseAgent:
218
218
  # For agent-level tools, inheritance logic:
219
219
  # - Decorated tools (@tool) keep their own scope (even default "all")
220
220
  # - Undecorated tools inherit agent scopes
221
- if hasattr(tool_func, '_robutler_is_tool') and tool_func._robutler_is_tool:
221
+ if hasattr(tool_func, '_webagents_is_tool') and tool_func._webagents_is_tool:
222
222
  # Tool is decorated - keep its own scope
223
223
  scope = tool_func._tool_scope
224
224
  else:
@@ -253,7 +253,7 @@ class BaseAgent:
253
253
  # Direct Handoff object
254
254
  self.register_handoff(handoff_item, source="agent")
255
255
  self.logger.debug(f"📨 Registered handoff target='{handoff_item.target}' type='{handoff_item.handoff_type}'")
256
- elif callable(handoff_item) and hasattr(handoff_item, '_robutler_is_handoff'):
256
+ elif callable(handoff_item) and hasattr(handoff_item, '_webagents_is_handoff'):
257
257
  # Function with @handoff decorator
258
258
  handoff_config = Handoff(
259
259
  target=getattr(handoff_item, '_handoff_name', handoff_item.__name__),
@@ -277,13 +277,13 @@ class BaseAgent:
277
277
  for capability_func in capabilities:
278
278
  if callable(capability_func):
279
279
  # Attempt to determine decorator type
280
- if hasattr(capability_func, '_robutler_is_tool') and capability_func._robutler_is_tool:
280
+ if hasattr(capability_func, '_webagents_is_tool') and capability_func._webagents_is_tool:
281
281
  self.register_tool(capability_func, source="agent")
282
- elif hasattr(capability_func, '_robutler_is_hook') and capability_func._robutler_is_hook:
282
+ elif hasattr(capability_func, '_webagents_is_hook') and capability_func._webagents_is_hook:
283
283
  priority = getattr(capability_func, '_hook_priority', 50)
284
284
  scope = getattr(capability_func, '_hook_scope', self.scopes)
285
285
  self.register_hook(getattr(capability_func, '_hook_event_type', 'on_request'), capability_func, priority, source="agent", scope=scope)
286
- elif hasattr(capability_func, '_robutler_is_handoff') and capability_func._robutler_is_handoff:
286
+ elif hasattr(capability_func, '_webagents_is_handoff') and capability_func._webagents_is_handoff:
287
287
  handoff_config = Handoff(
288
288
  target=getattr(capability_func, '_handoff_name', capability_func.__name__),
289
289
  handoff_type=getattr(capability_func, '_handoff_type', 'agent'),
@@ -292,7 +292,7 @@ class BaseAgent:
292
292
  )
293
293
  handoff_config.metadata = {'function': capability_func}
294
294
  self.register_handoff(handoff_config, source="agent")
295
- elif hasattr(capability_func, '_robutler_is_http') and capability_func._robutler_is_http:
295
+ elif hasattr(capability_func, '_webagents_is_http') and capability_func._webagents_is_http:
296
296
  self.register_http_handler(capability_func)
297
297
  self.logger.debug(f"🌐 Registered HTTP capability subpath='{getattr(capability_func, '_http_subpath', '<unknown>')}' method='{getattr(capability_func, '_http_method', 'get')}'")
298
298
 
@@ -360,25 +360,25 @@ class BaseAgent:
360
360
  continue
361
361
 
362
362
  # Check for @hook decorator
363
- if hasattr(attr, '_robutler_is_hook') and attr._robutler_is_hook:
363
+ if hasattr(attr, '_webagents_is_hook') and attr._webagents_is_hook:
364
364
  event_type = attr._hook_event_type
365
365
  priority = getattr(attr, '_hook_priority', 50)
366
366
  scope = getattr(attr, '_hook_scope', None)
367
367
  self.register_hook(event_type, attr, priority, source=skill_name, scope=scope)
368
368
 
369
369
  # Check for @tool decorator
370
- elif hasattr(attr, '_robutler_is_tool') and attr._robutler_is_tool:
370
+ elif hasattr(attr, '_webagents_is_tool') and attr._webagents_is_tool:
371
371
  scope = getattr(attr, '_tool_scope', None)
372
372
  self.register_tool(attr, source=skill_name, scope=scope)
373
373
 
374
374
  # Check for @prompt decorator
375
- elif hasattr(attr, '_robutler_is_prompt') and attr._robutler_is_prompt:
375
+ elif hasattr(attr, '_webagents_is_prompt') and attr._webagents_is_prompt:
376
376
  priority = getattr(attr, '_prompt_priority', 50)
377
377
  scope = getattr(attr, '_prompt_scope', None)
378
378
  self.register_prompt(attr, priority, source=skill_name, scope=scope)
379
379
 
380
380
  # Check for @handoff decorator
381
- elif hasattr(attr, '_robutler_is_handoff') and attr._robutler_is_handoff:
381
+ elif hasattr(attr, '_webagents_is_handoff') and attr._webagents_is_handoff:
382
382
  handoff_config = Handoff(
383
383
  target=getattr(attr, '_handoff_name', attr_name),
384
384
  handoff_type=getattr(attr, '_handoff_type', 'agent'),
@@ -389,7 +389,7 @@ class BaseAgent:
389
389
  self.register_handoff(handoff_config, source=skill_name)
390
390
 
391
391
  # Check for @http decorator
392
- elif hasattr(attr, '_robutler_is_http') and attr._robutler_is_http:
392
+ elif hasattr(attr, '_webagents_is_http') and attr._webagents_is_http:
393
393
  self.register_http_handler(attr, source=skill_name)
394
394
 
395
395
  # Central registration methods (thread-safe)
@@ -402,7 +402,7 @@ class BaseAgent:
402
402
  'scope': scope,
403
403
  'name': getattr(tool_func, '_tool_name', tool_func.__name__),
404
404
  'description': getattr(tool_func, '_tool_description', tool_func.__doc__ or ''),
405
- 'definition': getattr(tool_func, '_robutler_tool_definition', {})
405
+ 'definition': getattr(tool_func, '_webagents_tool_definition', {})
406
406
  }
407
407
  self._registered_tools.append(tool_config)
408
408
  self.logger.debug(f"🛠️ Tool registered name='{tool_config['name']}' source='{source}' scope={scope}")
@@ -451,7 +451,7 @@ class BaseAgent:
451
451
 
452
452
  def register_http_handler(self, handler_func: Callable, source: str = "manual"):
453
453
  """Register an HTTP handler function with conflict detection"""
454
- if not hasattr(handler_func, '_robutler_is_http'):
454
+ if not hasattr(handler_func, '_webagents_is_http'):
455
455
  raise ValueError(f"Function {handler_func.__name__} is not decorated with @http")
456
456
 
457
457
  subpath = getattr(handler_func, '_http_subpath')
@@ -1,5 +1,5 @@
1
1
  """
2
- Agent Handoffs - Robutler V2.0
2
+ Agent Handoffs - WebAgents V2.0
3
3
 
4
4
  LocalAgentHandoff implementation for same-instance agent transfers.
5
5
  Provides basic agent-to-agent handoff functionality within a single server instance.
@@ -1,7 +1,7 @@
1
1
  """
2
- Robutler Agents Skills
2
+ WebAgents Agents Skills
3
3
 
4
- This module provides the skill system for Robutler agents, including core skills,
4
+ This module provides the skill system for WebAgents agents, including core skills,
5
5
  platform skills, and ecosystem skills. Skills are modular components that provide
6
6
  specific functionality to agents.
7
7
  """
@@ -16,10 +16,10 @@ CORE_SKILLS = {
16
16
  "litellm": LiteLLMSkill,
17
17
  }
18
18
 
19
- # Import Robutler platform skills
19
+ # Import WebAgents platform skills
20
20
  from .robutler.crm import CRMAnalyticsSkill
21
21
 
22
- # Robutler platform skills - these integrate with Robutler services
22
+ # WebAgents platform skills - these integrate with WebAgents services
23
23
  ROBUTLER_SKILLS = {
24
24
  "crm": CRMAnalyticsSkill,
25
25
  "analytics": CRMAnalyticsSkill, # Alias for convenience
@@ -74,13 +74,13 @@ def get_skill(skill_name: str):
74
74
 
75
75
  # Lazy load ecosystem skills
76
76
  ecosystem_imports = {
77
- "google": ("robutler.agents.skills.ecosystem.google", "GoogleSkill"),
78
- "database": ("robutler.agents.skills.ecosystem.database", "DatabaseSkill"),
79
- "filesystem": ("robutler.agents.skills.ecosystem.filesystem", "FilesystemSkill"),
80
- "web": ("robutler.agents.skills.ecosystem.web", "WebSkill"),
81
- "crewai": ("robutler.agents.skills.ecosystem.crewai", "CrewAISkill"),
82
- "n8n": ("robutler.agents.skills.ecosystem.n8n", "N8nSkill"),
83
- "zapier": ("robutler.agents.skills.ecosystem.zapier", "ZapierSkill"),
77
+ "google": ("webagents.agents.skills.ecosystem.google", "GoogleSkill"),
78
+ "database": ("webagents.agents.skills.ecosystem.database", "DatabaseSkill"),
79
+ "filesystem": ("webagents.agents.skills.ecosystem.filesystem", "FilesystemSkill"),
80
+ "web": ("webagents.agents.skills.ecosystem.web", "WebSkill"),
81
+ "crewai": ("webagents.agents.skills.ecosystem.crewai", "CrewAISkill"),
82
+ "n8n": ("webagents.agents.skills.ecosystem.n8n", "N8nSkill"),
83
+ "zapier": ("webagents.agents.skills.ecosystem.zapier", "ZapierSkill"),
84
84
  }
85
85
 
86
86
  if skill_name in ecosystem_imports:
@@ -1,5 +1,5 @@
1
1
  """
2
- Base Skill Interface - Robutler V2.0
2
+ Base Skill Interface - WebAgents V2.0
3
3
 
4
4
  Core skill interface with unified context access, automatic registration support,
5
5
  and dependency resolution.
@@ -1,5 +1,5 @@
1
1
  """
2
- LiteLLM Skill Package - Robutler V2.0
2
+ LiteLLM Skill Package - WebAgents V2.0
3
3
 
4
4
  Cross-provider LLM routing with support for OpenAI, Anthropic, XAI/Grok, and more.
5
5
  Provides unified interface for multiple LLM providers with automatic fallbacks.
@@ -1,5 +1,5 @@
1
1
  """
2
- LiteLLM Skill - Robutler V2.0
2
+ LiteLLM Skill - WebAgents V2.0
3
3
 
4
4
  Cross-provider LLM routing using LiteLLM for unified access to:
5
5
  - OpenAI (GPT-4, GPT-3.5, etc.)
@@ -63,8 +63,8 @@ The `MCPSkill` provides comprehensive **Model Context Protocol (MCP) integration
63
63
  ### Basic Configuration
64
64
 
65
65
  ```python
66
- from robutler.agents import BaseAgent
67
- from robutler.agents.skills.core.mcp import MCPSkill
66
+ from webagents.agents import BaseAgent
67
+ from webagents.agents.skills.core.mcp import MCPSkill
68
68
 
69
69
  # Configure MCP skill with servers
70
70
  mcp_config = {
@@ -346,7 +346,7 @@ class MCPSkill(Skill):
346
346
 
347
347
  # Set tool attributes for registration
348
348
  dynamic_tool_func.__name__ = dynamic_tool_name
349
- dynamic_tool_func._robutler_is_tool = True
349
+ dynamic_tool_func._webagents_is_tool = True
350
350
  dynamic_tool_func._tool_scope = "all"
351
351
 
352
352
  # Convert MCP tool schema to OpenAI format
@@ -362,7 +362,7 @@ class MCPSkill(Skill):
362
362
  }
363
363
  }
364
364
 
365
- dynamic_tool_func._robutler_tool_definition = openai_schema
365
+ dynamic_tool_func._webagents_tool_definition = openai_schema
366
366
 
367
367
  # Store and register the dynamic tool
368
368
  self.dynamic_tools[dynamic_tool_name] = dynamic_tool_func
@@ -2,7 +2,7 @@
2
2
  LongTermMemorySkill - Persistent Memory Management
3
3
 
4
4
  Automatically extracts and stores key facts, preferences, and context
5
- from conversations for future reference using Robutler portal storage
5
+ from conversations for future reference using WebAgents portal storage
6
6
  via dependencies.
7
7
  """
8
8
 
@@ -37,7 +37,7 @@ class MemoryItem:
37
37
 
38
38
  class LongTermMemorySkill(Skill):
39
39
  """
40
- Long-term memory management skill with robutler portal integration via dependencies.
40
+ Long-term memory management skill with webagents portal integration via dependencies.
41
41
 
42
42
  Features:
43
43
  - Automatic memory extraction from conversations
@@ -45,14 +45,14 @@ class LongTermMemorySkill(Skill):
45
45
  - Importance scoring and prioritization
46
46
  - Searchable memory retrieval
47
47
  - Memory cleanup and maintenance
48
- - Integration with robutler portal storage via dependencies
48
+ - Integration with webagents portal storage via dependencies
49
49
  """
50
50
 
51
51
  def __init__(self, config: Optional[Dict[str, Any]] = None):
52
52
  super().__init__(config)
53
53
  self.max_memories = config.get('max_memories', 100) if config else 100
54
54
  self.auto_extract = config.get('auto_extract', True) if config else True
55
- self.use_robutler_storage = config.get('use_robutler_storage', True) if config else True
55
+ self.use_webagents_storage = config.get('use_webagents_storage', True) if config else True
56
56
  self.fallback_file = config.get('fallback_file', '/tmp/agent_memory.json') if config else '/tmp/agent_memory.json'
57
57
  self.memories: Dict[str, MemoryItem] = {}
58
58
  self.agent_name = config.get('agent_name', 'default_agent') if config else 'default_agent'
@@ -71,8 +71,8 @@ class LongTermMemorySkill(Skill):
71
71
  self.agent_name = agent_reference.name
72
72
 
73
73
  # Get JSON storage from dependencies
74
- if 'robutler.json_storage' in self.dependencies:
75
- self.storage = self.dependencies['robutler.json_storage']
74
+ if 'webagents.json_storage' in self.dependencies:
75
+ self.storage = self.dependencies['webagents.json_storage']
76
76
  elif hasattr(agent_reference, 'skills') and 'json_storage' in agent_reference.skills:
77
77
  # Fallback to agent skills
78
78
  self.storage = agent_reference.skills['json_storage']
@@ -267,7 +267,7 @@ EXAMPLE TRIGGERS:
267
267
  # Sort by importance and access count
268
268
  filtered_memories.sort(key=lambda x: (x['importance'], x['access_count']), reverse=True)
269
269
 
270
- storage_location = "robutler_json_storage" if self.storage else "local_file"
270
+ storage_location = "webagents_json_storage" if self.storage else "local_file"
271
271
 
272
272
  return json.dumps({
273
273
  "total_memories": len(self.memories),
@@ -392,7 +392,7 @@ EXAMPLE TRIGGERS:
392
392
  JSON string with memory statistics
393
393
  """
394
394
  try:
395
- storage_location = "robutler_json_storage" if self.storage else "local_file"
395
+ storage_location = "webagents_json_storage" if self.storage else "local_file"
396
396
 
397
397
  if not self.memories:
398
398
  return json.dumps({
@@ -548,7 +548,7 @@ EXAMPLE TRIGGERS:
548
548
  async def _load_memories(self):
549
549
  """Load memories from storage"""
550
550
  try:
551
- if self.use_robutler_storage and self.storage:
551
+ if self.use_webagents_storage and self.storage:
552
552
  # Try to load from webagents JSON storage
553
553
  result = await self.storage.retrieve_json_data(f"{self.agent_name}_memory.json")
554
554
  result_data = json.loads(result)
@@ -584,8 +584,8 @@ EXAMPLE TRIGGERS:
584
584
  }
585
585
  }
586
586
 
587
- if self.use_robutler_storage and self.storage:
588
- # Try to save to robutler JSON storage
587
+ if self.use_webagents_storage and self.storage:
588
+ # Try to save to webagents JSON storage
589
589
  result = await self.storage.store_json_data(
590
590
  f"{self.agent_name}_memory.json",
591
591
  data,
@@ -608,7 +608,7 @@ EXAMPLE TRIGGERS:
608
608
  """Get comprehensive skill information"""
609
609
  return {
610
610
  "name": "LongTermMemorySkill",
611
- "description": "Persistent long-term memory with robutler JSON storage via dependencies",
611
+ "description": "Persistent long-term memory with webagents JSON storage via dependencies",
612
612
  "version": "3.0.0",
613
613
  "capabilities": [
614
614
  "Automatic memory extraction from conversations",
@@ -616,7 +616,7 @@ EXAMPLE TRIGGERS:
616
616
  "Searchable memory retrieval",
617
617
  "Importance-based prioritization",
618
618
  "Memory cleanup and maintenance",
619
- "Robutler JSON storage integration via dependencies"
619
+ "WebAgents JSON storage integration via dependencies"
620
620
  ],
621
621
  "tools": [
622
622
  "extract_key_memories",
@@ -629,7 +629,7 @@ EXAMPLE TRIGGERS:
629
629
  "total_memories": len(self.memories),
630
630
  "categories": list(set(m.category for m in self.memories.values())) if self.memories else [],
631
631
  "config": {
632
- "use_robutler_storage": self.use_robutler_storage,
632
+ "use_webagents_storage": self.use_webagents_storage,
633
633
  "agent_name": self.agent_name,
634
634
  "max_memories": self.max_memories,
635
635
  "auto_extract": self.auto_extract,
@@ -1,5 +1,5 @@
1
1
  """
2
- Short-term Memory Skill Package - Robutler V2.0
2
+ Short-term Memory Skill Package - WebAgents V2.0
3
3
 
4
4
  Manages message context, conversation filtering, and immediate memory operations.
5
5
  """
@@ -1,5 +1,5 @@
1
1
  """
2
- Short-term Memory Skill - Robutler V2.0
2
+ Short-term Memory Skill - WebAgents V2.0
3
3
 
4
4
  Manages conversation context, message filtering, and immediate memory operations.
5
5
  Handles recent message history, context windowing, and conversation summarization.
@@ -10,11 +10,11 @@ Env configuration:
10
10
  - MILVUS_HOST (e.g., https://in03)
11
11
  - MILVUS_PORT (e.g., 443)
12
12
  - MILVUS_TOKEN (if required by Milvus/Cosmos)
13
- - MILVUS_COLLECTION (default: robutler_memory)
13
+ - MILVUS_COLLECTION (default: webagents_memory)
14
14
  - MILVUS_FORCE_RECREATE (truthy to recreate collection on init)
15
15
  - EMBEDDING_MODEL (default: text-embedding-3-small)
16
16
  - LITELLM_BASE_URL (default: http://localhost:2225)
17
- - LITELLM_API_KEY or ROBUTLER_API_KEY (bearer for embeddings)
17
+ - LITELLM_API_KEY or WEBAGENTS_API_KEY (bearer for embeddings)
18
18
  """
19
19
 
20
20
  from __future__ import annotations
@@ -58,16 +58,16 @@ class VectorMemorySkill(Skill):
58
58
  self.milvus_host = _get_env_str("MILVUS_HOST", "http://localhost")
59
59
  self.milvus_port = int(os.getenv("MILVUS_PORT", "19530"))
60
60
  self.milvus_token = _get_env_str("MILVUS_TOKEN")
61
- self.milvus_collection = _get_env_str("MILVUS_COLLECTION", "robutler_memory")
61
+ self.milvus_collection = _get_env_str("MILVUS_COLLECTION", "webagents_memory")
62
62
  self.milvus_force_recreate = _is_truthy(os.getenv("MILVUS_FORCE_RECREATE", "false"))
63
63
  # Embeddings config
64
64
  self.embed_model = _get_env_str("EMBEDDING_MODEL", "text-embedding-3-small")
65
65
  self.litellm_base = _get_env_str("LITELLM_BASE_URL", "http://localhost:2225")
66
- self.litellm_key = _get_env_str("LITELLM_API_KEY") or _get_env_str("ROBUTLER_API_KEY")
66
+ self.litellm_key = _get_env_str("LITELLM_API_KEY") or _get_env_str("WEBAGENTS_API_KEY")
67
67
 
68
68
  async def initialize(self, agent) -> None:
69
69
  self.agent = agent
70
- self.logger = get_logger('skill.robutler.vector_memory', agent.name)
70
+ self.logger = get_logger('skill.webagents.vector_memory', agent.name)
71
71
  if not _MILVUS_AVAILABLE:
72
72
  self.logger.warning("pymilvus not available; VectorMemorySkill disabled")
73
73
  return
@@ -96,7 +96,7 @@ class VectorMemorySkill(Skill):
96
96
  FieldSchema(name="content", dtype=DataType.VARCHAR, max_length=8192),
97
97
  FieldSchema(name="vector", dtype=DataType.FLOAT_VECTOR, dim=self.dim),
98
98
  ]
99
- schema = CollectionSchema(fields=fields, description="Robutler Vector Memory")
99
+ schema = CollectionSchema(fields=fields, description="WebAgents Vector Memory")
100
100
  self.collection = Collection(name=self.milvus_collection, schema=schema)
101
101
  try:
102
102
  self.collection.create_index(
@@ -1,5 +1,5 @@
1
1
  """
2
- Core Planning Skills - Robutler V2.0
2
+ Core Planning Skills - WebAgents V2.0
3
3
 
4
4
  Advanced task planning and orchestration capabilities.
5
5
  """
@@ -1 +1,3 @@
1
- # TODO: Implement CrewAI skill
1
+ from .skill import CrewAISkill
2
+
3
+ __all__ = ['CrewAISkill']
@@ -0,0 +1,158 @@
1
+ """
2
+ Simplified CrewAI Skill for WebAgents
3
+
4
+ This skill runs a pre-configured CrewAI crew with agents and tasks.
5
+ The crew configuration is provided during skill initialization.
6
+
7
+ Main use case: Execute a specific crew workflow on demand.
8
+ """
9
+
10
+ import os
11
+ import json
12
+ from typing import Dict, Any, Optional, List, Union
13
+ from datetime import datetime
14
+
15
+ from webagents.agents.skills.base import Skill
16
+ from webagents.agents.tools.decorators import tool, prompt
17
+
18
+ try:
19
+ from crewai import Agent, Task, Crew, Process
20
+ CREWAI_AVAILABLE = True
21
+ except ImportError:
22
+ CREWAI_AVAILABLE = False
23
+ Agent, Task, Crew, Process = None, None, None, None # type: ignore
24
+
25
+
26
+ class CrewAISkill(Skill):
27
+ """Simplified CrewAI skill for running pre-configured crews"""
28
+
29
+ def __init__(self, crew_or_config: Optional[Union[Dict[str, Any], Any]] = None):
30
+ super().__init__({}, scope="all")
31
+ if not CREWAI_AVAILABLE:
32
+ raise ImportError("CrewAI is not installed. Install with: pip install crewai")
33
+
34
+ # Handle both Crew object and configuration dictionary
35
+ if crew_or_config is None:
36
+ self.crew_config = {}
37
+ self.crew = None
38
+ elif hasattr(crew_or_config, 'agents') and hasattr(crew_or_config, 'tasks'):
39
+ # It's a Crew object
40
+ self.crew_config = {}
41
+ self.crew = crew_or_config
42
+ else:
43
+ # It's a configuration dictionary
44
+ self.crew_config = crew_or_config or {}
45
+ self.crew = None
46
+ self._setup_crew()
47
+
48
+ def get_dependencies(self) -> List[str]:
49
+ """Skill dependencies"""
50
+ return [] # No dependencies needed for simple crew execution
51
+
52
+ def _setup_crew(self):
53
+ """Set up the CrewAI crew from configuration"""
54
+ if not self.crew_config:
55
+ return
56
+
57
+ try:
58
+ # Get agents configuration
59
+ agents_config = self.crew_config.get('agents', [])
60
+ tasks_config = self.crew_config.get('tasks', [])
61
+ process_type = self.crew_config.get('process', 'sequential')
62
+
63
+ if not agents_config or not tasks_config:
64
+ return
65
+
66
+ # Create agents
67
+ agents = []
68
+ for agent_config in agents_config:
69
+ agent = Agent(
70
+ role=agent_config.get('role', 'Agent'),
71
+ goal=agent_config.get('goal', 'Complete assigned tasks'),
72
+ backstory=agent_config.get('backstory', 'An AI agent ready to help'),
73
+ verbose=agent_config.get('verbose', True),
74
+ allow_delegation=agent_config.get('allow_delegation', False)
75
+ )
76
+ agents.append(agent)
77
+
78
+ # Create tasks
79
+ tasks = []
80
+ for i, task_config in enumerate(tasks_config):
81
+ # Assign agent to task (default to first agent if not specified)
82
+ agent_index = task_config.get('agent_index', 0)
83
+ if agent_index >= len(agents):
84
+ agent_index = 0 # Fallback to first agent
85
+
86
+ task = Task(
87
+ description=task_config.get('description', f'Task {i+1}'),
88
+ agent=agents[agent_index],
89
+ expected_output=task_config.get('expected_output', 'Task completion')
90
+ )
91
+ tasks.append(task)
92
+
93
+ # Create crew
94
+ process = Process.sequential
95
+ if process_type.lower() == 'hierarchical':
96
+ process = Process.hierarchical
97
+
98
+ self.crew = Crew(
99
+ agents=agents,
100
+ tasks=tasks,
101
+ process=process,
102
+ verbose=self.crew_config.get('verbose', True)
103
+ )
104
+
105
+ # CrewAI crew initialized successfully
106
+
107
+ except Exception as e:
108
+ self.crew = None
109
+
110
+ @prompt(priority=40, scope=["owner", "all"])
111
+ def crewai_prompt(self) -> str:
112
+ """Prompt describing CrewAI capabilities"""
113
+ if not self.crew:
114
+ return """
115
+ CrewAI skill is available but no crew is configured.
116
+
117
+ To use CrewAI, initialize the skill with either:
118
+ 1. A CrewAI Crew object: CrewAISkill(crew)
119
+ 2. A crew configuration dictionary with agents, tasks, and process settings
120
+ """
121
+
122
+ agents_count = len(self.crew.agents) if self.crew else 0
123
+ tasks_count = len(self.crew.tasks) if self.crew else 0
124
+
125
+ return f"""
126
+ CrewAI multi-agent orchestration is ready. Available tool:
127
+
128
+ • crewai_run(inputs) - Execute the configured crew with the given inputs
129
+
130
+ Configured crew:
131
+ - {agents_count} agents with specialized roles
132
+ - {tasks_count} tasks in the workflow
133
+ - Ready to process your requests through collaborative AI agents
134
+
135
+ Provide inputs as a dictionary to run the crew workflow.
136
+ """
137
+
138
+ # Public tool
139
+ @tool(description="Execute the configured CrewAI crew with the given inputs")
140
+ async def crewai_run(self, inputs: Dict[str, Any]) -> str:
141
+ """Execute the configured CrewAI crew with the provided inputs"""
142
+ if not self.crew:
143
+ return "❌ No CrewAI crew configured. Please initialize the skill with a crew configuration."
144
+
145
+ if not inputs:
146
+ return "❌ Inputs are required to run the crew"
147
+
148
+ try:
149
+ # Execute the crew with inputs
150
+ result = self.crew.kickoff(inputs=inputs)
151
+
152
+ agents_count = len(self.crew.agents)
153
+ tasks_count = len(self.crew.tasks)
154
+
155
+ return f"✅ CrewAI execution completed successfully!\n👥 Agents: {agents_count}\n📝 Tasks: {tasks_count}\n\n📊 Result:\n{result}"
156
+
157
+ except Exception as e:
158
+ return f"❌ CrewAI execution failed: {str(e)}"
@@ -1 +1,3 @@
1
- # TODO: Implement Database skill
1
+ from .skill import SupabaseSkill
2
+
3
+ __all__ = ['SupabaseSkill']