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.
- claritty_sdk-1.0.0.dist-info/METADATA +356 -0
- claritty_sdk-1.0.0.dist-info/RECORD +17 -0
- claritty_sdk-1.0.0.dist-info/WHEEL +5 -0
- claritty_sdk-1.0.0.dist-info/licenses/LICENSE +21 -0
- claritty_sdk-1.0.0.dist-info/top_level.txt +1 -0
- clarity_sdk/__init__.py +98 -0
- clarity_sdk/agent.py +163 -0
- clarity_sdk/base.py +97 -0
- clarity_sdk/context.py +289 -0
- clarity_sdk/exceptions.py +43 -0
- clarity_sdk/executor.py +551 -0
- clarity_sdk/models.py +191 -0
- clarity_sdk/registry.py +158 -0
- clarity_sdk/setup.py +44 -0
- clarity_sdk/trigger.py +251 -0
- clarity_sdk/trigger_manager.py +554 -0
- clarity_sdk/workflow.py +213 -0
|
@@ -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,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
|
clarity_sdk/__init__.py
ADDED
|
@@ -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
|