webagents 0.1.12__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 (96) hide show
  1. webagents/__init__.py +18 -0
  2. webagents/agents/__init__.py +13 -0
  3. webagents/agents/core/__init__.py +19 -0
  4. webagents/agents/core/base_agent.py +1834 -0
  5. webagents/agents/core/handoffs.py +293 -0
  6. webagents/agents/handoffs/__init__.py +0 -0
  7. webagents/agents/interfaces/__init__.py +0 -0
  8. webagents/agents/lifecycle/__init__.py +0 -0
  9. webagents/agents/skills/__init__.py +109 -0
  10. webagents/agents/skills/base.py +136 -0
  11. webagents/agents/skills/core/__init__.py +8 -0
  12. webagents/agents/skills/core/guardrails/__init__.py +0 -0
  13. webagents/agents/skills/core/llm/__init__.py +0 -0
  14. webagents/agents/skills/core/llm/anthropic/__init__.py +1 -0
  15. webagents/agents/skills/core/llm/litellm/__init__.py +10 -0
  16. webagents/agents/skills/core/llm/litellm/skill.py +538 -0
  17. webagents/agents/skills/core/llm/openai/__init__.py +1 -0
  18. webagents/agents/skills/core/llm/xai/__init__.py +1 -0
  19. webagents/agents/skills/core/mcp/README.md +375 -0
  20. webagents/agents/skills/core/mcp/__init__.py +15 -0
  21. webagents/agents/skills/core/mcp/skill.py +731 -0
  22. webagents/agents/skills/core/memory/__init__.py +11 -0
  23. webagents/agents/skills/core/memory/long_term_memory/__init__.py +10 -0
  24. webagents/agents/skills/core/memory/long_term_memory/memory_skill.py +639 -0
  25. webagents/agents/skills/core/memory/short_term_memory/__init__.py +9 -0
  26. webagents/agents/skills/core/memory/short_term_memory/skill.py +341 -0
  27. webagents/agents/skills/core/memory/vector_memory/skill.py +447 -0
  28. webagents/agents/skills/core/planning/__init__.py +9 -0
  29. webagents/agents/skills/core/planning/planner.py +343 -0
  30. webagents/agents/skills/ecosystem/__init__.py +0 -0
  31. webagents/agents/skills/ecosystem/crewai/__init__.py +1 -0
  32. webagents/agents/skills/ecosystem/database/__init__.py +1 -0
  33. webagents/agents/skills/ecosystem/filesystem/__init__.py +0 -0
  34. webagents/agents/skills/ecosystem/google/__init__.py +0 -0
  35. webagents/agents/skills/ecosystem/google/calendar/__init__.py +6 -0
  36. webagents/agents/skills/ecosystem/google/calendar/skill.py +306 -0
  37. webagents/agents/skills/ecosystem/n8n/__init__.py +0 -0
  38. webagents/agents/skills/ecosystem/openai_agents/__init__.py +0 -0
  39. webagents/agents/skills/ecosystem/web/__init__.py +0 -0
  40. webagents/agents/skills/ecosystem/zapier/__init__.py +0 -0
  41. webagents/agents/skills/robutler/__init__.py +11 -0
  42. webagents/agents/skills/robutler/auth/README.md +63 -0
  43. webagents/agents/skills/robutler/auth/__init__.py +17 -0
  44. webagents/agents/skills/robutler/auth/skill.py +354 -0
  45. webagents/agents/skills/robutler/crm/__init__.py +18 -0
  46. webagents/agents/skills/robutler/crm/skill.py +368 -0
  47. webagents/agents/skills/robutler/discovery/README.md +281 -0
  48. webagents/agents/skills/robutler/discovery/__init__.py +16 -0
  49. webagents/agents/skills/robutler/discovery/skill.py +230 -0
  50. webagents/agents/skills/robutler/kv/__init__.py +6 -0
  51. webagents/agents/skills/robutler/kv/skill.py +80 -0
  52. webagents/agents/skills/robutler/message_history/__init__.py +9 -0
  53. webagents/agents/skills/robutler/message_history/skill.py +270 -0
  54. webagents/agents/skills/robutler/messages/__init__.py +0 -0
  55. webagents/agents/skills/robutler/nli/__init__.py +13 -0
  56. webagents/agents/skills/robutler/nli/skill.py +687 -0
  57. webagents/agents/skills/robutler/notifications/__init__.py +5 -0
  58. webagents/agents/skills/robutler/notifications/skill.py +141 -0
  59. webagents/agents/skills/robutler/payments/__init__.py +41 -0
  60. webagents/agents/skills/robutler/payments/exceptions.py +255 -0
  61. webagents/agents/skills/robutler/payments/skill.py +610 -0
  62. webagents/agents/skills/robutler/storage/__init__.py +10 -0
  63. webagents/agents/skills/robutler/storage/files/__init__.py +9 -0
  64. webagents/agents/skills/robutler/storage/files/skill.py +445 -0
  65. webagents/agents/skills/robutler/storage/json/__init__.py +9 -0
  66. webagents/agents/skills/robutler/storage/json/skill.py +336 -0
  67. webagents/agents/skills/robutler/storage/kv/skill.py +88 -0
  68. webagents/agents/skills/robutler/storage.py +389 -0
  69. webagents/agents/tools/__init__.py +0 -0
  70. webagents/agents/tools/decorators.py +426 -0
  71. webagents/agents/tracing/__init__.py +0 -0
  72. webagents/agents/workflows/__init__.py +0 -0
  73. webagents/api/__init__.py +17 -0
  74. webagents/api/client.py +1207 -0
  75. webagents/api/types.py +253 -0
  76. webagents/scripts/__init__.py +0 -0
  77. webagents/server/__init__.py +28 -0
  78. webagents/server/context/__init__.py +0 -0
  79. webagents/server/context/context_vars.py +121 -0
  80. webagents/server/core/__init__.py +0 -0
  81. webagents/server/core/app.py +843 -0
  82. webagents/server/core/middleware.py +69 -0
  83. webagents/server/core/models.py +98 -0
  84. webagents/server/core/monitoring.py +59 -0
  85. webagents/server/endpoints/__init__.py +0 -0
  86. webagents/server/interfaces/__init__.py +0 -0
  87. webagents/server/middleware.py +330 -0
  88. webagents/server/models.py +92 -0
  89. webagents/server/monitoring.py +659 -0
  90. webagents/utils/__init__.py +0 -0
  91. webagents/utils/logging.py +359 -0
  92. webagents-0.1.12.dist-info/METADATA +99 -0
  93. webagents-0.1.12.dist-info/RECORD +96 -0
  94. webagents-0.1.12.dist-info/WHEEL +4 -0
  95. webagents-0.1.12.dist-info/entry_points.txt +2 -0
  96. webagents-0.1.12.dist-info/licenses/LICENSE +1 -0
@@ -0,0 +1,359 @@
1
+ """
2
+ Robutler V2.0 Logging System
3
+
4
+ Comprehensive logging with color-coded agent names, structured output,
5
+ and context-aware logging for agents, skills, and server components.
6
+ """
7
+
8
+ import logging
9
+ import sys
10
+ import time
11
+ from typing import Optional, Dict, Any
12
+ from colorama import Fore, Back, Style, init
13
+ from datetime import datetime
14
+ from contextvars import ContextVar
15
+
16
+ # Initialize colorama for cross-platform color support
17
+ init(autoreset=True)
18
+
19
+ # Context variables for logging
20
+ CURRENT_AGENT: ContextVar[Optional[str]] = ContextVar('current_agent', default=None)
21
+ CURRENT_REQUEST_ID: ContextVar[Optional[str]] = ContextVar('current_request_id', default=None)
22
+ CURRENT_USER_ID: ContextVar[Optional[str]] = ContextVar('current_user_id', default=None)
23
+
24
+ # Color mapping for different agent types/names
25
+ AGENT_COLORS = {
26
+ # Core system colors
27
+ 'system': Fore.CYAN,
28
+ 'server': Fore.BLUE,
29
+ 'router': Fore.MAGENTA,
30
+
31
+ # Agent name-based colors (hash-based for consistency)
32
+ 'default': Fore.GREEN,
33
+ }
34
+
35
+ def get_agent_color(agent_name: str) -> str:
36
+ """Get consistent color for agent name based on hash"""
37
+ if agent_name in AGENT_COLORS:
38
+ return AGENT_COLORS[agent_name]
39
+
40
+ # Generate consistent color based on agent name hash
41
+ colors = [Fore.GREEN, Fore.YELLOW, Fore.BLUE, Fore.MAGENTA, Fore.CYAN, Fore.RED]
42
+ color_index = hash(agent_name) % len(colors)
43
+ return colors[color_index]
44
+
45
+ class RobutlerFormatter(logging.Formatter):
46
+ """Custom formatter with color-coded agent names and structured output"""
47
+
48
+ def format(self, record):
49
+ # Get context information
50
+ agent_name = CURRENT_AGENT.get() or getattr(record, 'agent_name', None)
51
+ request_id = CURRENT_REQUEST_ID.get() or getattr(record, 'request_id', None)
52
+ user_id = CURRENT_USER_ID.get() or getattr(record, 'user_id', None)
53
+
54
+ # Format timestamp
55
+ timestamp = datetime.fromtimestamp(record.created).strftime('%H:%M:%S.%f')[:-3]
56
+
57
+ # Format level with color
58
+ level_colors = {
59
+ 'DEBUG': Fore.WHITE,
60
+ 'INFO': Fore.GREEN,
61
+ 'WARNING': Fore.YELLOW,
62
+ 'ERROR': Fore.RED,
63
+ 'CRITICAL': Fore.RED + Back.WHITE
64
+ }
65
+ level_color = level_colors.get(record.levelname, Fore.WHITE)
66
+ colored_level = f"{level_color}{record.levelname:8s}{Style.RESET_ALL}"
67
+
68
+ # Format agent name with color
69
+ if agent_name:
70
+ agent_color = get_agent_color(agent_name)
71
+ colored_agent = f"{agent_color}{agent_name:15s}{Style.RESET_ALL}"
72
+ else:
73
+ # Try to extract agent name from logger name (e.g., openlicense-image.tool)
74
+ logger_parts = record.name.split('.')
75
+ if len(logger_parts) > 0 and '-' in logger_parts[0]:
76
+ potential_agent = logger_parts[0]
77
+ agent_color = get_agent_color(potential_agent)
78
+ colored_agent = f"{agent_color}{potential_agent[:15]:15s}{Style.RESET_ALL}"
79
+ else:
80
+ colored_agent = f"{'system':15s}"
81
+
82
+ # Format component (logger name)
83
+ component = record.name.split('.')[-1] if '.' in record.name else record.name
84
+ # Truncate very long component names
85
+ if len(component) > 12:
86
+ component = component[:12]
87
+
88
+ # Build context string
89
+ context_parts = []
90
+ if request_id:
91
+ context_parts.append(f"req={request_id[:8]}")
92
+ if user_id:
93
+ context_parts.append(f"user={user_id[:8]}")
94
+
95
+ context_str = f" [{':'.join(context_parts)}]" if context_parts else ""
96
+
97
+ # Format the log message
98
+ message = record.getMessage()
99
+
100
+ # Build final log line
101
+ log_line = f"{Fore.WHITE}{timestamp}{Style.RESET_ALL} {colored_level} {colored_agent} {Fore.BLUE}{component:12s}{Style.RESET_ALL}{context_str} {message}"
102
+
103
+ # Add exception info if present
104
+ if record.exc_info:
105
+ log_line += '\n' + self.formatException(record.exc_info)
106
+
107
+ return log_line
108
+
109
+ class AgentContextAdapter(logging.LoggerAdapter):
110
+ """Logger adapter that automatically includes agent context"""
111
+
112
+ def __init__(self, logger, agent_name: str):
113
+ super().__init__(logger, {})
114
+ self.agent_name = agent_name
115
+
116
+ def process(self, msg, kwargs):
117
+ # Add agent context to log record
118
+ extra = kwargs.get('extra', {})
119
+ extra['agent_name'] = self.agent_name
120
+
121
+ # Add current context if available
122
+ request_id = CURRENT_REQUEST_ID.get()
123
+ user_id = CURRENT_USER_ID.get()
124
+
125
+ if request_id:
126
+ extra['request_id'] = request_id
127
+ if user_id:
128
+ extra['user_id'] = user_id
129
+
130
+ kwargs['extra'] = extra
131
+ return msg, kwargs
132
+
133
+ def setup_logging(level: str = "INFO", log_file: Optional[str] = None) -> None:
134
+ """Setup the Robutler logging system"""
135
+
136
+ # Convert string level to logging constant
137
+ numeric_level = getattr(logging, level.upper(), logging.INFO)
138
+
139
+ # Create root logger
140
+ root_logger = logging.getLogger('robutler')
141
+ root_logger.setLevel(numeric_level)
142
+
143
+ # Clear any existing handlers
144
+ root_logger.handlers.clear()
145
+
146
+ # Console handler with color formatter
147
+ console_handler = logging.StreamHandler(sys.stdout)
148
+ console_handler.setLevel(numeric_level)
149
+ console_handler.setFormatter(RobutlerFormatter())
150
+ root_logger.addHandler(console_handler)
151
+
152
+ # File handler if specified (without colors)
153
+ if log_file:
154
+ file_handler = logging.FileHandler(log_file)
155
+ file_handler.setLevel(numeric_level)
156
+ file_formatter = logging.Formatter(
157
+ '%(asctime)s %(levelname)-8s %(name)-20s [%(agent_name)s] %(message)s',
158
+ datefmt='%Y-%m-%d %H:%M:%S'
159
+ )
160
+ file_handler.setFormatter(file_formatter)
161
+ root_logger.addHandler(file_handler)
162
+
163
+ # Disable propagation to avoid duplicate logs
164
+ root_logger.propagate = False
165
+
166
+ # Set levels for noisy libraries
167
+ logging.getLogger('urllib3').setLevel(logging.WARNING)
168
+ logging.getLogger('httpx').setLevel(logging.WARNING)
169
+ logging.getLogger('openai').setLevel(logging.WARNING)
170
+
171
+ # Configure LiteLLM logging to use our formatter
172
+ litellm_logger = logging.getLogger('LiteLLM')
173
+ litellm_logger.setLevel(logging.WARNING) # Only show warnings and errors
174
+ # Clear any existing handlers from LiteLLM
175
+ litellm_logger.handlers.clear()
176
+ # Add our console handler with formatter
177
+ litellm_handler = logging.StreamHandler(sys.stdout)
178
+ litellm_handler.setFormatter(RobutlerFormatter())
179
+ litellm_logger.addHandler(litellm_handler)
180
+ litellm_logger.propagate = False
181
+
182
+ # Also configure the root logger to catch any unconfigured loggers
183
+ # This will catch any dynamically created loggers that don't have handlers
184
+ root = logging.getLogger()
185
+ if not root.handlers:
186
+ # Only add handler if root doesn't have one already
187
+ root_handler = logging.StreamHandler(sys.stdout)
188
+ root_handler.setFormatter(RobutlerFormatter())
189
+ root_handler.setLevel(numeric_level)
190
+ root.addHandler(root_handler)
191
+ else:
192
+ # Update existing root handlers to use our formatter
193
+ for handler in root.handlers:
194
+ if isinstance(handler, logging.StreamHandler):
195
+ handler.setFormatter(RobutlerFormatter())
196
+ handler.setLevel(numeric_level)
197
+
198
+ def get_logger(name: str, agent_name: Optional[str] = None) -> logging.Logger:
199
+ """Get a logger for a specific component, optionally with agent context"""
200
+
201
+ logger_name = f"robutler.{name}" if not name.startswith('robutler') else name
202
+ logger = logging.getLogger(logger_name)
203
+
204
+ if agent_name:
205
+ return AgentContextAdapter(logger, agent_name)
206
+
207
+ return logger
208
+
209
+ def set_agent_context(agent_name: str, request_id: Optional[str] = None, user_id: Optional[str] = None):
210
+ """Set the current agent context for logging"""
211
+ CURRENT_AGENT.set(agent_name)
212
+ if request_id:
213
+ CURRENT_REQUEST_ID.set(request_id)
214
+ if user_id:
215
+ CURRENT_USER_ID.set(user_id)
216
+
217
+ def clear_agent_context():
218
+ """Clear the current agent context"""
219
+ CURRENT_AGENT.set(None)
220
+ CURRENT_REQUEST_ID.set(None)
221
+ CURRENT_USER_ID.set(None)
222
+
223
+ # Convenience functions for different log types
224
+ def log_agent_action(agent_name: str, action: str, details: Optional[Dict[str, Any]] = None):
225
+ """Log an agent action with structured data"""
226
+ logger = get_logger('agent.action', agent_name)
227
+ details_str = f" {details}" if details else ""
228
+ logger.info(f"{action}{details_str}")
229
+
230
+ def log_skill_event(agent_name: str, skill_name: str, event: str, details: Optional[Dict[str, Any]] = None):
231
+ """Log a skill event"""
232
+ logger = get_logger(f'skill.{skill_name}', agent_name)
233
+ details_str = f" {details}" if details else ""
234
+ logger.info(f"{event}{details_str}")
235
+
236
+ def log_tool_execution(agent_name: str, tool_name: str, duration_ms: int, success: bool = True):
237
+ """Log tool execution with timing"""
238
+ logger = get_logger('tool.execution', agent_name)
239
+ status = "SUCCESS" if success else "FAILED"
240
+ logger.info(f"Tool {tool_name} {status} ({duration_ms}ms)")
241
+
242
+ def log_handoff(agent_name: str, handoff_type: str, target: str, success: bool = True):
243
+ """Log handoff execution"""
244
+ logger = get_logger('handoff', agent_name)
245
+ status = "SUCCESS" if success else "FAILED"
246
+ logger.info(f"Handoff {handoff_type} -> {target} {status}")
247
+
248
+ def log_server_request(endpoint: str, method: str, status_code: int, duration_ms: int, agent_name: Optional[str] = None):
249
+ """Log server request with timing"""
250
+ logger = get_logger('server.request', agent_name)
251
+ logger.info(f"{method} {endpoint} {status_code} ({duration_ms}ms)")
252
+
253
+ # Performance logging utilities
254
+ class LogTimer:
255
+ """Context manager for timing operations with automatic logging"""
256
+
257
+ def __init__(self, operation_name: str, logger: logging.Logger, level: int = logging.INFO):
258
+ self.operation_name = operation_name
259
+ self.logger = logger
260
+ self.level = level
261
+ self.start_time = None
262
+
263
+ def __enter__(self):
264
+ self.start_time = time.time()
265
+ self.logger.log(self.level, f"Starting {self.operation_name}")
266
+ return self
267
+
268
+ def __exit__(self, exc_type, exc_val, exc_tb):
269
+ duration_ms = int((time.time() - self.start_time) * 1000)
270
+ if exc_type:
271
+ self.logger.error(f"{self.operation_name} FAILED ({duration_ms}ms): {exc_val}")
272
+ else:
273
+ self.logger.log(self.level, f"{self.operation_name} completed ({duration_ms}ms)")
274
+
275
+ def timer(operation_name: str, agent_name: Optional[str] = None, level: int = logging.INFO):
276
+ """Create a timing context manager"""
277
+ logger = get_logger('performance', agent_name)
278
+ return LogTimer(operation_name, logger, level)
279
+
280
+ def configure_external_logger(logger_name: str, level: Optional[str] = None) -> None:
281
+ """Configure an external logger to use our structured format
282
+
283
+ Args:
284
+ logger_name: Name of the logger to configure (e.g., 'litellm', 'openlicense')
285
+ level: Optional log level to set (defaults to current root level)
286
+ """
287
+ logger = logging.getLogger(logger_name)
288
+
289
+ # Clear any existing handlers
290
+ logger.handlers.clear()
291
+
292
+ # Get the current root level if not specified
293
+ if level is None:
294
+ root_logger = logging.getLogger('robutler')
295
+ numeric_level = root_logger.level
296
+ else:
297
+ numeric_level = getattr(logging, level.upper(), logging.INFO)
298
+
299
+ # Add our formatted handler
300
+ handler = logging.StreamHandler(sys.stdout)
301
+ handler.setFormatter(RobutlerFormatter())
302
+ handler.setLevel(numeric_level)
303
+ logger.addHandler(handler)
304
+ logger.setLevel(numeric_level)
305
+ logger.propagate = False
306
+
307
+ def capture_all_loggers() -> None:
308
+ """Ensure all existing loggers use our structured format
309
+
310
+ This function should be called after all modules are imported
311
+ to ensure any dynamically created loggers are properly configured.
312
+ """
313
+ root_formatter = RobutlerFormatter()
314
+ root_level = logging.getLogger('robutler').level
315
+
316
+ # Get all existing loggers
317
+ for name in logging.Logger.manager.loggerDict:
318
+ logger = logging.getLogger(name)
319
+
320
+ # Skip if it's already a robutler logger
321
+ if name.startswith('robutler'):
322
+ continue
323
+
324
+ # Skip if it has handlers (already configured)
325
+ if logger.handlers:
326
+ # Update handlers to use our formatter
327
+ for handler in logger.handlers:
328
+ if isinstance(handler, logging.StreamHandler):
329
+ handler.setFormatter(root_formatter)
330
+ else:
331
+ # Add our handler if no handlers exist
332
+ handler = logging.StreamHandler(sys.stdout)
333
+ handler.setFormatter(root_formatter)
334
+ handler.setLevel(root_level)
335
+ logger.addHandler(handler)
336
+ logger.propagate = False
337
+
338
+ # Custom logger class that automatically uses our formatter
339
+ class RobutlerLogger(logging.Logger):
340
+ """Custom logger that automatically gets our formatter"""
341
+
342
+ def __init__(self, name):
343
+ super().__init__(name)
344
+ # Automatically add our handler if this is a new logger
345
+ if not self.handlers and not name.startswith('robutler'):
346
+ handler = logging.StreamHandler(sys.stdout)
347
+ handler.setFormatter(RobutlerFormatter())
348
+ # Get the root level
349
+ root_level = logging.getLogger('robutler').level if logging.getLogger('robutler').level else logging.INFO
350
+ handler.setLevel(root_level)
351
+ self.addHandler(handler)
352
+ self.setLevel(root_level)
353
+ self.propagate = False
354
+
355
+ # Set our custom logger class as the default
356
+ logging.setLoggerClass(RobutlerLogger)
357
+
358
+ # Initialize logging on import (can be reconfigured later)
359
+ setup_logging()
@@ -0,0 +1,99 @@
1
+ Metadata-Version: 2.4
2
+ Name: webagents
3
+ Version: 0.1.12
4
+ Summary: Web AI Agents SDK
5
+ Author: Awesome Opensource Contributors and Robutler Team
6
+ License: TBD
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.10
9
+ Requires-Dist: colorama>=0.4.6
10
+ Requires-Dist: fastapi>=0.100.0
11
+ Requires-Dist: fastmcp>=2.3.0
12
+ Requires-Dist: httpx>=0.24.0
13
+ Requires-Dist: litellm>=1.0.0
14
+ Requires-Dist: pillow>=10.0.0
15
+ Requires-Dist: pydantic-settings>=2.0.0
16
+ Requires-Dist: pydantic>=2.7.0
17
+ Requires-Dist: python-dotenv>=1.0.0
18
+ Requires-Dist: tiktoken>=0.5.0
19
+ Requires-Dist: uvicorn>=0.23.0
20
+ Provides-Extra: dev
21
+ Requires-Dist: black>=23.0.0; extra == 'dev'
22
+ Requires-Dist: mypy>=1.0.0; extra == 'dev'
23
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
24
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
25
+ Requires-Dist: ruff>=0.0.270; extra == 'dev'
26
+ Provides-Extra: examples
27
+ Requires-Dist: openai-agents>=0.0.16; extra == 'examples'
28
+ Description-Content-Type: text/markdown
29
+
30
+ # Robutler
31
+
32
+ Build discoverable and monetizable AI agents.
33
+
34
+
35
+ ## Installation
36
+
37
+ ```bash
38
+ pip install robutler
39
+ ```
40
+
41
+ ## Quick Start
42
+
43
+ ### AI Agent Server
44
+
45
+ Create AI agents with OpenAI-compatible endpoints:
46
+
47
+ ```python
48
+ from robutler.server import RobutlerServer, pricing
49
+ from robutler.agent import RobutlerAgent
50
+
51
+ # Create tools with pricing
52
+ @pricing(credits_per_call=100)
53
+ def get_weather(location: str) -> str:
54
+ """Get current weather for a location"""
55
+ return f"Weather in {location}: Sunny, 72°F"
56
+
57
+ # Create an agent with intents
58
+ agent = RobutlerAgent(
59
+ name="assistant",
60
+ instructions="You are a helpful AI assistant.",
61
+ credits_per_token=5,
62
+ model="gpt-4o-mini",
63
+ tools=[get_weather],
64
+ intents=["help with weather", "provide assistance", "answer questions"]
65
+ )
66
+
67
+ # Create server with automatic endpoint creation
68
+ app = RobutlerServer(agents=[agent])
69
+
70
+ # Endpoints are automatically created:
71
+ # POST /assistant/chat/completions - OpenAI-compatible chat
72
+ # GET /assistant - Agent info
73
+ ```
74
+
75
+ Run the server:
76
+
77
+ ```bash
78
+ uvicorn main:app --host 0.0.0.0 --port 8000
79
+ ```
80
+
81
+ ### API Client
82
+
83
+ ```python
84
+ from robutler.api import RobutlerApi
85
+
86
+ async with RobutlerApi() as api:
87
+ user = await api.get_user_info()
88
+ credits = await api.get_user_credits()
89
+ ```
90
+
91
+ ## Documentation
92
+
93
+ For comprehensive documentation, visit: [docs.robutler.ai](https://docs.robutler.ai)
94
+
95
+ ## Environment Variables
96
+
97
+ ```bash
98
+ ROBUTLER_API_KEY=your_api_key
99
+ ```
@@ -0,0 +1,96 @@
1
+ webagents/__init__.py,sha256=81hdVapJ4bFsW9H_jpnuFFw7yn5UdHBxhy07ELy1skE,373
2
+ webagents/agents/__init__.py,sha256=JkRjxf5lqVrBNjbV40zdKUGKmv-QKT18Obo1pHZDiPU,244
3
+ webagents/agents/core/__init__.py,sha256=H_Pj76OywpsztZmcmptmJKAluRue3KK3kMnc1xKXlWg,541
4
+ webagents/agents/core/base_agent.py,sha256=BPpUxfLOJ3CLU0uDfghDVVyx8oPw72lX1REviuCvFlQ,93798
5
+ webagents/agents/core/handoffs.py,sha256=1IUIIXPAGzidLRa6vNBgkgEZEP8xFD97quuOZKu5xIg,11075
6
+ webagents/agents/handoffs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ webagents/agents/interfaces/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ webagents/agents/lifecycle/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ webagents/agents/skills/__init__.py,sha256=adsMcCrrzfvRd3DHLhtjyml2zJ5qsMajI0IpAR1B1pk,3199
10
+ webagents/agents/skills/base.py,sha256=76kYfbxTfT60MMeeTIiANWSXRhdd01OazbTnP1rkGQ4,5098
11
+ webagents/agents/skills/core/__init__.py,sha256=xT_-sPnLbxTUqjvg0toVCqQyB6OP-An_vBprdv_t0xA,258
12
+ webagents/agents/skills/core/guardrails/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ webagents/agents/skills/core/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ webagents/agents/skills/core/llm/anthropic/__init__.py,sha256=NkitGyW7aAdDPKsIeZaU979us3yg84Hej1L_Ogtw-f8,68
15
+ webagents/agents/skills/core/llm/litellm/__init__.py,sha256=IEvhO15GW1naAPGizpJc6wjMtzf9As13WLVKMKevUc8,271
16
+ webagents/agents/skills/core/llm/litellm/skill.py,sha256=nbeI7xnXt3YN9X4IdhqPA3KCKiCxP_ilEewWBisbg-Q,22266
17
+ webagents/agents/skills/core/llm/openai/__init__.py,sha256=eHvy20Z-geoVAZu8MstRiPXsEXZLJcBq3GtSZSLeOXo,65
18
+ webagents/agents/skills/core/llm/xai/__init__.py,sha256=HPcn0Ki-Di0kIzV5bvb-Vt-8vGW-ufBmHI9ZBeIdlA8,62
19
+ webagents/agents/skills/core/mcp/README.md,sha256=5uHOYvBR0XtTHCl4ZN4rZ5KA4-skLlb51KDGMeQOuk8,14948
20
+ webagents/agents/skills/core/mcp/__init__.py,sha256=0dBqPqObN8kREXP28fX-ANxxyf6NFol_n95TgxTYkjU,366
21
+ webagents/agents/skills/core/mcp/skill.py,sha256=sS7V5PUTKf0eRGBX3VP-6Rt2dyNnwR7wPjclXbGg8t8,30252
22
+ webagents/agents/skills/core/memory/__init__.py,sha256=EH3YM_WQ9GZcgJnbxfB5UaKZj6VU3a9k8pD-GcLnExI,328
23
+ webagents/agents/skills/core/memory/long_term_memory/__init__.py,sha256=Bk4DChm7NDLizK0yS-NBWTA7FWSc_SSVYI80F_BJ6MU,258
24
+ webagents/agents/skills/core/memory/long_term_memory/memory_skill.py,sha256=6SAFPcN0VNzL1b1k-v29eHeF10EIC8uYsKJ8v5PUFA0,24053
25
+ webagents/agents/skills/core/memory/short_term_memory/__init__.py,sha256=c9N68CZFCFyc5emkauutc2JNIKrN76emz4loDqVbzzo,216
26
+ webagents/agents/skills/core/memory/short_term_memory/skill.py,sha256=OkgGkfhC8cth-Py2HmneZOW426cHjhBzKto8KhvrPKI,12790
27
+ webagents/agents/skills/core/memory/vector_memory/skill.py,sha256=ZvqftsLyyIa59gESjAItjdgLG8G5SlPM8G2Su2q0xqw,19997
28
+ webagents/agents/skills/core/planning/__init__.py,sha256=vGmkhbYvVD2DFtZAKBLqhgG1qwQz0soxijGjk0u8Pr0,222
29
+ webagents/agents/skills/core/planning/planner.py,sha256=EFBH9vrYcYaWgXSlC0c8nUP9eGj6b_RyZ4dHbNjFVXU,13900
30
+ webagents/agents/skills/ecosystem/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
+ webagents/agents/skills/ecosystem/crewai/__init__.py,sha256=MfHsOOPpXVUWcXyiip2_svHF8YxrJ60cH28TM8ef__Q,30
32
+ webagents/agents/skills/ecosystem/database/__init__.py,sha256=x2y6F1FCplEmLaUXKztNDtNg_o1Y61ttiH1EiSrqCJ0,32
33
+ webagents/agents/skills/ecosystem/filesystem/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
+ webagents/agents/skills/ecosystem/google/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
+ webagents/agents/skills/ecosystem/google/calendar/__init__.py,sha256=s_e6EPc07c-iO06BUYaVyat1arGkNBLt29BKHubL6-0,77
36
+ webagents/agents/skills/ecosystem/google/calendar/skill.py,sha256=2yRiornRfF7kfFOO_IbkQpeYdzFRBzceTsMXg0ub25g,15622
37
+ webagents/agents/skills/ecosystem/n8n/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
+ webagents/agents/skills/ecosystem/openai_agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
+ webagents/agents/skills/ecosystem/web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
+ webagents/agents/skills/ecosystem/zapier/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
+ webagents/agents/skills/robutler/__init__.py,sha256=H2qNyHj358HnsdAtjfdvtPX0VIr5Rb_X6ExLtxqe3V8,164
42
+ webagents/agents/skills/robutler/storage.py,sha256=Q_L6YZvf98l7RBQqVYNKeur3U9LLZqZe2WkNObJX5RA,14684
43
+ webagents/agents/skills/robutler/auth/README.md,sha256=mRcuGF3ty3WyoMCwR0pxYnOWNOKyM7h5MW67-9Y3V4M,2556
44
+ webagents/agents/skills/robutler/auth/__init__.py,sha256=ch56w3JbDv2nQfdFmMV_HBoysJnJ17vFgc-XoPtCrXs,449
45
+ webagents/agents/skills/robutler/auth/skill.py,sha256=5qZhmsvohfhQGp4WOLdqV16UJOvnwoeXZHyq_vyTMzk,14819
46
+ webagents/agents/skills/robutler/crm/__init__.py,sha256=A0A4KxlJauzsfmlB9KRoqWorQ18PxHGeSb1jGP-pKLY,335
47
+ webagents/agents/skills/robutler/crm/skill.py,sha256=8yGheWkLoYrWmDti-zMKcI_SlTIqAZtgiGMTQaOlJJA,12949
48
+ webagents/agents/skills/robutler/discovery/README.md,sha256=GvLvi6VZSGkrBBYahtktnl1AUWVNQ7gf6NTfUlMtuuQ,9188
49
+ webagents/agents/skills/robutler/discovery/__init__.py,sha256=lWcOz75Ap7M2Fjno3eycYHjwmm8nL4_J3_6JbIfESGg,317
50
+ webagents/agents/skills/robutler/discovery/skill.py,sha256=TCJrsLR865z9iiFRVtB-_qO7i2XnqkNKxhkZzMYukDQ,9303
51
+ webagents/agents/skills/robutler/kv/__init__.py,sha256=sbaE6gr_OksCWIhJE0kFMpFErAHUnW_7coW8HiKePM8,53
52
+ webagents/agents/skills/robutler/kv/skill.py,sha256=ftZulx4gQD9lQVstCTj7ZjsWML2XcZ6PU-2lSGpePHU,3364
53
+ webagents/agents/skills/robutler/message_history/__init__.py,sha256=o8SVUowaFtDtVPScDy1BG650mT87_-MI_1IqkB8eUJA,213
54
+ webagents/agents/skills/robutler/message_history/skill.py,sha256=6GEdhZx4MwZqvjU_bmo6eu3ZmOd1USNhJuuHmMAFgyA,11176
55
+ webagents/agents/skills/robutler/messages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
+ webagents/agents/skills/robutler/nli/__init__.py,sha256=7N_RC2Pp00BFH3brNeUXEFbVhjQjARAIKM8Ep-axeHY,309
57
+ webagents/agents/skills/robutler/nli/skill.py,sha256=zzEqTeUiA4YzhyiyuLVnFsGzglDocc6UZzTZMxU5_o4,30598
58
+ webagents/agents/skills/robutler/notifications/__init__.py,sha256=N5ZWC0YkDRpKsIlazlVdYLBDMvhFg3s1ZIOzpi75EJg,74
59
+ webagents/agents/skills/robutler/notifications/skill.py,sha256=uJpAoCWh0XR475tPhETEePhu0RzvDSxz9cDH2SC7-qQ,5576
60
+ webagents/agents/skills/robutler/payments/__init__.py,sha256=w2hRAnGDQ29S_fxIKitJ6BM9pPe9TVYn0DfQYjaPYM4,1109
61
+ webagents/agents/skills/robutler/payments/exceptions.py,sha256=x2Wqu53D-INry2MH4dULUpBgnK24FEGC1bGcO3aI2VM,9696
62
+ webagents/agents/skills/robutler/payments/skill.py,sha256=Kaamttu19iTWjSpgS79mzXv0pqAXgrATrYvz50fZ26o,27859
63
+ webagents/agents/skills/robutler/storage/__init__.py,sha256=79t768tWloke6VSZWWy22T5IXWn3nvQCI1WM8mJA4fA,225
64
+ webagents/agents/skills/robutler/storage/files/__init__.py,sha256=00BpB6z2eJu05Gs6s5hN3Qzhb2InbQUX3uGuJ2Zs2tk,200
65
+ webagents/agents/skills/robutler/storage/files/skill.py,sha256=v9iJDbMUcJfZjdhsl6ufvpcMx28hqUY7_h16Sr_-FXU,19302
66
+ webagents/agents/skills/robutler/storage/json/__init__.py,sha256=bLyAhYxHLTkfg-CuHysiANI0UabqnN4BeSdC7ey1isg,188
67
+ webagents/agents/skills/robutler/storage/json/skill.py,sha256=d3u_apjCrS4fokXKLK_hWnbchRoBaYsFfQRfDTIh1X4,12423
68
+ webagents/agents/skills/robutler/storage/kv/skill.py,sha256=c-UqWT-v6Xpx3DYTCxy78U7Q0cC-VlFYoTekBdP4OPg,3347
69
+ webagents/agents/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
+ webagents/agents/tools/decorators.py,sha256=yma0Q0yMglJYDF2hSKza0j0O6UoiWXyOywet36UDjq8,17151
71
+ webagents/agents/tracing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
+ webagents/agents/workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
+ webagents/api/__init__.py,sha256=iSNQA260QMfGcMQhXTWE5oPrIdXjxpyTwVCSn_06Im4,400
74
+ webagents/api/client.py,sha256=pit48wgXkFMYn3RkIjGQ84ZWuvRiG-dlWkrr2lAgNkI,51712
75
+ webagents/api/types.py,sha256=x6L6Haxx7Nutxmp6WgNKjwyfF1mHxozfazye7YEq4zo,7582
76
+ webagents/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
+ webagents/server/__init__.py,sha256=7dpB8oYWeGvxVo3kXv-us7dAE6BMlUlZOqymAuBfMGM,606
78
+ webagents/server/middleware.py,sha256=CihiHnpPdW406SIZtxy3ewbCHHMcLO_5cAwgLQRwdzQ,12067
79
+ webagents/server/models.py,sha256=ncMD7I_NVMNAD2CkuRokHFH0xLw23ZVDZlcHyOpV83c,4800
80
+ webagents/server/monitoring.py,sha256=u-DbqU4dOFGYiSPlsC-6e1vr_JHw0Qe-amav_tv4ar4,20446
81
+ webagents/server/context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
+ webagents/server/context/context_vars.py,sha256=dPZqQPClYdwFrLI_oMtVBw_eglnkbVdiArHMxSDSVCE,3613
83
+ webagents/server/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
84
+ webagents/server/core/app.py,sha256=YG_uFzca9FKRbs_IxxEMbqJ9XGnQuZXVmWnE3K6Q700,38455
85
+ webagents/server/core/middleware.py,sha256=i5OmQCtuDKe_V1Z3cVSWn5TsEpo_K1CmiHNjmDHidMA,2225
86
+ webagents/server/core/models.py,sha256=w4KFjulstrdbojf4zaRj3k_wtATZMHZVAFX0XalJ6Sk,4674
87
+ webagents/server/core/monitoring.py,sha256=j6fKkKgb-vRZX3fxT5FzcNGzPK7ykws3D1R9lXjQdVQ,1523
88
+ webagents/server/endpoints/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
89
+ webagents/server/interfaces/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
90
+ webagents/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
91
+ webagents/utils/logging.py,sha256=F2Cfee7O_KgYvUIvuAqTZrkE8FXJ3_Zgvn-jR3rHC8Y,14057
92
+ webagents-0.1.12.dist-info/METADATA,sha256=NFP0dW63rBfma3WdAXKjys2NNR2rQQP6Cft5Q2w4FbU,2372
93
+ webagents-0.1.12.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
94
+ webagents-0.1.12.dist-info/entry_points.txt,sha256=bITAYBK8-H8EQUrDctEeEKuer4jAp3lfxKfvH5TT1eM,54
95
+ webagents-0.1.12.dist-info/licenses/LICENSE,sha256=A2JlSaWav2SO5ZFjs7isv2bDZRPLHnbW4ne8BEySbjA,3
96
+ webagents-0.1.12.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ webagents = webagents.__main__:main
@@ -0,0 +1 @@
1
+ TBD