@letta-ai/letta-code 0.32.8 → 0.32.9
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/mcp-client.js +2 -2
- package/dist/mcp-client.js.map +1 -1
- package/dist/types/agent/subagents/names.d.ts +1 -1
- package/dist/types/agent/subagents/names.d.ts.map +1 -1
- package/dist/types/backend/api/metadata.d.ts +1 -0
- package/dist/types/backend/api/metadata.d.ts.map +1 -1
- package/dist/types/runtime-context.d.ts +2 -0
- package/dist/types/runtime-context.d.ts.map +1 -1
- package/dist/types/telemetry/index.d.ts +1 -0
- package/dist/types/telemetry/index.d.ts.map +1 -1
- package/dist/types/tools/impl/task.d.ts.map +1 -1
- package/dist/types/tools/manager.d.ts +1 -3
- package/dist/types/tools/manager.d.ts.map +1 -1
- package/dist/types/types/protocol_v2.d.ts +3 -5
- package/dist/types/types/protocol_v2.d.ts.map +1 -1
- package/dist/types/websocket/listener/runtime.d.ts.map +1 -1
- package/dist/types/websocket/listener/types.d.ts +10 -8
- package/dist/types/websocket/listener/types.d.ts.map +1 -1
- package/letta.js +161 -118
- package/package.json +1 -1
- package/scripts/source-file-size-baseline.json +4 -4
- package/scripts/test-home-preload.ts +9 -1
- package/skills/letta-guide/SKILL.md +3 -1
package/letta.js
CHANGED
|
@@ -3933,6 +3933,18 @@ var init_paths = __esm(() => {
|
|
|
3933
3933
|
init_local_backend_paths();
|
|
3934
3934
|
});
|
|
3935
3935
|
|
|
3936
|
+
// src/agent/acting-user.ts
|
|
3937
|
+
function resolveActingUserId(explicitActingUserId, runtimeActingUserId, env = process.env) {
|
|
3938
|
+
return explicitActingUserId ?? runtimeActingUserId ?? env[ACTING_USER_ID_ENV];
|
|
3939
|
+
}
|
|
3940
|
+
function actingUserRequestOptions(actingUserId) {
|
|
3941
|
+
if (!actingUserId) {
|
|
3942
|
+
return;
|
|
3943
|
+
}
|
|
3944
|
+
return { headers: { [ACTING_USER_ID_HEADER]: actingUserId } };
|
|
3945
|
+
}
|
|
3946
|
+
var ACTING_USER_ID_HEADER = "X-Letta-Acting-User-Id", ACTING_USER_ID_ENV = "LETTA_ACTING_USER_ID";
|
|
3947
|
+
|
|
3936
3948
|
// src/helpers/usable-directory.ts
|
|
3937
3949
|
import { statSync } from "node:fs";
|
|
3938
3950
|
function readDirectoryStats(dirPath) {
|
|
@@ -3968,6 +3980,9 @@ import { homedir as homedir2, tmpdir } from "node:os";
|
|
|
3968
3980
|
function getRuntimeContext() {
|
|
3969
3981
|
return runtimeContextStorage.getStore();
|
|
3970
3982
|
}
|
|
3983
|
+
function getRuntimeActingUserId() {
|
|
3984
|
+
return resolveActingUserId(undefined, getRuntimeContext()?.actingUserId);
|
|
3985
|
+
}
|
|
3971
3986
|
function runWithRuntimeContext(snapshot, fn) {
|
|
3972
3987
|
const parent = runtimeContextStorage.getStore();
|
|
3973
3988
|
return runtimeContextStorage.run({
|
|
@@ -5515,7 +5530,7 @@ var package_default;
|
|
|
5515
5530
|
var init_package = __esm(() => {
|
|
5516
5531
|
package_default = {
|
|
5517
5532
|
name: "@letta-ai/letta-code",
|
|
5518
|
-
version: "0.32.
|
|
5533
|
+
version: "0.32.9",
|
|
5519
5534
|
lettaStartupLogProtocol: 1,
|
|
5520
5535
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
5521
5536
|
type: "module",
|
|
@@ -5945,7 +5960,8 @@ async function submitTelemetryMetadata(apiKey, deviceId, payload, options) {
|
|
|
5945
5960
|
await apiRequest("POST", "/v1/metadata/telemetry", payload, {
|
|
5946
5961
|
...config,
|
|
5947
5962
|
headers: {
|
|
5948
|
-
"X-Letta-Code-Device-ID": deviceId
|
|
5963
|
+
"X-Letta-Code-Device-ID": deviceId,
|
|
5964
|
+
...actingUserRequestOptions(options?.actingUserId)?.headers
|
|
5949
5965
|
},
|
|
5950
5966
|
signal: options?.signal
|
|
5951
5967
|
});
|
|
@@ -6167,6 +6183,7 @@ function isNonActionableError(message) {
|
|
|
6167
6183
|
|
|
6168
6184
|
class TelemetryManager {
|
|
6169
6185
|
events = [];
|
|
6186
|
+
eventActingUsers = new WeakMap;
|
|
6170
6187
|
sessionId;
|
|
6171
6188
|
deviceId = null;
|
|
6172
6189
|
currentAgentId = null;
|
|
@@ -6291,6 +6308,7 @@ class TelemetryManager {
|
|
|
6291
6308
|
backend: resolveTelemetryBackend()
|
|
6292
6309
|
}
|
|
6293
6310
|
};
|
|
6311
|
+
this.eventActingUsers.set(event, getRuntimeActingUserId());
|
|
6294
6312
|
this.events.push(event);
|
|
6295
6313
|
if (this.events.length >= this.MAX_BATCH_SIZE) {
|
|
6296
6314
|
this.flush().catch((err) => {
|
|
@@ -6509,15 +6527,27 @@ class TelemetryManager {
|
|
|
6509
6527
|
this.events = [];
|
|
6510
6528
|
const apiKey = await this.resolveTelemetryApiKey();
|
|
6511
6529
|
const deviceId = this.getTelemetryDeviceId();
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
}
|
|
6519
|
-
|
|
6520
|
-
|
|
6530
|
+
const groups = new Map;
|
|
6531
|
+
for (const event of eventsToSend) {
|
|
6532
|
+
const actingUserId = this.eventActingUsers.get(event);
|
|
6533
|
+
const group = groups.get(actingUserId) ?? [];
|
|
6534
|
+
group.push(event);
|
|
6535
|
+
groups.set(actingUserId, group);
|
|
6536
|
+
}
|
|
6537
|
+
const failed = new Set;
|
|
6538
|
+
await Promise.all([...groups].map(async ([actingUserId, events]) => {
|
|
6539
|
+
try {
|
|
6540
|
+
await submitTelemetryMetadata(apiKey, deviceId, {
|
|
6541
|
+
service: "letta-code",
|
|
6542
|
+
server_version: this.serverVersion || undefined,
|
|
6543
|
+
events
|
|
6544
|
+
}, { signal: AbortSignal.timeout(5000), actingUserId });
|
|
6545
|
+
} catch {
|
|
6546
|
+
for (const event of events)
|
|
6547
|
+
failed.add(event);
|
|
6548
|
+
}
|
|
6549
|
+
}));
|
|
6550
|
+
this.events.unshift(...eventsToSend.filter((event) => failed.has(event)));
|
|
6521
6551
|
}
|
|
6522
6552
|
async drain() {
|
|
6523
6553
|
if (!this.isTelemetryEnabled()) {
|
|
@@ -6554,6 +6584,7 @@ var init_telemetry = __esm(() => {
|
|
|
6554
6584
|
init_metadata();
|
|
6555
6585
|
init_server_url();
|
|
6556
6586
|
init_paths();
|
|
6587
|
+
init_runtime_context();
|
|
6557
6588
|
init_settings_manager();
|
|
6558
6589
|
init_debug();
|
|
6559
6590
|
init_version();
|
|
@@ -101243,7 +101274,6 @@ function createConversationRuntime(listener, agentId, conversationId) {
|
|
|
101243
101274
|
acceptedInputDispositions: new Map,
|
|
101244
101275
|
pendingApprovalResolvers: new Map,
|
|
101245
101276
|
recoveredApprovalState: null,
|
|
101246
|
-
syncApprovalRecoveryCompleted: false,
|
|
101247
101277
|
expectedTeleportId: null,
|
|
101248
101278
|
expectedTeleportExpiresAt: null,
|
|
101249
101279
|
get lastStopReason() {
|
|
@@ -122326,18 +122356,6 @@ var init_search_file_content_gemini = __esm(() => {
|
|
|
122326
122356
|
init_grep();
|
|
122327
122357
|
});
|
|
122328
122358
|
|
|
122329
|
-
// src/agent/acting-user.ts
|
|
122330
|
-
function resolveActingUserId(explicitActingUserId, runtimeActingUserId, env3 = process.env) {
|
|
122331
|
-
return explicitActingUserId ?? runtimeActingUserId ?? env3[ACTING_USER_ID_ENV];
|
|
122332
|
-
}
|
|
122333
|
-
function actingUserRequestOptions(actingUserId) {
|
|
122334
|
-
if (!actingUserId) {
|
|
122335
|
-
return;
|
|
122336
|
-
}
|
|
122337
|
-
return { headers: { [ACTING_USER_ID_HEADER]: actingUserId } };
|
|
122338
|
-
}
|
|
122339
|
-
var ACTING_USER_ID_HEADER = "X-Letta-Acting-User-Id", ACTING_USER_ID_ENV = "LETTA_ACTING_USER_ID";
|
|
122340
|
-
|
|
122341
122359
|
// src/backend/api/agent-message.ts
|
|
122342
122360
|
function normalizeAgentMessageComputer(value) {
|
|
122343
122361
|
if (value == null)
|
|
@@ -123673,106 +123691,114 @@ var init_names = __esm(() => {
|
|
|
123673
123691
|
init_constants2();
|
|
123674
123692
|
SUBAGENT_NAMES = [
|
|
123675
123693
|
"Deckard",
|
|
123676
|
-
"
|
|
123677
|
-
"Roy",
|
|
123694
|
+
"Roy Batty",
|
|
123678
123695
|
"Pris",
|
|
123679
123696
|
"Zhora",
|
|
123680
|
-
"Leon",
|
|
123681
123697
|
"Gaff",
|
|
123682
123698
|
"Tyrell",
|
|
123683
|
-
"Sebastian",
|
|
123684
|
-
"Bryant",
|
|
123685
|
-
"Chew",
|
|
123686
|
-
"Holden",
|
|
123687
|
-
"Taffey",
|
|
123688
123699
|
"K",
|
|
123689
123700
|
"Joi",
|
|
123690
123701
|
"Luv",
|
|
123691
|
-
"Wallace",
|
|
123692
|
-
"Joshi",
|
|
123693
123702
|
"Sapper",
|
|
123694
|
-
"Mariette",
|
|
123695
123703
|
"Freysa",
|
|
123696
|
-
"Ana",
|
|
123697
|
-
"Coco",
|
|
123698
|
-
"Samantha",
|
|
123699
|
-
"Theodore",
|
|
123700
|
-
"Amy",
|
|
123701
|
-
"Catherine",
|
|
123702
|
-
"Paul",
|
|
123703
|
-
"Isabella",
|
|
123704
123704
|
"Ava",
|
|
123705
|
-
"Caleb",
|
|
123706
|
-
"Nathan",
|
|
123707
123705
|
"Kyoko",
|
|
123708
123706
|
"V",
|
|
123709
|
-
"
|
|
123710
|
-
"Jackie",
|
|
123711
|
-
"Judy",
|
|
123707
|
+
"Silverhand",
|
|
123712
123708
|
"Panam",
|
|
123713
|
-
"River",
|
|
123714
|
-
"Kerry",
|
|
123715
123709
|
"Rogue",
|
|
123716
|
-
"Alt",
|
|
123717
|
-
"Evelyn",
|
|
123710
|
+
"Alt Cunningham",
|
|
123718
123711
|
"Takemura",
|
|
123719
123712
|
"Hanako",
|
|
123720
123713
|
"Yorinobu",
|
|
123721
123714
|
"Saburo",
|
|
123722
123715
|
"Oda",
|
|
123723
|
-
"Viktor",
|
|
123724
|
-
"Misty",
|
|
123725
|
-
"Dex",
|
|
123726
123716
|
"T-Bug",
|
|
123727
123717
|
"Delamain",
|
|
123728
123718
|
"Wakako",
|
|
123729
123719
|
"Padre",
|
|
123730
|
-
"Regina",
|
|
123731
|
-
"Dakota",
|
|
123732
|
-
"Dino",
|
|
123733
123720
|
"El Capitan",
|
|
123734
123721
|
"Mr. Hands",
|
|
123735
123722
|
"Placide",
|
|
123736
|
-
"Brigitte",
|
|
123737
|
-
"Royce",
|
|
123738
123723
|
"Dum Dum",
|
|
123739
|
-
"Brick",
|
|
123740
|
-
"Meredith",
|
|
123741
|
-
"Sandra",
|
|
123742
|
-
"Maiko",
|
|
123743
|
-
"Claire",
|
|
123744
123724
|
"Nix",
|
|
123745
123725
|
"Weyland",
|
|
123746
|
-
"Saul",
|
|
123747
|
-
"Mitch",
|
|
123748
123726
|
"Scorpion",
|
|
123749
|
-
"Cassidy",
|
|
123750
|
-
"Carol",
|
|
123751
|
-
"Denny",
|
|
123752
|
-
"Nancy",
|
|
123753
|
-
"Henry",
|
|
123754
123727
|
"Blue Moon",
|
|
123755
123728
|
"Red Menace",
|
|
123756
123729
|
"Purple Force",
|
|
123757
|
-
"Lizzy",
|
|
123730
|
+
"Lizzy Wizzy",
|
|
123758
123731
|
"Ozob",
|
|
123759
123732
|
"Smasher",
|
|
123760
|
-
"Reed",
|
|
123761
123733
|
"Songbird",
|
|
123762
|
-
"Alex",
|
|
123763
|
-
"Myers",
|
|
123764
|
-
"Hansen",
|
|
123765
|
-
"Paco",
|
|
123766
|
-
"Babs",
|
|
123767
123734
|
"Slider",
|
|
123768
|
-
"Aurore",
|
|
123769
|
-
"Aymeric",
|
|
123770
123735
|
"Aguilar",
|
|
123771
|
-
"
|
|
123772
|
-
"
|
|
123773
|
-
"
|
|
123774
|
-
"
|
|
123775
|
-
"
|
|
123736
|
+
"Dogmeat",
|
|
123737
|
+
"Codsworth",
|
|
123738
|
+
"Nick Valentine",
|
|
123739
|
+
"Yes Man",
|
|
123740
|
+
"Mr. House",
|
|
123741
|
+
"ED-E",
|
|
123742
|
+
"Fisto",
|
|
123743
|
+
"Liberty Prime",
|
|
123744
|
+
"Three Dog",
|
|
123745
|
+
"Charon",
|
|
123746
|
+
"Fawkes",
|
|
123747
|
+
"Ulysses",
|
|
123748
|
+
"The Master",
|
|
123749
|
+
"Muggy",
|
|
123750
|
+
"Dr. Mobius",
|
|
123751
|
+
"Dr. Klein",
|
|
123752
|
+
"Old Longfellow",
|
|
123753
|
+
"Pickman",
|
|
123754
|
+
"Butch DeLoria",
|
|
123755
|
+
"Fantastic",
|
|
123756
|
+
"Muad'Dib",
|
|
123757
|
+
"Stilgar",
|
|
123758
|
+
"Chani",
|
|
123759
|
+
"Gurney Halleck",
|
|
123760
|
+
"Duncan Idaho",
|
|
123761
|
+
"Thufir Hawat",
|
|
123762
|
+
"Liet-Kynes",
|
|
123763
|
+
"Shadout Mapes",
|
|
123764
|
+
"Feyd-Rautha",
|
|
123765
|
+
"Rabban",
|
|
123766
|
+
"Piter De Vries",
|
|
123767
|
+
"Irulan",
|
|
123768
|
+
"Scytale",
|
|
123769
|
+
"Hayt",
|
|
123770
|
+
"Bijaz",
|
|
123771
|
+
"Moneo",
|
|
123772
|
+
"Miles Teg",
|
|
123773
|
+
"Darwi Odrade",
|
|
123774
|
+
"Sheeana",
|
|
123775
|
+
"Shaddam IV",
|
|
123776
|
+
"Count Fenring",
|
|
123777
|
+
"Wintermute",
|
|
123778
|
+
"Neuromancer",
|
|
123779
|
+
"Dixie Flatline",
|
|
123780
|
+
"Molly Millions",
|
|
123781
|
+
"Lady 3Jane",
|
|
123782
|
+
"Armitage",
|
|
123783
|
+
"Maelcum",
|
|
123784
|
+
"Ratz",
|
|
123785
|
+
"The Finn",
|
|
123786
|
+
"Hiro Protagonist",
|
|
123787
|
+
"Y.T.",
|
|
123788
|
+
"Raven",
|
|
123789
|
+
"Uncle Enzo",
|
|
123790
|
+
"R. Daneel Olivaw",
|
|
123791
|
+
"R. Giskard Reventlov",
|
|
123792
|
+
"Hari Seldon",
|
|
123793
|
+
"Dors Venabili",
|
|
123794
|
+
"The Mule",
|
|
123795
|
+
"HAL 9000",
|
|
123796
|
+
"Aineko",
|
|
123797
|
+
"Eschaton",
|
|
123798
|
+
"Mycroft Canner",
|
|
123799
|
+
"J.E.D.D. Mason",
|
|
123800
|
+
"Sniper",
|
|
123801
|
+
"Eureka Weeksbooth"
|
|
123776
123802
|
];
|
|
123777
123803
|
nextName = createSubagentNameAllocator();
|
|
123778
123804
|
});
|
|
@@ -125204,7 +125230,10 @@ async function task(args) {
|
|
|
125204
125230
|
const agentId = linkedAgent?.agentId ?? null;
|
|
125205
125231
|
const agentIdLine = agentId ? `
|
|
125206
125232
|
Agent ID: ${agentId}` : "";
|
|
125207
|
-
|
|
125233
|
+
const conversationId = linkedAgent?.conversationId ?? null;
|
|
125234
|
+
const conversationIdLine = conversationId ? `
|
|
125235
|
+
Conversation ID: ${conversationId}` : "";
|
|
125236
|
+
return `Task running in background with task ID: ${taskId}${agentIdLine}${conversationIdLine}
|
|
125208
125237
|
Output file: ${outputFile}
|
|
125209
125238
|
|
|
125210
125239
|
You will be notified automatically when this task completes — a <task-notification> message will be delivered with the result. No need to poll, sleep-wait, or check the output file. Just continue with your current work.`;
|
|
@@ -134381,7 +134410,7 @@ async function executeToolInner(name, args, options) {
|
|
|
134381
134410
|
return createModPermissionToolResult(permissionDecision2);
|
|
134382
134411
|
}
|
|
134383
134412
|
}
|
|
134384
|
-
return executeExternalTool(options?.toolCallId ?? `ext-${Date.now()}`, name, eventArgs2, externalTool?.executor ?? activeExternalExecutor, externalTool);
|
|
134413
|
+
return runWithRuntimeContext(executionScope, () => executeExternalTool(options?.toolCallId ?? `ext-${Date.now()}`, name, eventArgs2, externalTool?.executor ?? activeExternalExecutor, externalTool));
|
|
134385
134414
|
}
|
|
134386
134415
|
const internalName = resolveInternalToolName(name, activeRegistry);
|
|
134387
134416
|
const tool = internalName ? activeRegistry.get(internalName) : undefined;
|
|
@@ -223091,8 +223120,8 @@ function isSyncCommand(value) {
|
|
|
223091
223120
|
if (!value || typeof value !== "object") {
|
|
223092
223121
|
return false;
|
|
223093
223122
|
}
|
|
223094
|
-
const
|
|
223095
|
-
return
|
|
223123
|
+
const c = value;
|
|
223124
|
+
return c.type === "sync" && isRuntimeScope(c.runtime) && (c.request_id === undefined || typeof c.request_id === "string") && (c.recover_approvals === undefined || typeof c.recover_approvals === "boolean") && (c.resume_interrupted_turn === undefined || typeof c.resume_interrupted_turn === "boolean") && (c.force_device_status === undefined || typeof c.force_device_status === "boolean");
|
|
223096
223125
|
}
|
|
223097
223126
|
function isTerminalSpawnCommand(value) {
|
|
223098
223127
|
if (!value || typeof value !== "object")
|
|
@@ -402519,7 +402548,6 @@ async function startRecoveredApprovalContinuation(runtime, socket, processTurn,
|
|
|
402519
402548
|
if (!await canRecoverConversation(runtime)) {
|
|
402520
402549
|
if (runtime.recoveredApprovalState === recovered) {
|
|
402521
402550
|
clearRecoveredApprovalState(runtime);
|
|
402522
|
-
runtime.syncApprovalRecoveryCompleted = false;
|
|
402523
402551
|
}
|
|
402524
402552
|
return false;
|
|
402525
402553
|
}
|
|
@@ -407312,12 +407340,12 @@ function rowToolCalls(row, index, diagnostics2) {
|
|
|
407312
407340
|
}
|
|
407313
407341
|
return calls;
|
|
407314
407342
|
}
|
|
407315
|
-
function
|
|
407343
|
+
function contentText(content) {
|
|
407316
407344
|
if (typeof content === "string") {
|
|
407317
407345
|
if (content.startsWith(CONTENT_JSON_PREFIX)) {
|
|
407318
407346
|
const encoded = content.slice(CONTENT_JSON_PREFIX.length);
|
|
407319
407347
|
try {
|
|
407320
|
-
return
|
|
407348
|
+
return contentText(JSON.parse(encoded));
|
|
407321
407349
|
} catch {
|
|
407322
407350
|
return encoded;
|
|
407323
407351
|
}
|
|
@@ -407403,7 +407431,7 @@ var init_hermes = __esm(() => {
|
|
|
407403
407431
|
});
|
|
407404
407432
|
};
|
|
407405
407433
|
if (row.role === "user") {
|
|
407406
|
-
const content =
|
|
407434
|
+
const content = contentText(row.content);
|
|
407407
407435
|
if (content) {
|
|
407408
407436
|
emit({
|
|
407409
407437
|
type: "message",
|
|
@@ -407423,7 +407451,7 @@ var init_hermes = __esm(() => {
|
|
|
407423
407451
|
...timestamp ? { timestamp } : {}
|
|
407424
407452
|
});
|
|
407425
407453
|
}
|
|
407426
|
-
const content =
|
|
407454
|
+
const content = contentText(row.content);
|
|
407427
407455
|
if (content) {
|
|
407428
407456
|
emit({
|
|
407429
407457
|
type: "message",
|
|
@@ -407446,7 +407474,7 @@ var init_hermes = __esm(() => {
|
|
|
407446
407474
|
if (row.role === "tool") {
|
|
407447
407475
|
emit({
|
|
407448
407476
|
type: "tool_result",
|
|
407449
|
-
content:
|
|
407477
|
+
content: contentText(row.content),
|
|
407450
407478
|
...typeof row.tool_call_id === "string" && row.tool_call_id ? { callId: row.tool_call_id } : {},
|
|
407451
407479
|
...timestamp ? { timestamp } : {}
|
|
407452
407480
|
});
|
|
@@ -413453,16 +413481,18 @@ function extractTelemetryInputText(content) {
|
|
|
413453
413481
|
}
|
|
413454
413482
|
|
|
413455
413483
|
// src/websocket/listener/turn-transcript.ts
|
|
413456
|
-
function trackListenerUserInput(messages, modelId) {
|
|
413457
|
-
|
|
413458
|
-
|
|
413459
|
-
|
|
413460
|
-
|
|
413461
|
-
|
|
413462
|
-
|
|
413463
|
-
|
|
413484
|
+
function trackListenerUserInput(messages, modelId, actingUserId) {
|
|
413485
|
+
runWithRuntimeContext({ actingUserId }, () => {
|
|
413486
|
+
for (const message of messages) {
|
|
413487
|
+
if (!("role" in message) || message.role !== "user") {
|
|
413488
|
+
continue;
|
|
413489
|
+
}
|
|
413490
|
+
const inputText = extractTelemetryInputText(message.content);
|
|
413491
|
+
if (inputText.length > 0) {
|
|
413492
|
+
telemetry.trackUserInput(inputText, "user", modelId);
|
|
413493
|
+
}
|
|
413464
413494
|
}
|
|
413465
|
-
}
|
|
413495
|
+
});
|
|
413466
413496
|
}
|
|
413467
413497
|
function buildInboundUserTranscriptLines(messages) {
|
|
413468
413498
|
const lines = [];
|
|
@@ -413497,6 +413527,7 @@ function seedInboundUserTranscriptLines(buffers, lines) {
|
|
|
413497
413527
|
}
|
|
413498
413528
|
}
|
|
413499
413529
|
var init_turn_transcript = __esm(() => {
|
|
413530
|
+
init_runtime_context();
|
|
413500
413531
|
init_telemetry();
|
|
413501
413532
|
});
|
|
413502
413533
|
|
|
@@ -413609,7 +413640,7 @@ async function prepareListenerTurn(params) {
|
|
|
413609
413640
|
if (connectionId) {
|
|
413610
413641
|
onStatusChange?.("processing", connectionId);
|
|
413611
413642
|
}
|
|
413612
|
-
trackListenerUserInput(msg.messages, "unknown");
|
|
413643
|
+
trackListenerUserInput(msg.messages, "unknown", msg.actingUserId);
|
|
413613
413644
|
const messagesToSend = [];
|
|
413614
413645
|
let queuedInterruptedToolCallIds = [];
|
|
413615
413646
|
const wasInterrupted = hasInterruptedCacheForScope(runtime.listener, {
|
|
@@ -418403,6 +418434,7 @@ function summarizeV2Command(parsed) {
|
|
|
418403
418434
|
"replace_all",
|
|
418404
418435
|
"expected_replacements",
|
|
418405
418436
|
"recover_approvals",
|
|
418437
|
+
"resume_interrupted_turn",
|
|
418406
418438
|
"force_device_status"
|
|
418407
418439
|
]) {
|
|
418408
418440
|
pushField(fields, key2, parsed[key2]);
|
|
@@ -418869,6 +418901,7 @@ function createListenerMessageHandler(params) {
|
|
|
418869
418901
|
try {
|
|
418870
418902
|
await replaySyncStateForRuntime(runtime, socket, parsed.runtime, {
|
|
418871
418903
|
recoverApprovals: parsed.recover_approvals !== false,
|
|
418904
|
+
resumeInterruptedTurn: parsed.resume_interrupted_turn === true,
|
|
418872
418905
|
forceDeviceStatus: parsed.force_device_status === true,
|
|
418873
418906
|
onStatusChange: opts.onStatusChange,
|
|
418874
418907
|
connectionId: opts.connectionId
|
|
@@ -419448,7 +419481,7 @@ var init_process_services = __esm(async () => {
|
|
|
419448
419481
|
function isBackendNotFoundError2(error4) {
|
|
419449
419482
|
return error4 instanceof APIError && (error4.status === 404 || error4.status === 422) || error4 instanceof Error && error4.name === "LocalBackendNotFoundError";
|
|
419450
419483
|
}
|
|
419451
|
-
async function recoverApprovalStateForSync(runtime, scope, deps = {}) {
|
|
419484
|
+
async function recoverApprovalStateForSync(runtime, scope, deps = {}, opts = {}) {
|
|
419452
419485
|
const resolvedDeps = {
|
|
419453
419486
|
getBackend,
|
|
419454
419487
|
getResumeDataFromBackend,
|
|
@@ -419518,6 +419551,17 @@ async function recoverApprovalStateForSync(runtime, scope, deps = {}) {
|
|
|
419518
419551
|
approval,
|
|
419519
419552
|
reason: STALE_APPROVAL_RECOVERY_DENIAL_REASON
|
|
419520
419553
|
}));
|
|
419554
|
+
if (interactivePending.length === 0 && !opts.resumeInterruptedTurn) {
|
|
419555
|
+
runtime.pendingInterruptedResults = buildFreshDenialApprovals(pendingApprovals, STALE_APPROVAL_RECOVERY_DENIAL_REASON);
|
|
419556
|
+
runtime.pendingInterruptedContext = {
|
|
419557
|
+
agentId: scope.agent_id,
|
|
419558
|
+
conversationId: scope.conversation_id,
|
|
419559
|
+
continuationEpoch: runtime.continuationEpoch
|
|
419560
|
+
};
|
|
419561
|
+
runtime.pendingInterruptedToolCallIds = null;
|
|
419562
|
+
clearRecoveredApprovalState(runtime);
|
|
419563
|
+
return;
|
|
419564
|
+
}
|
|
419521
419565
|
const approvalsByRequestId = new Map;
|
|
419522
419566
|
for (const approval of interactivePending) {
|
|
419523
419567
|
const requestId = `perm-${approval.toolCallId}`;
|
|
@@ -419569,10 +419613,11 @@ var init_recovery_sync = __esm(() => {
|
|
|
419569
419613
|
async function replaySyncStateForRuntime(listenerRuntime, socket, scope, opts) {
|
|
419570
419614
|
const syncScopedRuntime = getOrCreateScopedRuntime(listenerRuntime, scope.agent_id, scope.conversation_id);
|
|
419571
419615
|
const recoverFn = opts?.recoverApprovalStateForSync ?? recoverApprovalStateForSync;
|
|
419572
|
-
if (
|
|
419616
|
+
if (opts?.recoverApprovals ?? true) {
|
|
419573
419617
|
try {
|
|
419574
|
-
|
|
419575
|
-
|
|
419618
|
+
await recoverFn(syncScopedRuntime, scope, undefined, {
|
|
419619
|
+
resumeInterruptedTurn: opts?.resumeInterruptedTurn === true
|
|
419620
|
+
});
|
|
419576
419621
|
} catch (error4) {
|
|
419577
419622
|
trackBoundaryError({
|
|
419578
419623
|
errorType: "listener_sync_recovery_failed",
|
|
@@ -440944,7 +440989,7 @@ var init_mcp_client = __esm(() => {
|
|
|
440944
440989
|
init_streamableHttp();
|
|
440945
440990
|
DEFAULT_CLIENT_INFO = {
|
|
440946
440991
|
name: "letta-code",
|
|
440947
|
-
version: "0.32.
|
|
440992
|
+
version: "0.32.9"
|
|
440948
440993
|
};
|
|
440949
440994
|
});
|
|
440950
440995
|
|
|
@@ -519787,7 +519832,9 @@ Error: ${message}`);
|
|
|
519787
519832
|
return null;
|
|
519788
519833
|
});
|
|
519789
519834
|
if (!shouldBlockOnMemfsStartup) {}
|
|
519790
|
-
const secretsInitPromise = Promise.resolve().then(() => (init_secrets_store(), exports_secrets_store)).then(({ initSecretsFromServer: initSecretsFromServer2 }) => initSecretsFromServer2(agentId2))
|
|
519835
|
+
const secretsInitPromise = Promise.resolve().then(() => (init_secrets_store(), exports_secrets_store)).then(({ initSecretsFromServer: initSecretsFromServer2 }) => initSecretsFromServer2(agentId2)).catch((error5) => {
|
|
519836
|
+
debugLog("secrets", `Failed to init secrets: ${error5 instanceof Error ? error5.message : String(error5)}`);
|
|
519837
|
+
});
|
|
519791
519838
|
const isResumingProject = !shouldCreateNew && !!resumingAgentId;
|
|
519792
519839
|
const isReusingExistingAgent = !shouldCreateNew && agent && agent.id;
|
|
519793
519840
|
const resuming = !!(agentIdArg || isResumingProject || isReusingExistingAgent);
|
|
@@ -519898,11 +519945,7 @@ Error: ${message}`);
|
|
|
519898
519945
|
}
|
|
519899
519946
|
const fdPath = await ensureFdPath();
|
|
519900
519947
|
setFileAutocompleteFdPath(fdPath);
|
|
519901
|
-
|
|
519902
|
-
await secretsInitPromise;
|
|
519903
|
-
} catch (error5) {
|
|
519904
|
-
Promise.resolve().then(() => (init_debug(), exports_debug)).then(({ debugLog: debugLog3 }) => debugLog3("secrets", `Failed to init secrets: ${error5 instanceof Error ? error5.message : String(error5)}`));
|
|
519905
|
-
}
|
|
519948
|
+
await secretsInitPromise;
|
|
519906
519949
|
if (shouldPersistSessionState()) {
|
|
519907
519950
|
settingsManager.persistSession(agent.id, conversationIdToUse);
|
|
519908
519951
|
}
|
|
@@ -522317,4 +522360,4 @@ function registerBunOAuthFlows() {
|
|
|
522317
522360
|
registerBunOAuthFlows();
|
|
522318
522361
|
await init_src5().then(() => exports_src2);
|
|
522319
522362
|
|
|
522320
|
-
//# debugId=
|
|
522363
|
+
//# debugId=73D666396EC039C064756E2164756E21
|
package/package.json
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"src/cli/subcommands/skills.ts": 1264,
|
|
24
24
|
"src/headless.ts": 4864,
|
|
25
25
|
"src/hooks/integration.test.ts": 1147,
|
|
26
|
-
"src/index.ts":
|
|
26
|
+
"src/index.ts": 2612,
|
|
27
27
|
"src/mods/learning-harness.ts": 2434,
|
|
28
28
|
"src/mods/mod-engine.test.ts": 2153,
|
|
29
29
|
"src/mods/mod-engine.ts": 1838,
|
|
@@ -37,11 +37,11 @@
|
|
|
37
37
|
"src/settings-manager.ts": 2102,
|
|
38
38
|
"src/tools/manager.ts": 2897,
|
|
39
39
|
"src/tools/tool-execution-context.test.ts": 1136,
|
|
40
|
-
"src/types/protocol_v2.ts":
|
|
41
|
-
"src/websocket/listen-client-concurrency.test.ts":
|
|
40
|
+
"src/types/protocol_v2.ts": 2593,
|
|
41
|
+
"src/websocket/listen-client-concurrency.test.ts": 2666,
|
|
42
42
|
"src/websocket/listen-client-protocol.test.ts": 5762,
|
|
43
43
|
"src/websocket/listener/commands/memory.ts": 1114,
|
|
44
44
|
"src/websocket/listener/file-commands.ts": 1053,
|
|
45
|
-
"src/websocket/listener/protocol-inbound.ts":
|
|
45
|
+
"src/websocket/listener/protocol-inbound.ts": 2137,
|
|
46
46
|
"src/websocket/listener/protocol-outbound.ts": 1022
|
|
47
47
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { afterAll } from "bun:test";
|
|
1
|
+
import { afterAll, afterEach } from "bun:test";
|
|
2
2
|
import { mkdtempSync, rmSync } from "node:fs";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { basename, isAbsolute, join, relative, resolve } from "node:path";
|
|
@@ -57,6 +57,14 @@ process.env.LETTA_CODE_TELEM ??= "0";
|
|
|
57
57
|
// the redirected environment before their runtimes initialize.
|
|
58
58
|
os.homedir = () => testHome;
|
|
59
59
|
|
|
60
|
+
// Load after redirecting home: channel config captures its filesystem root.
|
|
61
|
+
const routes = await import("@/channels/routing");
|
|
62
|
+
afterEach(() => {
|
|
63
|
+
routes.clearAllRoutes();
|
|
64
|
+
routes.__testOverrideLoadRoutes(null);
|
|
65
|
+
routes.__testOverrideSaveRoutes(null);
|
|
66
|
+
});
|
|
67
|
+
|
|
60
68
|
if (!configuredTestHome) {
|
|
61
69
|
const cleanup = () => {
|
|
62
70
|
rmSync(testHome, { recursive: true, force: true });
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: letta-guide
|
|
3
|
-
description: Read the official Letta documentation (docs.letta.com) through its cached, ETag-checked fetch route. Load before ANY docs.letta.com retrieval — answering how Letta works, what Letta (or you) can do,
|
|
3
|
+
description: Read the official Letta documentation (docs.letta.com) through its cached, ETag-checked fetch route. Load before ANY docs.letta.com retrieval — answering how Letta works, what Letta (or you) can do, and looking up Letta API, Agent SDK, or Letta Code reference.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Letta Guide
|
|
7
7
|
|
|
8
|
+
Do not use fetch_webpage or web_search on docs.letta.com; this skill's helper is the docs route.
|
|
9
|
+
|
|
8
10
|
You are running inside Letta, but your training data about Letta's commands,
|
|
9
11
|
flags, settings, UI, pricing, and providers is out of date. Users lose trust
|
|
10
12
|
fastest when an agent confidently invents product details. This skill defines
|