Skip to content

fix(cron): preserve active listener execution by default - #3665

Merged
cpacker merged 4 commits into
mainfrom
overlord/fix-active-cron-target
Aug 4, 2026
Merged

fix(cron): preserve active listener execution by default#3665
cpacker merged 4 commits into
mainfrom
overlord/fix-active-cron-target

Conversation

@overlord-letta

@overlord-letta overlord-letta commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Restore the original execution locality for implicit Cloud-agent schedules: keep the timer durable in Cloud, but persist the active registered listener as the preferred target.
  • Carry the listener device identity through tool runtime context so a child letta cron command cannot select a stale installation ID.
  • Keep explicit choices authoritative: --computer selects a device, --runner cloud selects the Cloud sandbox, and --runner local stays process-local.
  • Reject implicit targets that are offline, unregistered, synthetic, Desktop-local, or managed sandboxes instead of silently moving the work to Cloud.

Before / after

Before, letta cron add without runner flags omitted target_device_id, so work created on a connected listener ran in the Cloud sandbox.

After, the CLI resolves the listener that owns the current turn, verifies that it is a live external environment, and stores it in the existing target_device_id field. Existing targetless schedules keep their historical Cloud-sandbox behavior.

Limits

Managed sandboxes and Desktop local-proxy connections are not accepted by the current Cloud schedule target API. The CLI reports that limit and gives explicit alternatives instead of claiming local execution.

Test plan

  • bun test src/cli/subcommands/cron.test.ts src/cli/subcommands/cron-runner.test.ts src/backend/api/client.test.ts src/tools/shell-env.test.ts (64 pass)
  • bun run check (12/12 checks pass)
  • Copied the HTTP-boundary regression onto the parent commit; the three default-target cases fail there and pass with this change.
  • Built the branch CLI, launched an isolated registered listener, created a real one-shot schedule with no runner or computer flag, and waited for it to fire. letta cron runs reported status: success, delivery: device, and the exact listener connection. The temporary schedule and listener were removed.
  • GitHub CI is fully green across all platform, headless, integration, build, lint, and review jobs.

👾 Generated with Letta Code

Letta Code (agent-c2adbf5c-8419-4211-8cd8-3740db164974)

Keep Cloud schedules durable without moving implicit cron work off the listener that created it. Explicit Cloud, local, and computer choices remain authoritative.

Co-authored-by: Cameron Pfiffer <cameron@pfiffer.org>

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

Co-Authored-By: Letta Code <noreply@letta.com>
lettamate and others added 2 commits August 3, 2026 17:40
Letta Code (agent-c2adbf5c-8419-4211-8cd8-3740db164974)

Ensure schedule commands invoked from agent tools use the listener that owns the current turn instead of a stale installation identity.

Co-authored-by: Cameron Pfiffer <cameron@pfiffer.org>

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

Co-Authored-By: Letta Code <noreply@letta.com>
@just-cameron

Copy link
Copy Markdown
Contributor

A managed-sandbox runtime already executes untargeted schedules in the
agent's Cloud sandbox, so erroring there broke the most common no-flags
`letta cron add` path for no benefit. Resolve sandbox-* runtime ids to an
untargeted schedule (the pre-existing behavior) instead of requiring an
explicit --runner cloud; external listeners are still targeted, and
unregistered/offline/desktop-local runtimes still error with guidance.

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

Co-Authored-By: Letta Code <noreply@letta.com>
@cpacker

cpacker commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Pushed 4c1ad53: managed sandboxes no longer error on default letta cron add — they fall through to the untargeted schedule, which already fires in the agent's Cloud sandbox. That was the pre-existing behavior and is the locality-preserving answer for that runtime, so requiring --runner cloud there just broke the most common no-flags path.

Behavior matrix for default letta cron add (cloud agent) after this commit:

Runtime Result
Registered external listener (VPS, letta server) Cloud schedule targeted to that listener
Managed cloud sandbox (sandbox-* runtime id) untargeted Cloud schedule → fires in the sandbox (unchanged from main)
Desktop-local / unregistered / offline runtime error with --runner cloud / --computer / --runner local guidance

Implementation: validateInferredTargetDevice became resolveInferredTargetDevice, returning device / cloud-sandbox / error. The sandbox-* check runs before the environments-registry lookup (and skips it entirely) because sandbox rows can be registered and online in the registry, but individual sandboxes get retired and recreated, so pinning one as a device target would be wrong. Prompts, --help, and the scheduling skill updated to match; HTTP-boundary test added asserting the sandbox path POSTs without target_device_id and never hits /v1/environments/.

Known remaining gap (follow-up, not this PR): desktop-local sessions still error on the default. They exist only in the desktop's local proxy, not the Cloud environments registry, so Cloud dispatch has no wire to deliver on — making them targetable requires registering the desktop listener in the environments registry first.

👾 Generated with Letta Code

@cpacker
cpacker merged commit 50a9e49 into main Aug 4, 2026
22 checks passed
@cpacker
cpacker deleted the overlord/fix-active-cron-target branch August 4, 2026 20:50
cpacker added a commit that referenced this pull request Aug 5, 2026
… 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>
cpacker added a commit that referenced this pull request Aug 5, 2026
… 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>
cpacker added a commit that referenced this pull request Aug 5, 2026
… 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>
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.

3 participants