Product

Changelog

Every change we ship, in the order we ship it. Bigger stories get written up on the blog.

July 2026

Feature

Fork a shared notebook with the author's variables intact

A fork arrived looking identical to the original and raised NameError on the first cell you ran, because the charts travelled and the memory behind them did not.

Forking a shared notebook copied its branches, cells, executions and outputs, so the copy looked exactly like the original: every chart in place, every result visible. Then you ran a cell and it raised NameError on a variable the output in front of you had plainly been computed from. The kernel was empty, because a fork never carried the author's saved state. That reads as a broken fork, and reasonably so.

Authors can now opt in. The share dialog has a "fork with your variables" toggle, nested under the fork setting because it means nothing without it, and off by default. That default is deliberate: a saved kernel is your entire namespace, including loaded DataFrames, API responses and model weights. Sharing your code and results is one decision; sharing your memory is a separate one, and none of the shares that already exist start carrying state retroactively. When state is included, the person forking is told before it lands and chooses what to copy.

It is best-effort by design. A fork will never fail over state it could not bring: if the saved state is missing, too large (the ceiling is 256 MiB, since each fork takes its own copy) or otherwise unavailable, the fork still succeeds and simply says it arrived without variables. One caveat worth knowing: what travels is your current saved state at the moment of the fork, not a frozen copy from when you shared the notebook.

Forking also used to fail outright, with a server error, on any shared notebook that had actually been run. The copy wrote a column to the executions table that has never existed, and the database rejects the whole write over one unknown field, so only notebooks that had never been executed could be forked. That has been fixed too.

Improvement

The model menu is organised by who pays for the model

A flat list was fine at six models and stopped being fine at eighteen.

The model picker has grown to eighteen entries spanning three quite different arrangements, and it was still one undivided list. It now has sections that name the distinction that matters: Clusy credits for models we serve, Your API key for models running on a key you have connected, and Your machine for CLIs running on a paired computer of yours.

Older models fold away behind a single row rather than padding out the list, and a model your plan does not include now names the plan that would unlock it instead of a generic prompt to upgrade, so you can tell at a glance whether it is one tier away or three. A model with a live outage is shown as unavailable with the reason attached, and is kept out of the upgrade suggestions entirely, since pointing at a broken model as the reason to pay is a poor welcome. Whatever you have selected always stays visible, even when it would otherwise sit inside a collapsed group.

Improvement

Long output folds away, and figures fit their cell

A cell that printed thousands of lines pushed the rest of the notebook off the screen, and a Plotly figure kept the width it was authored at.

Text output no longer runs unbounded down the page. Anything past roughly two dozen lines gets a header with its line count, a copy button and an expand control, and the output itself is capped until you open it. A training loop that prints for ten minutes now stays a tidy block you can scroll inside instead of burying every cell below it.

Plotly figures carried the width and height they were authored with straight into the notebook. The width made wide figures overflow their cell, and the height was ignored in favour of a fixed one, which quietly clipped the bottom of taller plots. Figures now size themselves to the cell they are in, keep the height they asked for, and have a full-screen control for when the inline size is not enough.

The agent has been told to match: display a DataFrame, a figure or a rendered formula directly rather than printing a text approximation of it, and to trust the full-screen control rather than shrinking or splitting a figure to fit. Symbolic maths in particular used to arrive as terminal-formatted matrices that wrapped badly at narrow widths; it now comes through as typeset output.

Improvement

Usage limits now count sandbox time, and hold during a long run

Both limits were only sampled when a turn began, and sandbox time did not count until the session closed, so a single long run could pass every check and then spend freely.

Clusy's usage limits had three holes that all pointed the same way. They were checked only at the moment a turn started, so a turn that ran for hours was unbounded once it had begun. Sandbox time did not enter the ledger until the session closed, which meant an open sandbox counted as nothing at all while it ran, despite being most of what a session actually costs. And the free-model fair-use window was a rolling five hours, which is refunded simply by waiting: idle for five hours and the meter cleared itself.

All three are closed. The remaining budget now rides into the run and is re-checked as it goes, sandbox time accrues while the sandbox is open rather than at the end, and the fair-use window is a calendar day, which cannot be reset by waiting. When a run does reach a limit it stops gracefully at the next step, with a small allowance to finish landing the notebook in a coherent state rather than stopping mid-edit. Nothing is killed in flight, which has been the rule since July 8.

Two follow-ups shipped alongside. The pause message no longer misdiagnoses why it appeared: it used to tell you your pay-as-you-go budget was exhausted, which is impossible on a Free plan, where pay-as-you-go cannot be enabled. And a run on a free promotional model is no longer cut short by the allowance meter, which does not count that model's usage in the first place. That regression was live for part of July 26 and cut some sessions off several times in a few minutes.

Fix

A check on the sign-in code request, and a block on six abusive domains

The endpoint that emails your sign-in code took requests from anyone, which is how sixty automated accounts were minted in a few days.

Asking Clusy to email you a sign-in code was an unauthenticated request, so it could be driven in bulk against any list of addresses: our email sender used as somebody else's, and throwaway accounts created faster than they could be found. That request now carries a Cloudflare Turnstile check. In practice you will usually see nothing at all, because the challenge only becomes visible when the signal is ambiguous, and it applies only to the emailed-code path. Signing in with Google and entering a code you have already received are unaffected.

Sixty accounts across six disposable-email domains were behind most of the recent abuse, all plainly automated: machine-generated usernames, no name on any of the sixty, and signups arriving in bursts that alternated between the domains. Those domains are now refused at sign-up. The list is data rather than code, so a domain can be added or removed without a deploy, and the sixty accounts were suspended in a way that can be reversed if any of them turn out to be real.

Fix

The Hub's Featured shelf shows all eight notebooks again

Featured picks were being matched against the first page of the recent feed, so they disappeared as the community feed grew past them.

The Featured tab on the Hub is a hand-picked set of eight notebooks, but it was assembled by fetching the first page of the recent community feed and keeping whichever picks happened to appear on it. As people published more, the curated notebooks aged off that first page and were silently dropped: by the time this was caught, only two of the eight were still showing.

Featured notebooks are now fetched by identity rather than found in a list, and presented in the order they were curated. The shelf no longer thins out as the Hub grows.

Feature

LaTeX renders, animated images play, and nothing shows up twice

A rendered formula or an animated GIF arrived as the words "IPython.core.display.Image object", because the output pipeline had no category for either.

Cell output is sorted into kinds (text, image, chart, table) before it reaches you, and anything without a matching kind falls back to its plain-text description. Animated GIFs, WebP images and LaTeX formulas had no kind, so a symbolic result from SymPy or an animation you had just built landed in the notebook as a line reading <IPython.core.display.Image object>. Both are now first-class: LaTeX is typeset with KaTeX, and $…$ and $$…$$ in markdown cells and prose are typeset too, including in the read-only share viewer.

Some libraries emit an image twice, once on its own and once wrapped inside a richer component. The notebook was faithfully rendering both, which is where the duplicated plots and the two-copies-of -one-GIF reports came from. The duplicate is now collapsed into a single output.

Large images in a shared notebook used to be replaced by a "too large" placeholder when the snapshot was captured. They are now stored separately and served from storage when the share is opened, so a shared notebook shows the same figures the author saw.

Improvement

Chat replies got slow for everyone because of one workspace

Median time to a reply reached about two minutes with no errors and healthy providers. The agent was busy counting files.

On July 23 chat slowed to a median of roughly two minutes per reply, with the error rate flat at about zero and every model provider healthy. Profiling the running agent found around 64% of its single core inside the routine that snapshots the sandbox filesystem to work out what changed during a turn. Because that work ran on the same thread that serves every stream, one very large workspace was enough to starve everybody else's chat.

The snapshot is now parsed with a much faster JSON reader and no longer rebuilt into new objects row by row. Measured against a real workspace of 300,000 files and a 21.5 MB payload, the path is 2.3 times faster end to end, and the step that dominated the profile is gone entirely. Unusually large workspaces are now logged as such, so the next one shows up as a name rather than as a mystery slowdown.

Fix

Publishing no longer claims your workspace is empty

Revisit a project a day later and the publish dialogs said there were no files, because they were listing a sandbox that had not woken up yet.

The GitHub, Kaggle and Hugging Face publish dialogs list the files in your live sandbox. Sandboxes are reaped when they go idle, so coming back to a project the next day meant the listing returned nothing and the dialog reported "No files in the sandbox workspace", even though every file was safe in storage and would reappear a moment later. The dialogs now know the difference: while the environment is still starting they say so and fill themselves in once it is up, and the empty-state hint only appears when the workspace is genuinely ready and genuinely empty.

Two other publish failures went with it. Publishing with files or artifacts attached broke on a malformed credential helper, which surfaced as a syntax error from the kernel rather than anything you could act on. And after creating a repository under your personal account, Clusy warned that pushes would not work whenever your installation covers all repositories, which is exactly the case where the new repo is already accessible and pushes work fine. The warning now fires only when it means something.

Improvement

Each model now brings its own default reasoning effort

Switching models carried the previous model's effort level across, so the setting shown on a model card was not the one you got by clicking it.

Reasoning effort used to be sticky across models: pick a model tuned to think hard, then switch to one that should default to a moderate setting, and it inherited the high setting anyway. The model card showed you that model's own default while clicking the card applied something else, which made the display quietly wrong.

Selecting a model now adopts that model's default effort, so what a card advertises is what choosing it does. This works the same way in the chat model pill and in Settings, and comparing two speed variants of the same underlying model still keeps the effort you deliberately chose.

Fix

Turns that think in silence are no longer killed for being quiet

A model reasoning privately sends nothing for minutes. A watchdog meant for dead streams could not tell that apart from a stream that had died.

Some models reason privately before they answer, and while they do it the connection carries nothing at all. Clusy sweeps up streams that have gone silent for three minutes, because a stream that stops sending is usually one that has died. It could not tell the two apart, so a model that was working perfectly well and thinking hard was swept away with the genuinely dead ones. This was the reason Sonnet 5 turns would end with no reply at all.

The agent now emits an empty keepalive every twenty seconds through those silent stretches, and the relay counts it as a sign of life without forwarding it to you or letting it disturb the transcript. Long silent reasoning now runs to completion and returns its answer.

Fix

Connecting a GitHub repo works again

Every install started from the Connect GitHub button failed, and a repo already attached elsewhere gave you nothing to act on.

The page GitHub returns you to preferred our own signed handoff over GitHub's OAuth code. Every install started from Clusy's own "Connect GitHub" button carries both, so it took the path that needs an access token a first-time installer has not minted yet, and failed. Over about seven hours, 19 of 19 attempts through that path failed and 9 of the 17 people affected gave up. The landing page now prefers the OAuth code whenever one is present, which mints the token and records the install in a single step. A failure there also navigates you somewhere useful instead of leaving a spinner turning.

Connecting a repo that is already attached to another project used to say only that. It now names the project holding it and offers to open it, and if you have edit rights on that project, to move the repo across. Should the move half-succeed, the error says so plainly rather than leaving the repo unlinked with no way forward. The other project is only ever named when you already have access to it.

Pulls also failed after the first one. The bare repository Clusy persists comes back without a fetch refspec, so a fast-forward had nothing to resolve; the first pull worked only because it ran through the clone path instead. The remote is now repaired before each fetch, which also restores the ahead and behind counts that had been silently reporting zero.

Separately, the routes that record a GitHub installation and list its repositories now require proof that you control that installation. One branch of that flow trusted any valid OAuth code, which allowed an installation to be recorded against another tenant's account.

Feature

A model outage no longer costs you the reply

When the provider behind your selected model fails mid-turn, the turn continues on Auto and tells you why, instead of coming back dead.

Until now, a provider failing in the middle of your turn (every key exhausted, a capacity limit, an outage upstream) ended that turn with nothing useful in it. The work was gone and the only remedy was to send the message again.

If the provider behind your selected model fails unrecoverably, Clusy now retries the turn once on Auto and carries on. The partial reply is cleared first, so you get one coherent answer rather than two spliced together, and a notice tells you the model changed and why. This applies to models Clusy serves; a model running on your own API key is deliberately excluded, because a failure of your key is something you need to see rather than have quietly worked around.

Models with a known, ongoing outage are now marked in the model menu as well. They appear as an unselectable row with the reason written under it instead of silently misbehaving when picked, and a saved selection pointing at one falls back to your plan's default. Kimi K3 is currently in that state because of a capacity limit at the provider.

Improvement

Qwen3.8 Max stopped queueing behind itself

Free-week load met a concurrency cap borrowed from a different provider's problem, so turns waited in a queue we had imposed on ourselves.

Qwen3.8 Max was capped at eight simultaneous requests. That number was inherited from another provider that genuinely needed it, and it was never true of Alibaba's gateway: probed against live production traffic, 32 simultaneous requests were all admitted with no rejections and a median response under three seconds. Qwen keeps thinking for the whole stream, so each of those eight slots was held for an entire turn, and under free-week load the rest of you sat in a queue that existed for no reason. The cap is now 32.

The keys behind the model are also rotated more intelligently. A key that hits its quota is now stood down until the reset time the provider states in the refusal, rather than for a flat few minutes, which stops an exhausted key from being retried every few minutes for the rest of the week. New sessions spread across the keys with the fewest live sessions instead of always filling the same one first, and each session stays pinned to its key so the prompt cache it has built up stays warm.

Fix

Sessions stuck on "New Chat" now get named

Auto-naming only ran on a session with no title at all, and a placeholder label is not the same thing as no title.

Clusy names a session from the work you did in it, and promotes that name to the project while the project is still unnamed. Both of those checks looked for a session carrying no title. A placeholder like "New Chat" or "Untitled" is not an absent title, so any session that picked one up was skipped by the namer and stayed a placeholder for good, keeping the project generic alongside it.

Placeholder labels are now cleared when the session is written, so auto-naming sees them for what they are and both the session and its project end up with real names.

Improvement

Share dialogs open with the title already drafted

The AI suggestion for a share's title, description and tags now runs the moment the dialog opens, instead of waiting for you to find the button.

Sharing a notebook used to start with three empty fields and a "Generate with AI" button you had to notice before anything happened. The suggestion now fires as the create or share form opens, so the title, description and tags are already filled in by the time you have finished reading the dialog.

It runs at most once per notebook per session, so reopening the dialog or starting a second share never spends another call. It runs quietly: if the suggestion times out, the fields fall back to the plain notebook name rather than throwing an error at you. And it never overwrites text you typed while the request was still in flight. The button is still there whenever you want a fresh draft.

Fix

Free trials are off, and cancelling a trial now ends it immediately

A trial granted a paid tier before any payment succeeded, so a ring of burner accounts held Plus, Pro and Max on cards that were blocked at every charge.

Clusy's free trial handed over a paid tier the moment it started, before a single charge had gone through. Twenty-two accounts built on burner emails and a handful of shared card fingerprints used that to hold Plus, Pro and Max entitlements with cards our payment provider blocked on every attempt. Nothing ever revoked the access, because nothing had ever been paid for it to revoke.

Free trials are disabled. Cancelling during a trial now ends the subscription at that moment instead of coasting to the trial end date, and the plan drops back to Free right away. That applies to cancellations made through the billing portal too, which previously came back as a scheduled cancellation and kept the tier alive.

Paid periods are untouched. If you cancel a plan you have actually paid for, it stays live until the end of the period you bought, exactly as before. That time was paid for, so it is yours.

Feature

Qwen3.8 Max in the model menu — free for everyone this week

Alibaba's 1M-token-context flagship joins the agent's model lineup, and through launch week it costs nothing on any plan.

Qwen3.8 Max, Alibaba's new flagship, is now in the model menu. It carries a one-million-token context window and always-on deep reasoning, which suits the work Clusy sessions turn into: long agentic runs that read a lot of data, hold a lot of intermediate state, and think before every step.

Qwen3.8 Max is free for everyone through launch week — every account, and Qwen turns don't count against your usage allowance. Pick it from the model selector. The free window has been extended through the weekend and now ends July 27 at 00:00 UTC; after that, Qwen3.8 Max stays in the lineup for paid plans.

Fix

Open models write cells, not code dumps in chat

Some models answered a notebook request with a wall of fenced code in the chat instead of runnable cells — a production audit measured it, and a targeted instruction stops it.

Clusy's contract is that code lands in notebook cells you can run, edit and branch — not as text in the chat. Some of the open models (the DeepSeek and Kimi families, and coding-tuned flagships especially) have a strong prior for answering with fenced code blocks, and on a fraction of turns they ignored the buried instruction and dumped scripts into the conversation. A production audit put the leak at several percent of chat turns for the worst offender.

Those model families now get the notebook-first rule restated at the point they're most likely to act on it, only on real notebook turns so nothing else changes. The leak is also instrumented: every turn that ends in a visible code fence without a cell write is logged, so the rate is measured rather than assumed.

Improvement

A shorter path through onboarding

The final onboarding screen duplicated the dashboard's own prompt box, so the flow now ends one step earlier.

Onboarding used to end on a "send your first prompt" screen — which is exactly what the dashboard you land on is for. The flow is now four screens ending at your profile, and both Finish and Skip drop you straight into the dashboard to start working. The transitions between steps were smoothed out along the way.

Fix

Worker traces follow the stream

A live subagent transcript grew below the fold and stayed there — now it sticks to the bottom while it streams, and lets go the moment you scroll.

When the agent hands work to a subagent, its transcript streams into a trace panel. That panel had no auto-scroll at all: while a worker ran — especially through long cell output — new content piled up below the fold and the view never moved. Watching a run meant dragging the scrollbar every few seconds.

Live traces now pin to the bottom and follow everything that grows the transcript, not just new messages. A real scroll of your own releases the pin so you can read back mid-run; scrolling near the bottom re-pins, and a scroll-to-bottom button appears whenever you're detached. Finished traces open at the top, where reading naturally starts. The main chat got the same treatment, fixing a jump-to-latest button that had drifted off-screen exactly when it was needed.

Fix

"Continue working" sorts by what you actually touched last

Chatting in an old project didn't move it up the recents list — the list sorted on a timestamp that messages never update.

The "Continue working" list on the home page is supposed to surface what you were just doing. It sorted projects by the project row's own last-modified time — but sending messages never updates that; only renames and workspace saves do. So the project you spent the afternoon in could sit buried under things you hadn't opened in weeks.

Each project is now ordered by the newest activity across the project and its sessions — the same rule the sidebar already used, now shared by both surfaces. The timestamp printed on each card reports that same value, so the order and the "3 days ago" labels can't contradict each other, and the list refreshes at the moment it matters: right after you send a message.

Feature

Kimi K3 in the model menu — free for everyone this week

Moonshot's 1M-token-context flagship joins the agent's model lineup, and through launch week it costs nothing on any plan.

Kimi K3, Moonshot's new flagship, is now in the model menu. It carries a one-million-token context window and always-on deep reasoning, which suits the work Clusy sessions turn into: long agentic runs that read a lot of data, hold a lot of intermediate state, and think before every step.

K3 is free for everyone through launch week — every account, and K3 turns don't count against your usage allowance. Pick it from the model selector. The free window ends July 23 at 00:00 UTC; after that, K3 stays in the lineup for paid plans.

Fix

Your variables survive a sandbox restart

One object the checkpoint could not pickle — an np.load handle, a cv2 matcher — and it was silently saving nothing at all.

When a sandbox goes away — an idle reap, a restart, you coming back tomorrow — the checkpoint is what brings your notebook's variables back with it. For a research notebook, four separate defects meant it mostly did not.

The checkpoint scanned your namespace, correctly identified the objects it could not pickle, printed them as skipped — and then pickled the whole namespace anyway, so the first unpicklable object aborted the entire save. One np.load handle left in a variable was enough to take the other fifty variables down with it. Work on the main branch was written to a key nothing ever reads. A child branch was rolled back to its fork point on cold start, discarding everything run since, even though a good checkpoint of it existed. And a large checkpoint — routine for a vision or ML namespace — exceeded the kernel connection's message ceiling, which does not truncate: it closes the connection.

Unpicklable objects are now dropped from the checkpoint instead of taking it down with them, and main and branch state are saved under the key each is actually read back from. Large checkpoints no longer overrun the connection: the ceiling is raised, the read-back moves in pieces, and what comes back is checked against the size the kernel recorded before anything is stored.

It is not a total guarantee. An open matcher, a file handle, some torch singletons still won't be there after a restart — they just no longer cost you everything else. And a namespace whose pickle runs past 2 GiB is skipped rather than saved, so state that large belongs in a file on disk, which is persisted separately, and not in a variable.

Feature

Ask the docs a question and get a cited answer

Every documentation page now has an ask bar. Type a plain-English question and a short answer comes back with links to the pages it came from.

The answer arrives with source cards pointing at the pages it was drawn from. It reads the page you have open and pins it into context, so a vague follow-up — "what about limits?" — stays anchored to what you were reading rather than drifting. Follow-ups carry the last three turns; New topic clears them, Esc closes the dock, and a stop button ends an answer in progress.

It is deliberately short and deliberately grounded: under a hundred words, written only from the documentation pages it retrieved for your question, and instructed to say the docs don't cover something rather than invent a setting, a flag, a price or a limit. This is a documentation lookup, not a chatbot — it has no tools, and it cannot see your notebook, your project or your account.

Limits worth knowing: it lives on docs.clusy.io only, not on clusy.io and not inside the app. It is capped at twelve questions an hour per IP address. And it reads the docs through a ten-minute cache, so a page published a moment ago isn't answerable quite yet.

Improvement

The docs were rebuilt

Most pages rewritten or expanded, with diagrams for the parts prose is bad at: what a fork's kernel carries, how Plan Mode's stages run, how a sandbox comes and goes.

docs.clusy.io has nineteen new inline diagrams, and the pages around them were rewritten rather than decorated. The branching page now names the actual gesture — hover the gap under a cell, the insert strip appears, and next to Code and Markdown there's a Fork button — and adds a section on what a fork doesn't carry, since the interesting part of a checkpoint is its edges.

Three things that shipped without documentation now have pages: pairing your own machine, bringing your own key, and the literature-review workflow. Search is rebuilt too, and remembers your last few queries, though only in the browser you typed them in.

Nothing in the product changed. This is a docs release.

Fix

An offline machine blocks the send instead of switching your model

When the runner on your paired machine isn't connected, Clusy says so and gives you the choice, rather than failing the turn or quietly moving it onto Clusy's compute.

Sending on a local-runner model whose machine was unreachable killed the turn with a bare "the local runner disconnected", and the composer let you send straight back into the same error. Worse, the send quietly rewrote the dead selection to a Clusy model and dispatched that instead — moving a turn you expected to run on your own machine, on your own subscription, onto Clusy credits, without telling you.

Now the composer blocks with a plain explanation and two ways forward: switch to Clusy's own compute, or restart the runner on your machine (Settings → Integrations has the pairing steps). Queued messages park instead of going out on a model you didn't pick. Presence is polled rather than pushed, so a machine that drops off in the seconds before you hit send can still cost you one failed turn before the block appears.

Three fixes from 11 July go with this. A runner turn that does fail now names the cause and what to do about it — machine offline, machine busy with another turn, the CLI missing or signed out, daemon out of date. An approval-gated tool call no longer hangs a runner turn indefinitely. And a long-running cell no longer trips a silence watchdog that killed the turn while the cell carried on. None of this saves a turn already in flight when the connection drops — that still dies, and still needs sending again.

Feature

See the exact charge before you change plans — and cancel in the app

Upgrades, downgrades and cancellation now run through one in-app confirmation that shows the real money before you commit.

Changing plans in Settings → Billing goes through a single confirmation. An upgrade renders a receipt — the new plan pro-rated for the rest of the cycle, credit for the unused time on the old one, any account credit, a Due today line — and the confirm button carries that amount. The number in the dialog is the number Stripe charges, to the cent: the preview's proration anchor is replayed on confirm rather than recomputed, and a dialog left open across a renewal is refused rather than quietly re-priced.

Two things here were simply broken. Upgrades weren't billed when you made them — Stripe was only creating pending proration items, so nothing was collected until the next renewal, and if you cancelled before then, nothing was collected at all. And the button that was supposed to end your subscription did nothing, so people who believed they had cancelled kept being charged. Cancelling now works, effective at the end of the period, with Resume to undo it.

A downgrade takes two deliberate steps, the last behind a press-and-hold confirm — keyboard and screen-reader users activate twice instead — and lands at the period boundary, so this month's allowance never shrinks retroactively underneath you. Anything scheduled sits in a banner with a one-click undo. Two refusals you now meet up front rather than at the end: you cannot upgrade while a payment is past due, and you cannot downgrade during a trial — there, cancelling is the path.

Improvement

Take a steered message back, and see where it landed

The composer now says whether your next message will steer the running turn or queue behind it — and a message the agent hasn't read yet can be withdrawn.

Steering already folds a message into a turn that is still running. What it did not tell you was whether the message you were about to send would actually get there.

Now, while the agent is working, the send button says which it will be. It reads Steer when the draft will reach the run in flight, and Queue when it will not — because it carries attachments or an @-reference, which are resolved when a turn starts and so always begin a fresh one, or because something is already queued ahead of it.

Messages sent mid-turn sit above the composer as pills carrying their real state: queued, sending, delivered. Withdraw one with × before the agent reads it and it never reaches the turn; if the withdrawal loses the race, the pill says so rather than pretending it worked. Edit hands the text back to the composer. Plain-text follow-ups also chain now — the next one steers into the same turn as soon as the one ahead of it lands, instead of waiting for the turn to end. When a steer is applied, the transcript row it inserts is highlighted once, so you can find it in a long stream.

Fix

The comparison card stopped calling the fastest run the winner

A batch experiment's comparison card put a trophy on one arm. It was choosing purely on wall-clock time, which in a sweep is often the worst model.

Open the run_batch_experiment row in chat and you get a comparison card: one row per variant, with its duration and a link into its branch. One of those rows carried a trophy and no other text — and a trophy with no label reads as "best". It was only ever the quickest clean run. In an accuracy or hyperparameter sweep the fastest arm is usually the one that did the least work: fewest epochs, smallest config. So the card you open to decide which variant won could be visually crowning the loser.

It is now an explicit Fastest badge with a timer icon, and a tooltip that says in words that this is not necessarily the best result. It appears only on runs that actually completed, and not at all when the batch has a single variant — "fastest of one" is noise. Nothing about how experiments run or how they are compared changed, and choosing a real winner is still the agent's call, made in the chat. The label was the part that was wrong.

Fix

Hub links open without an account

Send someone a Hub notebook or your public portfolio and they can read it while signed out.

The Hub and public portfolios were always meant to be readable by anyone — the routes were mounted outside the auth guard correctly — but a layout inside them fetched the signed-in profile unconditionally and threw. A logged-out visitor got an error page, which is an unfortunate property for the pages whose entire job is being sent to people without accounts.

Fix

Large plots, images and DataFrames arrive whole

Cell output above Jupyter's data-rate limit was being silently discarded on its way out of the sandbox. It now comes through intact.

Jupyter enforces a data-rate limit on output and, above it, discards the rest — no error, no marker, nothing in the cell to say anything is missing. So a big figure, a rendered image or a fat DataFrame was cut on its way out of the sandbox, and what you saw was a cell that had run perfectly well and then reported could not read from sandbox, or an image that simply never arrived. Saving a file out of the sandbox was the worst of it: that path ships the file by base64-printing it in one burst, so anything much past half a megabyte blew straight through the ceiling and was lost.

It cost the agent's work too. It saves a matplotlib overlay so its labels can be checked against the image, and that overlay never made it out — so the one artifact a labeling run could be judged on was gone. The story is here.

The limit is raised on both sandbox types: GPU sandboxes on 11 July, CPU sandboxes on 12 July. Files a cell writes are still capped at 25 MB each for auto-persist — above that they are skipped, and the agent is told rather than left guessing.

Fix

The login page and shared labs work on a phone

You can scroll /login and read a shared notebook on a phone.

The app shell pins the viewport so the three-column workspace can own the screen and scroll each column independently. The standalone read-top-to-bottom routes inherited that pin, which meant they could not scroll at all on a small screen — so anything below the fold was simply unreachable.

Feature

Pay-as-you-go overage is now billed

Usage past your monthly allowance is invoiced once the month closes, bounded by the cap you set. Until now, it never was.

Pay-as-you-go has been half-built since it shipped. You could turn it on and set a monthly cap, and Clusy would let your usage run past your included allowance up to that cap — and then nothing ever billed it. The meter worked, the gate worked, the invoice never came. It does now: once a calendar month closes, the overage is invoiced through Stripe against the card on file.

The cap you set in Settings → Billing & Usage bounds the invoice itself, not just the usage behind it. It applies from the moment you set it: lowering your cap mid-month binds everything you run after that, but it does not undo overage you have already run up. An invoice under $0.50 is not raised at all.

Nothing is billed backwards. Months that closed before this shipped are not invoiced, and usage from before you switched pay-as-you-go on is never billed — including usage earlier in the same month. The first month that can bill is July, invoiced in the first days of August. If pay-as-you-go is off, or your cap is zero, nothing is billed.

Fix

Stop now stops the cell you pressed it on

Stop was always sent to the primary kernel, whichever cell you asked it to interrupt — which during a parallel batch meant it stopped the wrong one.

Stop ignored which cell it was pressed on and interrupted the primary kernel. On a notebook running on main that happened to be right, because main shares the primary kernel. During a parallel batch experiment it was wrong twice over: the variant you were trying to stop never got the signal, so it kept burning compute until its timeout — while the notebook flipped the cell out of its running state and recorded the interrupt as delivered, so Stop looked like it had worked. And the signal landed on the primary kernel instead, where it could kill an unrelated cell you had running on main. The agent's own stop path had the same bug.

Stop is now delivered to the kernel that is actually running the cell, on both paths. It interrupts rather than tearing the kernel down, so a cell wedged inside uninterruptible native code can still take a moment to yield, or refuse to. Separately, a stop aimed at a kernel that had already gone away used to disappear quietly and be recorded as a success; it now leaves a failure trace rather than vanishing.

Feature

Run Clusy on your own Anthropic or OpenAI key

Connect an API key in Settings → Integrations and Sonnet 5, Opus 4.8 and GPT-5.6 appear in the model picker, for zero Clusy credits.

Access is gated on the connected key, and on nothing else. Turns on those models cost zero Clusy credits — including the work you don't see, since verification, sub-agents and context compaction stay on your key rather than falling back to a house model.

This covers model inference, not compute: the sandbox your notebook runs in is still metered as before. More on how it works.

Improvement

A calmer notebook canvas

Per-notebook tabs, scrolling that no longer fights you, and an editor that stops re-centring the view on every keystroke.

Several things that made long notebooks unpleasant:

  • Each notebook now gets its own tab on the canvas, so a project with several notebooks stops being one long scroll.
  • The virtualized cell list measures real row heights instead of guessing, which fixes the scrollbar drifting and cells jumping as you move through a large notebook.
  • The focus effect no longer re-centres the viewport on every keystroke while you type in a cell.
Feature

Upload a folder, at any size

Drag a whole directory into a project. Files go straight to storage over signed URLs, so there is no upload size ceiling and nested folders keep their structure.

Uploads used to be routed through the API, which capped how much you could add at once. They now go direct to storage over short-lived signed URLs, requested in bulk. A dataset of several thousand images uploads in a handful of authorized calls rather than one per file, and the folder structure you dragged in is the folder structure you get.

Feature

GPU sandboxes come with a vision stack

RF-DETR, Ultralytics YOLO, OpenCV, torchvision, pycocotools and a transformers build with SAM 3.1 support are preinstalled on the GPU image.

A GPU sandbox now starts with the segmentation and detection stack already there — import it, rather than spending the first cell installing it. The weights are not on the image, but they no longer need setting up: gated Hugging Face repos such as facebook/sam3.1 resolve inside the sandbox with no token work on your side. Clusy holds one Hugging Face identity that has accepted those particular licences — this is not per-user Hugging Face auth, and it does not unlock arbitrary gated repos. Weights land in a cache shared across sandboxes rather than being re-downloaded on each fresh one, so only the first sandbox that wants a model pays for the pull.

Three things worth knowing. The base moved from torch 2.3.1 / CUDA 12.1 to torch 2.7.1 / CUDA 12.8, so notebook code pinned to older torch or torchvision APIs may need adjusting. setfit is gone — its current release cannot coexist with the transformers version SAM 3 and RF-DETR require — so import setfit on a GPU sandbox now fails; sentence-transformers is preinstalled and covers the few-shot path. And Ultralytics is AGPL-licensed, which matters if what it produces ships in a commercial product. This is the GPU image only; CPU sandboxes stay lean.

Feature

Pair your machine and Clusy drives the CLI you already have

If you use Claude Code or Codex, pair the machine it runs on and those CLIs appear in the model picker — running on your own subscription, on your own laptop.

Pairing adds three rows to the picker, badged Your machine: Claude Code Sonnet, Claude Code Opus and Codex. Set it up from Settings → Integrations, which gives you a pairing code and two commands to run:

npm i -g https://api.clusy.io/local-runners/clusy-runner.tgz
clusy-runner pair <CODE>

pair installs a start-at-login background service (launchd on macOS, systemd on Linux) so the machine stays online; pass --no-service to run it yourself. It opens no inbound ports.

Your Anthropic or OpenAI login never leaves your machine — Clusy spawns the genuine CLI and it authenticates itself, in its own process. Your notebook still runs in the Clusy sandbox; only the reasoning moves to your laptop.

Limits worth knowing: one turn at a time per machine, the machine has to be awake, and Plan Mode, sub-agents and batch experiments aren't available on a local-runner turn (branching is). More on how it works.

Fix

Cells that write many files deliver all of them

A cell that writes one file per frame or per run now persists up to 100 of them, instead of silently keeping the first 20.

Only the first 20 files a cell wrote were persisted, and the rest were dropped without saying so — which meant a labelling job that wrote one mask per frame quietly delivered a fraction of its output and looked like it had finished.

The cap is now 100, and if a cell overruns it the agent is told, rather than the files vanishing in silence. It is still a cap: a job that writes thousands of files should write an archive.

Fix

Deliverables that actually download

Downloading a finished artifact could fail outright. Terminal and scratch outputs are also persisted now, so the file you were promised exists.

Several things were wrong at once: files written from a terminal or to scratch were never persisted, the download route could 500 on a file that wasn't where it was expected, and the UI happily offered you a download for an artifact that had never been uploaded.

Files produced by terminal and scratch runs are now persisted, downloads are gated on the file actually existing, and an upload that stalls fails loudly instead of sitting at 0%.

Fix

Shared notebooks no longer go blank as you scroll

Scroll a long shared lab end to end without hitting blank screens or having content jump under you.

The read-only share viewer rendered every code cell as a CodeMirror editor. CodeMirror virtualizes against the window, so in a long page it concluded most cells were offscreen and stopped painting them — leaving a reader scrolling through empty stretches.

Code in the share viewer is now plain rendered text, which is all a reader needed.

Improvement

Less waiting before the agent's first word

The agent starts responding sooner, both on the first message of a turn and after a long-running cell.

Every turn does setup before the model is called — loading session state, history, your preferences, credentials. That work ran as a chain of sequential awaits, so each round-trip's latency stacked on top of the last before a single token could be produced.

The setup now runs concurrently, and prompt caches are held for an hour so a follow-up message doesn't pay a cold prefill.

Fix

Chat auto-scroll follows the whole stream

Watch a turn stream without the view drifting off the newest token, and scroll up to re-read without the panel fighting you.

The chat panel now tracks whether your viewport is genuinely pinned to the bottom. If it is, it follows the stream; if you have scrolled up to re-read something, it leaves you where you are and offers a jump-to-bottom instead of yanking you back.

Fix

Long, silent GPU cells no longer drop their connection

A cell that trained for minutes without printing anything could lose its transport and report a connection error, despite running fine.

A training cell that produces no output for several minutes looked, to the layer in between, like a dead connection — so it was cut, and you got "connection dropped while streaming" on a cell that was working.

The execution stream and the kernel channel now both keep alive through silence.

Fix

Failed cells show the full traceback

When a cell the agent ran raises, you can read the whole traceback in the notebook instead of a single summary line.

Errors were surfaced as a one-line ename: evalue, which cut off exactly the part that matters — a CUDA out-of-memory message, for instance, arrived truncated before the numbers telling you how much memory was actually needed.

The cell's error output now carries the full traceback, and the agent sees it too.

Fix

Refreshing mid-turn no longer kills the run

Reload or reopen a tab while the agent is working and the live turn comes back, instead of dying.

A page reload used to leave the client with no record of the in-flight turn: the reply stopped rendering, the composer thought nothing was running, and sending the next message superseded the turn that was still going.

Active runs are now rehydrated on load — the in-progress reply re-renders from what has streamed so far, and the composer knows to steer rather than supersede.

Fix

A failed model now tells you it failed

When a model provider errors out, the transcript says so instead of going quiet.

A provider failure ended the turn with a clean terminal frame rather than an error frame, so the chat rendered nothing at all — the turn simply appeared to stop mid-thought, and you had no way to tell a crash from a model that had decided to say nothing.

Feature

Steer a running turn instead of restarting it

Send a message while the agent is working and it folds into the turn already in flight, rather than cancelling it and starting over.

Previously, typing while the agent was mid-task superseded the whole turn — twenty minutes of work discarded because you wanted to add one sentence.

Now the message is picked up at the agent's next step. If it is in the middle of executing a cell, it finishes that cell and reads your message before deciding what to do next, so a correction lands without throwing away the work already done.

Fix

The chat no longer looks frozen during long runs

A watchdog was killing turns that were working perfectly well, just quietly — it measured how long the turn had taken rather than how long it had been silent.

If the agent kicked off a long execution, the chat could appear to die while the cells kept running — the reply watchdog timed the whole turn rather than the gap since the last streamed token, so a legitimately long run tripped it.

It now measures stream silence, and the long-running phases send heartbeats while they work.

Fix

Kernels reconnect instead of wedging

If the kernel's connection dropped, the session used to hang until you reloaded. It now reconnects on its own.

A dropped kernel websocket would leave the project apparently alive but permanently unresponsive — cells queued and never ran, and the only way out was a reload. The gateway now detects the dead channel and reconnects it.

Feature

A bigger model shelf, and one picker for all of it

Auto, DeepSeek V4 Pro, Kimi K2.6, Kimi K2.7 Code, Kimi K2.7 Code Fast, Sonnet 5, Opus 4.8, Opus 4.7 and GPT-5.5 — selected from one menu in the composer.

Auto stays the default and picks a model per turn. When you want to choose yourself, the picker now covers the full shelf, and the agent's own background calls — verification, sub-agents, compaction — route on the same entitlements as your foreground turns instead of falling back to a house default.

Which models you can reach depends on your plan. The pricing page has the current mapping.

Improvement

Shared notebooks unfurl with a real preview

A Clusy link pasted into Slack, X or LinkedIn now previews with a cover image generated from the notebook's own output — the plot you actually made, not a grey box.

Sharing gives you a short clusy.io/s/… link. The preview card is built from the notebook itself: its title, its author, its cell and experiment counts, and a cover lifted from the first real image output in the notebook.

June 2026

Improvement

Sign-in, email and account deletion

One session across clusy.io and app.clusy.io, a welcome email that actually arrives, and account deletion that cancels your subscription with it.

  • Signing in on one Clusy subdomain signs you in across the others.
  • Transactional email — verification codes, welcome mail — is live, with one-click unsubscribe on everything that isn't a security message.
  • Deleting your account now cancels the subscription attached to it, instead of leaving a live Stripe subscription behind a deleted user.
Fix

Cancelling a turn no longer breaks the session

Stop a running turn — even mid-tool, even twice in a row — and keep chatting in the same session.

Cancelling before the model had produced any text or tool call could persist an empty assistant row in the history. On the next message, OpenAI-compatible providers rejected that row with a 400, and every subsequent turn in the session failed. The only fix was to abandon the session.

Empty interrupted turns are now dropped from history replay.

Fix

Retired: tree minimap, branch carousel, split view

Three overlapping surfaces for navigating branches, consolidated into one.

We had built three different ways to look at the branch tree. Between them they added a lot of code and overlapping ways to do the same thing, without making branch navigation clearer.

They are gone. Branches are switched from the branch bar above the notebook.

Improvement

The agent can edit a notebook the way you can

It can now change a cell's type, read a cell's source before rewriting it, move cells, insert above a cell, and delete one — rather than only appending to the end.

The agent used to be able to add cells and run them, which meant every correction became a new cell at the bottom and notebooks grew long and repetitive.

It can now restructure what is already there: convert a code cell to markdown, read a cell before editing it, reorder, insert in the middle, and remove a cell that is no longer earning its place.

Feature

Clusy Hub — publish a notebook as a public lab

Finished work can be published to a public page anyone can read and fork, with a portfolio under your name collecting what you have put out.

A published notebook keeps its cells, its outputs and its branches, and can be forked into a reader's own workspace in one click — so a result you share is a result someone else can run and change, not a screenshot of one.

The Hub is at clusy.io/hub, and inside the app under the Hub tab.

Feature

Every plan in the project, in one place

Open the "Open plans" tab to see all the plans in a project, not just the one from the session you happen to be in.

A plan describes work on the shared notebook, so it is no longer scoped to a single chat. Opening a plan shows its revision history, so you can read what changed between the version you approved and the version that ran.

Fix

A real 404, a security.txt, and corrected legal text

Housekeeping on the public site: a crafted not-found page instead of a silent redirect, a published security contact, and legal copy that names the right entity.

  • A crafted 404 page, rather than silently bouncing you to the homepage.
  • security.txt published, so a researcher who finds something knows where to send it.
  • Legal copy corrected to name the right entity (Clusy Inc.) with consistent governing law, and the privacy policy now identifies the data controller properly.
Feature

Attach files to a message and the agent can open them

Drag, paste or attach files in the composer, and they are staged into the agent's working directory before it writes any code.

Attachments used to land in project storage only, so the agent would go looking on the filesystem for a file that was never on disk. They are now copied into the sandbox working directory (/home/user) before the turn starts, and notebook code can open them by plain relative filename.

Staging is best-effort — if a file can't be pre-staged the agent is told, and reads it from project storage instead. Up to 50 attachments per message.

Improvement

A guided first run

A four-screen golden path from sign-up to a notebook that has actually executed something — connect a data source inline, pick a theme, and go.

The old first-run dropped you into an empty workspace and wished you luck. The new one walks from sign-up to a first executed cell: connect a data source inline (Kaggle, Hugging Face, an upload) without a detour through Settings, choose your theme, and land in a project that is already doing something.

Improvement

Quieter thinking blocks and grouped tool calls

Adjacent reasoning collapses into one disclosure, and tool calls group by what they were doing rather than listing one row per call.

A long turn used to produce a wall of individual tool rows and a dozen separate "Thinking…" blocks. Adjacent reasoning now folds into a single expandable block, and tool calls are grouped by category, so the transcript reads as a sequence of steps rather than a log file.

Feature

Connect Databricks or Snowflake

Add a personal access token in Settings and the agent can query your warehouse directly, instead of you exporting a CSV to upload.

Both connect from Settings → Integrations with a personal access token. Once connected, the agent gets SQL query tools against that warehouse and can pull what it needs itself — so the data stays where it lives and you stop round-tripping extracts through your downloads folder.

Improvement

DataFrames read like a spreadsheet

Numeric columns right-align with tabular figures, and missing values recede instead of competing with real data.

Numeric columns now right-align in both header and cells and use tabular figures, so digits line up in columns and you can compare magnitudes down a column at a glance. NaN, None, NaT and <NA> render dimmed and italic.

Feature

Public documentation

Concepts, guides and reference at docs.clusy.io.

Documentation is now public at docs.clusy.io — how branching works, how the sandbox works, how to pick a model, and how to get a first notebook running.

Fix

Deliverables only contain deliverables

The agent was flagging ordinary notebook cells as deliverables, so the panel filled with noise.

Every cell that produced a plot was being auto-promoted into the Deliverables panel, which made it useless for its actual job — holding the handful of artifacts you want to take away.

Feature

Reference a cell, plan, dataset or paper with @

Type @ in the composer to point the agent at something already in your project, instead of describing it and hoping it picks the right one.

Each pick becomes a chip on the message, and the agent resolves it into the artifact's current content — the cell's actual source, the plan's steps, the dataset entry — at send time, so it reflects the cell as it is now rather than as it was when you typed.

Limits: up to 20 references per message, and a referenced cell's body is truncated at 4,000 characters. Plans, datasets and papers only appear once the session has a plan.

Fix

Chinese, Japanese and Korean text renders in charts

CJK characters in chart axis labels, titles and legends show glyphs instead of empty boxes.

Plotly charts had no font family set, and the iframe that renders rich output shipped a Latin-only font stack — so any agent-produced chart with CJK labels came back as rows of tofu boxes.

Feature

Plan Mode — read the plan before the agent builds

Ask for something substantial and the agent writes a plan document first: the cells it intends to add, the experiments it intends to run, what it will measure. Nothing is written or executed until you approve it.

The plan opens as its own tab on the canvas. You can revise it, drop a step, or discard it outright. Approving it releases the agent to build; until you do, it cannot write a cell or run one.

The gate is enforced in the tool executor rather than asked for in the prompt, so it holds even when the model would rather get on with it.

Improvement

Projects and notebooks name themselves

A project gets a real name after its first turn instead of a truncated copy of your first prompt, and a notebook gets one from its contents.

A project started from the launcher used to keep your raw first message as its name, truncated mid-sentence. It is now renamed from a short summary of that first turn, and notebooks left on a default label are named from what they contain once they have run.