claritty-sdk 1.0.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.
@@ -0,0 +1,356 @@
1
+ Metadata-Version: 2.4
2
+ Name: claritty-sdk
3
+ Version: 1.0.0
4
+ Summary: Professional SDK for building AI-powered agentic applications on Clarity Platform
5
+ Home-page: https://github.com/Clarittyai/claritty-sdk
6
+ Author: Clarity Platform
7
+ Author-email: Clarity Platform <developers@clarity.ai>
8
+ License: MIT
9
+ Project-URL: Homepage, https://github.com/Clarittyai/claritty-sdk
10
+ Project-URL: Documentation, https://github.com/Clarittyai/claritty-sdk#readme
11
+ Project-URL: Repository, https://github.com/Clarittyai/claritty-sdk
12
+ Project-URL: Issues, https://github.com/Clarittyai/claritty-sdk/issues
13
+ Keywords: ai,agents,workflows,automation,clarity,agentic,llm
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Requires-Python: >=3.11
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: pydantic>=2.6.0
25
+ Requires-Dist: croniter>=2.0.1
26
+ Requires-Dist: pytz>=2024.1
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
29
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
30
+ Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
31
+ Requires-Dist: black>=24.1.0; extra == "dev"
32
+ Requires-Dist: mypy>=1.8.0; extra == "dev"
33
+ Dynamic: author
34
+ Dynamic: home-page
35
+ Dynamic: license-file
36
+ Dynamic: requires-python
37
+
38
+ # Clarity SDK
39
+
40
+ Professional Python SDK for building AI-powered agentic applications on the Clarity platform.
41
+
42
+ ## Features
43
+
44
+ - **๐Ÿค– Agent Decorator** - Define AI agents with clean, declarative syntax
45
+ - **๐Ÿ”„ Workflow Orchestration** - Chain agents into multi-step workflows
46
+ - **โฐ User-Configurable Triggers** - Let users control when workflows run
47
+ - **๐Ÿ”Œ Integration Management** - OAuth/API key handling built-in
48
+ - **๐Ÿ“Š Type Safety** - Full Pydantic validation
49
+ - **๐Ÿงช Production Ready** - Error handling, retries, timeouts included
50
+
51
+ ## Installation
52
+
53
+ ```bash
54
+ pip install clarity-sdk
55
+ ```
56
+
57
+ ## Quick Start
58
+
59
+ ### 1. Define an Agent
60
+
61
+ ```python
62
+ from clarity_sdk import agent, BaseAgent, AgentContext, AgentResult
63
+
64
+ @agent(
65
+ id="task-prioritizer",
66
+ name="Task Prioritizer",
67
+ description="Analyzes tasks and suggests priorities",
68
+ inputs={"tasks": list},
69
+ outputs={"priorities": dict},
70
+ category="productivity"
71
+ )
72
+ class TaskPrioritizerAgent(BaseAgent):
73
+ async def execute(self, context: AgentContext) -> AgentResult:
74
+ tasks = context.get_input("tasks", [])
75
+
76
+ # Your AI logic here
77
+ priorities = self._analyze_tasks(tasks)
78
+
79
+ return AgentResult(
80
+ success=True,
81
+ data={"priorities": priorities}
82
+ )
83
+
84
+ def _analyze_tasks(self, tasks):
85
+ # Use LangChain, Claude SDK, or your own logic
86
+ return {"high": [], "medium": [], "low": []}
87
+ ```
88
+
89
+ ### 2. Create a Workflow
90
+
91
+ ```python
92
+ from clarity_sdk import workflow, uses_agent, ExecutionMode
93
+
94
+ @workflow(
95
+ id="daily-task-summary",
96
+ name="Daily Task Summary",
97
+ description="Analyzes tasks and sends Slack summary",
98
+ execution_mode=ExecutionMode.SEQUENTIAL
99
+ )
100
+ @uses_agent("task-prioritizer", output_key="priorities")
101
+ @uses_agent("slack-notifier", input_from="priorities")
102
+ async def daily_task_summary(context):
103
+ # Workflow executes automatically based on @uses_agent chain
104
+ pass
105
+ ```
106
+
107
+ ### 3. Define a Trigger Template
108
+
109
+ ```python
110
+ from clarity_sdk import trigger_template, TriggerTemplateType
111
+
112
+ @trigger_template(
113
+ id="daily-review",
114
+ name="Daily Task Review",
115
+ description="Review your tasks at a specific time each day",
116
+ template_type=TriggerTemplateType.SCHEDULE_DAILY,
117
+ workflow_id="daily-task-summary",
118
+ config_fields=[
119
+ {
120
+ "key": "time",
121
+ "label": "What time?",
122
+ "type": "time",
123
+ "required": True,
124
+ "default": "09:00"
125
+ },
126
+ {
127
+ "key": "timezone",
128
+ "label": "Your Timezone",
129
+ "type": "timezone",
130
+ "required": True
131
+ }
132
+ ]
133
+ )
134
+ class DailyReviewTrigger:
135
+ pass
136
+ ```
137
+
138
+ **User Experience:**
139
+ - User sees "Daily Task Review" in platform UI
140
+ - User clicks "Create Trigger"
141
+ - User configures: 9:00 AM, America/New_York
142
+ - Workflow runs every day at 9 AM EST for that user!
143
+
144
+ ## Core Concepts
145
+
146
+ ### Agents
147
+
148
+ Agents are individual AI-powered units that perform specific tasks.
149
+
150
+ ```python
151
+ @agent(
152
+ id="unique-id",
153
+ name="User-Facing Name",
154
+ description="What this agent does",
155
+ inputs={"key": type}, # Expected inputs
156
+ outputs={"key": type}, # Expected outputs
157
+ category="productivity", # Category
158
+ timeout=300 # Timeout in seconds
159
+ )
160
+ class MyAgent(BaseAgent):
161
+ async def execute(self, context):
162
+ # Your logic
163
+ return AgentResult(success=True, data={...})
164
+ ```
165
+
166
+ ### Workflows
167
+
168
+ Workflows orchestrate multiple agents.
169
+
170
+ ```python
171
+ @workflow(id="my-workflow", name="My Workflow")
172
+ @uses_agent("agent-1", output_key="step1")
173
+ @uses_agent("agent-2", input_from="step1", output_key="step2")
174
+ async def my_workflow(context):
175
+ # Optional custom logic
176
+ pass
177
+ ```
178
+
179
+ ### Triggers
180
+
181
+ Triggers define when workflows run - **configured by end users**.
182
+
183
+ ```python
184
+ @trigger_template(
185
+ id="my-trigger",
186
+ template_type=TriggerTemplateType.SCHEDULE_DAILY,
187
+ workflow_id="my-workflow",
188
+ config_fields=[...] # User-configurable fields
189
+ )
190
+ class MyTrigger:
191
+ pass
192
+ ```
193
+
194
+ ## Integration Requirements
195
+
196
+ Agents can declare integration requirements (OAuth, API keys):
197
+
198
+ ```python
199
+ @agent(
200
+ id="slack-notifier",
201
+ integrations=[{
202
+ "service": "slack",
203
+ "auth_type": "oauth",
204
+ "description": "Connect your Slack workspace",
205
+ "scopes": ["chat:write"],
206
+ "config_fields": [{
207
+ "key": "bot_token",
208
+ "label": "Bot Token",
209
+ "type": "password",
210
+ "required": True
211
+ }]
212
+ }]
213
+ )
214
+ class SlackNotifierAgent(BaseAgent):
215
+ async def execute(self, context):
216
+ # Get user's connected Slack credentials
217
+ slack = context.get_integration("slack")
218
+
219
+ if not slack:
220
+ return AgentResult(
221
+ success=False,
222
+ error="Slack not connected"
223
+ )
224
+
225
+ # Use credentials
226
+ # ...
227
+ ```
228
+
229
+ ## Context Objects
230
+
231
+ ### AgentContext
232
+
233
+ Provided to agents during execution:
234
+
235
+ ```python
236
+ # Get input data
237
+ tasks = context.get_input("tasks", [])
238
+
239
+ # Get integration credentials
240
+ slack = context.get_integration("slack")
241
+
242
+ # Get workflow data
243
+ previous_result = context.get_workflow_data("previous_step")
244
+
245
+ # Get app config
246
+ api_key = context.get_config("api_key")
247
+
248
+ # Log
249
+ context.log("info", "Processing tasks", count=len(tasks))
250
+ ```
251
+
252
+ ### WorkflowContext
253
+
254
+ Provided to workflows:
255
+
256
+ ```python
257
+ # Get trigger data
258
+ trigger_data = context.get_trigger_data()
259
+
260
+ # Get step outputs
261
+ analysis = context.get_step_output("analysis")
262
+
263
+ # Log
264
+ context.log("info", "Workflow started")
265
+ ```
266
+
267
+ ## Trigger Template Types
268
+
269
+ | Type | Description | User Configures |
270
+ |------|-------------|-----------------|
271
+ | `SCHEDULE_DAILY` | Daily at specific time | Time, timezone, days |
272
+ | `SCHEDULE_CRON` | Custom cron expression | Cron expression, timezone |
273
+ | `SCHEDULE_INTERVAL` | Every X seconds | Interval duration |
274
+ | `DATA_THRESHOLD` | When value crosses threshold | Metric, threshold, operator |
275
+ | `DATA_CHANGE` | When database record changes | Table, operation, filter |
276
+ | `WEBHOOK` | External webhook | Endpoint, auth |
277
+ | `MANUAL` | User clicks button | Nothing (just execute) |
278
+
279
+ ## Config Field Types
280
+
281
+ For `config_fields` in trigger templates:
282
+
283
+ | Type | Description | Example |
284
+ |------|-------------|---------|
285
+ | `time` | Time picker (HH:MM) | "09:00" |
286
+ | `timezone` | Timezone selector | "America/New_York" |
287
+ | `number` | Numeric input | 42 |
288
+ | `text` | Text input | "My trigger" |
289
+ | `select` | Dropdown | "option1" |
290
+ | `multiselect` | Multiple choice | ["opt1", "opt2"] |
291
+ | `boolean` | Toggle | true |
292
+ | `cron` | Cron expression | "0 9 * * 1-5" |
293
+ | `secret` | Auto-generated secret | (hidden) |
294
+ | `date` | Date picker | "2026-02-18" |
295
+ | `datetime` | DateTime picker | "2026-02-18T09:00:00Z" |
296
+
297
+ ## Development
298
+
299
+ ### Install for Development
300
+
301
+ ```bash
302
+ git clone https://github.com/clarity-platform/clarity-sdk
303
+ cd clarity-sdk
304
+ pip install -e ".[dev]"
305
+ ```
306
+
307
+ ### Run Tests
308
+
309
+ ```bash
310
+ pytest
311
+ pytest --cov=clarity_sdk # With coverage
312
+ ```
313
+
314
+ ### Type Checking
315
+
316
+ ```bash
317
+ mypy clarity_sdk
318
+ ```
319
+
320
+ ### Formatting
321
+
322
+ ```bash
323
+ black clarity_sdk
324
+ ```
325
+
326
+ ## Examples
327
+
328
+ See the `/examples` directory for complete examples:
329
+
330
+ - `examples/task_manager/` - Task management app with Slack integration
331
+ - `examples/data_pipeline/` - Data processing pipeline with parallel execution
332
+ - `examples/chatbot/` - Conversational agent with memory
333
+
334
+ ## Documentation
335
+
336
+ - [Complete Design Document](../AGENTIC_APP_SEED_COMPLETE_DESIGN.md)
337
+ - [Trigger System Design](../TRIGGER_SYSTEM_DESIGN.md)
338
+ - [API Reference](https://docs.clarity.com/sdk)
339
+
340
+ ## Support
341
+
342
+ - **Discord**: https://discord.gg/clarity
343
+ - **Documentation**: https://docs.clarity.com
344
+ - **Issues**: https://github.com/clarity-platform/clarity-sdk/issues
345
+
346
+ ## License
347
+
348
+ MIT License - see [LICENSE](LICENSE) file for details.
349
+
350
+ ## Contributing
351
+
352
+ Contributions welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) first.
353
+
354
+ ---
355
+
356
+ **Built with โค๏ธ by the Clarity Platform team**
@@ -0,0 +1,17 @@
1
+ claritty_sdk-1.0.0.dist-info/licenses/LICENSE,sha256=e17pOMoFOeijUVj1fQs277Txrf1WM515hJeK7Say9Ik,1073
2
+ clarity_sdk/__init__.py,sha256=Vw2dPqUe03lVJPRyWlN3lXjUs573L43mslc6_jQHBfI,2231
3
+ clarity_sdk/agent.py,sha256=y4h-fgYIGMXDBSc26xHYUOcB5mSipDRMZBDikkkR97U,5637
4
+ clarity_sdk/base.py,sha256=MOvzZoUyVoh4jDZFTwSOMSTJda9D54i1RUKcdI9dN2Y,2450
5
+ clarity_sdk/context.py,sha256=TySicF8TXPV13OpBoMyBUhbKHNWuVtFvShjvnSYRVCs,8311
6
+ clarity_sdk/exceptions.py,sha256=PoChg9mbzR0m9q7hgVIenNXFkcOyraYmXM79h61tucc,800
7
+ clarity_sdk/executor.py,sha256=wgTu1ph7bfM47UHVDYvPfHoOvf65yvZsi5dOaHbFBTs,18919
8
+ clarity_sdk/models.py,sha256=Ecc34TAu0Oqx4E8i_8q1hZLY7cpSdcd2QmaZ4s_dr0c,7633
9
+ clarity_sdk/registry.py,sha256=2IfyExipnBPr73mB7UmGg-cth_GprC7qfuBmS8i9D24,5179
10
+ clarity_sdk/setup.py,sha256=7D29XJyKAiZ2pbNEITkTkz6cwPlI3A0tBNY7YPR7ZxY,1294
11
+ clarity_sdk/trigger.py,sha256=yCga59mBlkNHKGL5wqr6TR47Yaw3kKcmKmDNEz2cOhs,8882
12
+ clarity_sdk/trigger_manager.py,sha256=voGmjBGSX-MtkfjvscLpqF_3zIs3wtydmCjklFIVlnA,18743
13
+ clarity_sdk/workflow.py,sha256=WFKYSKhwA2Lv55XWeVlSUWshRcYIEJQnZOOVy1J9F7k,6998
14
+ claritty_sdk-1.0.0.dist-info/METADATA,sha256=u4VHY2JdUV3hfwJYPTQZAxRU0YSDV2lwaRm-LI0jx80,9380
15
+ claritty_sdk-1.0.0.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
16
+ claritty_sdk-1.0.0.dist-info/top_level.txt,sha256=mBhpBOZR9rCUlD2pYA243Avvlv49bCR498LhfbQ2dis,12
17
+ claritty_sdk-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Clarity Platform
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ clarity_sdk
@@ -0,0 +1,98 @@
1
+ """
2
+ Clarity SDK - Professional SDK for building AI-powered agentic applications
3
+
4
+ Provides decorators and utilities for defining:
5
+ - AI Agents (@agent)
6
+ - Workflows (@workflow, @uses_agent)
7
+ - Trigger Templates (@trigger_template)
8
+ - Integrations and context management
9
+
10
+ Example:
11
+ from clarity_sdk import agent, workflow, uses_agent, BaseAgent, AgentResult
12
+
13
+ @agent(
14
+ id="my-agent",
15
+ name="My Agent",
16
+ inputs={"text": str},
17
+ outputs={"result": str}
18
+ )
19
+ class MyAgent(BaseAgent):
20
+ async def execute(self, context):
21
+ return AgentResult(success=True, data={"result": "processed"})
22
+
23
+ @workflow(id="my-workflow")
24
+ @uses_agent("my-agent")
25
+ async def my_workflow(context):
26
+ pass
27
+ """
28
+
29
+ __version__ = "1.0.0"
30
+ __author__ = "Clarity Platform"
31
+
32
+ # Core decorators
33
+ from clarity_sdk.agent import agent
34
+ from clarity_sdk.workflow import workflow, uses_agent
35
+ from clarity_sdk.trigger import trigger_template, TriggerTemplateType
36
+
37
+ # Base classes
38
+ from clarity_sdk.base import BaseAgent, AgentResult
39
+
40
+ # Context objects
41
+ from clarity_sdk.context import AgentContext, WorkflowContext
42
+
43
+ # Registries (for advanced usage)
44
+ from clarity_sdk.registry import AgentRegistry, WorkflowRegistry, TriggerTemplateRegistry
45
+
46
+ # Exceptions
47
+ from clarity_sdk.exceptions import (
48
+ ClaritySDKError,
49
+ AgentError,
50
+ WorkflowError,
51
+ TriggerError,
52
+ ValidationError,
53
+ ExecutionError
54
+ )
55
+
56
+ # Enums
57
+ from clarity_sdk.workflow import ExecutionMode
58
+
59
+ # Executors (optional - for advanced usage)
60
+ from clarity_sdk.executor import WorkflowExecutor
61
+ from clarity_sdk.trigger_manager import DynamicTriggerManager
62
+
63
+ __all__ = [
64
+ # Decorators
65
+ "agent",
66
+ "workflow",
67
+ "uses_agent",
68
+ "trigger_template",
69
+
70
+ # Base classes
71
+ "BaseAgent",
72
+ "AgentResult",
73
+
74
+ # Context
75
+ "AgentContext",
76
+ "WorkflowContext",
77
+
78
+ # Registries
79
+ "AgentRegistry",
80
+ "WorkflowRegistry",
81
+ "TriggerTemplateRegistry",
82
+
83
+ # Enums
84
+ "ExecutionMode",
85
+ "TriggerTemplateType",
86
+
87
+ # Exceptions
88
+ "ClaritySDKError",
89
+ "AgentError",
90
+ "WorkflowError",
91
+ "TriggerError",
92
+ "ValidationError",
93
+ "ExecutionError",
94
+
95
+ # Executors (advanced)
96
+ "WorkflowExecutor",
97
+ "DynamicTriggerManager",
98
+ ]
clarity_sdk/agent.py ADDED
@@ -0,0 +1,163 @@
1
+ """
2
+ Agent decorator for defining AI agents
3
+
4
+ The @agent decorator registers agents with metadata and makes them
5
+ discoverable by the platform.
6
+
7
+ Example:
8
+ from clarity_sdk import agent, BaseAgent, AgentResult, AgentContext
9
+
10
+ @agent(
11
+ id="task-prioritizer",
12
+ name="Task Prioritizer",
13
+ description="Analyzes tasks and suggests priorities",
14
+ inputs={"tasks": list},
15
+ outputs={"priorities": dict},
16
+ category="productivity"
17
+ )
18
+ class TaskPrioritizerAgent(BaseAgent):
19
+ async def execute(self, context: AgentContext) -> AgentResult:
20
+ tasks = context.get_input("tasks", [])
21
+ # Your AI logic here
22
+ return AgentResult(success=True, data={"priorities": {}})
23
+ """
24
+
25
+ from typing import Dict, Any, List, Optional, Callable
26
+ from functools import wraps
27
+ from clarity_sdk.models import AgentMetadata, IntegrationRequirement
28
+ from clarity_sdk.registry import AgentRegistry
29
+ from clarity_sdk.exceptions import ValidationError, AgentError
30
+ import inspect
31
+
32
+
33
+ def agent(
34
+ id: str,
35
+ name: str,
36
+ description: str,
37
+ inputs: Dict[str, Any],
38
+ outputs: Dict[str, Any],
39
+ category: str = "general",
40
+ integrations: Optional[List[Dict[str, Any]]] = None,
41
+ capabilities: Optional[List[str]] = None,
42
+ version: str = "1.0.0",
43
+ rate_limit: Optional[Dict[str, int]] = None,
44
+ timeout: int = 300,
45
+ retry_policy: Optional[Dict[str, Any]] = None
46
+ ):
47
+ """
48
+ Decorator to define an AI agent with metadata.
49
+
50
+ The decorated class must inherit from BaseAgent and implement execute().
51
+
52
+ Args:
53
+ id: Unique agent identifier (lowercase, hyphens only)
54
+ name: User-facing name
55
+ description: What this agent does
56
+ inputs: Expected input schema (dict of key: type)
57
+ outputs: Expected output schema (dict of key: type)
58
+ category: Category for organization (default: "general")
59
+ integrations: List of integration requirements (optional)
60
+ capabilities: List of capability tags (optional)
61
+ version: Agent version (default: "1.0.0")
62
+ rate_limit: Rate limiting config {"calls": 100, "period": 3600}
63
+ timeout: Execution timeout in seconds (default: 300)
64
+ retry_policy: Retry configuration (optional)
65
+
66
+ Returns:
67
+ Decorated class with agent metadata
68
+
69
+ Raises:
70
+ ValidationError: If agent definition is invalid
71
+ TypeError: If class doesn't implement execute()
72
+
73
+ Example:
74
+ @agent(
75
+ id="slack-notifier",
76
+ name="Slack Notifier",
77
+ description="Send notifications to Slack",
78
+ inputs={"channel": str, "message": str},
79
+ outputs={"message_id": str, "success": bool},
80
+ category="integration",
81
+ integrations=[{
82
+ "service": "slack",
83
+ "auth_type": "oauth",
84
+ "description": "Connect your Slack workspace",
85
+ "scopes": ["chat:write"],
86
+ "config_fields": [{
87
+ "key": "bot_token",
88
+ "label": "Bot Token",
89
+ "type": "password",
90
+ "required": True
91
+ }]
92
+ }],
93
+ timeout=60
94
+ )
95
+ class SlackNotifierAgent(BaseAgent):
96
+ async def execute(self, context: AgentContext) -> AgentResult:
97
+ slack = context.get_integration("slack")
98
+ if not slack:
99
+ return AgentResult(
100
+ success=False,
101
+ error="Slack not connected"
102
+ )
103
+ # Send to Slack...
104
+ return AgentResult(success=True, data={...})
105
+ """
106
+
107
+ def decorator(cls):
108
+ # Validate class has execute method
109
+ if not hasattr(cls, 'execute'):
110
+ raise TypeError(
111
+ f"Agent class {cls.__name__} must implement execute() method. "
112
+ f"Make sure your class inherits from BaseAgent."
113
+ )
114
+
115
+ # Validate execute is async
116
+ execute_method = getattr(cls, 'execute')
117
+ if not inspect.iscoroutinefunction(execute_method):
118
+ raise TypeError(
119
+ f"Agent {cls.__name__}.execute() must be an async method. "
120
+ f"Use: async def execute(self, context)"
121
+ )
122
+
123
+ # Parse integrations
124
+ integration_objs = []
125
+ if integrations:
126
+ try:
127
+ for integ in integrations:
128
+ integration_objs.append(IntegrationRequirement(**integ))
129
+ except Exception as e:
130
+ raise ValidationError(f"Invalid integration requirement: {e}")
131
+
132
+ # Create metadata
133
+ try:
134
+ metadata = AgentMetadata(
135
+ id=id,
136
+ name=name,
137
+ description=description,
138
+ version=version,
139
+ category=category,
140
+ inputs=inputs,
141
+ outputs=outputs,
142
+ integrations=integration_objs,
143
+ capabilities=capabilities or [],
144
+ rate_limit=rate_limit,
145
+ timeout=timeout,
146
+ retry_policy=retry_policy or {"max_retries": 3, "backoff": "exponential"}
147
+ )
148
+ except Exception as e:
149
+ raise ValidationError(f"Invalid agent metadata for {id}: {e}")
150
+
151
+ # Store metadata on class
152
+ cls._clarity_metadata = metadata
153
+ cls._clarity_type = "agent"
154
+
155
+ # Register agent globally
156
+ AgentRegistry.register(metadata, cls)
157
+
158
+ # Add helper methods to class
159
+ cls.get_metadata = classmethod(lambda c: metadata)
160
+
161
+ return cls
162
+
163
+ return decorator