cycls.Web configures everything the user sees and the identity behind it. Pass
it to @cycls.agent(web=...).

The empty-chat screen uses the brand name, description and logo.
Branding
name, description, logo and brand are per locale, so call .brand()
again with "ar" for Arabic. Image paths are read at build time, SVGs inlined
and rasters embedded as data URIs, so assets do not need to ship with the
container.
Pulling copy from a CMS
.brand() call overrides the CMS for exactly that
field and no other.
Theme and colors
primary drives highlights and active states, secondary drives chips and
bubbles. The _dark variants override dark mode and default to the light values.
The empty-chat screen
- Suggestions
- Example gallery
SEO and social
.seo() covers the page title and meta description when they should differ from
the brand copy. .head() appends raw HTML to <head> and is repeatable.
Every agent also serves /og.png, a generated social preview, plus
/robots.txt, /sitemap.xml and /llms.txt.
Static files
https://your-agent.cycls.ai/public/logo.png.
Uploads
Analytics and push
.analytics(True) is shorthand for the PostHog default. Providers are plugins
over one canonical event pipe, and each can be scoped with an events allowlist.
.notifications() adds web push, where the permission card is ours and the
trigger is a platform decision.
Reacting to finished runs
Method reference
Next
Authentication
Clerk, any OIDC provider, and what lands in
context.user.