webagents 0.1.12__py3-none-any.whl → 0.2.0__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.
- webagents/__init__.py +1 -1
- webagents/__main__.py +55 -0
- webagents/agents/__init__.py +1 -1
- webagents/agents/core/__init__.py +1 -1
- webagents/agents/core/base_agent.py +15 -15
- webagents/agents/core/handoffs.py +1 -1
- webagents/agents/skills/__init__.py +11 -11
- webagents/agents/skills/base.py +1 -1
- webagents/agents/skills/core/llm/litellm/__init__.py +1 -1
- webagents/agents/skills/core/llm/litellm/skill.py +1 -1
- webagents/agents/skills/core/mcp/README.md +2 -2
- webagents/agents/skills/core/mcp/skill.py +2 -2
- webagents/agents/skills/core/memory/long_term_memory/memory_skill.py +14 -14
- webagents/agents/skills/core/memory/short_term_memory/__init__.py +1 -1
- webagents/agents/skills/core/memory/short_term_memory/skill.py +1 -1
- webagents/agents/skills/core/memory/vector_memory/skill.py +6 -6
- webagents/agents/skills/core/planning/__init__.py +1 -1
- webagents/agents/skills/ecosystem/google/calendar/skill.py +1 -1
- webagents/agents/skills/robutler/__init__.py +2 -2
- webagents/agents/skills/robutler/auth/__init__.py +3 -3
- webagents/agents/skills/robutler/auth/skill.py +16 -16
- webagents/agents/skills/robutler/crm/__init__.py +2 -2
- webagents/agents/skills/robutler/crm/skill.py +5 -5
- webagents/agents/skills/robutler/discovery/README.md +5 -5
- webagents/agents/skills/robutler/discovery/__init__.py +2 -2
- webagents/agents/skills/robutler/discovery/skill.py +21 -21
- webagents/agents/skills/robutler/message_history/__init__.py +2 -2
- webagents/agents/skills/robutler/message_history/skill.py +5 -5
- webagents/agents/skills/robutler/nli/__init__.py +1 -1
- webagents/agents/skills/robutler/nli/skill.py +9 -9
- webagents/agents/skills/robutler/payments/__init__.py +3 -3
- webagents/agents/skills/robutler/payments/exceptions.py +1 -1
- webagents/agents/skills/robutler/payments/skill.py +23 -23
- webagents/agents/skills/robutler/storage/__init__.py +2 -2
- webagents/agents/skills/robutler/storage/files/__init__.py +2 -2
- webagents/agents/skills/robutler/storage/files/skill.py +4 -4
- webagents/agents/skills/robutler/storage/json/__init__.py +1 -1
- webagents/agents/skills/robutler/storage/json/skill.py +3 -3
- webagents/agents/skills/robutler/storage/kv/skill.py +3 -3
- webagents/agents/skills/robutler/storage.py +6 -6
- webagents/agents/tools/decorators.py +12 -12
- webagents/server/__init__.py +3 -3
- webagents/server/context/context_vars.py +2 -2
- webagents/server/core/app.py +13 -13
- webagents/server/core/middleware.py +3 -3
- webagents/server/core/models.py +1 -1
- webagents/server/core/monitoring.py +2 -2
- webagents/server/middleware.py +1 -1
- webagents/server/models.py +2 -2
- webagents/server/monitoring.py +15 -15
- webagents/utils/logging.py +20 -20
- webagents-0.2.0.dist-info/METADATA +242 -0
- webagents-0.2.0.dist-info/RECORD +94 -0
- webagents-0.2.0.dist-info/licenses/LICENSE +20 -0
- webagents/api/__init__.py +0 -17
- webagents/api/client.py +0 -1207
- webagents/api/types.py +0 -253
- webagents-0.1.12.dist-info/METADATA +0 -99
- webagents-0.1.12.dist-info/RECORD +0 -96
- webagents-0.1.12.dist-info/licenses/LICENSE +0 -1
- {webagents-0.1.12.dist-info → webagents-0.2.0.dist-info}/WHEEL +0 -0
- {webagents-0.1.12.dist-info → webagents-0.2.0.dist-info}/entry_points.txt +0 -0
webagents/__init__.py
CHANGED
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()
|
webagents/agents/__init__.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
"""
|
2
|
-
BaseAgent -
|
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 '
|
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, '
|
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, '
|
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, '
|
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, '
|
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, '
|
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, '
|
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, '
|
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, '
|
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, '
|
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, '
|
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, '
|
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, '
|
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, '
|
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,7 +1,7 @@
|
|
1
1
|
"""
|
2
|
-
|
2
|
+
WebAgents Agents Skills
|
3
3
|
|
4
|
-
This module provides the skill system for
|
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
|
19
|
+
# Import WebAgents platform skills
|
20
20
|
from .robutler.crm import CRMAnalyticsSkill
|
21
21
|
|
22
|
-
#
|
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": ("
|
78
|
-
"database": ("
|
79
|
-
"filesystem": ("
|
80
|
-
"web": ("
|
81
|
-
"crewai": ("
|
82
|
-
"n8n": ("
|
83
|
-
"zapier": ("
|
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:
|
webagents/agents/skills/base.py
CHANGED
@@ -63,8 +63,8 @@ The `MCPSkill` provides comprehensive **Model Context Protocol (MCP) integration
|
|
63
63
|
### Basic Configuration
|
64
64
|
|
65
65
|
```python
|
66
|
-
from
|
67
|
-
from
|
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.
|
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.
|
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
|
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
|
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
|
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.
|
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 '
|
75
|
-
self.storage = self.dependencies['
|
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 = "
|
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 = "
|
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.
|
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.
|
588
|
-
# Try to save to
|
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
|
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
|
-
"
|
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
|
-
"
|
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,
|
@@ -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:
|
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
|
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", "
|
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("
|
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.
|
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="
|
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(
|
@@ -178,7 +178,7 @@ class GoogleCalendarSkill(Skill):
|
|
178
178
|
<head>
|
179
179
|
<meta charset=\"utf-8\" />
|
180
180
|
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />
|
181
|
-
<title>
|
181
|
+
<title>WebAgents – Google Calendar</title>
|
182
182
|
<style>
|
183
183
|
:root { color-scheme: light dark; }
|
184
184
|
html, body { height: 100%; margin: 0; font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji"; }
|
@@ -1,9 +1,9 @@
|
|
1
1
|
"""
|
2
|
-
AuthSkill Package -
|
2
|
+
AuthSkill Package - WebAgents V2.0
|
3
3
|
|
4
|
-
Authentication and authorization skill for
|
4
|
+
Authentication and authorization skill for WebAgents platform.
|
5
5
|
Provides user authentication, API key validation, role-based access control,
|
6
|
-
and integration with
|
6
|
+
and integration with WebAgents platform services.
|
7
7
|
"""
|
8
8
|
|
9
9
|
from .skill import AuthSkill, AuthScope, AuthContext, AuthenticationError, AuthorizationError
|
@@ -1,8 +1,8 @@
|
|
1
1
|
"""
|
2
|
-
AuthSkill -
|
2
|
+
AuthSkill - WebAgents V2.0 Platform Integration
|
3
3
|
|
4
|
-
Authentication and authorization skill for
|
5
|
-
Integrates with
|
4
|
+
Authentication and authorization skill for WebAgents platform.
|
5
|
+
Integrates with WebAgents Portal APIs for user authentication, API key validation,
|
6
6
|
and platform service integration.
|
7
7
|
"""
|
8
8
|
|
@@ -13,8 +13,8 @@ from enum import Enum
|
|
13
13
|
|
14
14
|
from webagents.agents.skills.base import Skill
|
15
15
|
from webagents.agents.tools.decorators import tool, hook
|
16
|
-
from
|
17
|
-
from
|
16
|
+
from robutler.api import RobutlerClient
|
17
|
+
from robutler.api.types import User, ApiKey, AuthResponse
|
18
18
|
from typing import Any as _Any
|
19
19
|
try:
|
20
20
|
from jose import jwt as jose_jwt # python-jose
|
@@ -49,10 +49,10 @@ class AuthContext:
|
|
49
49
|
|
50
50
|
class AuthSkill(Skill):
|
51
51
|
"""
|
52
|
-
Authentication and authorization skill for
|
52
|
+
Authentication and authorization skill for WebAgents platform
|
53
53
|
|
54
54
|
Features:
|
55
|
-
- Platform integration with
|
55
|
+
- Platform integration with WebAgents Portal APIs
|
56
56
|
- API key authentication and validation
|
57
57
|
- User information retrieval
|
58
58
|
- Credit tracking and usage management
|
@@ -82,13 +82,13 @@ class AuthSkill(Skill):
|
|
82
82
|
self.client: Optional[RobutlerClient] = None
|
83
83
|
|
84
84
|
async def initialize(self, agent) -> None:
|
85
|
-
"""Initialize AuthSkill with
|
85
|
+
"""Initialize AuthSkill with WebAgents Platform client"""
|
86
86
|
from webagents.utils.logging import get_logger, log_skill_event
|
87
87
|
|
88
88
|
self.agent = agent
|
89
|
-
self.logger = get_logger('skill.
|
89
|
+
self.logger = get_logger('skill.webagents.auth', agent.name)
|
90
90
|
|
91
|
-
# Initialize
|
91
|
+
# Initialize WebAgents Platform client
|
92
92
|
try:
|
93
93
|
# Use api_key as priority, fallback to agent's API key
|
94
94
|
final_api_key = self.api_key or getattr(agent, 'api_key', None)
|
@@ -101,12 +101,12 @@ class AuthSkill(Skill):
|
|
101
101
|
# Test connection
|
102
102
|
health_response = await self.client.health_check()
|
103
103
|
if health_response.success:
|
104
|
-
self.logger.info(f"Connected to
|
104
|
+
self.logger.info(f"Connected to WebAgents Platform: {self.platform_api_url}")
|
105
105
|
else:
|
106
106
|
self.logger.warning(f"Platform health check failed: {health_response.message}")
|
107
107
|
|
108
108
|
except Exception as e:
|
109
|
-
self.logger.error(f"Failed to initialize
|
109
|
+
self.logger.error(f"Failed to initialize WebAgents Platform client: {e}")
|
110
110
|
# Continue without platform integration for testing
|
111
111
|
self.client = None
|
112
112
|
|
@@ -121,7 +121,7 @@ class AuthSkill(Skill):
|
|
121
121
|
|
122
122
|
@hook("on_connection", priority=0, scope="all")
|
123
123
|
async def validate_request_auth(self, context) -> Any:
|
124
|
-
"""Validate authentication for incoming requests using
|
124
|
+
"""Validate authentication for incoming requests using WebAgents Platform"""
|
125
125
|
if not self.require_auth:
|
126
126
|
return context
|
127
127
|
|
@@ -241,7 +241,7 @@ class AuthSkill(Skill):
|
|
241
241
|
assertion_token,
|
242
242
|
selected_key,
|
243
243
|
algorithms=['RS256'],
|
244
|
-
audience=f"
|
244
|
+
audience=f"webagents-agent:{getattr(self.agent, 'id', '')}",
|
245
245
|
)
|
246
246
|
if claims.get('agent_id') and getattr(self.agent, 'id', None) and claims['agent_id'] != getattr(self.agent, 'id'):
|
247
247
|
raise Exception('Owner assertion agent_id mismatch')
|
@@ -265,7 +265,7 @@ class AuthSkill(Skill):
|
|
265
265
|
return None
|
266
266
|
|
267
267
|
async def _authenticate_api_key(self, api_key: str) -> Optional[AuthContext]:
|
268
|
-
"""Authenticate API key with
|
268
|
+
"""Authenticate API key with WebAgents Platform and merge optional owner assertion (JWT)."""
|
269
269
|
|
270
270
|
if not self.client:
|
271
271
|
self.logger.warning("Platform client not available for authentication")
|
@@ -321,7 +321,7 @@ class AuthSkill(Skill):
|
|
321
321
|
assertion_token,
|
322
322
|
selected_key,
|
323
323
|
algorithms=['RS256'],
|
324
|
-
audience=f"
|
324
|
+
audience=f"webagents-agent:{getattr(self.agent, 'id', '')}",
|
325
325
|
)
|
326
326
|
# Enforce agent binding if claim present
|
327
327
|
if claims.get('agent_id') and getattr(self.agent, 'id', None) and claims['agent_id'] != getattr(self.agent, 'id'):
|
@@ -1,7 +1,7 @@
|
|
1
1
|
"""
|
2
|
-
CRM & Analytics Skill Package -
|
2
|
+
CRM & Analytics Skill Package - WebAgents Platform Integration
|
3
3
|
|
4
|
-
CRM and analytics skill for
|
4
|
+
CRM and analytics skill for WebAgents platform.
|
5
5
|
Provides contact management and event tracking capabilities.
|
6
6
|
"""
|
7
7
|
|