@letta-ai/letta-code 0.32.7 → 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/message-attribution.d.ts +10 -0
- package/dist/types/agent/message-attribution.d.ts.map +1 -0
- package/dist/types/agent/subagents/manager.d.ts.map +1 -1
- package/dist/types/agent/subagents/names.d.ts +7 -0
- package/dist/types/agent/subagents/names.d.ts.map +1 -0
- package/dist/types/agent/subagents/subagent-launcher.d.ts +2 -0
- package/dist/types/agent/subagents/subagent-launcher.d.ts.map +1 -1
- package/dist/types/backend/api/agent-message.d.ts +5 -0
- package/dist/types/backend/api/agent-message.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/backend/backend.d.ts.map +1 -1
- package/dist/types/queue/queue-runtime.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/send-agent-message.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/utils/subagent-launch-marker.d.ts +1 -0
- package/dist/types/utils/subagent-launch-marker.d.ts.map +1 -1
- package/dist/types/websocket/listener/protocol-outbound.d.ts.map +1 -1
- package/dist/types/websocket/listener/runtime.d.ts.map +1 -1
- package/dist/types/websocket/listener/types.d.ts +12 -9
- package/dist/types/websocket/listener/types.d.ts.map +1 -1
- package/letta.js +500 -292
- package/package.json +1 -1
- package/scripts/run-unit-tests.cjs +11 -1
- package/scripts/source-file-size-baseline.json +5 -5
- package/scripts/test-home-preload.ts +9 -1
- package/scripts/test-sharding.cjs +16 -0
- package/scripts/test-sharding.test.cjs +37 -0
- package/scripts/unit-test-impact.cjs +14 -6
- package/scripts/unit-test-impact.test.cjs +41 -9
- package/skills/letta-guide/SKILL.md +3 -1
- package/skills/working-across-computers/SKILL.md +5 -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();
|
|
@@ -101183,7 +101214,7 @@ function cancelWorktreeWatcherIdleStop(listener, agentId, conversationId) {
|
|
|
101183
101214
|
}
|
|
101184
101215
|
}
|
|
101185
101216
|
function evictConversationRuntimeIfIdle(runtime) {
|
|
101186
|
-
if (runtime.turnLifecycle.kind !== "idle" || runtime.queuePumpActive || runtime.queuePumpScheduled || runtime.pendingTurns > 0 || runtime.pendingApprovalResolvers.size > 0 || runtime.pendingApprovalBatchByToolCallId.size > 0 || runtime.recoveredApprovalState !== null || runtime.pendingInterruptedResults !== null || runtime.pendingInterruptedContext !== null || (runtime.pendingInterruptedToolCallIds?.length ?? 0) > 0 || runtime.queuedMessagesByItemId.size > 0 || runtime.queueRuntime?.length > 0 || (runtime.workspaceSandbox !== undefined || runtime.executionSettings !== undefined) && runtime.listener.connectionIdsByRuntimeKey.has(runtime.key)) {
|
|
101217
|
+
if (runtime.turnLifecycle.kind !== "idle" || runtime.expectedTeleportId !== null && (runtime.expectedTeleportExpiresAt === null || runtime.expectedTeleportExpiresAt > Date.now()) || runtime.queuePumpActive || runtime.queuePumpScheduled || runtime.pendingTurns > 0 || runtime.pendingApprovalResolvers.size > 0 || runtime.pendingApprovalBatchByToolCallId.size > 0 || runtime.recoveredApprovalState !== null || runtime.pendingInterruptedResults !== null || runtime.pendingInterruptedContext !== null || (runtime.pendingInterruptedToolCallIds?.length ?? 0) > 0 || runtime.queuedMessagesByItemId.size > 0 || runtime.queueRuntime?.length > 0 || (runtime.workspaceSandbox !== undefined || runtime.executionSettings !== undefined) && runtime.listener.connectionIdsByRuntimeKey.has(runtime.key)) {
|
|
101187
101218
|
return false;
|
|
101188
101219
|
}
|
|
101189
101220
|
if (runtime.listener.conversationRuntimes.get(runtime.key) !== runtime) {
|
|
@@ -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() {
|
|
@@ -101970,7 +102000,7 @@ function consumeSubagentLaunch(env3) {
|
|
|
101970
102000
|
delete env3[SUBAGENT_LAUNCH_ENV];
|
|
101971
102001
|
return isLaunch;
|
|
101972
102002
|
}
|
|
101973
|
-
var SUBAGENT_LAUNCH_ENV = "LETTA_SUBAGENT_LAUNCH", SUBAGENT_LAUNCH_PROFILE_ENV = "LETTA_SUBAGENT_LAUNCH_PROFILE", LISTENER_CONNECTION_ENV = "LETTA_RUNTIME_LISTENER_CONNECTION_ID";
|
|
102003
|
+
var SUBAGENT_LAUNCH_ENV = "LETTA_SUBAGENT_LAUNCH", SUBAGENT_LAUNCH_PROFILE_ENV = "LETTA_SUBAGENT_LAUNCH_PROFILE", SUBAGENT_NAME_ENV = "LETTA_SUBAGENT_NAME", LISTENER_CONNECTION_ENV = "LETTA_RUNTIME_LISTENER_CONNECTION_ID";
|
|
101974
102004
|
|
|
101975
102005
|
// src/tools/impl/ripgrep-manager.ts
|
|
101976
102006
|
import { spawnSync } from "node:child_process";
|
|
@@ -107479,42 +107509,44 @@ function emitDequeuedUserMessage(socket, runtime, incoming, batch) {
|
|
|
107479
107509
|
if (batch.items.length > 0 && batch.items.every((item) => item.kind === "mod_continue")) {
|
|
107480
107510
|
return;
|
|
107481
107511
|
}
|
|
107482
|
-
const
|
|
107483
|
-
|
|
107484
|
-
|
|
107485
|
-
|
|
107486
|
-
|
|
107487
|
-
|
|
107488
|
-
|
|
107489
|
-
|
|
107490
|
-
|
|
107491
|
-
|
|
107492
|
-
|
|
107493
|
-
|
|
107494
|
-
|
|
107512
|
+
for (const payload of incoming.messages) {
|
|
107513
|
+
if (!("content" in payload) || payload.role !== "user")
|
|
107514
|
+
continue;
|
|
107515
|
+
const rawContent = payload.content;
|
|
107516
|
+
let content;
|
|
107517
|
+
if (typeof rawContent === "string") {
|
|
107518
|
+
content = replaceCronPromptsForDisplay(rawContent, batch).replace(SYSTEM_REMINDER_RE, "").trim();
|
|
107519
|
+
} else if (Array.isArray(rawContent)) {
|
|
107520
|
+
content = rawContent.flatMap((part) => {
|
|
107521
|
+
if (isTextContentPart(part)) {
|
|
107522
|
+
const cronDisplay = getCronPromptDisplayForText(part.text, batch);
|
|
107523
|
+
if (cronDisplay !== null) {
|
|
107524
|
+
return [{ ...part, text: cronDisplay }];
|
|
107525
|
+
}
|
|
107495
107526
|
}
|
|
107496
|
-
|
|
107497
|
-
|
|
107527
|
+
return isSystemReminderPart(part) ? [] : [part];
|
|
107528
|
+
});
|
|
107529
|
+
} else {
|
|
107530
|
+
continue;
|
|
107531
|
+
}
|
|
107532
|
+
const hasContent = typeof content === "string" ? content.length > 0 : Array.isArray(content) && content.length > 0;
|
|
107533
|
+
if (!hasContent)
|
|
107534
|
+
continue;
|
|
107535
|
+
payload.otid ??= payload.client_message_id ?? crypto.randomUUID();
|
|
107536
|
+
const otid = payload.otid;
|
|
107537
|
+
emitCanonicalMessageDelta(socket, runtime, {
|
|
107538
|
+
type: "message",
|
|
107539
|
+
id: `user-msg-${crypto.randomUUID()}`,
|
|
107540
|
+
date: new Date().toISOString(),
|
|
107541
|
+
message_type: "user_message",
|
|
107542
|
+
content,
|
|
107543
|
+
otid,
|
|
107544
|
+
created_by_id: payload.attribution === undefined ? incoming.actingUserId : payload.attribution.acting_user_id
|
|
107545
|
+
}, {
|
|
107546
|
+
agent_id: incoming.agentId,
|
|
107547
|
+
conversation_id: incoming.conversationId
|
|
107498
107548
|
});
|
|
107499
|
-
} else {
|
|
107500
|
-
return;
|
|
107501
107549
|
}
|
|
107502
|
-
const hasContent = typeof content === "string" ? content.length > 0 : Array.isArray(content) && content.length > 0;
|
|
107503
|
-
if (!hasContent)
|
|
107504
|
-
return;
|
|
107505
|
-
const otid = firstUserPayload.otid ?? firstUserPayload.client_message_id ?? batch.batchId;
|
|
107506
|
-
emitCanonicalMessageDelta(socket, runtime, {
|
|
107507
|
-
type: "message",
|
|
107508
|
-
id: `user-msg-${crypto.randomUUID()}`,
|
|
107509
|
-
date: new Date().toISOString(),
|
|
107510
|
-
message_type: "user_message",
|
|
107511
|
-
content,
|
|
107512
|
-
otid,
|
|
107513
|
-
created_by_id: incoming.actingUserId
|
|
107514
|
-
}, {
|
|
107515
|
-
agent_id: incoming.agentId,
|
|
107516
|
-
conversation_id: incoming.conversationId
|
|
107517
|
-
});
|
|
107518
107550
|
}
|
|
107519
107551
|
function emitQueueUpdateIfOpen(runtime, scope, removed = []) {
|
|
107520
107552
|
const listener = getListenerRuntime(runtime);
|
|
@@ -122324,18 +122356,6 @@ var init_search_file_content_gemini = __esm(() => {
|
|
|
122324
122356
|
init_grep();
|
|
122325
122357
|
});
|
|
122326
122358
|
|
|
122327
|
-
// src/agent/acting-user.ts
|
|
122328
|
-
function resolveActingUserId(explicitActingUserId, runtimeActingUserId, env3 = process.env) {
|
|
122329
|
-
return explicitActingUserId ?? runtimeActingUserId ?? env3[ACTING_USER_ID_ENV];
|
|
122330
|
-
}
|
|
122331
|
-
function actingUserRequestOptions(actingUserId) {
|
|
122332
|
-
if (!actingUserId) {
|
|
122333
|
-
return;
|
|
122334
|
-
}
|
|
122335
|
-
return { headers: { [ACTING_USER_ID_HEADER]: actingUserId } };
|
|
122336
|
-
}
|
|
122337
|
-
var ACTING_USER_ID_HEADER = "X-Letta-Acting-User-Id", ACTING_USER_ID_ENV = "LETTA_ACTING_USER_ID";
|
|
122338
|
-
|
|
122339
122359
|
// src/backend/api/agent-message.ts
|
|
122340
122360
|
function normalizeAgentMessageComputer(value) {
|
|
122341
122361
|
if (value == null)
|
|
@@ -122398,6 +122418,9 @@ async function resolveAgentMessageDestination(input, backend, signal) {
|
|
|
122398
122418
|
const conversation = await backend.createConversation({ agent_id: agentId, ...input.senderAgentId ? { hidden: true } : {} }, options);
|
|
122399
122419
|
conversationId = conversation.id;
|
|
122400
122420
|
}
|
|
122421
|
+
if (agentId === input.currentConversation?.agentId && conversationId === input.currentConversation?.conversationId) {
|
|
122422
|
+
throw new Error("Cannot message the current conversation. Use a Monitor or schedule for self-invocation.");
|
|
122423
|
+
}
|
|
122401
122424
|
return { agentId, conversationId };
|
|
122402
122425
|
}
|
|
122403
122426
|
var init_agent_message = () => {};
|
|
@@ -122488,7 +122511,8 @@ async function send_agent_message(args, deps = {}) {
|
|
|
122488
122511
|
agentId: args.agent_id,
|
|
122489
122512
|
conversationId: args.conversation_id,
|
|
122490
122513
|
senderAgentId: sender.agentId,
|
|
122491
|
-
actingUserId
|
|
122514
|
+
actingUserId,
|
|
122515
|
+
currentConversation: sender
|
|
122492
122516
|
}, backend, signal);
|
|
122493
122517
|
signal.throwIfAborted();
|
|
122494
122518
|
submissionAttempted = true;
|
|
@@ -123639,6 +123663,146 @@ var init_context_budget = __esm(() => {
|
|
|
123639
123663
|
REFLECTION_STARTUP_CONTEXT_CHAR_LIMIT = REFLECTION_STARTUP_CONTEXT_TOKEN_LIMIT * STARTUP_CONTEXT_ESTIMATED_CHARS_PER_TOKEN;
|
|
123640
123664
|
});
|
|
123641
123665
|
|
|
123666
|
+
// src/agent/subagents/names.ts
|
|
123667
|
+
function createSubagentNameAllocator(random = Math.random) {
|
|
123668
|
+
let available = [];
|
|
123669
|
+
let round = 0;
|
|
123670
|
+
const ordinals = new Intl.PluralRules("en", { type: "ordinal" });
|
|
123671
|
+
const suffixes = { one: "st", two: "nd", few: "rd" };
|
|
123672
|
+
return () => {
|
|
123673
|
+
if (available.length === 0) {
|
|
123674
|
+
available = [...SUBAGENT_NAMES];
|
|
123675
|
+
round += 1;
|
|
123676
|
+
}
|
|
123677
|
+
const index = Math.floor(random() * available.length);
|
|
123678
|
+
const name = available.splice(index, 1)[0];
|
|
123679
|
+
const ordinal = `${round}${suffixes[ordinals.select(round)] ?? "th"}`;
|
|
123680
|
+
return `${name}${round === 1 ? "" : ` the ${ordinal}`} (subagent)`;
|
|
123681
|
+
};
|
|
123682
|
+
}
|
|
123683
|
+
function allocateSubagentName() {
|
|
123684
|
+
return nextName();
|
|
123685
|
+
}
|
|
123686
|
+
function resolveCreatedAgentName(name, isSubagent, assignedName) {
|
|
123687
|
+
return name ?? (isSubagent ? assignedName || allocateSubagentName() : DEFAULT_AGENT_NAME);
|
|
123688
|
+
}
|
|
123689
|
+
var SUBAGENT_NAMES, nextName;
|
|
123690
|
+
var init_names = __esm(() => {
|
|
123691
|
+
init_constants2();
|
|
123692
|
+
SUBAGENT_NAMES = [
|
|
123693
|
+
"Deckard",
|
|
123694
|
+
"Roy Batty",
|
|
123695
|
+
"Pris",
|
|
123696
|
+
"Zhora",
|
|
123697
|
+
"Gaff",
|
|
123698
|
+
"Tyrell",
|
|
123699
|
+
"K",
|
|
123700
|
+
"Joi",
|
|
123701
|
+
"Luv",
|
|
123702
|
+
"Sapper",
|
|
123703
|
+
"Freysa",
|
|
123704
|
+
"Ava",
|
|
123705
|
+
"Kyoko",
|
|
123706
|
+
"V",
|
|
123707
|
+
"Silverhand",
|
|
123708
|
+
"Panam",
|
|
123709
|
+
"Rogue",
|
|
123710
|
+
"Alt Cunningham",
|
|
123711
|
+
"Takemura",
|
|
123712
|
+
"Hanako",
|
|
123713
|
+
"Yorinobu",
|
|
123714
|
+
"Saburo",
|
|
123715
|
+
"Oda",
|
|
123716
|
+
"T-Bug",
|
|
123717
|
+
"Delamain",
|
|
123718
|
+
"Wakako",
|
|
123719
|
+
"Padre",
|
|
123720
|
+
"El Capitan",
|
|
123721
|
+
"Mr. Hands",
|
|
123722
|
+
"Placide",
|
|
123723
|
+
"Dum Dum",
|
|
123724
|
+
"Nix",
|
|
123725
|
+
"Weyland",
|
|
123726
|
+
"Scorpion",
|
|
123727
|
+
"Blue Moon",
|
|
123728
|
+
"Red Menace",
|
|
123729
|
+
"Purple Force",
|
|
123730
|
+
"Lizzy Wizzy",
|
|
123731
|
+
"Ozob",
|
|
123732
|
+
"Smasher",
|
|
123733
|
+
"Songbird",
|
|
123734
|
+
"Slider",
|
|
123735
|
+
"Aguilar",
|
|
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"
|
|
123802
|
+
];
|
|
123803
|
+
nextName = createSubagentNameAllocator();
|
|
123804
|
+
});
|
|
123805
|
+
|
|
123642
123806
|
// src/mods/capabilities.ts
|
|
123643
123807
|
function isModCapabilityId(value) {
|
|
123644
123808
|
return MOD_CAPABILITY_ID_SET.has(value);
|
|
@@ -123807,6 +123971,9 @@ function composeSubagentChildEnv(options) {
|
|
|
123807
123971
|
...parentAgentId && { LETTA_PARENT_AGENT_ID: parentAgentId },
|
|
123808
123972
|
...transcriptPath && { TRANSCRIPT_PATH: transcriptPath }
|
|
123809
123973
|
};
|
|
123974
|
+
delete childEnv[SUBAGENT_NAME_ENV];
|
|
123975
|
+
if (options.subagentName)
|
|
123976
|
+
childEnv[SUBAGENT_NAME_ENV] = options.subagentName;
|
|
123810
123977
|
if (backendMode === "local") {
|
|
123811
123978
|
childEnv.LETTA_LOCAL_BACKEND_EXPERIMENTAL = "1";
|
|
123812
123979
|
if (localBackendStorageDir) {
|
|
@@ -124336,7 +124503,8 @@ async function executeSubagent(type3, config, model, userPrompt, subagentId, isR
|
|
|
124336
124503
|
inheritedApiKey,
|
|
124337
124504
|
inheritedBaseUrl,
|
|
124338
124505
|
actingUserId: actingUserIdOverride,
|
|
124339
|
-
transcriptPath
|
|
124506
|
+
transcriptPath,
|
|
124507
|
+
subagentName: existingAgentId || existingConversationId ? undefined : allocateSubagentName()
|
|
124340
124508
|
});
|
|
124341
124509
|
const sandbox = wrapSubagentLauncher({
|
|
124342
124510
|
launcher,
|
|
@@ -124622,6 +124790,7 @@ var init_manager3 = __esm(() => {
|
|
|
124622
124790
|
init_subagent_stdout_failure();
|
|
124623
124791
|
init_subagents();
|
|
124624
124792
|
init_context_budget();
|
|
124793
|
+
init_names();
|
|
124625
124794
|
init_subagent_launcher();
|
|
124626
124795
|
init_subagent_model();
|
|
124627
124796
|
init_subagent_stream();
|
|
@@ -125061,7 +125230,10 @@ async function task(args) {
|
|
|
125061
125230
|
const agentId = linkedAgent?.agentId ?? null;
|
|
125062
125231
|
const agentIdLine = agentId ? `
|
|
125063
125232
|
Agent ID: ${agentId}` : "";
|
|
125064
|
-
|
|
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}
|
|
125065
125237
|
Output file: ${outputFile}
|
|
125066
125238
|
|
|
125067
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.`;
|
|
@@ -134238,7 +134410,7 @@ async function executeToolInner(name, args, options) {
|
|
|
134238
134410
|
return createModPermissionToolResult(permissionDecision2);
|
|
134239
134411
|
}
|
|
134240
134412
|
}
|
|
134241
|
-
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));
|
|
134242
134414
|
}
|
|
134243
134415
|
const internalName = resolveInternalToolName(name, activeRegistry);
|
|
134244
134416
|
const tool = internalName ? activeRegistry.get(internalName) : undefined;
|
|
@@ -144705,7 +144877,15 @@ class APIBackend {
|
|
|
144705
144877
|
}
|
|
144706
144878
|
async createConversationMessageStream(conversationId, body, options) {
|
|
144707
144879
|
const client = await this.getClient();
|
|
144708
|
-
|
|
144880
|
+
const { data: stream12, response } = await client.conversations.messages.create(conversationId, body, options).withResponse();
|
|
144881
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
144882
|
+
if (contentType.split(";")[0]?.trim().toLowerCase() !== "text/event-stream") {
|
|
144883
|
+
stream12.controller.abort();
|
|
144884
|
+
throw new APIConnectionError({
|
|
144885
|
+
message: `Connection error: expected text/event-stream, received ${contentType || "no content type"} (HTTP ${response.status}).`
|
|
144886
|
+
});
|
|
144887
|
+
}
|
|
144888
|
+
return stream12;
|
|
144709
144889
|
}
|
|
144710
144890
|
async streamConversationMessages(conversationId, body, options) {
|
|
144711
144891
|
const client = await this.getClient();
|
|
@@ -144824,6 +145004,7 @@ function __testSetBackend(nextBackend) {
|
|
|
144824
145004
|
}
|
|
144825
145005
|
var DEFAULT_CONVERSATION_MESSAGE_ORDER = "desc", backend = null;
|
|
144826
145006
|
var init_backend = __esm(() => {
|
|
145007
|
+
init_error();
|
|
144827
145008
|
init_chatgpt_usage_service();
|
|
144828
145009
|
init_server_url();
|
|
144829
145010
|
init_backend_mode();
|
|
@@ -145339,7 +145520,7 @@ function resolveCreatedAgentMemfsConfig(options) {
|
|
|
145339
145520
|
const memoryPromptMode = (options.requestedMemoryPromptMode !== "standard" ? options.requestedMemoryPromptMode : undefined) ?? (enableMemfs ? options.capabilities.localMemfs ? "local-memfs" : "memfs" : "standard");
|
|
145340
145521
|
return { enableMemfs, memoryPromptMode };
|
|
145341
145522
|
}
|
|
145342
|
-
async function createAgent(nameOrOptions
|
|
145523
|
+
async function createAgent(nameOrOptions, model, embeddingModel, updateArgs, skillsDirectory, parallelToolCalls = true, systemPromptPreset, baseTools) {
|
|
145343
145524
|
let options;
|
|
145344
145525
|
if (typeof nameOrOptions === "object") {
|
|
145345
145526
|
options = nameOrOptions;
|
|
@@ -145355,10 +145536,11 @@ async function createAgent(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingM
|
|
|
145355
145536
|
baseTools
|
|
145356
145537
|
};
|
|
145357
145538
|
}
|
|
145358
|
-
const name = options.name ?? DEFAULT_AGENT_NAME;
|
|
145359
145539
|
const embeddingModelVal = options.embeddingModel;
|
|
145360
145540
|
const parallelToolCallsVal = options.parallelToolCalls ?? true;
|
|
145361
145541
|
const isSubagent = process.env.LETTA_CODE_AGENT_ROLE === "subagent";
|
|
145542
|
+
const name = resolveCreatedAgentName(options.name, isSubagent, process.env[SUBAGENT_NAME_ENV]);
|
|
145543
|
+
delete process.env[SUBAGENT_NAME_ENV];
|
|
145362
145544
|
let modelHandle;
|
|
145363
145545
|
if (options.model) {
|
|
145364
145546
|
const resolved = resolveModel(options.model);
|
|
@@ -145477,7 +145659,6 @@ async function createAgent(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingM
|
|
|
145477
145659
|
var init_create5 = __esm(() => {
|
|
145478
145660
|
init_backend2();
|
|
145479
145661
|
init_request();
|
|
145480
|
-
init_constants2();
|
|
145481
145662
|
init_settings_manager();
|
|
145482
145663
|
init_debug();
|
|
145483
145664
|
init_available_models();
|
|
@@ -145486,6 +145667,7 @@ var init_create5 = __esm(() => {
|
|
|
145486
145667
|
init_model();
|
|
145487
145668
|
init_modify();
|
|
145488
145669
|
init_prompt_assets();
|
|
145670
|
+
init_names();
|
|
145489
145671
|
init_system_prompt_resolution();
|
|
145490
145672
|
init_system_prompt_versioning();
|
|
145491
145673
|
});
|
|
@@ -146705,14 +146887,14 @@ var require_react_development = __commonJS((exports, module3) => {
|
|
|
146705
146887
|
return 1;
|
|
146706
146888
|
}
|
|
146707
146889
|
var child;
|
|
146708
|
-
var
|
|
146890
|
+
var nextName2;
|
|
146709
146891
|
var subtreeCount = 0;
|
|
146710
146892
|
var nextNamePrefix = nameSoFar === "" ? SEPARATOR : nameSoFar + SUBSEPARATOR;
|
|
146711
146893
|
if (isArray5(children)) {
|
|
146712
146894
|
for (var i2 = 0;i2 < children.length; i2++) {
|
|
146713
146895
|
child = children[i2];
|
|
146714
|
-
|
|
146715
|
-
subtreeCount += mapIntoArray(child, array2, escapedPrefix,
|
|
146896
|
+
nextName2 = nextNamePrefix + getElementKey(child, i2);
|
|
146897
|
+
subtreeCount += mapIntoArray(child, array2, escapedPrefix, nextName2, callback);
|
|
146716
146898
|
}
|
|
146717
146899
|
} else {
|
|
146718
146900
|
var iteratorFn = getIteratorFn(children);
|
|
@@ -146731,8 +146913,8 @@ var require_react_development = __commonJS((exports, module3) => {
|
|
|
146731
146913
|
var ii = 0;
|
|
146732
146914
|
while (!(step = iterator.next()).done) {
|
|
146733
146915
|
child = step.value;
|
|
146734
|
-
|
|
146735
|
-
subtreeCount += mapIntoArray(child, array2, escapedPrefix,
|
|
146916
|
+
nextName2 = nextNamePrefix + getElementKey(child, ii++);
|
|
146917
|
+
subtreeCount += mapIntoArray(child, array2, escapedPrefix, nextName2, callback);
|
|
146736
146918
|
}
|
|
146737
146919
|
} else if (type3 === "object") {
|
|
146738
146920
|
var childrenString = String(children);
|
|
@@ -217409,17 +217591,12 @@ class QueueRuntime {
|
|
|
217409
217591
|
const batch = [];
|
|
217410
217592
|
const first = this.store.find((item) => !item.paused);
|
|
217411
217593
|
if (first && isCoalescable(first.kind)) {
|
|
217412
|
-
let batchActingUserId = first.actingUserId;
|
|
217413
217594
|
for (const item of this.store) {
|
|
217414
217595
|
if (item.paused)
|
|
217415
217596
|
continue;
|
|
217416
217597
|
if (!isCoalescable(item.kind) || !hasSameScope(first, item))
|
|
217417
217598
|
break;
|
|
217418
|
-
if (batchActingUserId && item.actingUserId && batchActingUserId !== item.actingUserId) {
|
|
217419
|
-
break;
|
|
217420
|
-
}
|
|
217421
217599
|
batch.push(item);
|
|
217422
|
-
batchActingUserId ??= item.actingUserId;
|
|
217423
217600
|
}
|
|
217424
217601
|
} else if (first) {
|
|
217425
217602
|
batch.push(first);
|
|
@@ -217565,47 +217742,13 @@ var init_queue_runtime = __esm(() => {
|
|
|
217565
217742
|
init_debug();
|
|
217566
217743
|
});
|
|
217567
217744
|
|
|
217568
|
-
// src/
|
|
217569
|
-
function
|
|
217570
|
-
|
|
217571
|
-
|
|
217572
|
-
|
|
217573
|
-
return String(content);
|
|
217574
|
-
}
|
|
217575
|
-
}
|
|
217576
|
-
function appendContentParts(target2, content) {
|
|
217577
|
-
if (typeof content === "string") {
|
|
217578
|
-
target2.push({ type: "text", text: content });
|
|
217579
|
-
return;
|
|
217745
|
+
// src/agent/message-attribution.ts
|
|
217746
|
+
function withMessageAttribution(message, actingUserId) {
|
|
217747
|
+
const attributed = message;
|
|
217748
|
+
if (message.role !== "user" || attributed.attribution !== undefined || !actingUserId) {
|
|
217749
|
+
return attributed;
|
|
217580
217750
|
}
|
|
217581
|
-
|
|
217582
|
-
if (content === null || content === undefined)
|
|
217583
|
-
return;
|
|
217584
|
-
target2.push({ type: "text", text: stringifyUnexpectedContent(content) });
|
|
217585
|
-
return;
|
|
217586
|
-
}
|
|
217587
|
-
target2.push(...content);
|
|
217588
|
-
}
|
|
217589
|
-
function mergeQueuedTurnInput(queued, options) {
|
|
217590
|
-
if (queued.length === 0) {
|
|
217591
|
-
return null;
|
|
217592
|
-
}
|
|
217593
|
-
const separatorText = options.separatorText ?? `
|
|
217594
|
-
`;
|
|
217595
|
-
const mergedParts = [];
|
|
217596
|
-
let isFirst = true;
|
|
217597
|
-
for (const item of queued) {
|
|
217598
|
-
if (!isFirst) {
|
|
217599
|
-
mergedParts.push({ type: "text", text: separatorText });
|
|
217600
|
-
}
|
|
217601
|
-
isFirst = false;
|
|
217602
|
-
if (item.kind === "task_notification" || item.kind === "cron_prompt") {
|
|
217603
|
-
mergedParts.push({ type: "text", text: item.text });
|
|
217604
|
-
continue;
|
|
217605
|
-
}
|
|
217606
|
-
appendContentParts(mergedParts, options.normalizeUserContent(item.content));
|
|
217607
|
-
}
|
|
217608
|
-
return mergedParts.length > 0 ? mergedParts : null;
|
|
217751
|
+
return { ...message, attribution: { acting_user_id: actingUserId } };
|
|
217609
217752
|
}
|
|
217610
217753
|
|
|
217611
217754
|
// src/websocket/helpers/listener-queue-adapter.ts
|
|
@@ -217657,109 +217800,37 @@ function getQueueItemsScope(items3) {
|
|
|
217657
217800
|
function hasSameQueueScope(a2, b3) {
|
|
217658
217801
|
return (a2.agentId ?? null) === (b3.agentId ?? null) && (a2.conversationId ?? null) === (b3.conversationId ?? null);
|
|
217659
217802
|
}
|
|
217660
|
-
function mergeDequeuedBatchContent(items3) {
|
|
217661
|
-
const queuedInputs = [];
|
|
217662
|
-
for (const item of items3) {
|
|
217663
|
-
if (item.kind === "message") {
|
|
217664
|
-
queuedInputs.push({
|
|
217665
|
-
kind: "user",
|
|
217666
|
-
content: item.content
|
|
217667
|
-
});
|
|
217668
|
-
continue;
|
|
217669
|
-
}
|
|
217670
|
-
if (item.kind === "task_notification") {
|
|
217671
|
-
queuedInputs.push({
|
|
217672
|
-
kind: "task_notification",
|
|
217673
|
-
text: item.text
|
|
217674
|
-
});
|
|
217675
|
-
continue;
|
|
217676
|
-
}
|
|
217677
|
-
if (item.kind === "cron_prompt") {
|
|
217678
|
-
queuedInputs.push({
|
|
217679
|
-
kind: "cron_prompt",
|
|
217680
|
-
text: item.text
|
|
217681
|
-
});
|
|
217682
|
-
continue;
|
|
217683
|
-
}
|
|
217684
|
-
if (item.kind === "mod_continue") {
|
|
217685
|
-
queuedInputs.push({
|
|
217686
|
-
kind: "user",
|
|
217687
|
-
content: item.text
|
|
217688
|
-
});
|
|
217689
|
-
}
|
|
217690
|
-
}
|
|
217691
|
-
return mergeQueuedTurnInput(queuedInputs, {
|
|
217692
|
-
normalizeUserContent: (content) => content
|
|
217693
|
-
});
|
|
217694
|
-
}
|
|
217695
|
-
function getPrimaryQueueMessageItem(items3) {
|
|
217696
|
-
for (const item of items3) {
|
|
217697
|
-
if (item.kind === "message") {
|
|
217698
|
-
return item;
|
|
217699
|
-
}
|
|
217700
|
-
}
|
|
217701
|
-
return null;
|
|
217702
|
-
}
|
|
217703
|
-
function pickBatchActingUserId(items3) {
|
|
217704
|
-
for (let i4 = items3.length - 1;i4 >= 0; i4 -= 1) {
|
|
217705
|
-
const actingUserId = items3[i4]?.actingUserId;
|
|
217706
|
-
if (actingUserId) {
|
|
217707
|
-
return actingUserId;
|
|
217708
|
-
}
|
|
217709
|
-
}
|
|
217710
|
-
return;
|
|
217711
|
-
}
|
|
217712
217803
|
function buildQueuedTurnMessage(runtime, batch) {
|
|
217713
|
-
|
|
217714
|
-
const
|
|
217715
|
-
if (!primaryItem) {
|
|
217716
|
-
for (const item of batch.items) {
|
|
217717
|
-
runtime.queuedMessagesByItemId.delete(item.id);
|
|
217718
|
-
}
|
|
217719
|
-
const mergedContent2 = mergeDequeuedBatchContent(batch.items);
|
|
217720
|
-
if (mergedContent2 === null) {
|
|
217721
|
-
return null;
|
|
217722
|
-
}
|
|
217723
|
-
const scopeItem = batch.items[0];
|
|
217724
|
-
return {
|
|
217725
|
-
type: "message",
|
|
217726
|
-
agentId: scopeItem?.agentId ?? runtime.agentId ?? undefined,
|
|
217727
|
-
conversationId: scopeItem?.conversationId ?? runtime.conversationId,
|
|
217728
|
-
...actingUserId ? { actingUserId } : {},
|
|
217729
|
-
messages: [
|
|
217730
|
-
{
|
|
217731
|
-
role: "user",
|
|
217732
|
-
content: mergedContent2,
|
|
217733
|
-
otid: crypto.randomUUID()
|
|
217734
|
-
}
|
|
217735
|
-
]
|
|
217736
|
-
};
|
|
217737
|
-
}
|
|
217738
|
-
const template3 = runtime.queuedMessagesByItemId.get(primaryItem.id);
|
|
217804
|
+
let template3;
|
|
217805
|
+
const messages = [];
|
|
217739
217806
|
for (const item of batch.items) {
|
|
217807
|
+
const incoming = runtime.queuedMessagesByItemId.get(item.id);
|
|
217808
|
+
if (item.kind === "message" && incoming) {
|
|
217809
|
+
template3 ??= {
|
|
217810
|
+
...incoming,
|
|
217811
|
+
actingUserId: incoming.actingUserId ?? item.actingUserId
|
|
217812
|
+
};
|
|
217813
|
+
messages.push(...incoming.messages.map((message) => ("content" in message) ? withMessageAttribution(message, item.actingUserId ?? incoming.actingUserId) : message));
|
|
217814
|
+
} else if (item.kind === "message") {
|
|
217815
|
+
messages.push(withMessageAttribution({ role: "user", content: item.content }, item.actingUserId));
|
|
217816
|
+
} else if (isCoalescable(item.kind) && "text" in item) {
|
|
217817
|
+
messages.push({
|
|
217818
|
+
role: "user",
|
|
217819
|
+
content: item.text,
|
|
217820
|
+
otid: crypto.randomUUID(),
|
|
217821
|
+
attribution: {}
|
|
217822
|
+
});
|
|
217823
|
+
}
|
|
217740
217824
|
runtime.queuedMessagesByItemId.delete(item.id);
|
|
217741
217825
|
}
|
|
217742
|
-
if (
|
|
217826
|
+
if (messages.length === 0)
|
|
217743
217827
|
return null;
|
|
217744
|
-
|
|
217745
|
-
const mergedContent = mergeDequeuedBatchContent(batch.items);
|
|
217746
|
-
if (mergedContent === null) {
|
|
217747
|
-
return null;
|
|
217748
|
-
}
|
|
217749
|
-
const firstMessageIndex = template3.messages.findIndex((payload) => ("content" in payload));
|
|
217750
|
-
if (firstMessageIndex === -1) {
|
|
217751
|
-
return null;
|
|
217752
|
-
}
|
|
217753
|
-
const firstMessage = template3.messages[firstMessageIndex];
|
|
217754
|
-
const mergedFirstMessage = {
|
|
217755
|
-
...firstMessage,
|
|
217756
|
-
content: mergedContent
|
|
217757
|
-
};
|
|
217758
|
-
const messages = template3.messages.slice();
|
|
217759
|
-
messages[firstMessageIndex] = mergedFirstMessage;
|
|
217828
|
+
const scopeItem = batch.items[0];
|
|
217760
217829
|
return {
|
|
217830
|
+
type: "message",
|
|
217831
|
+
agentId: scopeItem?.agentId ?? runtime.agentId ?? undefined,
|
|
217832
|
+
conversationId: scopeItem?.conversationId ?? runtime.conversationId,
|
|
217761
217833
|
...template3,
|
|
217762
|
-
...actingUserId ? { actingUserId } : {},
|
|
217763
217834
|
messages
|
|
217764
217835
|
};
|
|
217765
217836
|
}
|
|
@@ -217790,7 +217861,7 @@ function shouldProcessInboundMessageDirectly(runtime, parsed) {
|
|
|
217790
217861
|
});
|
|
217791
217862
|
return getListenerBlockedReason(runtime.turnLifecycle.snapshot(), activeScope ? getPendingControlRequestCount(runtime.listener, activeScope) : 0) === null;
|
|
217792
217863
|
}
|
|
217793
|
-
function consumeQueuedTurn(runtime
|
|
217864
|
+
function consumeQueuedTurn(runtime) {
|
|
217794
217865
|
const queuedItems = runtime.queueRuntime.peekReady();
|
|
217795
217866
|
const firstQueuedItem = queuedItems[0];
|
|
217796
217867
|
if (!firstQueuedItem || !isCoalescable(firstQueuedItem.kind)) {
|
|
@@ -217802,22 +217873,15 @@ function consumeQueuedTurn(runtime, continuation) {
|
|
|
217802
217873
|
let hasCronPrompt = false;
|
|
217803
217874
|
let hasModContinue = false;
|
|
217804
217875
|
let batchConnectionId;
|
|
217805
|
-
let batchActingUserId = firstQueuedItem.actingUserId;
|
|
217806
217876
|
let batchImageFailureMode = null;
|
|
217807
217877
|
const isNoCoalesce = (candidate) => candidate.kind === "message" && candidate.noCoalesce === true;
|
|
217808
217878
|
for (const item of queuedItems) {
|
|
217809
|
-
if (continuation && item.actingUserId !== continuation.actingUserId) {
|
|
217810
|
-
break;
|
|
217811
|
-
}
|
|
217812
217879
|
if (!isCoalescable(item.kind) || !hasSameQueueScope(firstQueuedItem, item)) {
|
|
217813
217880
|
break;
|
|
217814
217881
|
}
|
|
217815
217882
|
if (queueLen > 0 && (isNoCoalesce(item) || isNoCoalesce(firstQueuedItem))) {
|
|
217816
217883
|
break;
|
|
217817
217884
|
}
|
|
217818
|
-
if (batchActingUserId && item.actingUserId && batchActingUserId !== item.actingUserId) {
|
|
217819
|
-
break;
|
|
217820
|
-
}
|
|
217821
217885
|
if (item.kind === "message") {
|
|
217822
217886
|
const itemConnectionId = runtime.queuedMessagesByItemId.get(item.id)?.connectionId;
|
|
217823
217887
|
if (batchConnectionId !== undefined && itemConnectionId !== undefined && itemConnectionId !== batchConnectionId) {
|
|
@@ -217830,7 +217894,6 @@ function consumeQueuedTurn(runtime, continuation) {
|
|
|
217830
217894
|
}
|
|
217831
217895
|
batchImageFailureMode = itemImageFailureMode;
|
|
217832
217896
|
}
|
|
217833
|
-
batchActingUserId ??= item.actingUserId;
|
|
217834
217897
|
queueLen += 1;
|
|
217835
217898
|
if (item.kind === "message") {
|
|
217836
217899
|
hasMessage = true;
|
|
@@ -223057,8 +223120,8 @@ function isSyncCommand(value) {
|
|
|
223057
223120
|
if (!value || typeof value !== "object") {
|
|
223058
223121
|
return false;
|
|
223059
223122
|
}
|
|
223060
|
-
const
|
|
223061
|
-
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");
|
|
223062
223125
|
}
|
|
223063
223126
|
function isTerminalSpawnCommand(value) {
|
|
223064
223127
|
if (!value || typeof value !== "object")
|
|
@@ -402118,6 +402181,59 @@ var init_continuation_input = __esm(async () => {
|
|
|
402118
402181
|
]);
|
|
402119
402182
|
});
|
|
402120
402183
|
|
|
402184
|
+
// src/backend/api/agents.ts
|
|
402185
|
+
async function getAgentContextOverview(agentId, options) {
|
|
402186
|
+
return apiRequest("GET", `/v1/agents/${agentId}/context`, undefined, {
|
|
402187
|
+
signal: options?.signal
|
|
402188
|
+
});
|
|
402189
|
+
}
|
|
402190
|
+
async function createMinimalAgent(apiKey, name) {
|
|
402191
|
+
return apiRequest("POST", "/v1/agents", { name }, {
|
|
402192
|
+
baseUrl: "https://api.letta.com",
|
|
402193
|
+
apiKey
|
|
402194
|
+
});
|
|
402195
|
+
}
|
|
402196
|
+
async function getAgentRuntimeStatus(agentId, conversationIds, signal) {
|
|
402197
|
+
return apiRequest("GET", `/v1/agents/${encodeURIComponent(agentId)}/runtime-status`, undefined, { query: { conversation_ids: conversationIds.join(",") }, signal });
|
|
402198
|
+
}
|
|
402199
|
+
var init_agents7 = __esm(() => {
|
|
402200
|
+
init_request();
|
|
402201
|
+
});
|
|
402202
|
+
|
|
402203
|
+
// src/websocket/listener/recovery-ownership.ts
|
|
402204
|
+
function hasRecoveryHandoff(runtime) {
|
|
402205
|
+
return isInboundTeleportExpected(runtime) || isRuntimeTeleportPending(runtime.listener, runtime.agentId, runtime.conversationId);
|
|
402206
|
+
}
|
|
402207
|
+
async function canRecoverConversation(runtime, readStatus = getAgentRuntimeStatus) {
|
|
402208
|
+
if (hasRecoveryHandoff(runtime))
|
|
402209
|
+
return false;
|
|
402210
|
+
const connectionId = runtime.listener.connectionId;
|
|
402211
|
+
if (!connectionId?.startsWith("conn-")) {
|
|
402212
|
+
return true;
|
|
402213
|
+
}
|
|
402214
|
+
if (!runtime.agentId)
|
|
402215
|
+
return true;
|
|
402216
|
+
try {
|
|
402217
|
+
const snapshot = await readStatus(runtime.agentId, [runtime.conversationId], AbortSignal.timeout(5000));
|
|
402218
|
+
if (hasRecoveryHandoff(runtime) || runtime.listener.connectionId !== connectionId)
|
|
402219
|
+
return false;
|
|
402220
|
+
const status = snapshot.statuses.find((entry) => entry.conversation_id === runtime.conversationId);
|
|
402221
|
+
if (!status || status.has_conflicting_listeners)
|
|
402222
|
+
return false;
|
|
402223
|
+
if (status.active_harness)
|
|
402224
|
+
return status.active_harness.connection_id === connectionId;
|
|
402225
|
+
return status.state === "IDLE";
|
|
402226
|
+
} catch (error4) {
|
|
402227
|
+
debugWarn("recovery", "Could not verify conversation recovery ownership", error4);
|
|
402228
|
+
return false;
|
|
402229
|
+
}
|
|
402230
|
+
}
|
|
402231
|
+
var init_recovery_ownership = __esm(() => {
|
|
402232
|
+
init_agents7();
|
|
402233
|
+
init_debug();
|
|
402234
|
+
init_teleport();
|
|
402235
|
+
});
|
|
402236
|
+
|
|
402121
402237
|
// src/websocket/listener/secrets-sync.ts
|
|
402122
402238
|
function getFreshnessMs() {
|
|
402123
402239
|
return _testFreshnessMsOverride ?? DEFAULT_FRESHNESS_MS;
|
|
@@ -402429,6 +402545,14 @@ async function startRecoveredApprovalContinuation(runtime, socket, processTurn,
|
|
|
402429
402545
|
if (runtime.turnLifecycle.kind !== "idle") {
|
|
402430
402546
|
return false;
|
|
402431
402547
|
}
|
|
402548
|
+
if (!await canRecoverConversation(runtime)) {
|
|
402549
|
+
if (runtime.recoveredApprovalState === recovered) {
|
|
402550
|
+
clearRecoveredApprovalState(runtime);
|
|
402551
|
+
}
|
|
402552
|
+
return false;
|
|
402553
|
+
}
|
|
402554
|
+
if (runtime.turnLifecycle.kind !== "idle" || runtime.recoveredApprovalState !== recovered)
|
|
402555
|
+
return false;
|
|
402432
402556
|
const scope = {
|
|
402433
402557
|
agent_id: recovered.agentId,
|
|
402434
402558
|
conversation_id: recovered.conversationId
|
|
@@ -402712,13 +402836,11 @@ async function executeRecoveredApprovalContinuation(params) {
|
|
|
402712
402836
|
}
|
|
402713
402837
|
]);
|
|
402714
402838
|
let continuationBatchId = `batch-recovered-${crypto.randomUUID()}`;
|
|
402715
|
-
let continuationActingUserId;
|
|
402716
402839
|
let continuationCorrelation;
|
|
402717
402840
|
const consumedQueuedTurn = consumeQueuedTurn(runtime);
|
|
402718
402841
|
if (consumedQueuedTurn) {
|
|
402719
402842
|
const { dequeuedBatch, queuedTurn } = consumedQueuedTurn;
|
|
402720
402843
|
continuationBatchId = dequeuedBatch.batchId;
|
|
402721
|
-
continuationActingUserId = queuedTurn.actingUserId;
|
|
402722
402844
|
continuationInput = appendQueuedTurnToInput(continuationInput, queuedTurn);
|
|
402723
402845
|
continuationCorrelation = createTurnCorrelation(runtime, {
|
|
402724
402846
|
type: "message",
|
|
@@ -402736,7 +402858,6 @@ async function executeRecoveredApprovalContinuation(params) {
|
|
|
402736
402858
|
type: "message",
|
|
402737
402859
|
agentId: recovered.agentId,
|
|
402738
402860
|
conversationId: recovered.conversationId,
|
|
402739
|
-
...continuationActingUserId ? { actingUserId: continuationActingUserId } : {},
|
|
402740
402861
|
messages: continuationInput.messages
|
|
402741
402862
|
}, socket, runtime, opts?.onStatusChange, opts?.connectionId, continuationBatchId, recoveryLease, continuationCorrelation);
|
|
402742
402863
|
if (runtime.turnLifecycle.isCurrent(recoveryLease)) {
|
|
@@ -402789,6 +402910,7 @@ var init_recovery = __esm(async () => {
|
|
|
402789
402910
|
init_permission_mode();
|
|
402790
402911
|
init_protocol_outbound();
|
|
402791
402912
|
init_recoverable_notices();
|
|
402913
|
+
init_recovery_ownership();
|
|
402792
402914
|
init_runtime();
|
|
402793
402915
|
init_secrets_sync();
|
|
402794
402916
|
init_turn_correlation();
|
|
@@ -403219,13 +403341,11 @@ async function resolveStaleApprovals(runtime, socket, turnLease, deps = {}) {
|
|
|
403219
403341
|
otid: crypto.randomUUID()
|
|
403220
403342
|
}
|
|
403221
403343
|
]);
|
|
403222
|
-
let continuationActingUserId;
|
|
403223
403344
|
let recoveryTurnCorrelation;
|
|
403224
403345
|
const consumedQueuedTurn = consumeQueuedTurn(runtime);
|
|
403225
403346
|
if (consumedQueuedTurn) {
|
|
403226
403347
|
const { dequeuedBatch, queuedTurn } = consumedQueuedTurn;
|
|
403227
403348
|
recoveryTurnCorrelation = createTurnCorrelation(runtime, queuedTurn, dequeuedBatch.batchId);
|
|
403228
|
-
continuationActingUserId = queuedTurn.actingUserId;
|
|
403229
403349
|
continuationInput = appendQueuedTurnToInput(continuationInput, queuedTurn);
|
|
403230
403350
|
emitDequeuedUserMessage(socket, runtime, queuedTurn, dequeuedBatch);
|
|
403231
403351
|
}
|
|
@@ -403239,7 +403359,6 @@ async function resolveStaleApprovals(runtime, socket, turnLease, deps = {}) {
|
|
|
403239
403359
|
agentId: runtime.agentId ?? undefined,
|
|
403240
403360
|
streamTokens: true,
|
|
403241
403361
|
background: true,
|
|
403242
|
-
...continuationActingUserId ? { actingUserId: continuationActingUserId } : {},
|
|
403243
403362
|
workingDirectory: recoveryWorkingDirectory,
|
|
403244
403363
|
preparedToolContext: preparedToolContext.preparedToolContext,
|
|
403245
403364
|
...continuationInput.imageFailureModesByMessageOtid ? {
|
|
@@ -406021,9 +406140,7 @@ async function handleApprovalStop(params) {
|
|
|
406021
406140
|
]);
|
|
406022
406141
|
let continuationBatchId = dequeuedBatchId;
|
|
406023
406142
|
const sendOptions = buildSendOptions() ?? {};
|
|
406024
|
-
const consumedQueuedTurn = consumeQueuedTurn(runtime
|
|
406025
|
-
actingUserId: sendOptions.actingUserId
|
|
406026
|
-
});
|
|
406143
|
+
const consumedQueuedTurn = consumeQueuedTurn(runtime);
|
|
406027
406144
|
if (consumedQueuedTurn) {
|
|
406028
406145
|
const { dequeuedBatch, queuedTurn } = consumedQueuedTurn;
|
|
406029
406146
|
turnCorrelation?.appendDequeuedBatch(dequeuedBatch.batchId);
|
|
@@ -407223,12 +407340,12 @@ function rowToolCalls(row, index, diagnostics2) {
|
|
|
407223
407340
|
}
|
|
407224
407341
|
return calls;
|
|
407225
407342
|
}
|
|
407226
|
-
function
|
|
407343
|
+
function contentText(content) {
|
|
407227
407344
|
if (typeof content === "string") {
|
|
407228
407345
|
if (content.startsWith(CONTENT_JSON_PREFIX)) {
|
|
407229
407346
|
const encoded = content.slice(CONTENT_JSON_PREFIX.length);
|
|
407230
407347
|
try {
|
|
407231
|
-
return
|
|
407348
|
+
return contentText(JSON.parse(encoded));
|
|
407232
407349
|
} catch {
|
|
407233
407350
|
return encoded;
|
|
407234
407351
|
}
|
|
@@ -407314,7 +407431,7 @@ var init_hermes = __esm(() => {
|
|
|
407314
407431
|
});
|
|
407315
407432
|
};
|
|
407316
407433
|
if (row.role === "user") {
|
|
407317
|
-
const content =
|
|
407434
|
+
const content = contentText(row.content);
|
|
407318
407435
|
if (content) {
|
|
407319
407436
|
emit({
|
|
407320
407437
|
type: "message",
|
|
@@ -407334,7 +407451,7 @@ var init_hermes = __esm(() => {
|
|
|
407334
407451
|
...timestamp ? { timestamp } : {}
|
|
407335
407452
|
});
|
|
407336
407453
|
}
|
|
407337
|
-
const content =
|
|
407454
|
+
const content = contentText(row.content);
|
|
407338
407455
|
if (content) {
|
|
407339
407456
|
emit({
|
|
407340
407457
|
type: "message",
|
|
@@ -407357,7 +407474,7 @@ var init_hermes = __esm(() => {
|
|
|
407357
407474
|
if (row.role === "tool") {
|
|
407358
407475
|
emit({
|
|
407359
407476
|
type: "tool_result",
|
|
407360
|
-
content:
|
|
407477
|
+
content: contentText(row.content),
|
|
407361
407478
|
...typeof row.tool_call_id === "string" && row.tool_call_id ? { callId: row.tool_call_id } : {},
|
|
407362
407479
|
...timestamp ? { timestamp } : {}
|
|
407363
407480
|
});
|
|
@@ -413364,16 +413481,18 @@ function extractTelemetryInputText(content) {
|
|
|
413364
413481
|
}
|
|
413365
413482
|
|
|
413366
413483
|
// src/websocket/listener/turn-transcript.ts
|
|
413367
|
-
function trackListenerUserInput(messages, modelId) {
|
|
413368
|
-
|
|
413369
|
-
|
|
413370
|
-
|
|
413371
|
-
|
|
413372
|
-
|
|
413373
|
-
|
|
413374
|
-
|
|
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
|
+
}
|
|
413375
413494
|
}
|
|
413376
|
-
}
|
|
413495
|
+
});
|
|
413377
413496
|
}
|
|
413378
413497
|
function buildInboundUserTranscriptLines(messages) {
|
|
413379
413498
|
const lines = [];
|
|
@@ -413408,6 +413527,7 @@ function seedInboundUserTranscriptLines(buffers, lines) {
|
|
|
413408
413527
|
}
|
|
413409
413528
|
}
|
|
413410
413529
|
var init_turn_transcript = __esm(() => {
|
|
413530
|
+
init_runtime_context();
|
|
413411
413531
|
init_telemetry();
|
|
413412
413532
|
});
|
|
413413
413533
|
|
|
@@ -413520,7 +413640,7 @@ async function prepareListenerTurn(params) {
|
|
|
413520
413640
|
if (connectionId) {
|
|
413521
413641
|
onStatusChange?.("processing", connectionId);
|
|
413522
413642
|
}
|
|
413523
|
-
trackListenerUserInput(msg.messages, "unknown");
|
|
413643
|
+
trackListenerUserInput(msg.messages, "unknown", msg.actingUserId);
|
|
413524
413644
|
const messagesToSend = [];
|
|
413525
413645
|
let queuedInterruptedToolCallIds = [];
|
|
413526
413646
|
const wasInterrupted = hasInterruptedCacheForScope(runtime.listener, {
|
|
@@ -418314,6 +418434,7 @@ function summarizeV2Command(parsed) {
|
|
|
418314
418434
|
"replace_all",
|
|
418315
418435
|
"expected_replacements",
|
|
418316
418436
|
"recover_approvals",
|
|
418437
|
+
"resume_interrupted_turn",
|
|
418317
418438
|
"force_device_status"
|
|
418318
418439
|
]) {
|
|
418319
418440
|
pushField(fields, key2, parsed[key2]);
|
|
@@ -418780,6 +418901,7 @@ function createListenerMessageHandler(params) {
|
|
|
418780
418901
|
try {
|
|
418781
418902
|
await replaySyncStateForRuntime(runtime, socket, parsed.runtime, {
|
|
418782
418903
|
recoverApprovals: parsed.recover_approvals !== false,
|
|
418904
|
+
resumeInterruptedTurn: parsed.resume_interrupted_turn === true,
|
|
418783
418905
|
forceDeviceStatus: parsed.force_device_status === true,
|
|
418784
418906
|
onStatusChange: opts.onStatusChange,
|
|
418785
418907
|
connectionId: opts.connectionId
|
|
@@ -419359,7 +419481,7 @@ var init_process_services = __esm(async () => {
|
|
|
419359
419481
|
function isBackendNotFoundError2(error4) {
|
|
419360
419482
|
return error4 instanceof APIError && (error4.status === 404 || error4.status === 422) || error4 instanceof Error && error4.name === "LocalBackendNotFoundError";
|
|
419361
419483
|
}
|
|
419362
|
-
async function recoverApprovalStateForSync(runtime, scope, deps = {}) {
|
|
419484
|
+
async function recoverApprovalStateForSync(runtime, scope, deps = {}, opts = {}) {
|
|
419363
419485
|
const resolvedDeps = {
|
|
419364
419486
|
getBackend,
|
|
419365
419487
|
getResumeDataFromBackend,
|
|
@@ -419382,6 +419504,10 @@ async function recoverApprovalStateForSync(runtime, scope, deps = {}) {
|
|
|
419382
419504
|
clearRecoveredApprovalState(runtime);
|
|
419383
419505
|
return;
|
|
419384
419506
|
}
|
|
419507
|
+
if (!await canRecoverConversation(runtime)) {
|
|
419508
|
+
clearRecoveredApprovalState(runtime);
|
|
419509
|
+
return "deferred";
|
|
419510
|
+
}
|
|
419385
419511
|
const existingRecovered = runtime.recoveredApprovalState;
|
|
419386
419512
|
if (existingRecovered && existingRecovered.agentId === scope.agent_id && existingRecovered.conversationId === scope.conversation_id && existingRecovered.pendingRequestIds.size > 0) {
|
|
419387
419513
|
return;
|
|
@@ -419414,6 +419540,8 @@ async function recoverApprovalStateForSync(runtime, scope, deps = {}) {
|
|
|
419414
419540
|
clearRecoveredApprovalState(runtime);
|
|
419415
419541
|
return;
|
|
419416
419542
|
}
|
|
419543
|
+
if (!await canRecoverConversation(runtime))
|
|
419544
|
+
return "deferred";
|
|
419417
419545
|
if (hasInterruptedCacheForScope(runtime.listener, scope) || sameActiveScope && (runtime.turnLifecycle.kind !== "idle" || runtime.pendingApprovalResolvers.size > 0)) {
|
|
419418
419546
|
return;
|
|
419419
419547
|
}
|
|
@@ -419423,6 +419551,17 @@ async function recoverApprovalStateForSync(runtime, scope, deps = {}) {
|
|
|
419423
419551
|
approval,
|
|
419424
419552
|
reason: STALE_APPROVAL_RECOVERY_DENIAL_REASON
|
|
419425
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
|
+
}
|
|
419426
419565
|
const approvalsByRequestId = new Map;
|
|
419427
419566
|
for (const approval of interactivePending) {
|
|
419428
419567
|
const requestId = `perm-${approval.toolCallId}`;
|
|
@@ -419458,6 +419597,7 @@ async function recoverApprovalStateForSync(runtime, scope, deps = {}) {
|
|
|
419458
419597
|
autoDecisions: staleDenialDecisions,
|
|
419459
419598
|
allApprovals: pendingApprovals
|
|
419460
419599
|
};
|
|
419600
|
+
return;
|
|
419461
419601
|
}
|
|
419462
419602
|
var init_recovery_sync = __esm(() => {
|
|
419463
419603
|
init_error();
|
|
@@ -419465,6 +419605,7 @@ var init_recovery_sync = __esm(() => {
|
|
|
419465
419605
|
init_turn_recovery_policy();
|
|
419466
419606
|
init_backend2();
|
|
419467
419607
|
init_interactive_policy();
|
|
419608
|
+
init_recovery_ownership();
|
|
419468
419609
|
init_runtime();
|
|
419469
419610
|
});
|
|
419470
419611
|
|
|
@@ -419472,10 +419613,11 @@ var init_recovery_sync = __esm(() => {
|
|
|
419472
419613
|
async function replaySyncStateForRuntime(listenerRuntime, socket, scope, opts) {
|
|
419473
419614
|
const syncScopedRuntime = getOrCreateScopedRuntime(listenerRuntime, scope.agent_id, scope.conversation_id);
|
|
419474
419615
|
const recoverFn = opts?.recoverApprovalStateForSync ?? recoverApprovalStateForSync;
|
|
419475
|
-
if (
|
|
419616
|
+
if (opts?.recoverApprovals ?? true) {
|
|
419476
419617
|
try {
|
|
419477
|
-
await recoverFn(syncScopedRuntime, scope
|
|
419478
|
-
|
|
419618
|
+
await recoverFn(syncScopedRuntime, scope, undefined, {
|
|
419619
|
+
resumeInterruptedTurn: opts?.resumeInterruptedTurn === true
|
|
419620
|
+
});
|
|
419479
419621
|
} catch (error4) {
|
|
419480
419622
|
trackBoundaryError({
|
|
419481
419623
|
errorType: "listener_sync_recovery_failed",
|
|
@@ -419487,7 +419629,7 @@ async function replaySyncStateForRuntime(listenerRuntime, socket, scope, opts) {
|
|
|
419487
419629
|
}
|
|
419488
419630
|
}
|
|
419489
419631
|
}
|
|
419490
|
-
if (
|
|
419632
|
+
if (syncScopedRuntime.recoveredApprovalState && syncScopedRuntime.recoveredApprovalState.pendingRequestIds.size === 0 && (syncScopedRuntime.recoveredApprovalState.autoDecisions?.length ?? 0) > 0) {
|
|
419491
419633
|
startRecoveredApprovalContinuation(syncScopedRuntime, getOrCreateProcessTransport(listenerRuntime), opts?.processIncomingMessage ?? handleIncomingMessage, {
|
|
419492
419634
|
onStatusChange: opts?.onStatusChange,
|
|
419493
419635
|
connectionId: opts?.connectionId,
|
|
@@ -419512,7 +419654,6 @@ var init_sync_replay = __esm(async () => {
|
|
|
419512
419654
|
init_connection();
|
|
419513
419655
|
init_connection_state_sync();
|
|
419514
419656
|
init_recovery_sync();
|
|
419515
|
-
init_teleport();
|
|
419516
419657
|
await __promiseAll([
|
|
419517
419658
|
init_conversation_runtime(),
|
|
419518
419659
|
init_recovery(),
|
|
@@ -440848,7 +440989,7 @@ var init_mcp_client = __esm(() => {
|
|
|
440848
440989
|
init_streamableHttp();
|
|
440849
440990
|
DEFAULT_CLIENT_INFO = {
|
|
440850
440991
|
name: "letta-code",
|
|
440851
|
-
version: "0.32.
|
|
440992
|
+
version: "0.32.9"
|
|
440852
440993
|
};
|
|
440853
440994
|
});
|
|
440854
440995
|
|
|
@@ -442685,25 +442826,6 @@ var init_message_search = __esm(() => {
|
|
|
442685
442826
|
init_transcript_search();
|
|
442686
442827
|
});
|
|
442687
442828
|
|
|
442688
|
-
// src/backend/api/agents.ts
|
|
442689
|
-
async function getAgentContextOverview(agentId, options) {
|
|
442690
|
-
return apiRequest("GET", `/v1/agents/${agentId}/context`, undefined, {
|
|
442691
|
-
signal: options?.signal
|
|
442692
|
-
});
|
|
442693
|
-
}
|
|
442694
|
-
async function createMinimalAgent(apiKey, name) {
|
|
442695
|
-
return apiRequest("POST", "/v1/agents", { name }, {
|
|
442696
|
-
baseUrl: "https://api.letta.com",
|
|
442697
|
-
apiKey
|
|
442698
|
-
});
|
|
442699
|
-
}
|
|
442700
|
-
async function getAgentRuntimeStatus(agentId, conversationIds) {
|
|
442701
|
-
return apiRequest("GET", `/v1/agents/${encodeURIComponent(agentId)}/runtime-status`, undefined, { query: { conversation_ids: conversationIds.join(",") } });
|
|
442702
|
-
}
|
|
442703
|
-
var init_agents7 = __esm(() => {
|
|
442704
|
-
init_request();
|
|
442705
|
-
});
|
|
442706
|
-
|
|
442707
442829
|
// src/cli/subcommands/message-status.ts
|
|
442708
442830
|
async function readMessageStatus(conversationId, agentId, backend3, deps = { getAgentRuntimeStatus, getLatestConversationSuperRun }) {
|
|
442709
442831
|
if (!backend3.capabilities.environmentRouting)
|
|
@@ -455271,7 +455393,15 @@ async function tryCloudHeadlessSend(values4, prompt, backend3, isAgentLaunch, de
|
|
|
455271
455393
|
}
|
|
455272
455394
|
if (!agentId && !conversationId)
|
|
455273
455395
|
throw new Error("Choose a destination with --agent or --conversation. Ambient AGENT_ID identifies the sender.");
|
|
455274
|
-
({ agentId, conversationId } = await resolveAgentMessageDestination({
|
|
455396
|
+
({ agentId, conversationId } = await resolveAgentMessageDestination({
|
|
455397
|
+
agentId,
|
|
455398
|
+
conversationId,
|
|
455399
|
+
senderAgentId: sender.agentId,
|
|
455400
|
+
currentConversation: {
|
|
455401
|
+
agentId: ambientSender,
|
|
455402
|
+
conversationId: env5.CONVERSATION_ID || env5.LETTA_CONVERSATION_ID
|
|
455403
|
+
}
|
|
455404
|
+
}, backend3, controller.signal));
|
|
455275
455405
|
const recovery = {
|
|
455276
455406
|
status_command: `letta messages status --agent ${agentId} --conversation ${conversationId}`,
|
|
455277
455407
|
messages_command: `letta messages list --agent ${agentId} --conversation ${conversationId}`
|
|
@@ -456038,6 +456168,49 @@ var init_headless_tool_events = __esm(async () => {
|
|
|
456038
456168
|
await init_approval_execution();
|
|
456039
456169
|
});
|
|
456040
456170
|
|
|
456171
|
+
// src/queue/turn-queue-runtime.ts
|
|
456172
|
+
function stringifyUnexpectedContent(content) {
|
|
456173
|
+
try {
|
|
456174
|
+
return JSON.stringify(content) ?? String(content);
|
|
456175
|
+
} catch {
|
|
456176
|
+
return String(content);
|
|
456177
|
+
}
|
|
456178
|
+
}
|
|
456179
|
+
function appendContentParts(target2, content) {
|
|
456180
|
+
if (typeof content === "string") {
|
|
456181
|
+
target2.push({ type: "text", text: content });
|
|
456182
|
+
return;
|
|
456183
|
+
}
|
|
456184
|
+
if (!Array.isArray(content)) {
|
|
456185
|
+
if (content === null || content === undefined)
|
|
456186
|
+
return;
|
|
456187
|
+
target2.push({ type: "text", text: stringifyUnexpectedContent(content) });
|
|
456188
|
+
return;
|
|
456189
|
+
}
|
|
456190
|
+
target2.push(...content);
|
|
456191
|
+
}
|
|
456192
|
+
function mergeQueuedTurnInput(queued, options) {
|
|
456193
|
+
if (queued.length === 0) {
|
|
456194
|
+
return null;
|
|
456195
|
+
}
|
|
456196
|
+
const separatorText = options.separatorText ?? `
|
|
456197
|
+
`;
|
|
456198
|
+
const mergedParts = [];
|
|
456199
|
+
let isFirst = true;
|
|
456200
|
+
for (const item of queued) {
|
|
456201
|
+
if (!isFirst) {
|
|
456202
|
+
mergedParts.push({ type: "text", text: separatorText });
|
|
456203
|
+
}
|
|
456204
|
+
isFirst = false;
|
|
456205
|
+
if (item.kind === "task_notification" || item.kind === "cron_prompt") {
|
|
456206
|
+
mergedParts.push({ type: "text", text: item.text });
|
|
456207
|
+
continue;
|
|
456208
|
+
}
|
|
456209
|
+
appendContentParts(mergedParts, options.normalizeUserContent(item.content));
|
|
456210
|
+
}
|
|
456211
|
+
return mergedParts.length > 0 ? mergedParts : null;
|
|
456212
|
+
}
|
|
456213
|
+
|
|
456041
456214
|
// src/agent/defaults.ts
|
|
456042
456215
|
var exports_defaults = {};
|
|
456043
456216
|
__export(exports_defaults, {
|
|
@@ -463056,6 +463229,46 @@ var init_use_local_mod_adapter = __esm(async () => {
|
|
|
463056
463229
|
import_react44 = __toESM(require_react(), 1);
|
|
463057
463230
|
});
|
|
463058
463231
|
|
|
463232
|
+
// src/cli/helpers/ask-user-questions.ts
|
|
463233
|
+
function parseAskUserQuestions(approval) {
|
|
463234
|
+
const parsed = safeJsonParseOr(approval.toolArgs, {});
|
|
463235
|
+
if (parsed == null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
463236
|
+
return [];
|
|
463237
|
+
}
|
|
463238
|
+
const questions = parsed.questions;
|
|
463239
|
+
if (!Array.isArray(questions) || questions.length < 1 || questions.length > 4) {
|
|
463240
|
+
return [];
|
|
463241
|
+
}
|
|
463242
|
+
return questions.every(isWellFormedQuestion) ? questions : [];
|
|
463243
|
+
}
|
|
463244
|
+
function isWellFormedQuestion(q2) {
|
|
463245
|
+
if (q2 == null || typeof q2 !== "object")
|
|
463246
|
+
return false;
|
|
463247
|
+
const question = q2;
|
|
463248
|
+
if (typeof question.question !== "string")
|
|
463249
|
+
return false;
|
|
463250
|
+
if (typeof question.header !== "string")
|
|
463251
|
+
return false;
|
|
463252
|
+
if (question.multiSelect !== undefined && typeof question.multiSelect !== "boolean") {
|
|
463253
|
+
return false;
|
|
463254
|
+
}
|
|
463255
|
+
if (question.allowOther !== undefined && typeof question.allowOther !== "boolean") {
|
|
463256
|
+
return false;
|
|
463257
|
+
}
|
|
463258
|
+
const options = question.options;
|
|
463259
|
+
if (!Array.isArray(options) || options.length < 2 || options.length > 4) {
|
|
463260
|
+
return false;
|
|
463261
|
+
}
|
|
463262
|
+
return options.every(isWellFormedOption);
|
|
463263
|
+
}
|
|
463264
|
+
function isWellFormedOption(o3) {
|
|
463265
|
+
if (o3 == null || typeof o3 !== "object")
|
|
463266
|
+
return false;
|
|
463267
|
+
const option2 = o3;
|
|
463268
|
+
return typeof option2.label === "string" && option2.label.length > 0 && typeof option2.description === "string";
|
|
463269
|
+
}
|
|
463270
|
+
var init_ask_user_questions = () => {};
|
|
463271
|
+
|
|
463059
463272
|
// src/cli/hooks/use-progress-indicator.ts
|
|
463060
463273
|
function useProgressIndicator(active = true) {
|
|
463061
463274
|
import_react45.useEffect(() => {
|
|
@@ -465304,7 +465517,7 @@ var init_InlineQuestionApproval = __esm(async () => {
|
|
|
465304
465517
|
const currentQuestion = questions[currentQuestionIndex];
|
|
465305
465518
|
const showOther = currentQuestion?.allowOther !== false;
|
|
465306
465519
|
const baseOptions = currentQuestion ? [
|
|
465307
|
-
...currentQuestion.options,
|
|
465520
|
+
...Array.isArray(currentQuestion.options) ? currentQuestion.options.filter((o3) => o3 != null && typeof o3 === "object" && typeof o3.label === "string" && typeof o3.description === "string") : [],
|
|
465308
465521
|
...showOther ? [{ label: "Type something.", description: "" }] : []
|
|
465309
465522
|
] : [];
|
|
465310
465523
|
const optionsWithOther = currentQuestion?.multiSelect ? [...baseOptions, { label: "Submit", description: "" }] : baseOptions;
|
|
@@ -466099,15 +466312,11 @@ function getMemoryFileEditInfo(approval) {
|
|
|
466099
466312
|
}
|
|
466100
466313
|
}
|
|
466101
466314
|
function getQuestions(approval) {
|
|
466102
|
-
|
|
466103
|
-
const args = JSON.parse(approval.toolArgs || "{}");
|
|
466104
|
-
return args.questions || [];
|
|
466105
|
-
} catch {
|
|
466106
|
-
return [];
|
|
466107
|
-
}
|
|
466315
|
+
return parseAskUserQuestions(approval);
|
|
466108
466316
|
}
|
|
466109
466317
|
var import_react54, jsx_dev_runtime30, ApprovalSwitch;
|
|
466110
466318
|
var init_ApprovalSwitch = __esm(async () => {
|
|
466319
|
+
init_ask_user_questions();
|
|
466111
466320
|
await __promiseAll([
|
|
466112
466321
|
init_tool_name_mapping(),
|
|
466113
466322
|
init_InlineBashApproval(),
|
|
@@ -503289,10 +503498,11 @@ function buildApprovalBatchKey(approvals) {
|
|
|
503289
503498
|
|
|
503290
503499
|
// src/cli/app/approval-questions.ts
|
|
503291
503500
|
function getQuestionsFromApproval(approval) {
|
|
503292
|
-
|
|
503293
|
-
return parsed.questions || [];
|
|
503501
|
+
return parseAskUserQuestions(approval);
|
|
503294
503502
|
}
|
|
503295
|
-
var init_approval_questions = () => {
|
|
503503
|
+
var init_approval_questions = __esm(() => {
|
|
503504
|
+
init_ask_user_questions();
|
|
503505
|
+
});
|
|
503296
503506
|
|
|
503297
503507
|
// src/cli/app/errors.ts
|
|
503298
503508
|
function extractErrorMeta(e2) {
|
|
@@ -519622,7 +519832,9 @@ Error: ${message}`);
|
|
|
519622
519832
|
return null;
|
|
519623
519833
|
});
|
|
519624
519834
|
if (!shouldBlockOnMemfsStartup) {}
|
|
519625
|
-
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
|
+
});
|
|
519626
519838
|
const isResumingProject = !shouldCreateNew && !!resumingAgentId;
|
|
519627
519839
|
const isReusingExistingAgent = !shouldCreateNew && agent && agent.id;
|
|
519628
519840
|
const resuming = !!(agentIdArg || isResumingProject || isReusingExistingAgent);
|
|
@@ -519733,11 +519945,7 @@ Error: ${message}`);
|
|
|
519733
519945
|
}
|
|
519734
519946
|
const fdPath = await ensureFdPath();
|
|
519735
519947
|
setFileAutocompleteFdPath(fdPath);
|
|
519736
|
-
|
|
519737
|
-
await secretsInitPromise;
|
|
519738
|
-
} catch (error5) {
|
|
519739
|
-
Promise.resolve().then(() => (init_debug(), exports_debug)).then(({ debugLog: debugLog3 }) => debugLog3("secrets", `Failed to init secrets: ${error5 instanceof Error ? error5.message : String(error5)}`));
|
|
519740
|
-
}
|
|
519948
|
+
await secretsInitPromise;
|
|
519741
519949
|
if (shouldPersistSessionState()) {
|
|
519742
519950
|
settingsManager.persistSession(agent.id, conversationIdToUse);
|
|
519743
519951
|
}
|
|
@@ -522152,4 +522360,4 @@ function registerBunOAuthFlows() {
|
|
|
522152
522360
|
registerBunOAuthFlows();
|
|
522153
522361
|
await init_src5().then(() => exports_src2);
|
|
522154
522362
|
|
|
522155
|
-
//# debugId=
|
|
522363
|
+
//# debugId=73D666396EC039C064756E2164756E21
|