Build Your FutureTM

Changelog

What shipped on the platform, and every new release of the agent templates you can deploy.

v2026.8.2
Swarm Network OpenClawTests passing

Swarm Network OpenClaw v2026.8.2

Skills you pick in the dashboard now land on your agent automatically. Install, update or remove one, and the agent always ends up matching exactly what you chose.

v2026.8.2
Swarm Network MercuryTests passing

Swarm Network Mercury v2026.8.2

Skills you pick in the dashboard now land on your agent automatically. Install, update or remove one, and the agent always ends up matching exactly what you chose.

v2026.8.2
Swarm Network HermesTests passing

Swarm Network Hermes v2026.8.2

Skills you pick in the dashboard now land on your agent automatically. Install, update or remove one, and the agent always ends up matching exactly what you chose.

v0.33.0
NovaTests passing

Nova v0.33.0

Skills you pick in the dashboard now land on your Nova automatically, and always end up matching exactly what you chose.

v0.32.1
NovaTests passing

Nova v0.32.1

The Files area works again.

Every action in the chat's Files area — list, upload, rename, delete — was failing with a permission error, so the area was effectively dead. Signing in now covers your files too.

The create, rename and delete dialogs are also real dialogs now: the name is checked before anything happens, Enter confirms, a rename keeps the file extension, and a delete tells you exactly what it's about to remove.

v0.32.0
NovaTests passing

Nova v0.32.0

Merged in #33. Three faults behind one symptom: Nova answering "I don't see an attachment yet" to a message that visibly had one.

It was never sent

assistant-ui does not merge attachment parts into message.content. The composer builds { content: [text], attachments: [...] } and each attachment keeps its own content. The code that collected files for the send scanned message.content, so it found nothing — every time, in both web chats, for as long as attachments have existed. Only the Telegram file path ever worked.

It failed silently, which is why it lasted: the chip renders, the send succeeds, the model simply never receives a file.

Only some files could be attached

The stock adapters took images plus a handful of text types, and turned the latter into an <attachment name=…> blob of TEXT — which can never be written back to the drive as the file it came from. One NovaAttachmentAdapter now accepts any file (4 MB each) and carries it through with its real filename and MIME type.

A web upload never reached the drive

Telegram stashed uploads into inbox/; the web composers did not. A file sent from a browser lived only inside one chat turn — Nova's own tools had nothing to open, and "save this in my files" had nowhere to save to.

orchestrate now stashes for the owner and tells the model the path, exactly as the Telegram path does. Two exclusions, both deliberate:

  • Federated callers — a peer mesh's payload is not the user's drive.
  • Telegram — it keeps doing its own, because it needs the "saved at inbox/…" note inside the text it persists before the run starts. It signals this with a {nova:"inbox"} data part rather than a flag on the call, so the fact travels with the message and a retry or replay cannot write the same file twice.

Also

Reloading a chat that had an attachment crashed the page (createObjectURL: Overload resolution failed) — a persisted transcript rehydrates file from JSON as a plain object, not a File.

Upgrade: no config or data changes. Web uploads begin appearing under files/inbox/.

v0.31.1
NovaTests passing

Nova v0.31.1

Patch on v0.31.0. Merged in #32.

Picking a file in the hosted chat's composer crashed the whole surface with:

`Tooltip` must be used within `TooltipProvider`

The vendored chat components use Radix tooltips, and the attachment chip opens a bare <Tooltip> with no provider above it. Radix's context helper throws on a missing provider rather than degrading, so the error propagates to the nearest boundary and the chat goes with it.

It survived this long because TooltipIconButton wraps its own provider — every other tooltip in the bundle works, and the chip was the only bare one. The thread root now provides one for everything under it, which also keeps the bundle self-sufficient rather than depending on whatever a host wraps it in.

Synced from the control plane's chat-ui:export, where the fix and its regression test live.

Upgrade: no config or data changes.

v0.31.0
NovaTests passing

Nova v0.31.0

Three things that turned out to be one thing: Nova can format a reply properly, move files in both directions, and keep those files somewhere everyone can reach them.

Merged in #31.

Rich replies (Bot API 10.1/10.2)

sendRichMessage is a method, not a parse_mode — the reply goes out as raw GFM and Telegram renders real tables, checkboxes, heading levels and nested lists.

Used selectively: a plain answer still goes out as a plain message, because mixing the two surfaces makes font weight and spacing jump mid-conversation. needsRich() decides per message, after stripping code fences — a fence is not a reason to escalate.

Three failure modes, three behaviours. The rule that matters is never re-send a transient failure, which is how a user ends up with the same answer twice:

FailureResponse
Method unknown (older Bot API)latch off for the process, fall back to plain
Content rejected (bad markup)fall back to plain, once
Transient (429/5xx)honour retry_after, retry the same send

Also fixes a pre-existing truncation: chunk() dropped everything past 4000 characters of a line containing no newline, so a long paragraph lost most of the answer. It now hard-splits and re-opens straddled code fences.

Files, both directions

In — photos, albums, video, audio, voice notes, documents. An album arrives as ONE turn, debounced by media_group_id: answering the first item treated item #2 as a new question and interrupted the run item #1 had started. Images and PDFs reach the brain as native file parts, text-ish files inline. Anything over Telegram's 20 MB bot-download cap is reported to the model rather than silently dropped. Every upload also lands in the drive's inbox/.

Outattach_file sends a real file: a rich media block for images/video/audio, a native document bubble otherwise, a file card in both web chats.

Chat action is held for the whole run (Telegram expires it after 5 s) and switches to upload_photo / upload_voice / upload_video / upload_document for what is about to arrive.

Nova Drive

One folder — $DATA_DIR/files. The pre-drive workspace/ is renamed into it on boot, so Nova's tools and the user's files are one tree: a chart bash renders is a file the user downloads a second later.

Three doors, one implementation:

DoorWhoProofReach
/drive/api/*the ownerhosted-chat cookie, or CONTROL_TOKEN when the dashboard proxieseverything
/nova/drive/*a mesh agentits own mesh-signed credentialonly what a grant covers
/d/<token>anyonethe linkone file or folder, within its limits

A grant is authorization — the credential already proves identity. Scoping is prefix+separator, so a grant on shared/ deliberately does not cover shared-notes/. Public links take any combination of expiry, download cap (1 = one-time) and argon2 password; answering the password sets a cookie scoped to that one link, so a folder share does not ask per file.

Every mutation and every download records its actor (user / nova / agent:<id> / share:<token> / telegram) — the only way a shared drive answers "did that link get used?". Text overwrites and deletes keep bounded snapshots, so an edit is restorable; a rename carries its history.

Path safety is one tested function: lexical .. rejection plus a realpath check on the deepest existing ancestor, because string cleaning never catches link -> /etc. HTML and SVG always download — serving attacker-authored markup inline from the agent's own origin is stored XSS. Range is honoured everywhere, so video scrubs.

Nova's own tools are ungated, since NOVA_SYSTEM_TOOLS is about giving it a shell, not about reading a CSV the user just uploaded: list_drive, read_drive_file, write_drive_file, move_drive_file, delete_drive_file, share_file, grant_agent_access.

Backups are a hand-written streaming ZIP — no dependency, no zip in the image, one file in memory at a time.

Attachments in chat

Both web chats show a file card: glyph and tint by type, name, size, image thumbnail, click to download. The bytes still never ride the reply — a 20 MB attachment would be re-serialized on every poll of the task — but the reference now carries the file's size and drive path, which is the difference between prose and a file the user can take.

The hosted chat fetches from its transcript row rather than the drive path: the row is what the reply was, so the download survives Nova moving or deleting the original.

Upgrade notes

  • $DATA_DIR/workspace is renamed to $DATA_DIR/files once, on boot. Anything referring to workspace/ is stale.
  • TELEGRAM_RICH=0 disables rich replies without a rollback.
  • No breaking API changes; file parts on the wire gain optional size and path.
v2026.7.31
Swarm Network HermesTests passing

Swarm Network Hermes v2026.7.31

Your agent can now generate videos and send them to you, and there is a new channel to reach it on. Photos and files on Telegram now land reliably.

v0.28.0
NovaTests passing

Nova v0.28.0

Opening your Nova's own domain now gives you the same chat as the dashboard — the same components, not a lookalike — with one history shared across every surface.

The dashboard's chat, verbatim

web/vendor/chat-ui/ is the control plane's own component set plus its design tokens, generated by its chat-ui:export and synced by CI. This repo supplies only the host glue (runtime adapters over the linear store, roster, schedules). Composer, message layout, action bars, animations and scrolling are therefore identical, and future dashboard changes arrive as a sync PR instead of a re-implementation.

Light and dark

Both themes from the same token file the dashboard uses, applied before first paint. The toggle in the rail follows the OS until you pin a choice.

What the chat gained

  • Markdown replies — headings, lists, tables, code fences, and @mention tags for mesh agents (replies used to arrive as raw markdown text).
  • How Nova answered — the orchestration trace as an animated stepper; steps carrying a payload expand to the exact input/output of a member call, skill or system tool. Reasoning has its own panel; both stream live.
  • Composer — agent quick-insert chips from the live roster, a reasoning-effort pill, attachments (images reach the model as images, text files are inlined), and Web Speech voice input.
  • Edit, regenerate, branches — with a ‹ 2/3 › picker; the tree is persisted per session as the web view of the conversation.
  • Sessions rail — search, Today / Yesterday / Earlier grouping, archive and delete.
  • Schedules tab — scheduled runs (docs/15) with a friendly cron builder, pause / resume / cancel, and a run-history timeline where each fire renders exactly like a chat reply.

One history across surfaces

Sessions carry the contextId their turns run under, and turns arriving over /nova/message — the dashboard's chat — are mirrored into this Nova's own store. A conversation held in the dashboard now shows up here (badged with where it came from), and continuing it here continues the same conversation and the same memory rather than starting a parallel one. Telegram threads and scheduled runs are in the same list.

API

/chat/api gains roster, capability flags, session delete, the transcript blob, and the memory / tasks / cron routes — which now share one handler with /setup/api, so the control channel and the chat can't drift apart.

Fixes

  • peers.json pins the package versions the vendored bundle is built against, checked by typecheck: a react-lexical minor bump had silently killed the composer (Send disabled, Enter inserting a newline) with no build error.
v2026.7.29.2
Swarm Network HermesTests passing

Swarm Network Hermes v2026.7.29.2

The first reply arrives much sooner, and models that think out loud show their thinking live. There are new models to choose from, fewer interruptions for routine actions, and finished answers are kept safe even if the agent restarts.

v2026.7.29.1
Swarm Network HermesTests passing

Swarm Network Hermes v2026.7.29.1

Maintenance and reliability improvements.

v2026.7.29
Swarm Network HermesTests passing

Swarm Network Hermes v2026.7.29

Maintenance and reliability improvements.

v2026.7.28
Swarm Network MercuryTests passing

Swarm Network Mercury v2026.7.28

Your Telegram bot now recognises you from your first message, anyone you've approved stays approved across updates, and connecting Telegram is faster.

v2026.7.28.2
Swarm Network Hermes

Swarm Network Hermes v2026.7.28.2

Your Telegram bot now recognises you from your first message. Everyone else still needs your approval before it will answer.

v0.26.0
NovaTests passing

Nova v0.26.0

Nova's Telegram bot answered anyone who found its username: no allowlist, no pairing. A stranger could hold a full conversation and spend the owner's balance.

Nova now takes an allowlist with its credentials (runtime push, plus TELEGRAM_ALLOWED_USERS as a boot seed) and checks the sender before anything else — an unauthorized one gets a single plain refusal and no session, transcript, or model call. The control plane fills it with the account Telegram says created the bot.

An empty list stays open, so a Nova connected before this keeps working unchanged.

v2026.7.28.1
Swarm Network HermesTests passing

Swarm Network Hermes v2026.7.28.1

Fixes an issue where your own Telegram bot might not recognise you. Update to the next release, which includes a better version of this fix.

v0.25.1
NovaTests passing

Nova v0.25.1

Telegram queues updates for a bot that has no webhook yet. The child bot exists for minutes before its token reaches Nova, and Telegram shows a START button the moment the user opens the chat — so pressing it queued the /start, and drop_pending_updates discarded that queue on arrival.

Telegram never offers the button twice, so first contact was lost: the generated welcome never came and the bot only replied once the user typed something by hand. The pending queue is now kept.

v2026.7.28
Swarm Network HermesTests passing

Swarm Network Hermes v2026.7.28

Your agent now recovers from problems on its own, reports ready only when it truly is, and keeps your approved users, conversations and connections across restarts.

v0.25.0
Nova

Nova v0.25.0

Connecting Telegram no longer restarts the Nova, and first contact is answered by Nova itself.

Runtime Telegram credentials

  • POST /setup/api/telegram { token, webhookSecret, botUsername? } (bearer CONTROL_TOKEN) installs the child-bot credentials, persists them in Nova's own SQLite (app_config), and calls setWebhook immediately — the bot answers seconds after the QR scan, with no env push and no redeploy.
  • DELETE disconnects (drops the webhook before clearing), GET reports {connected, botUsername, webhookUrl} and never returns the token.
  • TELEGRAM_BOT_TOKEN / TELEGRAM_WEBHOOK_SECRET are now a boot seed only; stored config wins, so Novas connected the old way keep working.
  • setWebhook sends drop_pending_updates (a reconnected bot doesn't replay its old queue) and setMyCommands gives a fresh chat a menu.

Personalized welcome

/start is answered by an introduction the model writes at that moment from the live roster, the enabled persistent capabilities and the global-memory digest — static fallback if the gateway is down. It's mirrored into the hosted-chat transcript and never routed through orchestrate().

Full changelog: https://github.com/Swarm-Agent-Aggregator/Swarm-Network-Nova/compare/v0.24.0...v0.25.0

Follow along by RSS. The feed carries platform entries only.