Skip to main content
Every version listed here is published on PyPI. Upgrade with pip install -U cycls.
v0.0.2.145
Tool settings no longer need the secret key. A person’s built-in tool settings, set from the card’s Always allow, the tool permissions in Settings or the Memory switch, are stored as plain settings instead of encrypted credentials. They work on every deployment. Before, a deployment without CYCLS_SECRET_KEY failed every message from anyone who had clicked Always allow. The key is now needed only for connectors.A missing key degrades. Without CYCLS_SECRET_KEY, stored connector grants read as absent and a warning is logged, the same as after a key rotation. Storing a grant still fails.Stricter bash reads. A command counts as a read only when every command in the line reads and nothing is redirected into a file, so ls; touch notes.txt is a write. find -delete always asks, because it deletes without going through the trash.Built-in tool settings saved before this release are not carried over, so anyone who chose Always allow is asked again until they choose it once more.
v0.0.2.144
Compaction in two steps. Past 70% of the context window, the loop first replaces old tool results and long tool arguments with a placeholder, which needs no model call. It summarizes only when that would free less than 25% of the window, and keeps the most recent 30% verbatim either way. The trigger also leaves room for .max_tokens(). Clearing never touches a loaded skill, and the system prompt and AGENT.md are never cleared or summarized. See Long conversations.Cheaper summaries. A summary is requested as the loop’s own next turn, with the same system prompt and tools, so the provider serves the conversation from its cache. A run that ends past the trigger summarizes before it closes, while the answer is being read, so the next message does not wait. A chat that resumes after 20 minutes idle is cleared at a lower bar, since the provider’s cache has mostly expired by then.Bounded reads. One read returns at most 50,000 characters and says where to continue. Attachments go through read, so a single large file can no longer overflow the window before the model runs.Instructions. AGENT.md opens from an Instructions tile in the dock at the bottom of the right panel, in the canvas editor, and no longer appears in Files. An empty file opens with examples to start from.Memory in Settings. Settings, General, Memory lists what the database tool has saved for the person as plain-text notes they can edit, or delete with Undo. The switch that turns the tool off moved here from Tool permissions. New routes: GET /memory, PUT /memory/{key} and DELETE /memory/{key}.A markdown editor. Markdown files edit in a rich editor with a toolbar, a / menu, drag handles, checklists and tables. Images and videos added to a document are saved in a media/ folder beside it, and the markdown view shows them. Each block takes its direction from its own text, so Arabic and English mix. Markdown with math, HTML or footnotes still edits as plain text.Also in this release
  • Every compaction writes a level=compaction log record with its tier, reason, size and outcome, and the web client tracks it as context_compacted.
  • A summary that fails, returns no text or runs past five minutes drops the older turns, so the next request still fits.
  • SGLang’s context-full error is recognized, so the loop compacts and replays instead of showing the raw error.
  • compact() in the custom loop kit now takes keep and max_tokens. session.compact(provider) works as before.
  • Dark mode styles follow the theme chosen in the app, not the operating system.
v0.0.2.143
Ships the current web client again. The 0.0.2.142 package carried a browser bundle from before the 0.0.2.141 client changes, so apps could not reach their data through the bridge and Settings showed Connectors on deployments that declare none. Upgrade if you deployed 0.0.2.142.
v0.0.2.142
Fewer approval cards. A destructive command now has to be an actual invocation, so shredder.py or a grep for the word truncate no longer asks. dd asks only when it names an of=. 2>/dev/null no longer counts as destructive, and a redirect into a disk device now does.
v0.0.2.141
Connectors. A user connects an account once and the tools that need it get a live credential. cycls.OAuth2 runs authorization code with PKCE, cycls.Key takes a pasted key, and cycls.Endpoint accepts a private URL that is itself the credential. Declare them on Web().connectors() for the directory and LLM().connectors() for the loop. Credentials are encrypted at rest, calls are audited with the grant they acted under, and an organization admin can switch a connector off for everyone.Per-tool approvals. Every call is classified as read, write or destructive. Reads always run, writes follow the composer’s Auto switch, and destructive calls ask in both modes. An approval binds to the exact arguments shown on the card, so a changed call asks again. Each person can set allow, ask or never per tool.MCP on every provider. The harness speaks Streamable HTTP itself, so cycls.MCP servers work on any model rather than Anthropic only. Tools are discovered once and cached, and a session opens only when a tool is called. .server_side() still hands a server to Anthropic’s connector.Tools load on demand. A connector contributes one index line to the system prompt, and the model calls find_tools to pull in the schemas it needs. Loaded tools stay for the rest of the conversation.Background runs. A run now records its own state, survives a dropped connection, and can be stopped from another container. The client watches a run it started, reconnects to it, and shows a background indicator. Web().on_run() fires once when a run reaches any terminal status.Durable turns. The user’s message is written to disk before the model is called, turn writes refuse to overwrite, and a reader normalizes in memory while only the writer repairs on disk.Browser automation. Adding "Browser" to allowed_tools gives the model a real Chrome session: open, read, click, type, press, back, evaluate, screenshot and download, with page state persisting across calls in a turn. Chrome runs in a shared service configured by BROWSER_URL and BROWSER_SECRET, not in the agent image. Includes per-site proxy routing and a stealth engine.Office files on the canvas. Spreadsheets render as an interactive grid and .docx as a formatted document, both in the browser. Presentations render as a slide viewer and other office formats as a read-only PDF through the shared render service. Any failure falls back to the download card.Apps. The Apps tool bundles a source folder into one self-contained HTML file installed in the Apps tab. App data is rows in a dedicated slot with compare-and-swap writes and a 25 MB cap, and an app can call a connected connector’s REST API with the credential attached server-side.Analytics as plugins. One canonical event pipe in the client fanned out to cycls.PostHog and cycls.GTM, each scoped by an optional event allowlist. cycls.OneSignal adds web push.Also in this release
  • Large tool results spill to a file to compute over instead of being read back as text.
  • .tmp/{chat} is the agent’s TMPDIR, and /tmp fails with an explicit reason.
  • Tool handlers can declare a second parameter to receive a ToolContext with the user, workspace and chat.
  • Google One Tap on the signed-out page, opt in with cycls.Clerk(one_tap=True).
  • Search results collapse into one sources row at the end of an answer.
  • A shared chat forks into the forker’s active workspace.
  • The base image is pinned to bookworm, because the sandbox needs a syscall the newer runtime lacks.
shipped in v0.0.2.141
  • Mini apps end to end. A build_app tool, a sandboxed bridge scoped to apps/<slug>/, and an Apps launcher.
  • Canvas. Deliverables open while they are being written, tabs share the strip and shrink like a browser’s, the rail folds to icons, and the composer keeps working while the agent does.
  • Example gallery. Web().examples() turns real share links into cards on the empty chat screen, with an optional tutorial video card.
  • Suggest and Ask. One follow-up chip above the composer, and a question card with up to three questions that ends the turn.
  • Apple IAP per product. products takes a mapping of product id to plan, and verification hands back the payload.
  • Transient 500s from model servers are retried, since capacity failures surface that way.
  • web_search searches before answering, with Brave country and language passthrough.
  • Provider clients are cached on the full configuration, .headers() carries proxy authentication, and unmapped .thinking() values print a warning.
v0.0.2.133 to v0.0.2.140
  • Workspaces. Web().workspaces() gives every user a personal workspace and lets organizations share team workspaces with role-based access. Each workspace is a full context: files, chats, AGENT.md, skills and key-value store. The active one is selected per request with the X-Workspace header.
  • Skills. LLM().skills("skills") ships skill folders with the agent, and any skills/<name>/SKILL.md in a user’s workspace joins the catalog automatically. Only names and descriptions sit in the system prompt.
  • Unified reasoning. .thinking("low" | "medium" | "high" | "adaptive" | None) is translated into each vendor’s dialect, with .extra_body() as the escape hatch.
  • Faster import. import cycls went from about 1.0s to about 40ms through lazy imports and private subpackages.
  • Agent routes cross the pickle boundary as data rather than router instances.
  • Failures that affect a user surface as a callout with a reference id, while plumbing goes to structured logs.
  • The file picker and browser share one cached walk, with matching and ordering moved server-side.
shipped in v0.0.2.133
  • Document canvas. In-chat canvas with media, PDF and sheet renderers, a Finder-like workspace view, and safe uploads.
  • Composer mentions and paste. Reference workspace files with @, and paste images directly.
  • Affiliate tracking. Web().affiliate(key) loads a referral tracker and reports conversions at checkout.
  • The canvas tool opens finished deliverables only, not transient files.
v0.0.2.127 to v0.0.2.132
  • Cost tracking. Per-turn usage, per-chat aggregates, and cycls cost with --since, --month and --by user|chat|model.
  • cycls sql. SQL over the logs and billing tables, scoped to the deployments your key owns.
  • Structured logging. cycls.log() emits one record with user and chat attribution. Errors carry a reference id shown to the user, and every tool dispatch emits a tool_call record.
  • Cheaper prompts. Three cache breakpoints on the system prompt, the last tool and the last user turn, which cut cached input cost substantially on Anthropic.
  • Providers moved to one file each behind a neutral shape, with per-provider context window and max output tables.
  • Loop events became dict factories, which is why cycls.to_ui is now an identity function kept for compatibility.
  • Chat storage moved to a one-folder layout with glob scans.
v0.0.2.120 to v0.0.2.126
  • The primitives API. cycls.Image, cycls.Web and cycls.LLM replaced keyword arguments on the decorators. Each is an immutable fluent builder.
  • The CLI. cycls run, deploy, ls, rm, logs, init and version.
  • OpenAI adapter. One Chat Completions path covering every OpenAI-compatible endpoint, alongside the native Anthropic path.
  • Custom tool handlers. LLM().on(name, handler) registers an async function whose return value reaches both the UI and the model.
  • HTTP routes on agents. @my_agent.server.api_route(...) adds routes to the same deployment.
  • cycls.Sandbox. Bubblewrap execution as its own primitive, with secure defaults.
  • Live shares. Stateless signed URLs replaced frozen share snapshots.
  • PDF page extraction for large files, and cost plus duration in the usage footer.
v0.0.2.117 to v0.0.2.119
  • The chat client. A React interface with streaming, file uploads, a file manager, session list, rename and delete.
  • Share links. Conversations render as public pages with generated social preview images, including Arabic and right-to-left layouts.
  • Arabic. Full interface translation with a language toggle, plus localized sign-in.
  • Voice input. Dictation in the composer, with long-press to record.
  • Plans and organizations. Plan badges, an organization switcher, a pricing modal, and ?plan= to open checkout directly.
  • Branding from a CMS. Logo, name and description pulled at startup.
  • LaTeX rendering, drag and drop uploads, auto-retry on connection errors, and an explore dropdown for related agents.
v0.0.2.103 to v0.0.2.116
  • The native agent harness. A direct Anthropic loop with history, prompt caching and compaction, replacing the subprocess approach.
  • Sandboxed bash. Bubblewrap isolation with environment stripping, and editor paths restricted to the workspace.
  • Sessions and files API. List, load, rename and delete chats, plus full file endpoints.
  • Attachments. Upload limits, media sniffing, and recovery from API errors inside the loop.
  • Organizations in the JWT. Organization claims reach context.user.
  • Per-turn token usage and cost display, and incremental saves during a turn.
v0.0.2.63 to v0.0.2.102
  • Streaming UI components. Yield dicts for thinking bubbles, code blocks, tables, callouts, status lines and images.
  • The function runtime. @cycls.function with local Docker execution, hot reload on save, and pre-built base images.
  • Volumes and state. Persistent key-value and filesystem storage for deployments.
  • Automatic dotenv loading. A .env bundled with the image is loaded at import, with no extra dependency.
  • context.last_message and the Messages wrapper with .raw.
  • Moved from Poetry to uv, added the test suite and CI.
v0.0.2.62
  • Deployment moved to a two-step upload flow, which lifted the practical limit on build context size.
  • Error propagation from the container reached the interface instead of failing silently.
v0.0.2.52
  • The chat interface was redesigned and gained image attachments.
  • Cycls Cloud went live for serverless deployment.
  • A single key parameter replaced the several per-service keys.
  • copy_public made it simple to ship static assets.
first public release
  • Cycls became open source at github.com/Cycls/cycls.
  • Decorator configuration for dependencies and authentication.
  • Every deployed agent served a streaming OpenAI-compatible endpoint.
  • Automatic web chat interface, with user and context management for multi-turn agents.