What’s new

A running log of user-visible changes shipped to OpenEnsemble. Newest at the top.

If you auto-update (oe update), you’ll get these as they land. If not, run oe update in your install directory to pull the latest.


2026-10-09

Cleaner image replies Generated images no longer add a duplicate [Image: …] / Saved to: … text reply. Older replies also hide matching duplicate receipts when the image is displayed, while keeping captions, tool history, and saved files intact. Tool activity stays above the images it produced, including after a reload or switching agents.

Project updates on the toolbar Unread project updates now appear as a count on Projects and goals. Open the project view and choose Updates to review them. The floating notice near the chat controls has been removed. Project prompts also preserve the requested helper count when the goal title repeats the prompt, and older goal controls now enforce the same pause, completion, and removal rules as project controls.

Direct requests to named models Requests such as “Have Grok create a cat sitting in a tree” and “Use Gemini to summarize this document” now expose the model catalog and launch one worker on the named target. The launcher recognizes these requests without requiring the word “agent” or “background”, preserves the selected provider, and rejects substitutions. See Providers.

Provider capability discovery Settings and chat now share native capability readers for Claude, Gemini, OpenRouter, Grok, Ollama, and LM Studio. Discovery retains nested tool and thinking flags, supported parameters, context and output limits, and explicit restrictions. Gemini fills missing capabilities from exact official model pages; OpenRouter requests select endpoints that support their tools and reasoning parameters. Sources are retained, unknown fields remain unknown, and provider or skill permissions are unchanged. See Providers.

Current model capabilities and image editing OE retains provider model capabilities through Settings, discovery, and chat, and fills missing OpenAI capability information from official model documentation. This restores hosted image editing and web search for GPT-6 models without adding a new model-name allowlist. Image edit follow-ups attach the original saved image. Existing skill permissions and provider restrictions still apply. See Providers.

Enter the project prompt up front What should this project accomplish? is now a full prompt box for tasks, constraints, and requested agents. The saved prompt keeps its formatting and appears in a visible Instructions for this run box before Start work. Long prompts remain available after reload, and Edit goal lets you revise the saved instructions. See Projects and goals.

Older goals join Projects and goals Goals previously saved outside a project now appear in General goals, preserving their progress, status, deadlines, reference files, and prepared drafts. Existing projects and their goals stay in place. General chat can still access the converted goals, while earlier conversations and schedules remain where they were. Conversion saves a recovery copy and safely retries interrupted moves. See Existing goals and projects.


2026-10-08

Project goal controls and edit recovery Manage project goals in Overview, including Mark complete, Reopen goal, and Remove goal. Completion asks you to verify the saved condition; removal keeps work conversations and files. Running work and pending requests must be paused before completing or removing a goal. Prepared work links project goals to these controls while keeping optional drafts and general goals available. Conflicting goal edits can be compared and combined without losing newer progress. New Project text and goal edit drafts survive a reload in the same tab. See Projects and goals.

Projects and goals work together Choose Add Project to open New Project, define its goal, and select reference files in one flow. Files are also visible in Overview and the Files tab beside it. Add further goals inside the project. The unused Preparation settings shortcut has been removed. Overview shows completion conditions, next steps, blockers, and live work status. Start work launches the selected lead agent in a separate project conversation so you can keep chatting. Continue keeps prior results, Pause stops that goal’s work, and permission requests stay in its conversation. Existing project goals appear automatically; a finished reply does not automatically complete a goal. See Projects and goals.

Provider updates are tested before use OE checks Models.dev and LiteLLM for compatible provider changes. Supported changes receive a small test request before use; failed checks preserve the previous settings and explain the result in chat and Settings → Providers → Provider updates. SuperGrok’s outdated-client recovery now tests the required version before saving it. Changes that need new adapter code are reported instead of silently applied. See Providers.

Provider connections and current model catalogs Ollama Cloud validates replacement keys before saving and explains rejected credentials in Settings. Grok image/video selections now come from live catalogs. Together uses its current API host, Perplexity uses its documented Agent and Sonar endpoints, and Fireworks no longer adds unavailable legacy image models to its catalog. Compatible chat APIs remember successful parameter adjustments across restarts. See Providers.

Grok worker routing and automatic client recovery Requests such as “Make a Grok agent…” and “Tell Grok to…” now expose the model catalog and worker launch tools. Grok 4.7 can use the hosted image tool when the account has Image Generator enabled. SuperGrok connections automatically recover once from an explicit outdated-client rejection and retain xAI’s required version for future requests. See Providers.

Enable a needed skill from chat When a needed skill is disabled, OE asks before enabling it. Reply yes or choose Enable and continue to resume the request; account restrictions and hidden-tool choices still apply. See Skills.


2026-10-07

Inspect each agent’s work Expand Progress, actions & conclusion in the chat’s Agents panel to inspect each delegated task’s assignment, live activity, recorded tool inputs and results, and final report. Individual worker conclusions remain available after reload through the original conversation, and Download work record exports the displayed evidence. Failed and stopped tasks preserve their recorded actions; missing outcomes are not shown as successful. See Agent activity.


2026-10-06

Delete a project Use Delete project at the bottom of a project’s Context & tasks tab to permanently remove its conversations, saved progress and results, goals, prepared work, and scheduled tasks. Confirmation names the project and explains what will be removed. OE blocks deletion during running replies or project tasks and rejects outdated project views. Profile files are kept, and open project tabs return to general chat. Archive remains available for keeping a finished project. See Project spaces.

Follow work across project chats Project spaces now bring original and saved conversations together in Chats & activity, with running and waiting states, unread updates, and links to each conversation. Project updates surfaces finished replies and requests for input while you work elsewhere. Completed saved-chat turns now release their running status correctly.

Keep assignments and useful results with the project Project tasks support an assigned agent and chat, prerequisites, status, file-overlap warnings, and result links. Save decisions, references, or outputs directly from replies, or save a checkpoint without clearing the conversation. Outputs collects generated documents, media, and supported code links with their source chats. See Project spaces.

Keep chat usable when model discovery fails A temporary error while loading the model list no longer crashes the chat UI. Error responses leave the model list empty until it can be loaded successfully.


2026-10-05

One Skills drawer for Finance, Tutor, and custom panels Open Skills using the grid icon in the sidebar, or Menu → Skills on mobile, to see your enabled skill drawers as app icons. Search for a skill and select its icon to open the panel. All skills returns to the grid with your search and scroll position preserved. See Skills.

New custom drawers appear automatically Skill Builder now explains where to find a skill’s icon and uses the shared Skills navigation. Adding, updating, or removing a custom drawer refreshes the launcher even while your agent is responding, without reloading the page. Interactive custom drawers also start correctly when opened.


2026-10-02

Wait between routine actions Choose Routines → + Add action → Wait to pause for seconds, minutes, or hours before the next action. Waits survive closing the browser and restarting OE. Pending actions appear in Tasks → Scheduled tasks, where you can cancel the remaining sequence. Home Assistant calls and waits can be tested without a paired voice device. See Routines.

Choose Home Assistant devices and their supported controls The routine editor’s HA Device action lists physical devices from Home Assistant. Search by device or room, then choose a control and settings exposed by that device, including its available operating modes. Existing service calls remain editable through the advanced editor. Refreshing devices preserves unfinished edits, and unchanged device actions can stay saved while Home Assistant is offline.

Your saved fast paths, alongside your routines Open Routines → Saved fast paths to see and delete your saved device phrases, device aliases, and learned tool phrases. Both routines and fast paths belong to the signed-in account. Overlapping phrases show when a routine takes priority; a matching routine runs before ordinary device control in chat and voice.

Ask your agent to add a fast path for a Home Assistant device. It saves the exact device and action for that phrase and asks which device you mean when the reference is ambiguous. Saving does not operate the device. If a saved device action fails, OE reports the failure without trying a different device.

More reliable Gmail inbox loading Gmail reads limit simultaneous requests and retry temporary failures. Connection errors and rate limits now produce a clear message instead of an empty or incomplete inbox. The inbox toolbar stays available after a loading failure so you can refresh or switch accounts.


2026-09-26

Search your memories in chat Ask “show me my food preferences” or “what do you know about me” to search saved facts and notes across your profile. Search runs locally using Nomic and, when enabled with a compatible model, Cortex. Your chat model receives a small page of matching excerpts to explain, rather than the complete memory store. Refine the topic or request another page to explore more; a short answer is not a complete inventory. See Cortex.

Memory context and search results share a 1,000-byte output limit per turn, with at most two searches. Repeated searches share that allowance, and raw search-result pages from earlier turns are not replayed into future model requests. Normal conversation history and other tools have their own limits.

More selective memory context Unrelated pinned memories and preferences no longer automatically enter every answer. A complete new question is evaluated on its own; follow-ups can still use the recent conversation. With relevance checking enabled on a compatible Cortex model, Nomic and the existing Cortex model both check applicability. No additional relevance model is required. Retrieval alone no longer increases a memory’s importance.

Summaries keep the original words and outcome New session summaries use short, attributed conversation excerpts and retain links to the original turns when available. This helps preserve corrections, cancellations, and failed actions. Older generated summaries remain searchable but are excluded from automatic answer context and preference learning.

Approval buttons stay beside the current request When a new action replaces an earlier approval of the same kind, its Approve / Cancel card moves beside the latest request. This also works when chat history reloads. Duplicate events keep their position, and outdated approvals cannot resolve a newer request.


2026-09-25

Task results have their own ledger Open Tasks → Ledger to follow running tasks and review their results or errors. The ledger is now the default task view. Scheduled runs and Run now keep their prompts, replies, progress, and failures out of chat history and future chat context, including work done by background agents. Use Schedules to manage tasks and Monitors for condition-triggered watches. Results refresh automatically and can be filtered by status.

History is kept for 30 days, up to 5,000 runs per profile, with the latest 200 shown. Results remain after a one-time task finishes or its schedule is deleted. Reminders and explicitly requested notifications keep their configured delivery. See Tasks.

Separate portrait and landscape dashboard layouts Choose Portrait or Landscape above the dashboard editor to arrange each orientation’s cards, sections, colors, and page elements independently. Existing dashboards start both orientations from their original layout, and the standalone display selects the matching layout when the device rotates. Fit and 100% control the preview size. Undo, Redo, and draft recovery stay with the orientation being edited. See Dashboards.

Node jobs report back when the work finishes Long-running commands on remote nodes now trigger an automatic agent follow-up with the result, without another message from you. Quick checks return their output directly. Jobs that continue after their launch command exits can use a completion check to track the actual work; SMART disk self-tests require one.

Failed commands are marked as failures, and long results retain final diagnostics and exit status. If monitoring times out or an OE restart interrupts it, the result explains that the remote job may still be running and its outcome is unknown. OpenAI replies also keep final answers separate from progress commentary, reducing repeated completion messages.


2026-09-10

Explainable memory New answers can show the memories supplied as context, why each was included, and its source conversation when available. This is outdated corrects a memory for future answers while preserving the original context record. See Cortex.

Voice detail and room calibration Voice diagnostics show recent recognized speech, agent routing, wake decisions, and response timings. A guided quiet-room and wake check can suggest a device-specific average-score cutoff, with an explicit Apply button and reset control. See Voice devices.

Dashboard undo and recovery Customize adds Undo, Redo, saved layout versions, and recovery of unfinished layout edits after failed or conflicting saves. See Dashboards.

Task results and schedule previews Review saved outputs after one-time tasks finish or schedules are deleted, and preview upcoming runs in each task’s timezone. Scheduled work keeps its own chat-turn identity, preventing a completed action from being mislabeled because it tried to save into the scheduling conversation’s finished turn. Recording failures and actual retry counts are reported separately. See Tasks.

Project progress survives clearing context Use Clear session or type /clear by itself to start a fresh conversation. Inside a project, OE first saves the conversation and a handoff automatically, then includes saved progress in future project chats. Older history is also saved before automatic trimming. Review handoffs or download saved conversations from the project’s Progress tab. If saving fails, the conversation stays intact. See Project spaces.


2026-09-09

Project spaces Keep a project’s brief, decisions, next steps, checklist, files, and agent conversations together. Delegated and scheduled work carry the project’s context, and unsaved project drafts survive reloads. Open Project spaces from the sidebar folder button. See Project spaces.

Resumable agent jobs Supported background workers and single-stage agent delegations save progress and can continue in their original chat after an OE restart. If an interrupted action has an uncertain outcome, the job pauses with Review & resume so you can check what happened before it continues. See Resumable agent jobs.

Routines and voice diagnostics Open saved Routines directly from the sidebar or mobile menu, with shortcuts from Tasks and Learn. Voice devices → Voice diagnostics adds guided device and browser microphone checks, connection history, and response timing. The browser microphone check analyzes audio locally without uploading it. See Voice devices.

Safer learning and Undo For newly accepted learning suggestions, Undo can restore the previous setting within 24 hours. OE checks for later manual edits before restoring and directs you to review conflicting changes in Learn. Memory edits and deletions also stay consistent with personalization. See Personalization.

Goals and prepared work Track an ongoing goal with a next step, blocker, deadline, and completion condition. Goals stay with their project and follow future chats. Open the new sidebar view to review meeting briefs, summaries, reply drafts, comparisons, and proposed project next steps. Choose whether OE suggests preparation or produces private drafts automatically in Settings → Personalization.

Help when circumstances change Calendar and project changes, linked Gmail replies, task failures, and approaching deadlines can trigger preparation. OE checks that the source is still current, holds interruptions during chats and calendar events, and keeps routine items for review or a briefing. Snooze, dismiss, and usefulness feedback help control what appears next.


2026-09-08

Live agent activity in chat Open the Agents pop-out to follow background work, see current activity, and stop jobs. Completed agent results now return when you reload the chat.

More reliable worker launches and scheduling Improved worker discovery and guidance for inheriting the owner’s configured model and reasoning effort. Optional tool arguments stay optional when using Codex. Scheduling better distinguishes requests from examples, discussion, and instructions not to create reminders; requests to edit existing tasks no longer accidentally create new ones.

Backup and task recovery Backup restores are validated and staged before restart, so accounts, credentials, and scheduled tasks load from the restored state together. Backups also include custom-provider configuration. Task cancellation, recovery, and draft editing received reliability fixes. See Backups and updates.

Voice firmware 0.2.94-reliability The bundled firmware improves playback recovery, pairing retries, OTA validation, wake-word updates, and persisted device alarms. Up to eight armed alarms can ring during a Wi-Fi or server outage. After a device reboot, recovering saved deadlines still requires clock synchronization.


2026-09-04

Build an agent team from any configured model Any agent can now launch background workers on any model available to your OpenEnsemble profile, regardless of which provider or model is running the parent. Ask for “five Luna agents,” “Terra agents,” “one Qwen and one Grok,” or any other homogeneous or mixed combination across OpenAI, Anthropic, xAI, Ollama, LM Studio, OpenRouter, and compatible providers. Exact requests stay exact: if a requested provider or model is unavailable, OE reports that instead of quietly substituting another target.

Reasoning effort now matches the model doing the work Each worker validates its requested reasoning level against its own target model, so a level such as low, medium, high, xhigh, ultra, or ultra-code is used only when that model supports it. OE refreshes provider-advertised models and reasoning levels into a writable local capability catalog, allowing newly added models and levels to appear without waiting for an OE code update. OpenAI “ultra” requests remain visible as ultra even when the provider’s wire protocol names that setting differently.

See exactly where delegated work ran Agent controls and Run Inspector now show each worker’s requested and resolved provider, model, and reasoning effort. Mixed teams retain their individual assignments through planning, retries, saved skills, and nested parallel work, making routing drift and unsupported combinations visible instead of silent.


2026-09-02

See remote-node health on a dashboard Add a read-only Nodes card from Add card → Widgets to see which machines paired to the active profile are online, recently recovered, not responding, or offline. Attention states sort first, and the card never exposes node addresses, paths, access settings, or command controls. Node permission and access-schedule changes are rechecked on every refresh.

Swipe between display dashboards On a standalone display, swipe left for the next dashboard or right for the previous one. Navigation follows the profile’s saved dashboard order and wraps at both ends. A compact Previous/name-and-position/Next control in the top toolbar provides the same navigation without touch. Configure mode and gestures that begin on controls stay put, the destination opens at its default focus, and an explicit fullscreen query carries across. Every dashboard keeps its own stable address for browsers that should open one display directly.

A complete dashboard guide The new Display dashboards Guide page covers creation, editing, cards, Calendar, Email, Nodes, custom-skill widgets, colors, page elements, tablet setup, authentication, permissions, privacy, deletion, and troubleshooting.


2026-09-01

Custom colors for every dashboard Dashboard settings now include a saved color palette for the background, surfaces, cards, primary and muted text, accent, greeting, and tagline. Each color can inherit from Midnight or Warm daylight or use an exact custom value, so changing one dashboard never changes another dashboard.

Every dashboard page element is optional Dashboard settings now control the complete display frame, not only its cards. The sidebar, top toolbar, OpenEnsemble branding, focus and section navigation, connection status, hero status line, greeting, tagline, clock, Home Assistant summary, and section headings can each be shown or hidden per dashboard. The status line and greeting can use OE’s automatic text or exact custom text, and an empty tagline stays empty. Configure mode always keeps its management controls reachable even when the standalone display hides them.

Dashboards can also be reduced to a truly blank canvas: the final section may be removed, while Configure mode retains a clear way to create a new section. Existing dashboards keep their current appearance until their owner changes a setting.


2026-08-30

Dashboards can show your calendar, inbox, and custom skills The OE dashboard studio now includes read-only Calendar and Email cards next to Home Assistant devices. Each card refreshes independently, follows the signed-in profile’s skill permissions and access schedule, and fails in place without blanking the rest of a wall display.

Custom skills can contribute dashboard widgets too. Skill Builder can add or update a declarative dashboardWidgets contract tied to an exact readOnly:true data tool. OE—not the skill—renders the bounded summary, metrics, and list data, so a custom skill cannot inject HTML or JavaScript into the dashboard. Existing skills can gain a widget without being recreated.

One Dashboard entry everywhere Dashboard in the main Chat/Dashboard/Workspace switcher and Dashboard in the left menu now open the same drawer; choose Display dashboards there to enter the per-profile studio. The former Desktop widget grid remains available as Workspace.


2026-07-23

Home Assistant commands now confirm against live events OpenEnsemble keeps a persistent connection to Home Assistant’s event stream and maintains a current entity-state snapshot. State-changing tool calls wait briefly for the matching update instead of rereading the old state a few milliseconds after the command. If a device is slow to report back, OE says the command was accepted and confirmation is pending; it no longer describes the stale state as a failure. The connection automatically reconnects and resynchronizes state, with bounded REST polling as its fallback.

Home Assistant automations can fire saved OE routines An HA automation can fire the custom event openensemble_event to run an existing OpenEnsemble routine without exposing OE to arbitrary prompts or tool calls. Use the routine’s existing webhook token as the capability:

actions:
  - event: openensemble_event
    event_data:
      v: 1
      action: run_routine
      routine_id: goodnight
      webhook_token: !secret oe_goodnight_token

The token determines both the routine and its owner; an event-supplied user identity or device target is never trusted. Set the routine’s target device in OE if it needs to speak or play audio. Put the token in Home Assistant’s secrets.yaml, and rotate it with the routine editor’s Regen button if needed. The token is still present in HA’s runtime event data and automation traces, so users who can inspect HA events must be trusted with that routine capability. Depending on HA permissions, subscribing to custom events may require a long-lived token owned by an HA administrator; OE reports Live states only when state streaming works but routine events are not authorized. A persistent loop breaker latches a routine capability after 20 fires without a 12-hour quiet period; Regen explicitly resets it. Custom events are ephemeral while HA or OE is offline, while entity state is automatically resynchronized after reconnect.

2026-07-17

One assistant or a full agent team — switch whenever you want Single-assistant mode is now built into OpenEnsemble. Go to Settings → Agents → Agent setup and choose Single assistant for one primary assistant that handles every enabled skill, or Agent ensemble for the classic team of specialists. You can also say “switch me to single-agent mode” in chat. Once a single-mode account has its assistant, New Agent is disabled; switch back to the ensemble before adding another. Existing accounts stay in ensemble mode until you change them; new accounts start with one assistant. Owners and admins can manage each account separately from Settings → Users.

Switching modes never deletes your setup Moving to one assistant parks the other agents instead of removing them. Their roles, custom-skill assignments, personalities, histories, model choices, and memories remain intact and return unchanged when you restore the ensemble. Changes apply to the next message; if an assistant is currently replying, finish or stop that reply before switching.

Watchers follow the active setup and return home afterwards Your existing watchers keep their original saved targets. In single-assistant mode they resolve through the primary assistant so alerts continue arriving; switch back to the ensemble and each watcher resumes using its original specialist. Updating, cancelling, counting, and delivering watcher results all use the same live projection, so a mode change cannot strand a watcher on a parked agent.

Delegation now fits the mode you’re using In ensemble mode, agents can use ask_agent to hand work to the right specialist. In single-assistant mode that tool disappears—the primary already owns the full skill set—but it can still launch bounded background workers for slow or parallel work. Switching back restores normal agent-to-agent delegation automatically. Account permissions continue to apply in either mode.

Pick a model and reasoning effort for each role or skill Every built-in role and custom skill now has an Execution section in Settings → Skills. Leave it inherited, or choose a specific configured model and reasoning effort for that kind of work. The choice is validated against the account’s providers and model access before every turn, and Deep Research carries its selected profile through planning, parallel research, and final synthesis instead of silently falling back partway through.

Background jobs finish—and stop—when the real work does Long tasks now carry ownership through nested delegations, workers, scheduled children, MCP calls, and Deep Research. A parent no longer reports “done” while a child is still running, and Stop or timeout cancellation follows the chain to the process actually doing the work. Late completions are rejected after cancellation, while results that were already delivered remain recorded.

Email and Telegram retries no longer create duplicate effects Telegram updates are durably deduplicated before processing, and outgoing deliveries use an at-most-once ledger so a retry cannot send the same result twice. Email replies preserve their real message identity, distinguish the sending address from account identity, and correlate automatic notifications so a recovered or retried turn does not quietly repeat a send.

Requests reach the right tool more consistently The router now distinguishes “send this email” from “search my mailbox,” keeps official-source lookups on the web path instead of accidentally opening coding or deep-research workflows, and avoids triggering custom skills from quoted payloads or message bodies. Weather, calendar, task, TV, video, and research phrasing also received tighter conflict guards. Local shortcuts are recorded only after the chat turn itself is safely saved.

Run Inspector shows the routing decision, not a reconstruction Admins can now see the exact matched skills, authoritative turn source, requested reasoning effort, effort actually sent to the provider, and separate local versus provider-reported tool evidence. Structured tool-call history also preserves parallel and multi-round call identities, making failed or uncertain actions diagnosable without exposing credentials or pretending a provider attested to data it never returned.

Completed work survives a later model failure If a tool succeeds and the provider fails afterwards, OpenEnsemble now keeps the completed tool, media, and delivery evidence instead of making the whole turn look empty. Uncertain external effects are marked as possibly completed so recovery will not blindly retry them, and OAuth-backed connections surface their automatic-renewal state more clearly.

2026-07-07

Give your agents a personality New Agent and Edit Agent now have a Personality field — describe how the agent should talk (“warm and encouraging, keeps things light”, “dry, blunt, zero fluff”) and it sticks across every reply, voice included. It’s separate from the description (which tells the Coordinator what the agent is for), it survives renames and role changes, and edits apply from your very next message. Personality shapes tone only — it never changes what tools or skills the agent can use.

Updates reach your browser immediately Static files used to be cached for an hour with no way to check for changes, so after an update a phone or laptop could keep running a stale — or worse, mixed old-and-new — copy of the interface. The page now pins every script and stylesheet to a build id: repeat visits load instantly from cache, and the moment the server updates, the next page load atomically picks up the whole new version. Voice-device firmware downloads also got lighter (unchanged files answer “not modified” instead of re-sending).

Custom skill panels open from the sidebar again Buttons for skill-built panels were wired in a way the browser’s security policy silently blocks, so clicking them did nothing on desktop. They now use the same mechanism as the built-in sidebar buttons and work everywhere, including the phone menu.

Node agents can pair through a reverse proxy Installing a node agent with --server https://your-domain now works: the agent keeps the https scheme and port instead of forcing plain http on :3737, pairs over TLS, connects over wss, and self-updates over https. Plain LAN installs (10.0.0.10:3737) behave exactly as before.

Node CLI renamed: oe → oenode The node agent’s command collided with the OE server’s own oe command — on a machine running both, the node agent shadowed the server CLI and (worse) node uninstall deleted it. The node command is now oenode everywhere (sudo oenode update, sudo oenode uninstall, …); updating an agent migrates the wrapper automatically, and cleanup only ever touches oe when it’s provably the old node wrapper, never the server’s.

Removing a node actually uninstalls it now Clicking Remove told the agent to self-destruct, but the cleanup script was killed a fraction of a second later as part of the agent’s own shutdown — so the service resurrected itself every 5 seconds forever (one field machine hit 7,700 restarts). The self-destruct now re-launches itself outside the agent’s service before doing anything, and the agent gives it time to get clear — Remove reliably stops the service, removes the files, and stays gone.

Dashboard updates un-brick themselves A v2 node that was missing the server’s update-signing key (upgraded via oe update before it learned to pin the key) used to refuse every dashboard push. Now the server notices the refusal, delivers the key over the node’s already-trusted command channel, restarts the agent, and retries the update automatically — one click on Update and the node heals itself. oe update also pins the key itself now, so fresh upgrades can’t get into this state.

Switch agents from the bottom bar The bottom bar now shows which agent you’re talking to; tap it (or the Agents button beside it) to slide up an agent picker — the same sheet style as the ⋮ menu — with your current agent highlighted and a pulsing dot on any agent that’s still working in the background. Sheets also dismiss the way you’d expect now: swipe down on the handle, tap the handle, or tap anywhere outside.

Mobile now has everything desktop has The phone layout got a full refresh. Tapping ⋮ opens a bottom sheet with every feature as an icon tile — including ones mobile was missing before (Learn, Today · Tutor, Nodes, Voice devices, custom skill panels, and the advanced tools when they’re enabled) — plus quick actions for search, switching profiles, signing out, and clearing the session. The menu builds itself from the same list desktop uses, so anything added later shows up on your phone automatically. A Chat/Dashboard/Workspace switch now lives in the top bar, unread and alert badges carry over to the menu tiles, and a small dot on ⋮ tells you when something needs attention (new mail, a node alert, or an available update).

Learning now knows your automations aren’t you Personalization observations now carry provenance: activity fired by your scheduled tasks and watchers is tagged as automated, and reflection weighs each automation once as a deliberate choice you made (“keeps a watch on X”) instead of reading its every firing as you actively doing something. Routine-heavy users still get full learning — it’s just honest about what’s a habit and what’s a heartbeat.

“What I’ve learned about you” moved to the Learn drawer The ledger of facts the coordinator has inferred about you now lives in the Learn drawer alongside pending suggestions, standing rules, and the rest of the learning audit — no more digging into Settings to review it. Confirm or forget individual facts right there; Settings → Personalization keeps the setup controls (on/off, model choice, Run now, Start fresh).

Voice devices say decimals and prices properly Numbers with a decimal point are now spoken the way you’d say them — “1.609 kilometers” comes out “one point six zero nine kilometers” instead of “one six-oh-nine.” Dollar amounts read as money (“$5.99” is “five dollars and ninety-nine cents”), and distances in “km” are spoken as kilometers.

2026-07-05

Personalization you control OpenEnsemble can now learn quietly from your activity — the questions you ask, your calendar, patterns in what the coordinator does for you — and turn that into small, useful nudges in your daily briefing or a reminder before something you have coming up. It only ever suggests; nothing runs without your say-so, and accepting the same kind of suggestion twice in a row offers to make it automatic from then on.

You pick what does the learning New Settings → Personalization panel: choose “Off,” “Same as coordinator” (the default), or any other configured provider — local providers stay fully on this machine, cloud providers get one-line activity summaries, never raw email or calendar content. Every fact it’s learned about you shows up in a ledger you can confirm, delete, or wipe clean with one “Start fresh” button.

It follows up so you don’t have to When the coordinator can’t answer something right away — “is this back in stock,” “did the price drop” — it can now say so once and check back on its own, announcing what it finds instead of making you ask again.

2026-07-04

Send several files in one message Attachments now truly travel together: everything in the tray goes with the message you’re typing (up to 6 per message), the assistant sees all of them at once, and they’re remembered — reloading a chat shows every file that was attached to a message, not just the pictures from this tab session.

Task drawer shows what happened and what’s next Each scheduled task in the drawer now shows its next run time, a warning when it keeps failing, and a History view — every past run with whether it fired on time, fired late (and by how much), failed, or was skipped and why.

Sessions list names your machines Node sessions now show the machine’s actual hostname (like voice devices already did), so you can tell your machines apart at a glance.

Destructive actions now show an approval card When the assistant stages something destructive (purging a sender’s email, deleting transactions, promoting a service to trusted, cancelling another agent’s watcher), a card now appears with Approve and Cancel buttons — no more typing “APPROVE PURGE” from memory, no more losing the staged action to a typo. Typing the phrase still works, and the card survives a page reload.

Drafts follow their agent; attach multiple files A half-typed message now stays with the agent you typed it for — switch away and back, or reload, and it’s still there. The attach button accepts multiple files with a tray showing each one (sent one per message for now).

Scheduled tasks: see what happened and what’s next Every task now records a run history — fired on time, fired late (and by how much), failed, or skipped and why — so “why didn’t Tuesday’s briefing arrive?” finally has an answer. Tasks also expose their next run time, and the desktop widget shows it along with a warning badge when a task keeps failing.

Background work survives restarts Completed background delegations and workers are now remembered for 7 days — a server restart or a busy day no longer erases what finished and how. Workers spawned during a scheduled task are also now properly waited on, so a scheduled run can’t report “done” while its worker is still going.

Email auto-labeling you can trust Auto-label rules can now keep messages in your inbox (per-rule setting), the poller respects what you’ve taught the assistant about senders (a learned correction beats a rule; learned keep-inbox is honored), every action is recorded in an activity view, and “put the last batch back” undoes the most recent run.

Self-healing is no longer silent When a provider rejects a capability (native web search, reasoning effort), a login token refreshes itself, or proposal suggestions pause because they weren’t landing, you now get a one-line toast instead of silence.

Skill authoring: undo button and test bench Skill code and manifest changes now keep the last 10 versions — skill_rollback lists and restores them. New skill_try_tool runs a single tool with real arguments through the production sandbox before you rely on it. And console output from skill runs is saved to the skill’s log even when the run “succeeds,” so successful-but-wrong is debuggable.

“Why didn’t my tool get called?” A new admin diagnostic walks all ~12 gates a tool must pass (manifest, bundling, allowlists, per-turn trimming, voice allowlist, intent routing…) and names the first one that dropped it — ask “why isn’t my tool being called?” and the assistant can now actually tell you.

Sessions you can recognize — and revoke everywhere The session list now shows what each session is (browser, node, voice device — with names). One “Log out everywhere” button revokes all other browser sessions, and optionally unpairs voice devices and nodes too (they can’t sneak back in — re-pairing is required).

Conversations no longer end early on routed answers In conversation mode, replies that were routed to a specialist behind the scenes (calendar, email, weather, and friends) now keep the listen window open just like direct answers — previously any routed reply silently ended the conversation. Timer disambiguation (“the 5 or 10 minute one?”) also now holds the mic open for the full 30 seconds it will accept your pick, even with conversation mode off — no wake word needed to answer.

“What’s the weather tomorrow” actually answers for tomorrow Asking about tomorrow now leads with tomorrow’s forecast instead of re-reading today’s. Weather replies are also cleaner spoken aloud — no more ZIP code or “Source:” footer read to the room.

Instant phrases can’t hijack built-in requests A custom skill’s instant phrases can no longer claim requests that belong to a built-in — “set a reminder for tomorrow morning” goes to reminders, never to a weather skill that happens to know the word “tomorrow.” When a request sits too close to a built-in domain (reminders, calendar, email, timers, home control, messaging, media), the fast-path steps aside and the normal assistant handles it. Skill authors get warned at build time when their phrasings sit too close to a built-in domain.

Background work announces when it’s actually done When delegated work spawns further sub-tasks, the device used to say “done” and stop its waiting ring while the sub-tasks were still running — then stay silent when everything truly finished. The announcement and the ring now track the whole job.

Chat & device polish Opening a chat lands you at the latest messages (no more mid-history jumps), the “jump to latest” pill counts how many new messages arrived while you were scrolled up, and sending while disconnected now tells you instead of silently dropping. Voice device cards show Wi-Fi signal strength (flagged when weak) and audio drop counts, so “why does it sound choppy” is answerable at a glance. Provider failover now also catches “overloaded” errors, not just timeouts and 5xx.

Teach your own instant phrases Tell your assistant “when I say check the deals, run my Publix skill” and it’s learned on the spot — the phrase now triggers that skill’s tool instantly on-device, with no cloud round-trip, in chat or by voice. “Forget that phrase” undoes it. Skills you build also get smarter about this on their own: when a custom skill keeps handling the same kind of simple request the slow way, OpenEnsemble notices and offers to make it instant — one tap to accept. And skill authors get guardrails: the skill-builder now auto-merges redundant fast-path intents and warns when two intents’ phrasings overlap enough to shadow each other.

Voice replies speak places and weather naturally “Springfield, IL: 76°F, wind 3 mph” is now spoken as “Springfield, Illinois: 76 degrees, wind 3 miles per hour” — state abbreviations, degree symbols, speeds, and slashed number pairs are naturalized before synthesis, for every skill and every agent.

Calendar follow-ups without repeating yourself After a calendar answer, a bare follow-up like “what about Wednesday?” or “and next week?” is answered instantly from the same local mirror — no need to say “what’s on my calendar” again. Strictly guarded: the follow-up must name a day or range and must come immediately after a calendar answer, so unrelated follow-ups (“what’s in my email?”) route normally.

Background work you can see and hear sooner When the assistant hands work to another agent (“I’ve asked the researcher — I’ll tell you when it’s back”), the voice device’s LED ring now keeps a rotating rainbow going until the result arrives (firmware 0.2.73), so a quiet device no longer looks like something failed. Results are also spoken sooner: completed background work now speaks as soon as the device is quiet — including while it’s sitting in a listen window waiting for you — instead of holding for several extra seconds, and the follow-up window re-opens afterwards so you can react.

Calendar answers in about a second “What’s on my calendar today”, “do I have anything Friday”, “what’s my next meeting” — these are now answered instantly from a local mirror of your Google Calendar instead of a slow round-trip through the model (voice turns that used to take a minute or more now speak in a second or two). The mirror covers every calendar you have visible in Google, refreshes itself every few minutes, and double-checks with Google right before answering, so an event you just added or cancelled is always reflected — a stale answer is never spoken. Harder questions (“when am I free for two hours next week?”) still go to the assistant, which now reads your whole schedule in a single calendar_snapshot call instead of listing each calendar one by one. Requires Google Calendar to be connected; everything falls back to the old path if the mirror is unavailable.

Voice devices: real back-and-forth conversations New per-device Conversation mode (Settings → Voice devices, or PATCH conversation_mode): say the wake word once, and after every reply the device keeps listening for about 8 seconds so you can just keep talking — no wake word between turns. The conversation ends when you go quiet, say something like “stop”, “that’s all”, or “goodbye”, or someone else’s wake word takes over. Requires voice-device firmware 0.2.65.

Interrupt a reply just by speaking In conversation mode, start talking while the assistant is mid-reply and it pauses to listen. If you were actually saying something, the reply is cancelled and your interjection becomes the next turn; if it was a cough, the TV, or an “um”, the reply picks back up right where it paused. Wake-word interruptions still work everywhere, as before.

Voice replies are harder to break A deep reliability pass on the whole voice turn path. Every message between the device and server now carries a turn ID, so leftovers from a cancelled reply can’t confuse the next one (this fixes music resuming over you mid-command after a barge-in). The device now recovers within seconds — instead of up to 90, or sometimes never — when the server drops mid-reply, a reply never starts, or an error ends a turn. Follow-up listening windows (“Which one did you mean?”) now open when the device finishes speaking the question instead of expiring while it’s still talking, and soft-spoken answers no longer lose their first syllable.

Faster voice turns With firmware 0.2.65 the device streams your words to the server while you’re speaking instead of uploading the whole recording afterwards, so transcription starts the moment you stop. The server also stops re-reading device config files on every single turn.

Music ducks under the assistant’s voice instead of stopping The device firmware (0.2.68+) gained a real audio mixer: when the assistant speaks over ambient sound or AirPlay, the music now dips smoothly to about 10% volume, the voice speaks on top, and the music swells back — no more abrupt pause and restart. Saying “stop” or “that’s enough” during a reply now stops the reply and leaves your rain sounds or music playing; a bare “stop” with only music playing still stops the music.

Background work announces itself when it’s done If you ask for something slow — an image, a delegated task — the assistant says “On it, give me a moment,” the LED ring switches to a rotating rainbow so you can see work is happening, and the microphone comes back to you during the wait. When the work finishes, the result is spoken as a one-line announcement the next time the device is quiet (ducking over any music), even if you’ve asked other questions in between. Saying “stop” mid-task now cancels the whole chain, including the specialist doing the work.

Voice replies sound like a person, not a screen reader Spoken replies no longer read out URLs, calendar event IDs, or emoji — those are stripped before synthesis (the full text stays in your chat). Dates and times are spoken naturally: “Saturday, July 4th, 2026, 5 AM to 8 AM” instead of “Sat, Jul 4 · 5:00 AM–8:00 AM”. List-style content gets natural pauses between items instead of running together. Voice turns can also read your calendar directly now, and always know today’s actual date.


2026-07-03

Replies start faster, and voice replies stop pausing mid-thought A round of performance work across the whole turn path. The fixed setup cost before every reply (memory recall, tool selection, context building — previously run one after another) now runs in parallel, cutting it to roughly a third. On voice devices, the next sentence of a reply is now synthesized while the current one is still playing, so longer answers no longer have awkward silent gaps between sentences. Long conversations also stop re-sending every old tool result with every message, which keeps more of your actual conversation in the model’s context and makes long sessions cheaper.

The app stays responsive while background work streams While a delegated/background task was streaming progress, the browser fired a task-list refresh (two requests plus a full drawer re-render) for every progress update, and the server rewrote the whole watcher file for each one — with enough updates this made everything feel sticky. Progress updates now batch (the drawer refreshes at most every couple of seconds, immediately when something finishes), the tool-activity panel only re-renders when it’s actually open, and the tool-suggestion bar under the composer no longer re-scans on every keystroke. Server-side, scheduled-task bookkeeping now touches only the affected user’s file instead of rewriting every user’s tasks on each fire.

Email sorting and large code projects: less waiting Sorting a big inbox re-read the learned label store once per email (200 emails = 200 reads of the same file) — it’s now read once per change. For IMAP accounts, message previews fetch only the first 2 KB instead of entire message bodies, and operations reuse one connection instead of a fresh login per action. The Code Projects pane also stops freezing the server while it sizes up large projects. The 🌐 Everyone button on document sharing looked like it worked, but other users could never see or open the document — the share was recorded on the file yet never entered the discovery list, so it silently behaved like “share with nobody”. Everyone-shares now show up (and open) for every user, existing everyone-shared documents are repaired automatically, and un-sharing removes both visibility and access as expected.

Cloud replies retry through brief provider hiccups; token/cost metrics stop reading zero A momentary provider overload (the classic Anthropic 529, a 429 rate-limit, or a dropped connection) used to fail the whole turn immediately. All cloud providers now retry the request a couple of times with short waits (respecting the provider’s requested back-off) before giving up — nothing double-executes, since only the initial request is retried. Separately, token usage for OpenAI-compatible providers and OpenRouter was always recorded as 0 (the usage report was never requested, and when present it arrived after the point the stream stopped reading); real input/output/cached-token counts now land in your usage metrics. Claude models routed through OpenRouter also get prompt caching now (20–40% cheaper long conversations, same as the direct Anthropic path), local models via Ollama no longer lose the second tool call when the model fires two at once, and screenshots/generated images now reach LM Studio vision models instead of a “can’t see images” note.

Chat stays where you’re reading while a reply streams Scrolling up to re-read something while the assistant was still typing used to be impossible — every token yanked the view back to the bottom, several times a second. Now the chat only follows the stream while you’re already at the bottom: scroll up and it stays put, with a ↓ Jump to latest pill you can tap to catch back up. Sending a message or switching agents still lands you at the latest message. Streaming is also much smoother in long replies (the whole message no longer re-renders on every token), and you can select text mid-stream without losing the selection. (If you updated earlier today: the pill initially showed but ignored clicks — it was rendering underneath the chat layer. Fixed; hard-refresh the tab after updating.)

Long chats load faster and stop bloating the tab Very long sessions used to render every message on every update, which made switching to a busy agent slow and let long-lived tabs eat memory. The chat now renders the most recent 150 messages with a Load earlier messages button at the top — click it to page further back without losing your place. Generated-image memory is also reclaimed when bubbles re-render, so image-heavy chats no longer grow the tab’s footprint over time.

Stop and errors no longer tangle the next reply After pressing Stop (or after a turn failed), the next reply could get glued onto the aborted bubble. Both now finalize cleanly: what streamed before the Stop stays as its own message, and the next reply starts fresh. A connection blip mid-reply also no longer leaves the text painting into a bubble that’s no longer on screen.

Voice-device dropdowns save on every input method In Settings → Devices, picking a voice, wake word, or user with the keyboard (or on many phone pickers) silently didn’t save — only mouse clicks did. All the slot dropdowns now save on the actual change, whatever input method you use.

Tutor quizzes: switching agents mid-answer no longer eats the reply Answering a tutor widget (quiz, flashcard…) and switching agent tabs before the response finished used to swallow the reply — and could swallow the next reply too. The response now survives the switch and shows as a normal message when you come back.


2026-06-08

Removing a voice user now frees its slot and wipes the wake word off your devices Voice devices give each user in your Global Voice Configuration a wake-word “slot,” numbered by the order they’re listed. Removing someone used to leave a hole: the people below them kept their original slot numbers, and the removed user’s wake word stayed loaded in the device’s memory — so it could still fire until you happened to reassign that slot. Now removing a user packs everyone up a slot (so a list of Alex, Test, Jordan with Test removed becomes Alex = slot 0, Jordan = slot 1) and clears the freed slot off every paired device, deleting its wake word from the device’s storage so it stops responding immediately (online devices right away; offline ones the next time they connect). The push happens automatically when you remove a user — no separate Push click. (Requires firmware ≥ 0.2.48; older devices keep the previous behavior until they update.)


2026-06-07

Reset a voice device’s Wi-Fi from the app Moving a voice device to a different Wi-Fi network used to mean re-flashing it over USB (the saved Wi-Fi lives in NVS, which re-flashing preserves). Now there’s a ⟳ Reset Wi-Fi button on each online device in Settings → Devices: it tells the device to wipe its Wi-Fi/pairing and reboot into its setup AP (oe-voice-XXXX), so you can join that and enter the new network — no computer, no button-fishing. Because the device comes back as a fresh pairing, OpenEnsemble also removes it from your device list when you do this (it reappears once you re-pair it on the new network). Wake-word models on the device are kept. (Requires the device to be online to receive the command, and firmware ≥ 0.2.44.)

Routines: announcement finishes before ambient sound starts In a routine that both says something and plays an ambient sound, the sound used to start while (or before) the spoken announcement played, talking over it. Now the routine speaks its reply first and only starts the ambient sound after the announcement has finished, so you actually hear it. Applies to voice-triggered routines, the Test button, and webhook/NFC fires.


2026-06-06

Pick which GPU runs local Speech-to-Text On a machine with more than one NVIDIA GPU, the local Faster-Whisper STT service used to always grab the default GPU (device 0) — a problem if you wanted that card free for something else, like training a model. Settings → Providers → STT now shows a STT GPU picker (when you’re on the GPU profile and have 2+ GPUs): choose which card Faster-Whisper runs on, and OpenEnsemble re-pins the service and restarts it (~15 s). The choice survives reboots and reinstalls. Single-GPU and CPU setups don’t see the picker — nothing changes for them.

Voice device settings: edit freely, push when ready In Settings → Devices, changing a voice device’s wake word, voice, cutoff, or avg cutoff used to update your device over-the-air on every change. Now those edits just save — your device only receives them when you click the new Push button (now next to the Avg cutoff field). If you were used to changes taking effect on the device automatically, this is the difference: tweak everything you want, then Push once. It also stops the device’s wake word from reloading on every keystroke, which could leave it on a stale model until a restart.

ElevenLabs speech-pace slider ElevenLabs’ fast default cadence — especially the low-latency Turbo model — could make spoken replies sound rushed or sped-up. There’s now a Speech pace slider under Settings → Providers → TTS that appears when ElevenLabs is selected: slide it down (toward 0.7) to slow speech to a natural pace, or up toward 1.2 to speed it up. It defaults to 0.85, which fixes the rushed delivery out of the box. (Piper already had its own pace control; now both providers do.)


2026-06-03

Skill proposer stops false-firing on shared utility tools The auto-skill proposer used to skip any candidate that shared even one tool name with an existing custom skill — so a five-tool workflow that happened to use web_search would never get proposed if you also had a tiny web_search-using skill installed. Now it computes per-skill Jaccard overlap and only treats ≥50% shared tools as a duplicate. When real overlap is detected, it also checks usage telemetry: actively-used skills (3+ invocations) block proposals as before, but dormant skills (zero invocations, >7 days old) and fresh skills (recent, untried) are tracked with distinct reason codes so future “want to revive your unused skill X?” prompts have a hook.

Skill-builder catches type errors, manifest/code drift, AND runtime crashes before code lands When the coder creates / updates / patches a custom skill, the new code goes through three pre-write gates: a TypeScript type-check (wrong import depths, forgotten ctx parameter, missing await on async helpers, CommonJS leftovers); a manifest/code consistency validator that catches the silent failure where manifest.json declares tool weather_lookup but execute.mjs handles get_weather; and a per-tool smoke runner that actually invokes every tool the manifest declares with generated args, catching handler crashes, wrong-typed returns (object instead of string), hangs (3s timeout per tool), and silent arg-name mismatches. Tools that legitimately can’t be smoke-tested (sends email, deletes things, smart-home actions) get a destructive: true annotation in the manifest and are skipped with a warning instead of being invoked. All three gates run together so one fix-and-retry handles every bug class. Strict default: any error blocks the write; warnings surface in the success message. Separate skip_lsp / skip_validator / skip_smoke flags let the coder bypass one gate precisely when another is the legit catch. Infrastructure failures (TS missing, smoke timeout on a tool’s own internal sleep) never block.

MCP (Model Context Protocol) — local, remote, and OAuth You can now plug any Model Context Protocol server into OpenEnsemble — local subprocesses (stdio), remote HTTP servers, and OAuth-protected remote servers. New Settings → MCP tab with a Browse catalog button (10 popular servers pre-filled with their package name + required secrets), live status badges, and conversational management through your coordinator (mcp_list_servers, mcp_add_server, etc.).

Each user manages their own MCP servers — no cross-user sharing. If two users in a household want the same integration (Calendar, GitHub, etc.), each adds it with their own credentials. This keeps the user-isolation boundary clean; one user’s token never powers another user’s agent call.

For remote servers that require OAuth (Cloudflare and others): pick http transport + OAuth authentication when adding, click Authorize on the server card, complete the consent screen in the popup that opens. Tokens are stored encrypted under your account and refreshed automatically. Headers-based auth (Personal Access Tokens etc.) remains for everything else.

Cheaper, faster turns via prompt-cache tiering The system prompt your agents send to the model is now split into three layers — a stable persona+tooling layer, a per-turn skill SPA layer, and a volatile layer with the date and one-shot notes. On Anthropic models, each layer gets its own cache marker so the bulk of the prompt is reused turn-to-turn instead of being re-sent. On OpenAI models, the same reorder lets OpenAI’s automatic prefix cache hit on more of the prompt. Verified: a follow-up turn on Sydney hit 36% prompt-cache the first time the tier path activated. The tool-router also now puts always-on tools at fixed leading positions in the tools list and appends per-turn-matched tools at the end, so the cache hits the tools block too. New [provider] cache: mode=tiered hit=N% log lines surface the hit rate.

Quieter node_exec results for the LLM When an agent runs apt, pip, docker pull, or similar on a remote node, the live stream you see in chat is unchanged — but the version of the output the LLM reads at the end is now noise-stripped (download progress, per-package “Setting up …”, layer-pull chatter, progress bars). Typical apt install drops from ~5KB to ~500 bytes of tool result. If the cleaned output is still over the cap, head + tail are kept (instead of head-only) since the meaningful “did it succeed?” line usually lives at the end.

Save or discard chat attachments after the reply Before today, every file you dropped or pasted into chat — images, PDFs, audio, video — silently persisted to your profile files forever, even if you only meant to ask one question about it. The ✕ on the preview pill only cleared client state; the file stayed on disk. Now after each turn that had an attachment, a small “Keep foo.png in your files?” bar appears with Keep and Discard buttons. Keep is a no-op (the file is already saved). Discard deletes it from your profile-files folder, and for documents it also prunes the entry from your docs index so it stops showing up in list_profile_files. The prompt fires for everything uploaded via drag-drop, paste, OR the attachment button, but not for voice-device turns (no screen) or routine follow-ups (the original turn already prompted). If you ignore it, the file stays — no expiration sweep.

Specialists can now escalate to the coordinator Until today, only the coordinator could call ask_agent. If you asked a specialist for something just outside its domain — “send me an email of the latest videos from my channels” to your YouTube agent, for instance — it would respond with “I can’t email” and stop. Now every specialist has ask_agent restricted to one target: coordinator. The specialist does its part of the work, then escalates with a task description that includes what it gathered, and the coordinator routes the remainder to whoever can finish (the email agent, the coder, etc.). Two safeguards prevent chains from spiraling: max delegation depth is 2 hops, and specialists can only escalate up (never to another specialist directly). The coordinator’s full delegate roster is unchanged.

Background-task replies stay around after a reload When an agent delegated work to a specialist in the background, the specialist’s final reply used to render as a tagged bubble for the rest of the session — but on a browser refresh it would either disappear or render as a flat assistant message with a [<name> finished in background] prefix and no sender styling. Now the persisted entry carries enough metadata that the same tagged bubble renders on reload, with the agent name in the header and the body cleaned up. The bubble also has a height cap with internal scrolling, so a long reply (e.g. “top 3 videos from each of N channels”) no longer pushes the rest of the conversation off-screen. Older entries from before this fix get the same treatment retroactively via prefix detection.

Settings → Skills now separates Roles, Custom Skills, and Tools Three independent sections instead of one mixed list. Custom skills (the ones you or your coder built) live in their own section with an agent-picker dropdown per skill, so you can see at a glance who owns what and reassign in one click. Built-in tools (Web Search, Task Scheduler, Profile Files, etc.) are listed below, with a clear “available to any agent” label. A handful of internal capabilities — Active Agents, Skill Builder — are now bundled with the coordinator and coder roles respectively and no longer appear in the Tools list (they were never user-assignable in any meaningful way, and listing them confused things).

New-agent and /claim pickers now show custom skills When you create a new agent, the Role dropdown groups choices under “Roles” and “Custom skills” — picking a custom skill assigns it to the new agent immediately, transferring ownership from whoever held it before. Same fix applies to the /claim / /release slash-command picker in chat: typing /claim now shows both roles and custom skills, each tagged with their kind and current owner. Typing /claim with no argument lists everything that’s assignable so you can browse.

Coordinator always sees a full roster of your agents “Who are my agents?” used to miss any agent you created after your coordinator was first set up — because the coordinator’s stored system prompt was written before the dynamic-roster feature shipped. Now the roster is auto-appended on every turn for any agent whose primary role is coordinator, regardless of what the stored prompt says. Includes unassigned agents too (a newly-created “Test” agent shows up immediately, even without any skills).

Agent description edits no longer revert Editing an agent’s description and saving used to look successful but the value would re-render to the old text on the next load — the PATCH route’s allowlist silently dropped the description and systemPrompt fields. Fixed; both fields now persist, and changing the description also rebuilds the agent’s stored system prompt so the new wording reflects in the agent’s behavior on its next turn.

**HA “turn on X” no longer matches entities named “ None"** A handful of HA integrations create entities whose `friendly_name` ends in the literal word `None` (a misconfigured subentity label that the integration stringifies as Python's `None`). When you said "turn on window ac", the fast-path could match `Window AC None` instead of your real window AC entity, fire `turn_on` on the wrong device, and report success even though nothing happened. These entities are now filtered out of the fast-path index at load time, so the resolver picks a properly-named sibling (or misses and falls back to the LLM, which lists devices and asks you to confirm).

Skill Builder now keeps the manifest in sync with the code A new skill_update_tool_def tool lets the skill author update one tool’s description or parameters in an existing skill’s manifest without rewriting the whole file. Crucially, the skill-builder system prompt now requires this call any time a code patch changes what a tool returns or what arguments it accepts — without it, the calling agent reads the stale description, doesn’t trust the new behavior, and either reproduces the work with generic fallback tools (fetch_url, web_search) or skips the change entirely. End-result: when you ask the coder to update one of your custom skills, the next time the owning agent calls one of its tools, it actually uses the new behavior instead of working around it.

Voice-device firmware 0.2.36: quieter serial log (developer) The wake-word audio_lvl=… periodic stats line moved from INFO to DEBUG. Same data still streams server-side via the wake_avg_prob telemetry channel; the local print was clutter at the default log level. No user-visible behavior change — only relevant if you’ve been watching serial output.

Voice-device firmware 0.2.35: bigger task stacks + per-task stack diagnostics Voice devices were occasionally panicking after long uptimes with a FreeRTOS vApplicationStackOverflowHook trap — typically when several heavy audio paths (TTS playback, ambient streaming, wake interruption) chained in quick succession. The mp3 decoder + audio resampler combined can carry ~5-6 KB of stack frames, and a few tasks were sized at 4 KB or 8 KB — close enough to the limit that an unlucky deep call would tip over. Bumped five tasks (tts_worker, drive, ambient_w to 12 KB; audio_play, audio_cap to 6 KB; hb to 4 KB) and added per-task stack-high-water-mark logging to the heartbeat task ([hb] stack hwm ...) every minute so future overflows can be pinned to a specific task name. (0.2.34 shipped the diagnostic but blew the heartbeat task’s own stack — 0.2.35 fixes that.) Update via the Devices drawer when a paired device shows 0.2.35 available.

Custom skills now belong to one agent — pick which one in Settings Specialists used to silently inherit every custom skill you’d ever built — so an email specialist might end up with 70 tools in its context even though only 13 were email-related. That bloated every turn and made the LLM more likely to grab a wrong tool. Now each custom skill is assigned to exactly one agent, and only that agent sees its tools. Settings → Skills has a new “Custom skills” section with a dropdown per skill — pick the agent that should own it (defaults to your coordinator). You can also chat with an agent and say /claim <skill-id> to move a skill to it, or /release <skill-id> to clear the assignment.

If you’re updating from a previous version, all of your existing custom skills get auto-assigned to your coordinator on first boot — nothing disappears, but if you had a custom skill that you specifically wanted on a specialist, move it via the new Settings UI or /claim it from a chat with that agent.

Aliases — say “the kitchen lights” once, OE remembers it OpenEnsemble now learns the names you use for things. Reference a skill, agent, node, email account, project, or watched YouTube channel by a friendly name — e.g. “ask the researcher”, “the pihole server”, “my work email”, “the side project repo”, “any new videos from that channel I added last week” — and the coordinator skips the usual list-then-filter dance and goes straight to the right tool with the right id. Aliases auto-save the first time they’re resolved (so the second mention is instant) and cascade-delete when the underlying thing is removed. If the LLM asks “did you mean X?” and you reply “yes”, that learns the alias too. Custom skills with their own catalogs can opt in via a small alias_catalog block in their manifest — Skill Builder knows the pattern.

Routine HA actions no longer hang on slow Home Assistant Routines that touch Home Assistant (like the goodnight routine doing light.turn_off entity_id=light.all) used to block up to 15 seconds per action when HA was slow to acknowledge — typical when one call expands to many bulbs. Now those calls are fire-and-forget: OE waits 1.5 s for transport-level errors (HA actually down) then moves on, treating slow responses as “queued, will finish async.” Same change applies to the HA fast-path (“turn off the kitchen lights”) so you get an immediate spoken confirmation instead of a 15-second silence followed by a confused LLM paraphrase.

Ambient sound resumes on its own after a wake interruption If you say a wake word while ambient audio is playing (rain, white noise, sleep sounds from the goodnight routine), the firmware interrupts playback so it can listen. Previously the ambient stayed off after the wake handler completed — even if no new ambient was started by the resulting turn. Now the server snapshots the device’s ambient state at the start of a voice turn, and if nothing this turn started or explicitly stopped ambient, the same stream resumes ~3 seconds later (long enough for any TTS reply to finish first).

Voice-device firmware 0.2.33: end mp3 decoder pitch glitches Two related fixes for the brief audio glitches some users heard on long ambient playback:

  • libhelix occasionally mis-parses an mp3 frame header during network jitter and reports a phantom sample rate (22050 or 32000 on a 44100 file — caused by a flipped MPEG-version bit). The firmware now locks the stream rate on the first valid frame and ignores subsequent rate reports, so a brief misparse no longer plays the recovery buffer at the wrong pitch.
  • The same lock pattern applies to TTS playback — covers different providers cleanly (Piper 22050, OpenAI 24000, ElevenLabs 44100), resets between sentences so a provider switch picks up the new rate.

Update via the Devices drawer when a paired device shows 0.2.33 available.

Routine editor: long ambient filenames no longer overflow the panel The play_ambient action’s filename dropdown stretched its grid column to fit the longest option, pushing the whole routine editor off-screen for files with long names. Constrained to its container width with a hover-tooltip showing the full filename.

install.sh: ffmpeg now detected on existing-tool systems A fresh install on a system that already had build-essential, python3, etc. would skip the ffmpeg install entirely (the detection loop didn’t check for it), then Voice Devices would later complain ffmpeg is not installed. ffmpeg + openssl now in the detection list alongside the other tools.


2026-06-02

Voice devices: spoken time/date, false-fire gating, and clearer auth errors A handful of voice-device polish items shipped together:

  • “What time is it?” / “What day is it?” now answers in natural spoken form on voice devices (“two fifteen P.M.”, “Tuesday, June second”) instead of digits-and-colons. Browser and Telegram chats keep the existing compact format. Also fixes a regression where Faster-Whisper’s trailing period was breaking the trivia fast-path — any phrasing that worked before still works, plus the punctuated variants STT produces.
  • New Avg cutoff field on each wake-word slot in Settings → Voice devices. It’s a server-side gate on the firmware’s rolling-window average probability — useful for filtering brief cross-fires (e.g. a different slot’s wake firing on a TV or on your own TTS playback). Leave blank to disable, or set 0.85–0.95 to drop marginal fires while keeping confident ones. Set independently from the existing peak cutoff.
  • If your coordinator’s LLM provider rejects its credentials mid-turn (session revoked elsewhere, refresh token expired, etc.), the device now speaks “Your coordinator’s provider needs to be reauthenticated. Please reconnect it in Settings.” instead of going silent. OpenAI/ChatGPT OAuth specifically tries one auto-refresh first — if upstream truly revoked the session, you get the spoken reconnect prompt rather than a hung chat.

Local Faster-Whisper STT — keep transcription private and offline Speech-to-text now has a local option alongside the existing remote-API one. Settings → Providers → Speech-to-Text has a top-level Provider dropdown: pick Remote API for OpenAI/Groq/etc. or Local — Faster-Whisper large-v3-turbo to run on this server. Local mode offers two profiles you choose at install:

  • CPU profile — large-v3-turbo int8, ~810 MB on disk, ~2 GB RAM at runtime. Works on any system without a GPU. Speed varies by CPU: modern desktops run ~2-3× real-time; older laptops/SBCs land near real-time.
  • GPU profile — large-v3-turbo float16, ~810 MB model + ~2 GB NVIDIA CUDA libs (auto-installed via pip into a dedicated venv), ~2.5 GB VRAM. Requires an NVIDIA GPU + driver (installer fails fast with a clear error if nvidia-smi isn’t present). 14-40× real-time. Not supported: AMD/Intel GPUs and macOS — use CPU profile there.

Switching between CPU and GPU re-runs the installer (1-2 min); switching between Remote and Local preserves your API credentials for next time so you can flip back without re-entering them.

Transcribe audio and video in chat Drop an audio or video file into the chat and say “transcribe this” — the transcript comes back without an LLM round-trip (the fast-path runs your configured STT directly). Supports common audio formats (wav, mp3, flac, ogg, m4a, aac, opus) and video formats (mp4, mov, mkv, webm, avi — audio is extracted via ffmpeg first). 500 MB upload cap; the previous 10 MB cap that blocked large videos has been lifted. If your STT isn’t configured, the request falls through to the coordinator instead of erroring silently.

Audio is now its own profile folder Chat-uploaded audio used to land in your Documents folder mixed with PDFs and CSVs. Now it goes to a dedicated Audio folder (alongside Images and Videos), with its own tab in the Docs drawer and an inline player so you can preview clips without opening a viewer. Existing files in Documents stay where they are.

@-mentions in chat: agents and files Two new chat-input behaviors. Type @ and an autocomplete menu drops in:

  • @<agent-name> routes the message to that agent and auto-switches your active chat tab to theirs. Works from any agent’s chat panel — useful for quickly delegating without opening a different drawer first.
  • @audio/foo.wav, @video/clip.mp4, @image/sunset.png references a file already in your profile folders. Tab-completes to the exact filename and the server resolves it to an absolute path so transcribe (or any path-aware tool) can act on it. Typing @a shows both any agent whose name starts with a and the audio/ folder as completion options.

@audio/<file> transcribe this fires the transcribe fast-path on your saved files the same way attaching a fresh file does.

Wake-word false-positive recovery When a voice device fires a wake word on noise (TV, a cough, a sentence ending in the wake word) and the STT comes back empty or near-empty, the device used to sit in THINKING forever waiting for a reply that never arrived. Now a server-side fast-path catches these and replies “I’m sorry, I didn’t catch that” so the device immediately returns to listening. Doesn’t pollute your chat history — false-positive wakes don’t appear as turns.

Speech pace slider for Piper voices Settings → Providers → Text-to-Speech → Piper has a new Speech pace slider when Piper is installed. Range 0.80×-1.50× (Piper’s default is 1.00×; OE ships at 1.10× because the VITS voices read a little fast for most listeners). Saves on release so the next TTS call uses the new pace immediately.

Piper TTS goes multi-voice with a downloadable voice catalog Piper now runs as a multi-voice service instead of being locked to a single model at install time. Settings → Providers → Text-to-Speech → Piper shows a catalog of voices you can download independently — including a custom OpenEnsemble Australian female voice (en_AU-OE_custom-medium) hosted on our HuggingFace repo, plus seven popular voices from the public Piper catalog (Amy, Lessac, Ryan, LibriTTS-R, Alba, Jenny, and Cori-high). You pick which voice to install when you first set up Piper; additional voices download independently from the same catalog. The service hot-picks new voices up without a restart. In Voice Devices, each slot now has a dropdown of installed Piper voices instead of a numeric speaker ID, so different users / different wake-word slots can talk in different voices simultaneously. Multi-speaker voices like LibriTTS-R get an extra speaker-id field after voice selection. Existing numeric voice values keep working — they’re auto-mapped to LibriTTS-R behind the scenes.

KittenTTS — a tiny local TTS option for machines without a GPU A new text-to-speech provider lands alongside OpenAI, ElevenLabs, and Piper. KittenTTS is a 25 M-parameter ONNX model that runs on CPU — no GPU, no API key, ~50 MB total install. It ships 8 preset voices (expr-voice-2-f through expr-voice-5-m); voice cloning is not supported, which is the trade-off for being so small. Quality is functional, not class-leading — the right pick when the alternatives are “pay for a remote API” or “buy a GPU”. Three ways to install: tick the prompt during a fresh install.sh, click “Install KittenTTS” in Settings → Providers → Text-to-Speech, or ask the coordinator (“install kittentts on this server”).


2026-05-31

Voice-friendly email output When you ask a voice device about your latest email or have one read aloud, the reply no longer recites IDs, dates, thread IDs, or “→ summary” prefixes that the email formatting rules tell the model to include on web. The response just states the sender, subject, and a short summary, with long bodies trimmed so the device summarizes instead of reading the whole message verbatim. Message IDs are still in the tool result for follow-ups (“trash it”, “reply to that”) — they’re just no longer spoken.

Skills can now poll automatically and notify by voice, email, or Telegram A new monitoring primitive lets any skill — including ones the skill builder writes for you on demand — set up a recurring check on an external source (a feed, a page, a price, a queue, an inbox) and notify you when it changes. The skill picks a cadence preset (minutely / 5-min / hourly / daily / weekly) and a delivery mode. The default runs a coordinator turn so it can speak the news on a voice device. Email delivery sends from your connected Gmail / Outlook / IMAP account directly to your inbox — zero AI tokens spent composing it. Telegram delivery messages you via your linked bot chat — also zero tokens. Switching delivery on an existing watcher works the same way: ask again with the new preference and the old registration is replaced so you don’t end up with duplicates.

Skill builder learned the monitored-source pattern When you ask for a recurring watcher (“make a tracker for [thing]”, “ping me when [source] changes”, “watch [feed] for new posts”), the skill builder now scaffolds a four-piece proactive skill in one shot: a fetcher for the source, an appropriate cadence (weekly for store ads, hourly for channels, fast for prices), a filter that reads your stored preferences from memory so you only hear about items you care about, and a notification path of your choice. No more manually wiring up polling, filter logic, and delivery each time you describe a watcher.

Auto-offer monitoring on the kinds of questions you ask repeatedly When you ask the coordinator something time-varying (“any new uploads from [channel]?”, “what’s on sale at [store]?”, “is [thing] back in stock?”, “did [person] post yet?”), the coordinator now recognizes the shape of the question and offers — after answering — to set up automatic monitoring. Decline once and the offer goes away for that turn; the next topical question will offer again. Recognized via a small embedding classifier, no extra AI round-trip.

See what other agents are doing Asking the coordinator “is [agent] still working?” or “what’s [agent] doing?” now returns concrete detail: which background dispatches are in flight, the task they were given, which tool they’re currently running, and how many tools they’ve used. The activity panel in the corner of the chat also shows live “running [tool name]” updates as background agents work, replacing the static spinner that was there before.

AirPlay pause / resume reliability + iPhone UI sync (firmware 0.2.28 – 0.2.29) Voice-pausing AirPlay music now both updates the iPhone Music app to show “Paused” AND locally mutes the speaker as a safety net. The hybrid means voice-resume works reliably even after long pauses (the local-mute side stays good even if iOS would otherwise tear down the stream), and tapping pause in the iPhone Music app silences the speaker within ~10 ms instead of waiting for the local audio buffer to drain. Devices on 0.2.27 or older will auto-OTA to 0.2.29 on their next chat round-trip; USB flash also works.


2026-05-28

Voice control of AirPlay sessions (firmware 0.2.24 – 0.2.27) While AirPlaying music to a voice device, you can now say “hey [coordinator] skip” / “next song” to advance, “back” / “previous” to go back a track, “pause” / “play” / “resume” to pause and resume, and “stop” to end the session. The device sends control commands back to the iPhone / iPad / Mac that’s streaming, so the music app reflects the new state (paused, advanced track, etc.) within a fraction of a second. Resume sends both playresume and play so it works regardless of iOS version. Voice control works in headphone mode too — the wake word fires during music playback, the LED responds immediately, and audio resumes cleanly on play.

Headphone mode for voice devices (firmware 0.2.21-headphone) A new per-device “headphone mode” setting that, when on, keeps the speaker amplifier disabled and routes audio out through the 3.5 mm jack only. This lets the wake word stay sensitive while music plays — the device’s normal wake-during-music suppression is a side effect of the amplifier being on, so muting the internal speaker preserves wake-word detection on headphone listening. Toggle by saying “headphones on” / “headphones off” to a voice device, or via PATCH /api/devices/<id> with {"headphone_mode": true|false}. Persisted across reboot. Internal-speaker case is unchanged.

Wake word fires faster during music playback (firmware 0.2.22-cutoff) When the device is actively playing audio (TTS, AirPlay, ambient), per-frame wake probability builds slower because the I²S audio bus is busy. The device now temporarily lowers the wake-word probability cutoff while playback is active and snaps it back the moment playback ends — restoring first-try wake during music without affecting idle-room sensitivity or false-positive characteristics.

LED responds the instant the wake word fires (firmware 0.2.23-led-first) Before, the LED ring switched to LISTENING only after the device finished its barge-in cleanup (pausing AirPlay, flushing audio buffers, sending the WebSocket stop signal). That cleanup includes a network write that can stall 50–500 ms depending on connection state, so the LED visibly lagged the wake. The visual ack now fires first; cleanup happens after, off-screen.


2026-05-27

AirPlay no longer goes silent after a wake-word conversation (firmware 0.2.20-airplay) If you used the wake word + had a conversation with a voice device, then tried to AirPlay to it, the device would often play nothing — the speaker stayed muted and the device looked asleep. Root cause: the speaker amplifier is enabled only around text-to-speech replies and then disabled when TTS finishes (to keep wake-word detection sensitive). AirPlay was never asking for it back, so the first AirPlay session after any conversation played into a muted speaker. The AirPlay receiver now turns the amp on as soon as audio frames start arriving and releases it on session end, so AirPlay-after-conversation just works.

AirPlay volume slider now controls the voice device (firmware 0.2.16-airplay) Adjusting the volume from iOS Control Center / lock screen / Apple Music while AirPlaying to a voice device now changes the device’s actual playback volume in real time. Previously the slider moved on screen but the device kept playing at its own volume. The new value applies for the rest of the AirPlay session only — when iOS disconnects, the device returns to whatever volume it was at before (or whatever you last set via voice command), so leaving an AirPlay session at very low volume won’t leave the device effectively muted next time.

Voice device network responsiveness hardening (firmware 0.2.17 – 0.2.19-airplay) Defensive Wi-Fi changes shipped alongside the AirPlay work above: the radio is now pinned to always-on after every reconnect (not just at boot), the IDF default that drops the radio into low-power mode on disconnect is turned off, the DTIM listen interval is set to its minimum, and NTP polls every 30 s to keep the AP-side forwarding table warm. None of these were the actual “AirPlay silent” cause — that was the amplifier above — but they reduce the odds of intermittent OE WebSocket / mDNS hiccups under flaky Wi-Fi. Devices on 0.2.15-airplay or newer auto-OTA to 0.2.20 on their next chat round-trip.

Active monitors: node health collapsed into one row If you have several nodes paired, each one was registering its own row in Active monitors and burying the rest of your watchers. They now collapse under a single “🖥️ Node health · N nodes” row at the top of the section. Click it to expand and see / cancel / extend individual nodes; all the per-node controls still work exactly as before, just behind one click instead of crowding the list.

AirPlay pause/resume reliability (firmware 0.2.15-airplay) Pausing an AirPlay stream from iOS — Control Center, lock screen, or just stopping inside Apple Music — and then hitting play used to produce a few seconds of robotic / clipped audio before things stabilized, especially after pauses longer than half a minute. Renaming a voice device during playback could also drop the stream and bring it back glitchy. Both are fixed: the receiver now re-handshakes timing with iOS on every pause and the audio resampler resets its phase state at the right moment, so resume sounds clean from the first sample. A rename mid-stream no longer races two decoders against each other. Devices on 0.2.13-airplay will auto-OTA to 0.2.15-airplay on their next chat round-trip (or reboot to force the pull).

Tailscale integration in Settings Settings → System → Private Mesh (Tailscale) is a new panel right beneath Public Access (Cloudflare Tunnel). Shows whether Tailscale is installed and running on this host, the assigned tailnet IP (with copy button), and your MagicDNS name. Two ways to set it up: paste a reusable auth key + sudo password directly in the panel for a one-click install, or click “Ask the coordinator instead” to drop into chat with the install request prefilled — same recipe runs either way, with the same audit log + one-click revert. Owner/admin only.

Rename voice devices live Edit a device’s name in Settings → Voice devices (click the name at the top of any device card) and press Enter — the new name is saved, pushed to the device, and the AirPlay picker label on iOS updates within ~5 seconds. No reboot needed, and an active music stream isn’t interrupted by the rename.

Voice devices are now AirPlay receivers Paired voice devices (XVF3800 + ESP32-S3 with firmware 0.2.13-airplay or later) show up in your iOS Control Center → AirPlay picker as the device name you set in Settings → Voice devices. Cast Apple Music, Spotify, YouTube Music, or any iOS system audio to one and it plays through the speaker — at full 44.1 kHz CD quality via Apple’s ALAC codec. Saying your wake word during music pauses playback for the conversation and resumes after the reply. Music keeps playing through brief network blips because the device buffers ~9 seconds of audio in PSRAM. Devices need to be on the same Wi-Fi network as the iOS device. After updating, reboot the voice device so the new firmware loads — paired devices will auto-OTA on their next chat round-trip.

Inbox drawer: back button now returns to the email list After opening an email in the Inbox drawer, clicking the ← back button would show “Failed: internal error” instead of returning to the message list — clicking the account tab refreshed it. Affected all providers (Gmail, Microsoft, IMAP) though Microsoft and IMAP users hit it most. The refresh ↻ button in the same toolbar had the same defect. Both now work as expected.


2026-05-26

CRITICAL fix: bulk user-save no longer wipes the master-key file A pre-existing bug in the bulk-user-save helper would rm -rf any subdirectory of users/ that wasn’t a current user — including the system-only users/_system/ directory that holds the master key used to encrypt your API keys in config.json. Triggers included /claim in chat, setting a news preference via chat (“only show me science news”), renaming an agent via chat (“call yourself Iris”), and any admin user-management action. If you’ve ever lost API keys after typing one of those, this was why. After updating, those actions are safe. If your config.json already has encrypted blobs that won’t decrypt, you’ll need to re-enter the affected keys in Settings → Providers; there’s no way to recover them without a backup of the original users/_system/.master-key file.

Providers added by OE Admin show up in Settings + the model picker When you (or any OE Admin–assigned agent) add a new OpenAI-compatible provider via the OE Admin tools, it now renders as its own provider card under Settings → Providers and appears as a labelled group in every agent’s model dropdown — alongside the built-in providers. Previously the provider worked in chat dispatch but was invisible to the UI, so users couldn’t actually select its models for their agents.

Voice routines now have webhook triggers Every routine gets its own webhook URL. Open Settings → Voice devices → Routines, edit a routine, and copy the Webhook URL at the bottom. POST to that URL from anywhere — including an iPhone NFC tag via Shortcuts (“When NFC tag is scanned” → “Get contents of URL”) — and the routine fires. Anyone with the URL can trigger it, so don’t share it widely; the “Regen” button revokes the old URL if you need to rotate.

Target device picker for routines Each routine now has a Target device dropdown in the editor. When set, the routine’s play ambient and tts say actions run on that device regardless of which voice device heard the trigger — so “goodnight” said in the kitchen can play sounds in the bedroom. Required for webhook fires too, since they have no originating device.

Webhook + Test work with idle devices Reminders, the Test button, and webhook fires now push spoken replies via the same one-shot MP3 path as scheduled reminders, so a target device doesn’t need an active chat session to speak.

Your OE Admin agent can install Tailscale on the OE host If you have the OE Admin role assigned to an agent (Settings → Agents → edit → Role: OE Admin), ask it to “install Tailscale on this server” and it walks the install: prompts for your auth key via the secure widget, runs the installer with sudo, enables tailscaled, and brings up the node. Same path works for Cloudflared. The system restarts when needed, with auto-revert if the server fails to come back.

Ambient preview is now a play/stop toggle Settings → Voice devices → Ambient library: the ▶ button changes to ■ while a clip is playing. Click again to stop instead of waiting for the file to finish.

Routine editor: spacebar in ID field The ID field (e.g. goodnight) is a slug, not a phrase — spaces are now blocked from being typed, and any other invalid characters are auto-converted to underscores on save with a notification telling you what the slug became.

Routine editor: adding actions no longer collapses the row Adding a new action (e.g. HA scene) before any others existed in a new routine used to collapse the editor. Fixed.

Routine drops are now visible If a routine fails server-side validation on save (e.g. an ha_scene action without a scene picked, or a play_ambient pointing at a deleted file), the UI now shows a specific error explaining which field tripped it instead of pretending the save succeeded.

Health-check ticks are quieter on your nodes Background service-health monitoring no longer spawns a separate bash process per signal — every node’s due signals run as one composite shell invocation per cycle (~4× fewer processes on a node like shareserver). Profile ticks across multiple nodes are also dispersed across the cadence window so they don’t all spike at the same instant.


This site uses Just the Docs, a documentation theme for Jekyll.