@letta-ai/letta-code 0.30.5 → 0.30.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/agent-presets.js +3 -13
  2. package/dist/agent-presets.js.map +2 -2
  3. package/dist/channels-slack.js +1 -1
  4. package/dist/channels-slack.js.map +3 -3
  5. package/dist/mcp-client.js +2 -2
  6. package/dist/mcp-client.js.map +1 -1
  7. package/dist/types/agent/subagents/manager.d.ts.map +1 -1
  8. package/dist/types/agent/subagents/subagent-launcher.d.ts +2 -0
  9. package/dist/types/agent/subagents/subagent-launcher.d.ts.map +1 -1
  10. package/dist/types/backend/api/client.d.ts +1 -0
  11. package/dist/types/backend/api/client.d.ts.map +1 -1
  12. package/dist/types/backend/dev/pi-local-endpoint-provider.d.ts.map +1 -1
  13. package/dist/types/backend/dev/pi-model-factory.d.ts.map +1 -1
  14. package/dist/types/backend/dev/pi-models-runtime.d.ts.map +1 -1
  15. package/dist/types/backend/dev/pi-openai-compatible-provider.d.ts +14 -0
  16. package/dist/types/backend/dev/pi-openai-compatible-provider.d.ts.map +1 -0
  17. package/dist/types/backend/dev/pi-provider-registry.d.ts +3 -1
  18. package/dist/types/backend/dev/pi-provider-registry.d.ts.map +1 -1
  19. package/dist/types/backend/local/local-provider-auth-store.d.ts +1 -1
  20. package/dist/types/backend/local/local-provider-auth-store.d.ts.map +1 -1
  21. package/dist/types/channels/accounts.d.ts.map +1 -1
  22. package/dist/types/channels/config.d.ts.map +1 -1
  23. package/dist/types/channels/plugin-types.d.ts +1 -0
  24. package/dist/types/channels/plugin-types.d.ts.map +1 -1
  25. package/dist/types/channels/slack/ingress-controller.d.ts.map +1 -1
  26. package/dist/types/channels/slack/ingress-policy.d.ts +1 -0
  27. package/dist/types/channels/slack/ingress-policy.d.ts.map +1 -1
  28. package/dist/types/channels/types.d.ts +2 -0
  29. package/dist/types/channels/types.d.ts.map +1 -1
  30. package/dist/types/cli/helpers/error-formatter.d.ts +1 -0
  31. package/dist/types/cli/helpers/error-formatter.d.ts.map +1 -1
  32. package/dist/types/providers/byok-providers.d.ts.map +1 -1
  33. package/dist/types/runtime-context.d.ts +2 -0
  34. package/dist/types/runtime-context.d.ts.map +1 -1
  35. package/dist/types/tools/impl/shell-env.d.ts.map +1 -1
  36. package/dist/types/tools/toolset.d.ts +1 -0
  37. package/dist/types/tools/toolset.d.ts.map +1 -1
  38. package/dist/types/websocket/listener/mod-adapter.d.ts +1 -0
  39. package/dist/types/websocket/listener/mod-adapter.d.ts.map +1 -1
  40. package/letta.js +429 -197
  41. package/package.json +1 -1
  42. package/scripts/check-test-mock-isolation.js +5 -1
  43. package/scripts/isolated-unit-tests.json +15 -0
  44. package/scripts/source-file-size-baseline.json +1 -1
  45. package/skills/scheduling-tasks/SKILL.md +58 -54
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letta-ai/letta-code",
3
- "version": "0.30.5",
3
+ "version": "0.30.6",
4
4
  "description": "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
5
5
  "type": "module",
6
6
  "packageManager": "bun@1.3.0",
@@ -91,7 +91,11 @@ function moduleMatches(moduleSpecifier, suffixes) {
91
91
  }
92
92
 
93
93
  function isRelativeInternalModule(moduleSpecifier) {
94
- return moduleSpecifier.startsWith("../") || moduleSpecifier.startsWith("./");
94
+ return (
95
+ moduleSpecifier.startsWith("../") ||
96
+ moduleSpecifier.startsWith("./") ||
97
+ moduleSpecifier.startsWith("@/")
98
+ );
95
99
  }
96
100
 
97
101
  function lineAndColumn(sourceText, index) {
@@ -1,10 +1,25 @@
1
1
  {
2
2
  "tests": [
3
+ {
4
+ "path": "src/channels/discord-reconcile.test.ts",
5
+ "timeoutMs": 15000,
6
+ "reason": "Mocks the backend client module in beforeAll; the mock leaks into later files in the same process."
7
+ },
3
8
  {
4
9
  "path": "src/channels/discord-registry.test.ts",
5
10
  "timeoutMs": 15000,
6
11
  "reason": "Uses a top-level Bun module mock for the backend client."
7
12
  },
13
+ {
14
+ "path": "src/channels/slack-registry.test.ts",
15
+ "timeoutMs": 15000,
16
+ "reason": "Uses a top-level Bun module mock for the backend client."
17
+ },
18
+ {
19
+ "path": "src/channels/telegram-registry.test.ts",
20
+ "timeoutMs": 15000,
21
+ "reason": "Uses a top-level Bun module mock for the backend client."
22
+ },
8
23
  {
9
24
  "path": "src/channels/discord-service.test.ts",
10
25
  "timeoutMs": 15000,
@@ -24,7 +24,7 @@
24
24
  "src/cli/subcommands/skills.ts": 1264,
25
25
  "src/headless.ts": 5242,
26
26
  "src/hooks/integration.test.ts": 1147,
27
- "src/index.ts": 2776,
27
+ "src/index.ts": 2773,
28
28
  "src/mods/learning-harness.ts": 2434,
29
29
  "src/mods/mod-engine.test.ts": 2153,
30
30
  "src/mods/mod-engine.ts": 1847,
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: scheduling-tasks
3
- description: Schedules reminders and recurring tasks via the letta cron CLI. Use when the user asks to be reminded of something, wants periodic messages, or needs to manage scheduled tasks.
3
+ description: Schedules reminders and recurring tasks via the letta cron CLI. Use when the user asks to be reminded of something, wants periodic work or check-ins, or needs to list, inspect, replace, or cancel scheduled tasks.
4
4
  ---
5
5
 
6
6
  # Scheduling Tasks
@@ -14,28 +14,24 @@ This skill lets you create, list, and manage scheduled tasks using the `letta cr
14
14
  - User wants a one-shot delayed message ("in 30 minutes, check on X")
15
15
  - User wants to see or cancel existing scheduled tasks
16
16
 
17
- ## Where Schedules Run (`--runner`)
17
+ ## Where Schedules Run — Omit the Flags
18
18
 
19
- There are two schedule runners, selected with the optional `--runner local|cloud` flag:
19
+ **Default guidance: omit `--runner` and `--computer`.** The CLI places the schedule so the work keeps running on the computer where it was created. Don't move scheduled work to a different computer than the active conversation without a reason: two computers working the same conversation can conflict.
20
20
 
21
- - **`cloud`** (default for cloud agents): a durable Cloud schedule stored by the Letta API. It fires from the cloud and executes in the agent's cloud sandbox, so it survives local shutdown — the computer, sandbox, or session that created it can disappear and the schedule still fires.
22
- - **`local`**: a task local to the current computer (`~/.letta/crons.json`), executed by the Letta session running there. It only fires while a session is running on that computer, and it dies with that computer's local state.
21
+ Pass a flag only when you have a requirement the default can't infer:
23
22
 
24
- You normally don't need the flag — the default does the right thing. Local-backend agents (`agent-local-*`) and self-hosted servers always use the local runner.
23
+ - **`--runner cloud`** — the schedule must fire no matter which computers are online; execute in the agent's cloud sandbox.
24
+ - **`--computer <deviceId>`** — the work needs a specific connected computer (its filesystem, services, or credentials). Get the deviceId from `letta environments list`. If that computer is offline at fire time, execution falls back to the cloud sandbox.
25
+ - **`--runner local`** — the work must only ever run on the current computer, even if that means missing fires while no session is running here.
25
26
 
26
- If the scheduled work must run on a **specific computer** (it needs that computer's filesystem, local services, or credentials e.g. a bring-your-own machine like a Railway/VPS box or a home workstation), prefer a Cloud schedule that executes on that computer:
27
+ The CLI reports its placement in the command output. If it warns that the schedule is local (this happens when the cloud scheduler cannot reach the current computer), the schedule only fires while a Letta session is running here read the warning and decide whether that's acceptable.
27
28
 
28
- ```bash
29
- letta cron add ... --computer <deviceId>
30
- ```
31
-
32
- The deviceId comes from `letta environments list`. The computer must be connected to your Letta account (run `letta server` on it, or enable remote access in the desktop app). The schedule stays durable in the cloud; if the computer is offline when it fires, execution falls back to the agent's cloud sandbox. Use `--runner local` (run on the target computer itself) only when that sandbox fallback is unacceptable — a local task never runs anywhere but its own computer.
29
+ ### Fast Follow-ups vs Recurring Jobs
33
30
 
34
- Notes for the cloud runner:
31
+ Two patterns cover most schedules:
35
32
 
36
- - Untargeted schedules execute in the agent's cloud sandbox, not on the computer where you created them; `--computer` executes on the named computer with sandbox fallback.
37
- - Recurring `--cron` expressions are currently interpreted in UTC (the CLI output includes a note about this). `--at` and `--every` are unaffected.
38
- - If creating a Cloud schedule fails, no schedule is created — there is no silent fallback to local storage. Retry, or pass `--runner local` deliberately.
33
+ - **Fast follow-ups** ("check on the PR in 5m"): the default is right same computer as the active conversation. If the session dies before it fires, the follow-up usually died with the task anyway.
34
+ - **Recurring jobs** ("every Monday 11am, start the lunch order"): prefer durability. If the CLI warned that a recurring schedule is local, that's usually wrong for the user's intent — recreate it with `--runner cloud`, or `--computer` if the job needs a specific always-on computer. Also consider whether the job should post into a dedicated conversation rather than this one (continuity in one thread vs a fresh context per run).
39
35
 
40
36
  ## CLI Usage
41
37
 
@@ -59,7 +55,7 @@ letta cron add --name <short-name> --description <text> --prompt <text> <schedul
59
55
 
60
56
  | Flag | Type | Example |
61
57
  |------|------|---------|
62
- | `--every <interval>` | Recurring | `5m`, `2h`, `1d` |
58
+ | `--every <interval>` | Recurring (cron shorthand) | `5m`, `2h`, `1d` |
63
59
  | `--at <time>` | One-shot | `"3:00pm"`, `"in 45m"` |
64
60
  | `--cron <expr>` | Raw cron (recurring) | `"0 9 * * 1-5"` |
65
61
 
@@ -69,8 +65,9 @@ letta cron add --name <short-name> --description <text> --prompt <text> <schedul
69
65
  |------|-------------|
70
66
  | `--agent <id>` | Agent ID (defaults to `LETTA_AGENT_ID` from the current shell/session) |
71
67
  | `--conversation <id>` | Conversation ID (defaults to `LETTA_CONVERSATION_ID` from the current shell/session, otherwise `"default"`) |
72
- | `--runner <runner>` | `cloud` or `local` — see "Where Schedules Run" above (defaults to `cloud` for cloud agents) |
73
- | `--computer <id>` | (cloud runner only) Execute on a connected computer instead of the agent's sandbox; falls back to the sandbox if the computer is offline |
68
+ | `--runner <runner>` | `cloud` or `local` — normally omit; see "Where Schedules Run" above |
69
+ | `--computer <id>` | Execute on a specific connected computer normally omit |
70
+ | `--once` | Mark `--at` as one-shot (already the default for `--at`) |
74
71
 
75
72
  ### Listing Tasks
76
73
 
@@ -78,14 +75,24 @@ letta cron add --name <short-name> --description <text> --prompt <text> <schedul
78
75
  letta cron list
79
76
  ```
80
77
 
81
- Optional filters: `--agent <id>`, `--conversation <id>`
78
+ Optional filters: `--agent <id>`, `--conversation <id>`, `--runner local|cloud`
82
79
 
83
80
  ### Getting a Single Task
84
81
 
82
+ `get` accepts an ID or name:
83
+
85
84
  ```bash
86
- letta cron get <task-id>
85
+ letta cron get <id-or-name> [--runner local|cloud] [--agent <id>]
87
86
  ```
88
87
 
88
+ ### Reading Run History
89
+
90
+ ```bash
91
+ letta cron runs --id <task-id> [--limit <n>] [--runner local|cloud] [--agent <id>]
92
+ ```
93
+
94
+ For local run history, `--run-id <id>` selects one run. Cloud history ignores that flag.
95
+
89
96
  ### Binding a Task to the Right Conversation
90
97
 
91
98
  If exact routing matters, pass both `--agent` and `--conversation` explicitly.
@@ -110,58 +117,60 @@ Then verify the binding explicitly:
110
117
  letta cron list --agent "$AGENT_ID" --conversation "$CONVERSATION_ID"
111
118
  ```
112
119
 
113
- ### Deleting Tasks
120
+ ### Deleting or Replacing Tasks
121
+
122
+ `delete` accepts an ID or name; `remove` is an alias.
114
123
 
115
124
  ```bash
116
125
  # Delete a specific task
117
- letta cron delete <task-id>
126
+ letta cron delete <id-or-name> [--runner local|cloud] [--agent <id>]
118
127
 
119
- # Delete all tasks for the current agent
120
- letta cron delete --all
128
+ # Delete all tasks for one agent
129
+ letta cron delete --all --agent "$AGENT_ID"
121
130
  ```
122
131
 
123
- ## Examples
132
+ In-place editing is not available. To change a schedule, create and verify the replacement before deleting the old one.
124
133
 
125
- ### "Remind me every morning at 9am to walk the dog"
134
+ ## Timezones Convert Before Writing `--cron`
126
135
 
127
- ```bash
128
- letta cron add \
129
- --name "dog-walk-reminder" \
130
- --description "Daily morning reminder to walk the dog" \
131
- --prompt "Hey! It's 9am — time to walk the dog." \
132
- --every 1d
133
- ```
136
+ Cloud-schedule recurring expressions (both `--cron` and the expression `--every` compiles to) are interpreted in **UTC**. Users say times in their local timezone, so convert before writing the expression: a user in PDT asking for "9am daily" needs `--cron "0 16 * * *"` (9am PDT = 16:00 UTC; 17:00 during PST). State the conversion in your reply so the user can catch a wrong assumption. Local-runner tasks use the computer's local timezone — no conversion. `--at` stores one absolute timestamp parsed in the current process timezone, so it needs no conversion either.
134
137
 
135
- Note: `--every 1d` fires once daily at midnight. For a specific time like 9am, use a raw cron expression:
138
+ ## Examples
139
+
140
+ ### "Remind me every morning at 9am to walk the dog" (user in UTC−7)
136
141
 
137
142
  ```bash
138
143
  letta cron add \
139
144
  --name "dog-walk-reminder" \
140
- --description "Daily 9am reminder to walk the dog" \
145
+ --description "Daily 9am (America/Los_Angeles) reminder to walk the dog" \
141
146
  --prompt "Hey! It's 9am — time to walk the dog." \
142
- --cron "0 9 * * *"
147
+ --cron "0 16 * * *"
143
148
  ```
144
149
 
150
+ Note: `--every 1d` fires daily at midnight (UTC on a Cloud schedule), so use `--cron` for a specific time of day, converting the user's local time to UTC first.
151
+
145
152
  ### "Check on the deploy in 30 minutes"
146
153
 
147
154
  ```bash
148
155
  letta cron add \
149
156
  --name "deploy-check" \
150
157
  --description "One-time check on deployment status" \
151
- --prompt "The user asked you to check on the deploy — ask them how it went." \
158
+ --prompt "Check the deployment status and report the result here." \
152
159
  --at "in 30m"
153
160
  ```
154
161
 
155
- ### "Every weekday at 5pm, remind me to submit my timesheet"
162
+ ### "Every weekday at 5pm, remind me to submit my timesheet" (user in UTC−7)
156
163
 
157
164
  ```bash
158
165
  letta cron add \
159
166
  --name "timesheet-reminder" \
160
- --description "Weekday 5pm timesheet reminder" \
167
+ --description "Weekday 5pm (America/Los_Angeles) timesheet reminder" \
161
168
  --prompt "Friendly reminder: don't forget to submit your timesheet before EOD!" \
162
- --cron "0 17 * * 1-5"
169
+ --cron "0 0 * * 2-6"
163
170
  ```
164
171
 
172
+ Note the day shift: 5pm UTC−7 is midnight UTC the *next* day, so weekdays Mon–Fri become `2-6`. Always re-derive both the hour and the day fields after converting.
173
+
165
174
  ### "What reminders do I have?"
166
175
 
167
176
  ```bash
@@ -176,12 +185,8 @@ letta cron list --agent "$AGENT_ID" --conversation "$CONVERSATION_ID"
176
185
 
177
186
  ### "Cancel the dog walk reminder"
178
187
 
179
- First list to find the task ID, then delete:
180
-
181
188
  ```bash
182
- letta cron list
183
- # Find the task ID from the output, then:
184
- letta cron delete <task-id>
189
+ letta cron delete dog-walk-reminder
185
190
  ```
186
191
 
187
192
  ## Writing Good Prompts
@@ -198,15 +203,14 @@ Include context about what the user originally asked for, so you can give a help
198
203
  - **Minimum granularity**: 1 minute. Intervals under 60 seconds are rounded up.
199
204
  - **Recurring tasks**: No longer auto-expire. They remain active until explicitly cancelled.
200
205
  - **One-shot cleanup (local runner)**: One-shot local tasks are garbage-collected 24 hours after firing.
201
- - **Timezone**: Local-runner tasks use the user's local timezone. Cloud-runner recurring `--cron` expressions are currently interpreted in UTC.
202
206
  - **Default binding precedence**: `letta cron add` uses `--agent` / `--conversation` first, then falls back to `LETTA_AGENT_ID` / `LETTA_CONVERSATION_ID`, then finally uses `"default"` for the conversation if no env var is present.
203
- - **Local scheduler requirement**: Local-runner tasks only fire while a Letta session is running on that computer (a WS listener must be active). If no session is running, tasks will be marked as missed. Cloud-runner schedules fire from the cloud regardless.
207
+ - **Local scheduler requirement**: Local schedules only fire while a Letta session is running on their computer; fires while no session runs are marked as missed. Cloud schedules fire from the cloud regardless.
204
208
  - **`--at` for specific times**: `--at "3:00pm"` schedules a one-shot. If the time has already passed today, it schedules for tomorrow.
205
- - **`--every` for daily**: `--every 1d` fires daily at midnight. For a specific time of day, use `--cron` instead (e.g. `--cron "0 9 * * *"` for 9am daily).
209
+ - **Cloud schedule creation failures are loud**: if creating a cloud schedule fails, no schedule is created — a failed create never silently becomes a local schedule. (The local placement for computers the cloud scheduler can't reach is decided before creation and reported in the output.)
206
210
 
207
211
  ## Cron Expression Reference
208
212
 
209
- For `--cron`, use standard 5-field cron syntax:
213
+ For `--cron`, use numeric 5-field cron syntax (named days/months, seconds, `?`, `L`, and `#` are not supported):
210
214
 
211
215
  ```
212
216
  ┌───────────── minute (0-59)
@@ -218,9 +222,9 @@ For `--cron`, use standard 5-field cron syntax:
218
222
  * * * * *
219
223
  ```
220
224
 
221
- Common patterns:
225
+ Common patterns (UTC on Cloud schedules):
222
226
  - `*/5 * * * *` — every 5 minutes
223
227
  - `0 */2 * * *` — every 2 hours
224
- - `0 9 * * *` — daily at 9am
225
- - `0 9 * * 1-5` — weekdays at 9am
226
- - `30 8 1 * *` — 8:30am on the 1st of each month
228
+ - `0 9 * * *` — daily at 9:00 UTC
229
+ - `0 9 * * 1-5` — weekdays at 9:00 UTC
230
+ - `30 8 1 * *` — 8:30 UTC on the 1st of each month