v2.3.4: The Reminder That Never Fired, Gmail Drafts That Lost Their Thread, and a 950 MB Diet
v2.3.4 is a bug-fix and hardening release with one confession at its center: every time an agent promised "I'll remind you tomorrow at 9am", it was lying. One-time scheduled tasks never fired. That is fixed, along with Gmail reply drafts that kept spawning orphan conversations, a Docker image that lost almost a full gigabyte, and a much friendlier experience for SaaS workspaces on a free trial.
The reminder that never fired
Recurring tasks have always worked: ask an employee for a daily report at 9am and the report shows up at 9am. But one-time tasks ("remind me tomorrow at 5pm", "ping me when the trial ends Friday") silently did nothing. The skill reported everything as healthy, the task sat in the data file looking legitimate, and at the scheduled time it just flipped to "will not run".
The root cause was an architecture leftover. There are two scheduling code paths, and one-time tasks fell into the gap between them. The real executor is the platform scheduler, which watches every agent's task file and fires prompts on schedule; it expects a cron expression on every task. The skill, however, wrote one-time tasks in an older format with no cron expression at all, so the platform scheduler logged a complaint and moved on. Meanwhile, the skill's local daemon (the thing reporting "RUNNING") was a vestige of an earlier design: it only knew about tasks that existed when it started, and its delivery path timed out against the current platform anyway. Two schedulers, two formats, zero reminders.
There was even a bonus time bomb in the expiry check: it rebuilt one-time dates using the current year, so a task created in December for January would have been instantly discarded as expired. We caught that one before anyone hit it in production.
The fix lands on both sides. The skill now writes the platform format natively, with validation (past dates rejected, dates more than a year out rejected) and a new optional timezone argument, so an agent can schedule "9am Asia/Jerusalem" without doing UTC math, daylight saving included. Legacy tasks already sitting in agents' folders are picked up through a compatibility shim and migrated automatically. One-time tasks are now removed right after they fire, so they can never re-fire a year later. And the obsolete local daemon is gone; its commands remain as harmless no-ops that explain scheduling is platform-managed.
Validation was end-to-end on a live agent: a new-format task scheduled in Jerusalem time fired at the exact second, a hand-crafted legacy task fired through the shim two minutes later, and both cleaned themselves up afterwards.
Gmail reply drafts now land in the right thread
When an employee prepared a reply draft for you to review, that draft showed up in Gmail as a brand-new conversation with a "Re:" subject, detached from the original thread. If you validated and sent it as-is, your correspondent received a duplicate thread and the conversation history broke in both directions.
The cause was an API that accepted threading information and then ignored it. The internal draft endpoint took the thread id and reply headers in its payload but never read them, while the send endpoint applied them correctly. That is why direct replies threaded fine and drafts did not.
The endpoint now applies the threading fields exactly like sending does. On top of that, the Gmail skill gained a proper reply-draft mode: point it at the original message and it derives the recipient, prefixes the subject, builds the reference chain, and threads the draft automatically. Verified against a real Gmail account: drafts land in the original thread, with the right recipient and subject.
The image lost 950 MB
The Docker image shipped a complete headless-Chromium stack (browser, Playwright, and some 300 MB of system libraries) for a server-side video-call feature that is hidden in the UI and unused. All of it is gone from the build. The dormant code now loads its dependency lazily and fails with a clear "feature is disabled in this build" message if it is ever invoked, instead of crashing.
Result: the image dropped from 3.02 GB to 2.07 GB. Faster pulls, faster deploys, smaller disks, and nothing user-facing changed. The removal is fully reversible if the feature ever returns.
SaaS trials: locked Max tier and a quota banner that speaks human
Two related improvements for SaaS workspaces, both driven by the same gap: the instance had access to the workspace's billing state (trial status, credits, plan, upgrade link) and used none of it.
First, while a workspace is in its free trial, the Max intelligence tier is now visibly locked in both places you pick a model: the provider settings and the in-chat picker. The row is greyed out with a lock icon and a one-line explanation, plus a link to activate the plan. When the trial ends, Max unlocks automatically on the next session.
Second, running out of credits used to surface as a raw provider error in the chat, complete with internal budget numbers and a suggestion to "check the Custom LLM configuration". Alarming, and useless to a SaaS customer. That error is now detected and replaced by a clean system badge: "Free trial limit reached" during the trial, "Credits exhausted" on a paid plan, each with the right call to action linking straight to the workspace billing page. The same badge appears in the conversation-history panel, and the detection is strict enough to never misfire on ordinary messages.
BYOK instances are deliberately exempt from both: self-hosted operators keep the raw diagnostics, because when you run your own infrastructure, the real error is the useful one.
Picking it up
Backend-side fixes (the scheduler shim included) apply immediately after the update; existing employees get the new timezone argument by resyncing the task-scheduler skill. Hard refresh (Ctrl+Shift+R) to load the new frontend.
Want to test the most advanced AI employees? Try it here: https://Geta.Team