cycls 0.0.2.93__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,282 @@
1
+ Metadata-Version: 2.4
2
+ Name: cycls
3
+ Version: 0.0.2.93
4
+ Summary: Distribute Intelligence
5
+ Author-email: "Mohammed J. AlRujayi" <mj@cycls.com>
6
+ Requires-Python: >=3.10
7
+ Requires-Dist: cloudpickle>=3.1.1
8
+ Requires-Dist: docker>=7.1.0
9
+ Requires-Dist: email-validator>=2.0.0
10
+ Requires-Dist: fastapi>=0.111.0
11
+ Requires-Dist: httpx>=0.27.0
12
+ Requires-Dist: pyjwt>=2.8.0
13
+ Requires-Dist: uvicorn>=0.30.0
14
+ Requires-Dist: watchfiles>=1.0.0
15
+ Provides-Extra: state
16
+ Requires-Dist: agentfs-sdk==0.4.0; extra == 'state'
17
+ Description-Content-Type: text/markdown
18
+
19
+ <h3 align="center">
20
+ Distribute Intelligence
21
+ </h3>
22
+
23
+ <h4 align="center">
24
+ <a href="https://cycls.com">Website</a> |
25
+ <a href="https://docs.cycls.com">Docs</a> |
26
+ <a href="docs/tutorial.md">Tutorial</a>
27
+ </h4>
28
+
29
+ <h4 align="center">
30
+ <a href="https://pypi.python.org/pypi/cycls"><img src="https://img.shields.io/pypi/v/cycls.svg?label=cycls+pypi&color=blueviolet" alt="cycls Python package on PyPi" /></a>
31
+ <a href="https://github.com/Cycls/cycls/actions/workflows/tests.yml"><img src="https://github.com/Cycls/cycls/actions/workflows/tests.yml/badge.svg" alt="Tests" /></a>
32
+ <a href="https://blog.cycls.com"><img src="https://img.shields.io/badge/newsletter-blueviolet.svg?logo=substack&label=cycls" alt="Cycls newsletter" /></a>
33
+ <a href="https://x.com/cyclsai">
34
+ <img src="https://img.shields.io/twitter/follow/CyclsAI" alt="Cycls Twitter" />
35
+ </a>
36
+ </h4>
37
+
38
+ ---
39
+
40
+ # Cycls
41
+
42
+ The open-source SDK for distributing AI agents.
43
+
44
+ ```
45
+ Agent extends App (prompts, skills)
46
+ └── App extends Function (web UI)
47
+ └── Function (containerization)
48
+ ```
49
+
50
+ ## Distribute Intelligence
51
+
52
+ Write a function. Deploy it as an API, a web interface, or both. Add authentication, analytics, and monetization with flags.
53
+
54
+ ```python
55
+ import cycls
56
+
57
+ cycls.api_key = "YOUR_CYCLS_API_KEY"
58
+
59
+ @cycls.app(pip=["openai"])
60
+ async def app(context):
61
+ from openai import AsyncOpenAI
62
+ client = AsyncOpenAI()
63
+
64
+ stream = await client.responses.create(
65
+ model="o3-mini",
66
+ input=context.messages,
67
+ stream=True,
68
+ reasoning={"effort": "medium", "summary": "auto"},
69
+ )
70
+
71
+ async for event in stream:
72
+ if event.type == "response.reasoning_summary_text.delta":
73
+ yield {"type": "thinking", "thinking": event.delta} # Renders as thinking bubble
74
+ elif event.type == "response.output_text.delta":
75
+ yield event.delta
76
+
77
+ app.deploy() # Live at https://agent.cycls.ai
78
+ ```
79
+
80
+ ## Installation
81
+
82
+ ```bash
83
+ pip install cycls
84
+ ```
85
+
86
+ Requires Docker. See the [full tutorial](docs/tutorial.md) for a comprehensive guide.
87
+
88
+ ## What You Get
89
+
90
+ - **Streaming API** - OpenAI-compatible `/chat/completions` endpoint
91
+ - **Web Interface** - Chat UI served automatically
92
+ - **Authentication** - `auth=True` enables JWT-based access control
93
+ - **Analytics** - `analytics=True` tracks usage
94
+ - **Monetization** - `plan="cycls_pass"` integrates with [Cycls Pass](https://cycls.ai) subscriptions
95
+ - **Native UI Components** - Render thinking bubbles, tables, code blocks in responses
96
+
97
+ ## Running
98
+
99
+ ```python
100
+ app.local() # Development with hot-reload (localhost:8080)
101
+ app.local(watch=False) # Development without hot-reload
102
+ app.deploy() # Production: https://agent.cycls.ai
103
+ ```
104
+
105
+ Get an API key at [cycls.com](https://cycls.com).
106
+
107
+ ## Authentication & Analytics
108
+
109
+ See the [tutorial](docs/tutorial.md#authentication) for full auth and monetization examples.
110
+
111
+ ```python
112
+ @cycls.app(pip=["openai"], auth=True, analytics=True)
113
+ async def app(context):
114
+ # context.user available when auth=True
115
+ user = context.user # User(id, email, name, plans)
116
+ yield f"Hello {user.name}!"
117
+ ```
118
+
119
+ | Flag | Description |
120
+ |------|-------------|
121
+ | `auth=True` | Universal user pool via Cycls Pass (Clerk-based). You can also use your own Clerk auth. |
122
+ | `analytics=True` | Rich usage metrics available on the Cycls dashboard. |
123
+ | `plan="cycls_pass"` | Monetization via Cycls Pass subscriptions. Enables both auth and analytics. |
124
+
125
+ ## Native UI Components
126
+
127
+ Yield structured objects for rich streaming responses. See the [tutorial](docs/tutorial.md#native-ui-components) for all component types and examples.
128
+
129
+ ```python
130
+ @cycls.app()
131
+ async def demo(context):
132
+ yield {"type": "thinking", "thinking": "Analyzing the request..."}
133
+ yield "Here's what I found:\n\n"
134
+
135
+ yield {"type": "table", "headers": ["Name", "Status"]}
136
+ yield {"type": "table", "row": ["Server 1", "Online"]}
137
+ yield {"type": "table", "row": ["Server 2", "Offline"]}
138
+
139
+ yield {"type": "code", "code": "result = analyze(data)", "language": "python"}
140
+ yield {"type": "callout", "callout": "Analysis complete!", "style": "success"}
141
+ ```
142
+
143
+ | Component | Streaming |
144
+ |-----------|-----------|
145
+ | `{"type": "thinking", "thinking": "..."}` | Yes |
146
+ | `{"type": "code", "code": "...", "language": "..."}` | Yes |
147
+ | `{"type": "table", "headers": [...]}` | Yes |
148
+ | `{"type": "table", "row": [...]}` | Yes |
149
+ | `{"type": "status", "status": "..."}` | Yes |
150
+ | `{"type": "callout", "callout": "...", "style": "..."}` | Yes |
151
+ | `{"type": "image", "src": "..."}` | Yes |
152
+
153
+ ### Thinking Bubbles
154
+
155
+ The `{"type": "thinking", "thinking": "..."}` component renders as a collapsible thinking bubble in the UI. Each yield appends to the same bubble until a different component type is yielded:
156
+
157
+ ```python
158
+ # Multiple yields build one thinking bubble
159
+ yield {"type": "thinking", "thinking": "Let me "}
160
+ yield {"type": "thinking", "thinking": "analyze this..."}
161
+ yield {"type": "thinking", "thinking": " Done thinking."}
162
+
163
+ # Then output the response
164
+ yield "Here's what I found..."
165
+ ```
166
+
167
+ This works seamlessly with OpenAI's reasoning models - just map reasoning summaries to the thinking component.
168
+
169
+ ## Context Object
170
+
171
+ ```python
172
+ @cycls.app()
173
+ async def chat(context):
174
+ context.messages # [{"role": "user", "content": "..."}]
175
+ context.messages.raw # Full data including UI component parts
176
+ context.user # User(id, email, name, plans) when auth=True
177
+ ```
178
+
179
+ ## API Endpoints
180
+
181
+ | Endpoint | Format |
182
+ |----------|--------|
183
+ | `POST chat/cycls` | Cycls streaming protocol |
184
+ | `POST chat/completions` | OpenAI-compatible |
185
+
186
+ ## Streaming Protocol
187
+
188
+ Cycls streams structured components over SSE:
189
+
190
+ ```
191
+ data: {"type": "thinking", "thinking": "Let me "}
192
+ data: {"type": "thinking", "thinking": "analyze..."}
193
+ data: {"type": "text", "text": "Here's the answer"}
194
+ data: {"type": "callout", "callout": "Done!", "style": "success"}
195
+ data: [DONE]
196
+ ```
197
+
198
+ See [docs/streaming-protocol.md](docs/streaming-protocol.md) for frontend integration.
199
+
200
+ ## Declarative Infrastructure
201
+
202
+ Define your entire runtime in the decorator. See the [tutorial](docs/tutorial.md#declarative-infrastructure) for more details.
203
+
204
+ ```python
205
+ @cycls.app(
206
+ pip=["openai", "pandas", "numpy"],
207
+ apt=["ffmpeg", "libmagic1"],
208
+ copy=["./utils.py", "./models/", "/absolute/path/to/config.json"],
209
+ copy_public=["./assets/logo.png", "./static/"],
210
+ )
211
+ async def my_app(context):
212
+ ...
213
+ ```
214
+
215
+ ### `pip` - Python Packages
216
+
217
+ Install any packages from PyPI. These are installed during the container build.
218
+
219
+ ```python
220
+ pip=["openai", "pandas", "numpy", "transformers"]
221
+ ```
222
+
223
+ ### `apt` - System Packages
224
+
225
+ Install system-level dependencies via apt-get. Need ffmpeg for audio processing? ImageMagick for images? Just declare it.
226
+
227
+ ```python
228
+ apt=["ffmpeg", "imagemagick", "libpq-dev"]
229
+ ```
230
+
231
+ ### `copy` - Bundle Files and Directories
232
+
233
+ Include local files and directories in your container. Works with both relative and absolute paths. Copies files and entire directory trees.
234
+
235
+ ```python
236
+ copy=[
237
+ "./utils.py", # Single file, relative path
238
+ "./models/", # Entire directory
239
+ "/home/user/configs/app.json", # Absolute path
240
+ ]
241
+ ```
242
+
243
+ Then import them in your function:
244
+
245
+ ```python
246
+ @cycls.app(copy=["./utils.py"])
247
+ async def chat(context):
248
+ from utils import helper_function # Your bundled module
249
+ ...
250
+ ```
251
+
252
+ ### `copy_public` - Static Files
253
+
254
+ Files and directories served at the `/public` endpoint. Perfect for images, downloads, or any static assets your agent needs to reference.
255
+
256
+ ```python
257
+ copy_public=["./assets/logo.png", "./downloads/"]
258
+ ```
259
+
260
+ Access them at `https://your-app.cycls.ai/public/logo.png`.
261
+
262
+ ---
263
+
264
+ ### What You Get
265
+
266
+ - **One file** - Code, dependencies, configuration, and infrastructure together
267
+ - **Instant deploys** - Unchanged code deploys in seconds from cache
268
+ - **No drift** - What you see is what runs. Always.
269
+ - **Just works** - Closures, lambdas, dynamic imports - your function runs exactly as written
270
+
271
+ No YAML. No Dockerfiles. No infrastructure repo. The code is the deployment.
272
+
273
+ ## Learn More
274
+
275
+ - [Tutorial](docs/tutorial.md) - Comprehensive guide from basics to advanced
276
+ - [Streaming Protocol](docs/streaming-protocol.md) - Frontend integration
277
+ - [Runtime](docs/runtime.md) - Containerization details
278
+ - [Examples](examples/) - Working code samples
279
+
280
+ ## License
281
+
282
+ MIT
@@ -0,0 +1,15 @@
1
+ cycls/__init__.py,sha256=efbq0vRijGOByKtz9bRF8WQFYmnPSgZV1DH-54s6iwQ,493
2
+ cycls/app.py,sha256=_-RoN8JuNE7fWSOHk80GpQ2GyaoXv-vtUWc_W8tDzm0,3243
3
+ cycls/auth.py,sha256=xkndHZyCfnlertMMEKerCJjf23N3fVcTRVTTSXTTuzg,247
4
+ cycls/cli.py,sha256=cVbIkTDnVofohvByyYUrXF_RYDQZVQECJqo7cPBPJfs,4781
5
+ cycls/function.py,sha256=FP94mCd5hfCASFwsTSYny7KOEsJOh3LME9oZgiVfgzo,14795
6
+ cycls/state.py,sha256=3RL_BqcbfiAkJ6byeEo4Q9L99VurYyYKYJJhJhEVmAo,210
7
+ cycls/web.py,sha256=v-hyWL9nlh4SyqAVgRzOkx96YuBntxqw6Q6phpAMDv0,6172
8
+ cycls/themes/default/index.html,sha256=L8tZ4RktYhVlmp48bT3Q-dvpFxz40uMHqQ_MRHoyX0s,1082
9
+ cycls/themes/default/assets/index-Xh0IeurI.js,sha256=P2jy3GnsJfxlD5X06qm2yt4_LYHOcQN4LvYRBkHQSho,1356696
10
+ cycls/themes/default/assets/index-oGkkm3Z8.css,sha256=xHhbrJvvz8mIN_Otrl6nawKJcA41L3tCFhVEOstGhVU,6498
11
+ cycls/themes/dev/index.html,sha256=QJBHkdNuMMiwQU7o8dN8__8YQeQB45D37D-NCXIWB2Q,11585
12
+ cycls-0.0.2.93.dist-info/METADATA,sha256=rl9q236k7yvmSS2tlu1BTm_Z0VZsob1OvU4dC73kc4M,8869
13
+ cycls-0.0.2.93.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
14
+ cycls-0.0.2.93.dist-info/entry_points.txt,sha256=CktT5eNvW_Qxomf7L_Ez_GdUbL6qAfx_Utm6_HtUJwE,41
15
+ cycls-0.0.2.93.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ cycls = cycls.cli:main