Skip to content

fix(cron): fall back to a local schedule when Cloud cannot reach this computer - #3682

Merged
cpacker merged 2 commits into
mainfrom
fix/cron-local-clock-fallback
Aug 5, 2026
Merged

fix(cron): fall back to a local schedule when Cloud cannot reach this computer#3682
cpacker merged 2 commits into
mainfrom
fix/cron-local-clock-fallback

Conversation

@cpacker

@cpacker cpacker commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Bare letta cron add on a desktop-local or unregistered runtime now creates a local schedule with a warning, instead of erroring. After fix(cron): preserve active listener execution by default #3665, those runtimes had no working no-flags path: Cloud scheduling cannot deliver into a computer that is not in the environments registry, so the local scheduler is the only placement that keeps the work executing where the conversation lives.
  • Recurring schedules that hit this fallback get a louder caution — "every Monday" pinned to a session that must stay open is usually not what the user meant — with the durable alternatives (--runner cloud, --computer <deviceId>) spelled out.
  • Rewrites the scheduling-tasks skill around intention rather than the flag matrix: omit --runner/--computer and the CLI keeps the schedule on the computer that created it, so scheduled work never conflicts with the active conversation from a second computer. Adds fast-followup vs recurring-job guidance and UTC-conversion instructions for cloud cron expressions (agents were previously shown examples that would silently schedule 9am UTC for a user asking for 9am local).
  • Folds in the verified CLI-reference corrections from docs(skills): clarify cron clock and execution targets #3675: --once, id-or-name for get/delete (+ remove alias), runs history, --every compiling to a UTC cron expression on cloud schedules, numeric-only cron fields, and no in-place editing. Cameron is co-authored for those.

Stacked on #3683 (system prompts defer cron mechanics to the skill), so this PR touches only code and the skill — the skill is the single place placement behavior is documented.

Resulting default (no flags, cloud agent)

Runtime Placement
Registered external listener Cloud schedule targeting that listener (#3665)
Managed cloud sandbox untargeted Cloud schedule → fires in the sandbox
Desktop-local / unregistered computer local schedule + warning (was: error)
Local-backend agent / self-hosted local schedule (unchanged)

Explicit flags stay authoritative and unchanged: --computer picks a registered device, --runner cloud picks the sandbox, --runner local pins this computer.

Implementation

resolveInferredTargetDevice now returns device | cloud-sandbox | local-fallback (the error arm is gone); handleAdd routes local-fallback to the local runner and threads the reason into the JSON output's warning field, merged with the existing no-scheduler-running warning when both apply. User-facing messages use plain wording ("not connected to your Letta account"), and guidance text avoids runtime taxonomy — the CLI reports its placement in output, and the skill teaches reading that instead of predicting it.

Follow-up (separate track): registering desktop-local listeners in the Cloud environments registry would let those runtimes get durable Cloud schedules targeting the desktop, at which point this fallback narrows naturally. Until then, local is the honest placement.

Supersedes #3675.

Test plan

  • bun test src/cli/subcommands/cron.test.ts src/cli/subcommands/cron-runner.test.ts src/tools/shell-env.test.ts — includes new HTTP-boundary tests: unregistered runtime creates a local task (no schedule POST) with fallback + recurring warnings; one-shot fallback omits the recurring caution
  • bun run check (12/12)

👾 Generated with Letta Code

@cpacker
cpacker changed the base branch from main to refactor/defer-cron-detail-to-skill August 5, 2026 01:58
@cpacker
cpacker force-pushed the fix/cron-local-clock-fallback branch 2 times, most recently from 707f3fa to e56e6b0 Compare August 5, 2026 02:07
Base automatically changed from refactor/defer-cron-detail-to-skill to main August 5, 2026 02:15
cpacker and others added 2 commits August 4, 2026 19:17
… computer

Bare `letta cron add` from a desktop-local or unregistered runtime errored
after #3665, leaving the most common interactive environments with no
no-flags path. Cloud scheduling has no wire to deliver into those runtimes
(they are not in the environments registry), so the locality-preserving
placement is the local scheduler: the schedule is stored in
~/.letta/crons.json with a warning explaining the durability tradeoff, and
recurring schedules get a louder caution since "every Monday" pinned to a
session is usually not what the user meant.

Also rewrites the scheduling-tasks skill around intention (omit the flags;
the CLI preserves execution locality so follow-ups never race the active
conversation from a second environment), adds the fast-followup vs
recurring-job guidance, documents UTC conversion for Cloud cron
expressions, and folds in the CLI reference corrections from #3675
(--once, id-or-name lookup, runs history, --every UTC semantics, no
in-place editing).

Co-Authored-By: Cameron <cameron@pfiffer.org>

👾 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta Code <noreply@letta.com>
The skill and system prompts explained the CLI's placement rules by
enumerating runtime types (external listener on a VPS/Railway box,
managed sandbox, desktop-local session). That taxonomy is implementation
detail that will churn; the durable guidance is the decision rule: omit
the flags (work stays on the computer that created it), override only
for a requirement (fire-regardless -> --runner cloud, specific computer
-> --computer), and read the CLI output warning when placement is local.
Also plain-languages the user-facing fallback messages ("not connected
to your Letta account" instead of "not a registered Cloud environment").

👾 Generated with [Letta Code](https://letta.com)

Co-Authored-By: Letta Code <noreply@letta.com>
@cpacker
cpacker force-pushed the fix/cron-local-clock-fallback branch from e56e6b0 to 0bb3569 Compare August 5, 2026 02:17
@cpacker
cpacker merged commit ee9d96f into main Aug 5, 2026
21 checks passed
@cpacker
cpacker deleted the fix/cron-local-clock-fallback branch August 5, 2026 02:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant