@letta-ai/letta-code 0.34.23 → 0.34.25
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.
- package/dist/app-server-client.cjs +2 -2
- package/dist/app-server-client.cjs.map +3 -3
- package/dist/app-server-client.js +2 -2
- package/dist/app-server-client.js.map +3 -3
- package/dist/gateway-core.js +7 -4
- package/dist/gateway-core.js.map +3 -3
- package/dist/mcp-client.js +2 -2
- package/dist/mcp-client.js.map +1 -1
- package/dist/mcp-oauth.js +2 -2
- package/dist/mcp-oauth.js.map +1 -1
- package/dist/types/agent/memory-constraints.d.ts +1 -1
- package/dist/types/agent/turn-recovery-policy.d.ts +3 -3
- package/dist/types/agent/turn-recovery-policy.d.ts.map +1 -1
- package/dist/types/backend/api/schedules.d.ts +6 -5
- package/dist/types/backend/api/schedules.d.ts.map +1 -1
- package/dist/types/backend/api/unified-mcp.d.ts.map +1 -1
- package/dist/types/backend/dev/fake-headless-backend.d.ts +1 -0
- package/dist/types/backend/dev/fake-headless-backend.d.ts.map +1 -1
- package/dist/types/backend/dev/provider-turn-executor.d.ts.map +1 -1
- package/dist/types/backend/local/local-conversation-key.d.ts +6 -0
- package/dist/types/backend/local/local-conversation-key.d.ts.map +1 -0
- package/dist/types/backend/local/local-store.d.ts.map +1 -1
- package/dist/types/channels/control-request-coordinator.d.ts.map +1 -1
- package/dist/types/cli/helpers/git-context.d.ts +5 -2
- package/dist/types/cli/helpers/git-context.d.ts.map +1 -1
- package/dist/types/cron/cron-file.d.ts +2 -3
- package/dist/types/cron/cron-file.d.ts.map +1 -1
- package/dist/types/cron/process-identity.d.ts +9 -0
- package/dist/types/cron/process-identity.d.ts.map +1 -1
- package/dist/types/cron/runner.d.ts +2 -2
- package/dist/types/cron/runner.d.ts.map +1 -1
- package/dist/types/cron/scheduler.d.ts +3 -2
- package/dist/types/cron/scheduler.d.ts.map +1 -1
- package/dist/types/permissions/checker.d.ts +8 -0
- package/dist/types/permissions/checker.d.ts.map +1 -1
- package/dist/types/queue/queue-runtime.d.ts +7 -19
- package/dist/types/queue/queue-runtime.d.ts.map +1 -1
- package/dist/types/tools/impl/shell-launchers.d.ts.map +1 -1
- package/dist/types/tools/impl/wake.d.ts +4 -2
- package/dist/types/tools/impl/wake.d.ts.map +1 -1
- package/dist/types/types/app-server-info.d.ts +0 -2
- package/dist/types/types/app-server-info.d.ts.map +1 -1
- package/dist/types/types/protocol.d.ts +2 -3
- package/dist/types/types/protocol.d.ts.map +1 -1
- package/dist/types/types/protocol_v2.d.ts +1 -1
- package/dist/types/types/protocol_v2.d.ts.map +1 -1
- package/dist/types/types/schedule-protocol.d.ts +2 -2
- package/dist/types/types/schedule-protocol.d.ts.map +1 -1
- package/dist/types/utils/rename-sync-with-retry.d.ts +3 -0
- package/dist/types/utils/rename-sync-with-retry.d.ts.map +1 -0
- package/dist/types/websocket/listener/connection.d.ts +2 -0
- package/dist/types/websocket/listener/connection.d.ts.map +1 -1
- package/dist/types/websocket/listener/constants.d.ts +1 -0
- package/dist/types/websocket/listener/constants.d.ts.map +1 -1
- package/dist/types/websocket/listener/device-git-context.d.ts.map +1 -1
- package/dist/types/websocket/listener/interrupted-turn-record.d.ts.map +1 -1
- package/dist/types/websocket/listener/interrupted-turn-storage.d.ts.map +1 -1
- package/dist/types/websocket/listener/queue.d.ts +1 -2
- package/dist/types/websocket/listener/queue.d.ts.map +1 -1
- package/dist/types/websocket/listener/recovery-lineage-sidecar.d.ts.map +1 -1
- package/dist/types/websocket/listener/turn-correlation.d.ts +0 -8
- package/dist/types/websocket/listener/turn-correlation.d.ts.map +1 -1
- package/dist/types/websocket/listener/turn-finished-replay.d.ts.map +1 -1
- package/dist/types/websocket/listener/types.d.ts +14 -1
- package/dist/types/websocket/listener/types.d.ts.map +1 -1
- package/letta.js +876 -614
- package/npm-shrinkwrap.json +18 -18
- package/package.json +7 -4
- package/scripts/build-pypi.py +6 -6
- package/scripts/claude-watch/runtime-probe.test.ts +1 -1
- package/scripts/claude-watch/runtime-sandbox.ts +1 -1
- package/scripts/codex-watch/release-analysis.test.ts +70 -0
- package/scripts/codex-watch/release-analysis.ts +5 -5
- package/scripts/source-file-size-baseline.json +3 -3
- package/skills/maintaining-deferred-memory/SKILL.md +2 -0
- package/skills/scheduling-tasks/SKILL.md +1 -1
- package/skills/working-across-computers/references/connect-a-computer-for-remote-access.md +2 -2
- package/dist/types/websocket/listener/mcp-originator-scope.d.ts +0 -9
- package/dist/types/websocket/listener/mcp-originator-scope.d.ts.map +0 -1
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@letta-ai/letta-code",
|
|
3
|
-
"version": "0.34.
|
|
3
|
+
"version": "0.34.25",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"packages": {
|
|
6
6
|
"node_modules/@alcalzone/ansi-tokenize": {
|
|
@@ -3047,9 +3047,9 @@
|
|
|
3047
3047
|
}
|
|
3048
3048
|
},
|
|
3049
3049
|
"node_modules/es-toolkit": {
|
|
3050
|
-
"version": "1.
|
|
3051
|
-
"resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.
|
|
3052
|
-
"integrity": "sha512-
|
|
3050
|
+
"version": "1.53.0",
|
|
3051
|
+
"resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.53.0.tgz",
|
|
3052
|
+
"integrity": "sha512-3+AYXp9fmJ/UhHBMYj2/U+RaUouMD90SzoItyDOB2Za7W6dB7fQApFGnZPl2MF6K8/Tv1koh1JyirSx/kju6Pw==",
|
|
3053
3053
|
"license": "MIT",
|
|
3054
3054
|
"workspaces": [
|
|
3055
3055
|
"docs",
|
|
@@ -3519,9 +3519,9 @@
|
|
|
3519
3519
|
}
|
|
3520
3520
|
},
|
|
3521
3521
|
"node_modules/hono": {
|
|
3522
|
-
"version": "4.13.
|
|
3523
|
-
"resolved": "https://registry.npmjs.org/hono/-/hono-4.13.
|
|
3524
|
-
"integrity": "sha512-
|
|
3522
|
+
"version": "4.13.14",
|
|
3523
|
+
"resolved": "https://registry.npmjs.org/hono/-/hono-4.13.14.tgz",
|
|
3524
|
+
"integrity": "sha512-yhRLQ21U6qa9Hsu2N7Qcbh8tE+WKEcoErjIo56LeSGiGXGp9sA7UpE86Ui9uexb61KakiGwuHMn2QdV7w6i6kQ==",
|
|
3525
3525
|
"license": "MIT",
|
|
3526
3526
|
"engines": {
|
|
3527
3527
|
"node": ">=16.9.0"
|
|
@@ -3687,9 +3687,9 @@
|
|
|
3687
3687
|
}
|
|
3688
3688
|
},
|
|
3689
3689
|
"node_modules/ip-address": {
|
|
3690
|
-
"version": "10.7.
|
|
3691
|
-
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.
|
|
3692
|
-
"integrity": "sha512-
|
|
3690
|
+
"version": "10.7.5",
|
|
3691
|
+
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.5.tgz",
|
|
3692
|
+
"integrity": "sha512-t2v0rkILYv9WXmSL7TpAaU3HXgaFYOPUcH3QHgwQ++gpJuH3bqyMy4Fvt/DJCTKwzH3Cf+bAp5W/mFL39KPLzA==",
|
|
3693
3693
|
"license": "MIT",
|
|
3694
3694
|
"engines": {
|
|
3695
3695
|
"node": ">= 12"
|
|
@@ -5248,14 +5248,14 @@
|
|
|
5248
5248
|
}
|
|
5249
5249
|
},
|
|
5250
5250
|
"node_modules/unist-util-visit": {
|
|
5251
|
-
"version": "5.
|
|
5252
|
-
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.
|
|
5253
|
-
"integrity": "sha512-
|
|
5251
|
+
"version": "5.2.0",
|
|
5252
|
+
"resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.2.0.tgz",
|
|
5253
|
+
"integrity": "sha512-fpsYs/VVoZxfGY9/j3FQpZmN8wdLJaV1Pt38AaJNZu9uKIHcFU3halCdBveEq1HGKO1OEfJY65w1zvoFV1b3qQ==",
|
|
5254
5254
|
"license": "MIT",
|
|
5255
5255
|
"dependencies": {
|
|
5256
5256
|
"@types/unist": "^3.0.0",
|
|
5257
5257
|
"unist-util-is": "^6.0.0",
|
|
5258
|
-
"unist-util-visit-parents": "^6.
|
|
5258
|
+
"unist-util-visit-parents": "^6.1.0"
|
|
5259
5259
|
},
|
|
5260
5260
|
"funding": {
|
|
5261
5261
|
"type": "opencollective",
|
|
@@ -5263,9 +5263,9 @@
|
|
|
5263
5263
|
}
|
|
5264
5264
|
},
|
|
5265
5265
|
"node_modules/unist-util-visit-parents": {
|
|
5266
|
-
"version": "6.0
|
|
5267
|
-
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.
|
|
5268
|
-
"integrity": "sha512-
|
|
5266
|
+
"version": "6.1.0",
|
|
5267
|
+
"resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.1.0.tgz",
|
|
5268
|
+
"integrity": "sha512-vKXxz6O38sKDj1mtx/k2cWvkkFBuYGx6uGrlzBkVeWCRF/F8sdI0j3Wbkz/5rVNRRuVc8UrgRdbCxNhmYXgP3w==",
|
|
5269
5269
|
"license": "MIT",
|
|
5270
5270
|
"dependencies": {
|
|
5271
5271
|
"@types/unist": "^3.0.0",
|
|
@@ -5456,7 +5456,7 @@
|
|
|
5456
5456
|
},
|
|
5457
5457
|
"": {
|
|
5458
5458
|
"name": "@letta-ai/letta-code",
|
|
5459
|
-
"version": "0.34.
|
|
5459
|
+
"version": "0.34.25",
|
|
5460
5460
|
"dependencies": {
|
|
5461
5461
|
"@earendil-works/pi-ai": "^0.99.1",
|
|
5462
5462
|
"@janhapke/sharp-electron": "0.35.3-electron.1",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@letta-ai/letta-code",
|
|
3
|
-
"version": "0.34.
|
|
3
|
+
"version": "0.34.25",
|
|
4
4
|
"lettaStartupLogProtocol": 1,
|
|
5
5
|
"description": "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
6
6
|
"type": "module",
|
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
"license": "Apache-2.0",
|
|
144
144
|
"engines": {
|
|
145
145
|
"bun": ">=1.3.2",
|
|
146
|
-
"node": "
|
|
146
|
+
"node": "^22.23.4 || ^24.22.1 || ^26.12.1"
|
|
147
147
|
},
|
|
148
148
|
"publishConfig": {
|
|
149
149
|
"access": "public"
|
|
@@ -220,7 +220,7 @@
|
|
|
220
220
|
"prepublishOnly": "bun run runtime-graph:verify && bun run build",
|
|
221
221
|
"postinstall": "node scripts/postinstall-patches.js || echo letta: vendor patches skipped && node -e \"try{require('fs').chmodSync(require('path').join(require.resolve('node-pty/package.json'),'../prebuilds/darwin-arm64/spawn-helper'),0o755)}catch(e){}\" || true",
|
|
222
222
|
"mod-learning:memory-citations": "bun scripts/mod-learning/learn-mod.ts --env docs/examples/mods/learning/memory-citations.env.json",
|
|
223
|
-
"test:built-entrypoints": "LETTA_TEST_CLI_BUNDLE=\"$PWD/letta.js\" LETTA_TEST_BUILT_ARTIFACT=1 bun test src/cli/subcommands/lifecycle-output.test.ts src/websocket/app-server-dream.test.ts --timeout 60000"
|
|
223
|
+
"test:built-entrypoints": "LETTA_TEST_CLI_BUNDLE=\"$PWD/letta.js\" LETTA_TEST_BUILT_ARTIFACT=1 bun test src/subcommand-exit.test.ts src/cli/subcommands/lifecycle-output.test.ts src/websocket/app-server-dream.test.ts --timeout 60000"
|
|
224
224
|
},
|
|
225
225
|
"lint-staged": {
|
|
226
226
|
"*.{ts,tsx,js,jsx,json}": [
|
|
@@ -275,5 +275,8 @@
|
|
|
275
275
|
},
|
|
276
276
|
"lettaLifecycleProtocol": 1,
|
|
277
277
|
"lettaRuntimeGraphProtocol": 1,
|
|
278
|
-
"lettaRuntimeGraphSha512": "sha512-
|
|
278
|
+
"lettaRuntimeGraphSha512": "sha512-75ArKlsNj6BLjfiYR7ejV9jl0U3L7r1mXtWLYoNBVFkpR+NgT29dy3I6c7xawN3klfWjTCPVa5kpHtS7gVbD0A==",
|
|
279
|
+
"patchedDependencies": {
|
|
280
|
+
"@earendil-works/pi-ai@0.99.1": "patches/@earendil-works%2Fpi-ai@0.99.1.patch"
|
|
281
|
+
}
|
|
279
282
|
}
|
package/scripts/build-pypi.py
CHANGED
|
@@ -21,33 +21,33 @@ import zipfile
|
|
|
21
21
|
from pathlib import Path
|
|
22
22
|
|
|
23
23
|
ROOT = Path(__file__).resolve().parents[1]
|
|
24
|
-
NODE = "22.
|
|
24
|
+
NODE = "22.23.4"
|
|
25
25
|
# Official nodejs.org SHASUMS256.txt; pin the archive, not only the version.
|
|
26
26
|
TARGETS = {
|
|
27
27
|
("Linux", "x86_64"): (
|
|
28
28
|
"linux-x64",
|
|
29
29
|
"manylinux_2_28_x86_64",
|
|
30
|
-
"
|
|
30
|
+
"b8492284c76a54baf58d61668dd0e41ee0fc98adabf9503d30f05d08f55b4406",
|
|
31
31
|
),
|
|
32
32
|
("Linux", "aarch64"): (
|
|
33
33
|
"linux-arm64",
|
|
34
34
|
"manylinux_2_28_aarch64",
|
|
35
|
-
"
|
|
35
|
+
"f7a1e486dbc8b286847815b477d4fb5e9fb963ed4489c3e1588853d685f589f9",
|
|
36
36
|
),
|
|
37
37
|
("Darwin", "arm64"): (
|
|
38
38
|
"darwin-arm64",
|
|
39
39
|
"macosx_14_0_arm64",
|
|
40
|
-
"
|
|
40
|
+
"c9e1dbc748b33ed2d14f42445191ecaf14c56259c7a9a26d0042c49ec2b66428",
|
|
41
41
|
),
|
|
42
42
|
("Darwin", "x86_64"): (
|
|
43
43
|
"darwin-x64",
|
|
44
44
|
"macosx_14_0_x86_64",
|
|
45
|
-
"
|
|
45
|
+
"efcc2b0db6f94bf53eddb038fe2b370277a042bd29e4f19b8f8e23598795b819",
|
|
46
46
|
),
|
|
47
47
|
("Windows", "AMD64"): (
|
|
48
48
|
"win-x64",
|
|
49
49
|
"win_amd64",
|
|
50
|
-
"
|
|
50
|
+
"cbc74b5e0982c9dbb41525fd8fb5dcd32fbee237863f7829072f4639a1ce5f20",
|
|
51
51
|
),
|
|
52
52
|
}
|
|
53
53
|
|
|
@@ -140,7 +140,7 @@ describe("command planning", () => {
|
|
|
140
140
|
const serialized = sandboxed.args.join(" ");
|
|
141
141
|
expect(sandboxed.command).toBe("/usr/bin/docker");
|
|
142
142
|
expect(serialized).toContain("/tmp/probe-root:/watch:rw");
|
|
143
|
-
expect(serialized).toContain("node:22.
|
|
143
|
+
expect(serialized).toContain("node:22.23.4-bookworm@sha256:");
|
|
144
144
|
expect(serialized).toContain("--cap-drop ALL");
|
|
145
145
|
expect(serialized).toContain("--read-only");
|
|
146
146
|
expect(serialized).toContain("--env ANTHROPIC_API_KEY");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
|
|
3
3
|
const RUNTIME_SANDBOX_IMAGE =
|
|
4
|
-
"node:22.
|
|
4
|
+
"node:22.23.4-bookworm@sha256:63538dfe497cc29dfafdda25ada09b46db68a3f4cc205abf1f5d6bf0913f3384";
|
|
5
5
|
const AUTH_ENV_KEYS = ["ANTHROPIC_API_KEY", "CLAUDE_CODE_OAUTH_TOKEN"] as const;
|
|
6
6
|
|
|
7
7
|
export interface CommandSpec {
|
|
@@ -115,6 +115,76 @@ describe("Codex GitHub release fetch", () => {
|
|
|
115
115
|
expect(sleeps).toEqual([1000, 2000]);
|
|
116
116
|
});
|
|
117
117
|
|
|
118
|
+
test("retries a disconnected successful response body", async () => {
|
|
119
|
+
const sleeps: number[] = [];
|
|
120
|
+
let requests = 0;
|
|
121
|
+
const releases = await listStableReleases({
|
|
122
|
+
fetchImpl: (async () => {
|
|
123
|
+
requests++;
|
|
124
|
+
if (requests === 1) {
|
|
125
|
+
return new Response(
|
|
126
|
+
new ReadableStream({
|
|
127
|
+
pull(controller) {
|
|
128
|
+
controller.error(new TypeError("fetch failed: ECONNRESET"));
|
|
129
|
+
},
|
|
130
|
+
}),
|
|
131
|
+
{ status: 200 },
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
return Response.json(STABLES);
|
|
135
|
+
}) as typeof fetch,
|
|
136
|
+
sleep: async (delayMs) => {
|
|
137
|
+
sleeps.push(delayMs);
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
expect(requests).toBe(2);
|
|
142
|
+
expect(sleeps).toEqual([1000]);
|
|
143
|
+
expect(releases).toEqual(STABLES);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
test("stops retrying disconnected bodies at the existing budget", async () => {
|
|
147
|
+
const sleeps: number[] = [];
|
|
148
|
+
let requests = 0;
|
|
149
|
+
const result = listStableReleases({
|
|
150
|
+
fetchImpl: (async () => {
|
|
151
|
+
requests++;
|
|
152
|
+
return new Response(
|
|
153
|
+
new ReadableStream({
|
|
154
|
+
pull(controller) {
|
|
155
|
+
controller.error(new TypeError("fetch failed: ECONNRESET"));
|
|
156
|
+
},
|
|
157
|
+
}),
|
|
158
|
+
);
|
|
159
|
+
}) as typeof fetch,
|
|
160
|
+
sleep: async (delayMs) => {
|
|
161
|
+
sleeps.push(delayMs);
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
await expect(result).rejects.toThrow("after 3 attempts");
|
|
166
|
+
expect(requests).toBe(3);
|
|
167
|
+
expect(sleeps).toEqual([1000, 2000]);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
test("does not retry malformed JSON", async () => {
|
|
171
|
+
const sleeps: number[] = [];
|
|
172
|
+
let requests = 0;
|
|
173
|
+
const result = listStableReleases({
|
|
174
|
+
fetchImpl: (async () => {
|
|
175
|
+
requests++;
|
|
176
|
+
return new Response("not JSON");
|
|
177
|
+
}) as typeof fetch,
|
|
178
|
+
sleep: async (delayMs) => {
|
|
179
|
+
sleeps.push(delayMs);
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
await expect(result).rejects.toBeInstanceOf(SyntaxError);
|
|
184
|
+
expect(requests).toBe(1);
|
|
185
|
+
expect(sleeps).toEqual([]);
|
|
186
|
+
});
|
|
187
|
+
|
|
118
188
|
test("fails immediately on a client error", async () => {
|
|
119
189
|
const sleeps: number[] = [];
|
|
120
190
|
let requests = 0;
|
|
@@ -190,8 +190,7 @@ export async function listStableReleases(
|
|
|
190
190
|
|
|
191
191
|
for (let page = 1; page <= 10; page++) {
|
|
192
192
|
const url = `https://api.github.com/repos/${CODEX_REPO}/releases?per_page=100&page=${page}`;
|
|
193
|
-
const
|
|
194
|
-
const batch = (await res.json()) as Release[];
|
|
193
|
+
const batch = await fetchGitHubReleasesPage(url, headers, fetchImpl, sleep);
|
|
195
194
|
releases.push(...batch);
|
|
196
195
|
if (batch.length < 100) break;
|
|
197
196
|
}
|
|
@@ -205,12 +204,15 @@ async function fetchGitHubReleasesPage(
|
|
|
205
204
|
headers: Record<string, string>,
|
|
206
205
|
fetchImpl: typeof fetch,
|
|
207
206
|
sleep: (delayMs: number) => Promise<void>,
|
|
208
|
-
): Promise<
|
|
207
|
+
): Promise<Release[]> {
|
|
209
208
|
for (let attempt = 1; ; attempt++) {
|
|
210
209
|
let response: Response;
|
|
211
210
|
try {
|
|
212
211
|
response = await fetchImpl(url, { headers });
|
|
212
|
+
// A successful fetch can still lose its connection while reading the body.
|
|
213
|
+
if (response.ok) return (await response.json()) as Release[];
|
|
213
214
|
} catch (error) {
|
|
215
|
+
if (error instanceof SyntaxError) throw error;
|
|
214
216
|
if (attempt === GITHUB_RELEASES_FETCH_ATTEMPTS) {
|
|
215
217
|
throw new Error(
|
|
216
218
|
`GitHub releases API request failed after ${attempt} attempts: ${String(error)}`,
|
|
@@ -221,8 +223,6 @@ async function fetchGitHubReleasesPage(
|
|
|
221
223
|
continue;
|
|
222
224
|
}
|
|
223
225
|
|
|
224
|
-
if (response.ok) return response;
|
|
225
|
-
|
|
226
226
|
const message = `GitHub releases API failed (${response.status}): ${await response.text()}`;
|
|
227
227
|
if (response.status < 500 || attempt === GITHUB_RELEASES_FETCH_ATTEMPTS) {
|
|
228
228
|
throw new Error(message);
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"src/agent/client-skills.test.ts": 1132,
|
|
3
3
|
"src/agent/memory-git.ts": 2013,
|
|
4
4
|
"src/backend/local-backend.test.ts": 2472,
|
|
5
|
-
"src/backend/local/local-store.ts":
|
|
5
|
+
"src/backend/local/local-store.ts": 3260,
|
|
6
6
|
"src/backend/pi-stream-adapter.test.ts": 1255,
|
|
7
7
|
"src/cli/app/AppCoordinator.tsx": 5131,
|
|
8
8
|
"src/cli/app/AppView.tsx": 1732,
|
|
9
9
|
"src/cli/app/use-approval-flow.ts": 1099,
|
|
10
10
|
"src/cli/app/use-configuration-handlers.ts": 1417,
|
|
11
|
-
"src/cli/app/use-conversation-loop.ts":
|
|
11
|
+
"src/cli/app/use-conversation-loop.ts": 2878,
|
|
12
12
|
"src/cli/app/use-submit-handler.ts": 3797,
|
|
13
13
|
"src/cli/components/AgentSelector.tsx": 1104,
|
|
14
14
|
"src/cli/components/InputRich.tsx": 2124,
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"src/settings-manager.ts": 2092,
|
|
35
35
|
"src/tools/manager.ts": 2609,
|
|
36
36
|
"src/tools/tool-execution-context.test.ts": 1092,
|
|
37
|
-
"src/types/protocol_v2.ts":
|
|
37
|
+
"src/types/protocol_v2.ts": 2409,
|
|
38
38
|
"src/websocket/listen-client-concurrency.test.ts": 2554,
|
|
39
39
|
"src/websocket/listen-client-protocol.test.ts": 5664,
|
|
40
40
|
"src/websocket/listener/commands/memory.ts": 1114,
|
|
@@ -58,6 +58,8 @@ Discovery runs through the `MEMORY.md` chain, one level at a time:
|
|
|
58
58
|
|
|
59
59
|
After adding or moving a file, trace the path a future request would take from root `MEMORY.md` to the file. If any step depends on knowing the file already exists, fix the index.
|
|
60
60
|
|
|
61
|
+
Indexes are the only way the agent finds deferred memory: it opens a file only when every entry on the path from root names what it is looking for. Keep them accurate as memory changes. Whenever you add, move, or substantially change what a directory holds, reread its entry in each parent `MEMORY.md` up to root and rewrite it to name the topics the directory now covers, in the words a future request would use. An entry written when the directory was new goes stale as it fills, and a topic no entry mentions is effectively lost.
|
|
62
|
+
|
|
61
63
|
## Design for progressive disclosure
|
|
62
64
|
|
|
63
65
|
Each level should give the agent enough to decide whether to go deeper, and nothing it would have to read past to decide.
|
|
@@ -23,7 +23,7 @@ Execution determines schedule ownership; there is no runner selection flag:
|
|
|
23
23
|
- In a managed Cloud sandbox, schedules are durable Cloud schedules and run in the agent's Cloud sandbox.
|
|
24
24
|
- On a user-managed computer or self-hosted runtime, schedules are local and fire only while a Letta session is running there.
|
|
25
25
|
|
|
26
|
-
From a managed Cloud sandbox, `--computer <deviceId>` can run the scheduled work on a specific connected computer. Get the device ID from `letta computers list`. If that computer is offline at fire time,
|
|
26
|
+
From a managed Cloud sandbox, `--computer <deviceId>` can run the scheduled work on a specific connected computer. Get the device ID from `letta computers list`. If that computer is offline at fire time, that occurrence fails (`TARGET_DEVICE_UNAVAILABLE`) and does not run; omit `--computer` to run in the Cloud sandbox. Local execution cannot target another computer.
|
|
27
27
|
|
|
28
28
|
Creation and execution follow those rules, while management commands still show and cancel both local and Cloud inventory. This keeps schedules created by older CLI versions visible without changing where new schedules run.
|
|
29
29
|
|
|
@@ -18,7 +18,7 @@ curl -sS -X POST "$LETTA_BASE_URL/v1/environments/connect-token" \
|
|
|
18
18
|
|
|
19
19
|
The response is `{ "deviceCode": "...", "organizationId": "...", "expiresIn": 900 }`. A 403 means this sandbox key does not resolve to an owner; tell the user and fall back to Option 2.
|
|
20
20
|
|
|
21
|
-
Ask the user to install [Node.js 22.
|
|
21
|
+
Ask the user to install [Node.js ^22.23.4, ^24.22.1, or ^26.12.1](https://nodejs.org/en/download) if they do not have it, then run this **on the computer they want to connect**, filling in both values from the response:
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
24
|
npm install -g @letta-ai/letta-code
|
|
@@ -31,7 +31,7 @@ The command signs in as the owner. Send it only to that person: a DM, or the thr
|
|
|
31
31
|
|
|
32
32
|
## Option 2: CLI server (browser sign-in)
|
|
33
33
|
|
|
34
|
-
Ask the user to install [Node.js 22.
|
|
34
|
+
Ask the user to install [Node.js ^22.23.4, ^24.22.1, or ^26.12.1](https://nodejs.org/en/download), then run these commands in a terminal **on the target computer**:
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
37
|
npm install -g @letta-ai/letta-code
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { IncomingMessage } from "./types";
|
|
2
|
-
export type McpOriginatorScope = {
|
|
3
|
-
superRunId: string;
|
|
4
|
-
tokenPresent: boolean;
|
|
5
|
-
} | null;
|
|
6
|
-
export declare function getMcpOriginatorScope(message?: Pick<IncomingMessage, "mcpOriginatorSuperRunId" | "mcpOriginatorTokenPresent">): McpOriginatorScope;
|
|
7
|
-
export declare function sameMcpOriginatorScope(a: McpOriginatorScope, b: McpOriginatorScope): boolean;
|
|
8
|
-
export declare function getEffectiveMcpOriginatorId(message: Pick<IncomingMessage, "mcpOriginatorSuperRunId" | "mcpOriginatorTokenPresent">): string | undefined;
|
|
9
|
-
//# sourceMappingURL=mcp-originator-scope.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-originator-scope.d.ts","sourceRoot":"","sources":["../../../../src/websocket/listener/mcp-originator-scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;CACvB,GAAG,IAAI,CAAC;AAET,wBAAgB,qBAAqB,CACnC,OAAO,CAAC,EAAE,IAAI,CACZ,eAAe,EACf,yBAAyB,GAAG,2BAA2B,CACxD,GACA,kBAAkB,CAOpB;AAED,wBAAgB,sBAAsB,CACpC,CAAC,EAAE,kBAAkB,EACrB,CAAC,EAAE,kBAAkB,GACpB,OAAO,CAIT;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,IAAI,CACX,eAAe,EACf,yBAAyB,GAAG,2BAA2B,CACxD,GACA,MAAM,GAAG,SAAS,CAIpB"}
|