@letta-ai/letta-code 0.34.13 → 0.34.14
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/agent-presets.js +1 -1
- package/dist/agent-presets.js.map +3 -3
- package/dist/mcp-client.js +2 -2
- package/dist/mcp-client.js.map +1 -1
- package/dist/mcp-oauth.js +41 -13
- package/dist/mcp-oauth.js.map +7 -6
- package/dist/types/agent/agent-tags.d.ts +4 -0
- package/dist/types/agent/agent-tags.d.ts.map +1 -1
- package/dist/types/backend/local/local-backend.d.ts +1 -0
- package/dist/types/backend/local/local-backend.d.ts.map +1 -1
- package/dist/types/backend/local/local-store.d.ts +2 -13
- package/dist/types/backend/local/local-store.d.ts.map +1 -1
- package/dist/types/backend/local/local-transcript.d.ts +9 -5
- package/dist/types/backend/local/local-transcript.d.ts.map +1 -1
- package/dist/types/browser-device-mcp-oauth.d.ts +15 -0
- package/dist/types/browser-device-mcp-oauth.d.ts.map +1 -1
- package/dist/types/cli/subcommands/mcp-connect.d.ts +1 -1
- package/dist/types/cli/subcommands/mcp-connect.d.ts.map +1 -1
- package/dist/types/cli/subcommands/mcp-io.d.ts.map +1 -1
- package/dist/types/cli/subcommands/mcp.d.ts.map +1 -1
- package/dist/types/mcp-oauth-callback.d.ts +10 -1
- package/dist/types/mcp-oauth-callback.d.ts.map +1 -1
- package/dist/types/mcp-oauth-client-name.d.ts +9 -0
- package/dist/types/mcp-oauth-client-name.d.ts.map +1 -0
- package/dist/types/mcp-oauth-public.d.ts +14 -0
- package/dist/types/mcp-oauth-public.d.ts.map +1 -1
- package/dist/types/mcp-oauth.d.ts +14 -0
- package/dist/types/mcp-oauth.d.ts.map +1 -1
- package/dist/types/tools/impl/claude-stream-session.d.ts.map +1 -1
- package/dist/types/tools/impl/codex-app-server.d.ts +4 -0
- package/dist/types/tools/impl/codex-app-server.d.ts.map +1 -1
- package/dist/types/tools/impl/remote-external-coding-agent.d.ts.map +1 -1
- package/dist/types/utils/systemd-workload-scope.d.ts.map +1 -1
- package/letta.js +268 -86
- package/npm-shrinkwrap.json +8 -8
- package/package.json +2 -2
- package/scripts/source-file-size-baseline.json +1 -1
- package/skills/working-across-computers/references/connect-a-computer-for-remote-access.md +26 -3
package/letta.js
CHANGED
|
@@ -5913,7 +5913,7 @@ var package_default;
|
|
|
5913
5913
|
var init_package = __esm(() => {
|
|
5914
5914
|
package_default = {
|
|
5915
5915
|
name: "@letta-ai/letta-code",
|
|
5916
|
-
version: "0.34.
|
|
5916
|
+
version: "0.34.14",
|
|
5917
5917
|
lettaStartupLogProtocol: 1,
|
|
5918
5918
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
5919
5919
|
type: "module",
|
|
@@ -6188,7 +6188,7 @@ var init_package = __esm(() => {
|
|
|
6188
6188
|
},
|
|
6189
6189
|
lettaLifecycleProtocol: 1,
|
|
6190
6190
|
lettaRuntimeGraphProtocol: 1,
|
|
6191
|
-
lettaRuntimeGraphSha512: "sha512-
|
|
6191
|
+
lettaRuntimeGraphSha512: "sha512-ttHuf5WcGVfNYOggfqOqLRZnllxSSFje3ETZWA/cYFUEoMLz54/CApUxOjoR7xn7X6PbqVnZEzmUQnv+Ic3xzg=="
|
|
6192
6192
|
};
|
|
6193
6193
|
});
|
|
6194
6194
|
|
|
@@ -98826,8 +98826,10 @@ var init_backend_mode = __esm(() => {
|
|
|
98826
98826
|
// src/agent/agent-tags.ts
|
|
98827
98827
|
var exports_agent_tags = {};
|
|
98828
98828
|
__export(exports_agent_tags, {
|
|
98829
|
+
isMemfsOptOutCreateTags: () => isMemfsOptOutCreateTags,
|
|
98829
98830
|
buildCreatedAgentTags: () => buildCreatedAgentTags,
|
|
98830
98831
|
ONBOARDING_ORIGIN_TAG: () => ONBOARDING_ORIGIN_TAG,
|
|
98832
|
+
MEMFS_DISABLED_TAG: () => MEMFS_DISABLED_TAG,
|
|
98831
98833
|
LETTA_CODE_SUBAGENT_TAG: () => LETTA_CODE_SUBAGENT_TAG,
|
|
98832
98834
|
LETTA_CODE_ORIGIN_TAG: () => LETTA_CODE_ORIGIN_TAG,
|
|
98833
98835
|
GIT_MEMORY_ENABLED_TAG: () => GIT_MEMORY_ENABLED_TAG
|
|
@@ -98845,7 +98847,10 @@ function buildCreatedAgentTags(options = {}) {
|
|
|
98845
98847
|
}
|
|
98846
98848
|
return Array.from(new Set(tags));
|
|
98847
98849
|
}
|
|
98848
|
-
|
|
98850
|
+
function isMemfsOptOutCreateTags(tags) {
|
|
98851
|
+
return Array.isArray(tags) && tags.includes(MEMFS_DISABLED_TAG);
|
|
98852
|
+
}
|
|
98853
|
+
var LETTA_CODE_ORIGIN_TAG = "origin:letta-code", ONBOARDING_ORIGIN_TAG = "origin:onboarding", LETTA_CODE_SUBAGENT_TAG = "role:subagent", GIT_MEMORY_ENABLED_TAG = "git-memory-enabled", MEMFS_DISABLED_TAG = "memfs:disabled";
|
|
98849
98854
|
|
|
98850
98855
|
// src/utils/directory-limits.ts
|
|
98851
98856
|
function parsePositiveIntEnv(value, fallback, min, max) {
|
|
@@ -110137,15 +110142,46 @@ function readJsonFile2(path8) {
|
|
|
110137
110142
|
function readJsonlFile(path8) {
|
|
110138
110143
|
if (!existsSync14(path8))
|
|
110139
110144
|
return [];
|
|
110140
|
-
|
|
110141
|
-
|
|
110145
|
+
const items3 = [];
|
|
110146
|
+
const buffer = Buffer.alloc(64 * 1024);
|
|
110147
|
+
const pending = [];
|
|
110148
|
+
const fd = openSync2(path8, "r");
|
|
110149
|
+
try {
|
|
110150
|
+
let bytesRead = 0;
|
|
110151
|
+
do {
|
|
110152
|
+
bytesRead = readSync(fd, buffer, 0, buffer.length, null);
|
|
110153
|
+
let lineStart = 0;
|
|
110154
|
+
for (let index = 0;index < bytesRead; index += 1) {
|
|
110155
|
+
if (buffer[index] !== 10)
|
|
110156
|
+
continue;
|
|
110157
|
+
const suffix = buffer.subarray(lineStart, index);
|
|
110158
|
+
const line = pending.length ? Buffer.concat([...pending, suffix]) : suffix;
|
|
110159
|
+
pending.length = 0;
|
|
110160
|
+
const text = line.toString("utf8");
|
|
110161
|
+
if (text.trim().length > 0)
|
|
110162
|
+
items3.push(JSON.parse(text));
|
|
110163
|
+
lineStart = index + 1;
|
|
110164
|
+
}
|
|
110165
|
+
if (lineStart < bytesRead) {
|
|
110166
|
+
pending.push(Buffer.from(buffer.subarray(lineStart, bytesRead)));
|
|
110167
|
+
}
|
|
110168
|
+
} while (bytesRead > 0);
|
|
110169
|
+
} finally {
|
|
110170
|
+
closeSync2(fd);
|
|
110171
|
+
}
|
|
110172
|
+
if (pending.length > 0) {
|
|
110173
|
+
const text = Buffer.concat(pending).toString("utf8");
|
|
110174
|
+
if (text.trim().length > 0)
|
|
110175
|
+
items3.push(JSON.parse(text));
|
|
110176
|
+
}
|
|
110177
|
+
return items3;
|
|
110142
110178
|
}
|
|
110143
110179
|
function readJsonlFileSuffix(path8, maxBytes) {
|
|
110144
110180
|
if (!existsSync14(path8))
|
|
110145
|
-
return { items: [], reachedStart: true, startOffset: 0 };
|
|
110181
|
+
return { items: [], reachedStart: true, startOffset: 0, bytesRead: 0 };
|
|
110146
110182
|
const size = statSync3(path8).size;
|
|
110147
110183
|
if (size === 0)
|
|
110148
|
-
return { items: [], reachedStart: true, startOffset: 0 };
|
|
110184
|
+
return { items: [], reachedStart: true, startOffset: 0, bytesRead: 0 };
|
|
110149
110185
|
const bytesToRead = Math.min(size, Math.max(1, maxBytes));
|
|
110150
110186
|
const start = size - bytesToRead;
|
|
110151
110187
|
const buffer = Buffer.alloc(bytesToRead);
|
|
@@ -110167,6 +110203,7 @@ function readJsonlFileSuffix(path8, maxBytes) {
|
|
|
110167
110203
|
items: text.split(`
|
|
110168
110204
|
`).filter((line) => line.trim().length > 0).map((line) => JSON.parse(line)),
|
|
110169
110205
|
reachedStart,
|
|
110206
|
+
bytesRead: bytesToRead,
|
|
110170
110207
|
startOffset: reachedStart ? 0 : firstNewlineByte >= 0 ? start + firstNewlineByte + 1 : size
|
|
110171
110208
|
};
|
|
110172
110209
|
}
|
|
@@ -110283,29 +110320,46 @@ function repairSyntheticConversationTimestamps(conversation, messages, timing) {
|
|
|
110283
110320
|
function normalizeLocalMessageForPi(message) {
|
|
110284
110321
|
return message;
|
|
110285
110322
|
}
|
|
110323
|
+
function localTranscriptTailByteBudget(conversation, agentSettings) {
|
|
110324
|
+
const conversationRecord = isRecord2(conversation) ? conversation : {};
|
|
110325
|
+
const conversationSettings = isRecord2(conversationRecord.model_settings) ? conversationRecord.model_settings : {};
|
|
110326
|
+
const agentSettingsRecord = isRecord2(agentSettings) ? agentSettings : {};
|
|
110327
|
+
const contextWindow = [
|
|
110328
|
+
conversationRecord.context_window_limit,
|
|
110329
|
+
conversationSettings.context_window_limit,
|
|
110330
|
+
agentSettingsRecord.context_window_limit
|
|
110331
|
+
].find((value) => typeof value === "number" && Number.isFinite(value) && value > 0);
|
|
110332
|
+
return (contextWindow ?? LEGACY_LOCAL_CONTEXT_WINDOW_LIMIT) * LOCAL_TRANSCRIPT_BYTES_PER_CONTEXT_TOKEN;
|
|
110333
|
+
}
|
|
110286
110334
|
function localTranscriptTailMessages(rows, messageFormat, activeMessageIds, storageDir, conversationDir) {
|
|
110287
110335
|
const transcript2 = localTranscriptRowsResult(rows, messageFormat, activeMessageIds);
|
|
110288
110336
|
assertNoLegacyUiMessageRows(transcript2.messages, storageDir, conversationDir);
|
|
110289
110337
|
const messages = removeOrphanLocalToolResults(transcript2.messages.map(normalizeLocalMessageForPi)).messages;
|
|
110290
110338
|
return { transcript: transcript2, messages };
|
|
110291
110339
|
}
|
|
110292
|
-
function readLocalTranscriptTailWindow(messagesPath, messageFormat, activeMessageIds, minMessages, storageDir, conversationDir) {
|
|
110340
|
+
function readLocalTranscriptTailWindow(messagesPath, messageFormat, activeMessageIds, minMessages, storageDir, conversationDir, maxTailBytes = LOCAL_TRANSCRIPT_TAIL_MAX_BYTES) {
|
|
110293
110341
|
const targetCount = activeMessageIds.length > 0 ? activeMessageIds.length : minMessages;
|
|
110342
|
+
const byteBudget = Math.max(64 * 1024, Math.floor(maxTailBytes));
|
|
110294
110343
|
let maxBytes = 64 * 1024;
|
|
110295
110344
|
for (;; ) {
|
|
110296
110345
|
const tail = readJsonlFileSuffix(messagesPath, maxBytes);
|
|
110297
|
-
|
|
110346
|
+
let result = localTranscriptTailMessages(tail.items, messageFormat, activeMessageIds, storageDir, conversationDir);
|
|
110298
110347
|
const found = result.transcript.messages.length;
|
|
110299
|
-
if (found >= targetCount || tail.reachedStart) {
|
|
110348
|
+
if (found >= targetCount || tail.reachedStart || maxBytes >= byteBudget) {
|
|
110349
|
+
if (activeMessageIds.length === 0 && result.messages.length > minMessages) {
|
|
110350
|
+
const inferredIds = result.messages.slice(-minMessages).map((message) => message.id);
|
|
110351
|
+
result = localTranscriptTailMessages(tail.items, messageFormat, inferredIds, storageDir, conversationDir);
|
|
110352
|
+
}
|
|
110300
110353
|
const returnedIds = new Set(result.messages.map((message) => message.id));
|
|
110301
110354
|
return {
|
|
110302
110355
|
...result,
|
|
110303
110356
|
reachedStart: tail.reachedStart,
|
|
110357
|
+
bytesRead: tail.bytesRead,
|
|
110304
110358
|
headBytes: tail.startOffset,
|
|
110305
|
-
liveInContextIds: activeMessageIds.filter((id2) => returnedIds.has(id2))
|
|
110359
|
+
liveInContextIds: activeMessageIds.length > 0 ? activeMessageIds.filter((id2) => returnedIds.has(id2)) : result.messages.map((message) => message.id)
|
|
110306
110360
|
};
|
|
110307
110361
|
}
|
|
110308
|
-
maxBytes = Math.max(maxBytes * 2, found > 0 ? Math.ceil(maxBytes / found * targetCount * 1.25) : 0);
|
|
110362
|
+
maxBytes = Math.min(byteBudget, Math.max(maxBytes * 2, found > 0 ? Math.ceil(maxBytes / found * targetCount * 1.25) : 0));
|
|
110309
110363
|
}
|
|
110310
110364
|
}
|
|
110311
110365
|
function spliceOutOfContextMessages(messages, inContextIds, floor) {
|
|
@@ -110434,8 +110488,9 @@ function overlayResidentLocalMessageSuffix(diskSuffix, residentTail, isPersisted
|
|
|
110434
110488
|
}
|
|
110435
110489
|
return overlayResidentLocalMessageTail(diskSuffix, overlayTail);
|
|
110436
110490
|
}
|
|
110437
|
-
var LOCAL_TRANSCRIPT_LEGACY_SCHEMA_VERSION = 1, LOCAL_TRANSCRIPT_SCHEMA_VERSION = 2, LOCAL_TRANSCRIPT_LEGACY_MESSAGE_FORMAT = "pi-ai-message-jsonl", LOCAL_TRANSCRIPT_MESSAGE_FORMAT = "pi-session-entry-jsonl", LOCAL_TRANSCRIPT_PROVIDER_STACK = "pi-ai", LocalTranscriptMigrationRequiredError, LocalTranscriptRepairRequiredError;
|
|
110491
|
+
var LOCAL_TRANSCRIPT_LEGACY_SCHEMA_VERSION = 1, LOCAL_TRANSCRIPT_SCHEMA_VERSION = 2, LOCAL_TRANSCRIPT_LEGACY_MESSAGE_FORMAT = "pi-ai-message-jsonl", LOCAL_TRANSCRIPT_MESSAGE_FORMAT = "pi-session-entry-jsonl", LOCAL_TRANSCRIPT_PROVIDER_STACK = "pi-ai", LOCAL_TRANSCRIPT_TAIL_MAX_BYTES, LOCAL_TRANSCRIPT_BYTES_PER_CONTEXT_TOKEN = 8, LEGACY_LOCAL_CONTEXT_WINDOW_LIMIT = 128000, LocalTranscriptMigrationRequiredError, LocalTranscriptRepairRequiredError;
|
|
110438
110492
|
var init_local_transcript = __esm(() => {
|
|
110493
|
+
LOCAL_TRANSCRIPT_TAIL_MAX_BYTES = 16 * 1024 * 1024;
|
|
110439
110494
|
LocalTranscriptMigrationRequiredError = class LocalTranscriptMigrationRequiredError extends Error {
|
|
110440
110495
|
constructor(storageDir) {
|
|
110441
110496
|
const command = localTranscriptMigrationCommand(storageDir);
|
|
@@ -110808,7 +110863,7 @@ class LocalStore {
|
|
|
110808
110863
|
return record4;
|
|
110809
110864
|
const contextWindowLimit = record4.model_settings.context_window_limit;
|
|
110810
110865
|
const defaultContextWindowLimit = defaults4.context_window_limit;
|
|
110811
|
-
const shouldReplaceLegacyContextWindow = contextWindowLimit ===
|
|
110866
|
+
const shouldReplaceLegacyContextWindow = contextWindowLimit === LEGACY_LOCAL_CONTEXT_WINDOW_LIMIT2 && typeof defaultContextWindowLimit === "number" && defaultContextWindowLimit > LEGACY_LOCAL_CONTEXT_WINDOW_LIMIT2;
|
|
110812
110867
|
return {
|
|
110813
110868
|
...record4,
|
|
110814
110869
|
model_settings: {
|
|
@@ -111746,12 +111801,13 @@ class LocalStore {
|
|
|
111746
111801
|
return;
|
|
111747
111802
|
}
|
|
111748
111803
|
const conversation = this.conversations.get(key);
|
|
111804
|
+
const activeMessageIds = conversation?.in_context_message_ids ?? [];
|
|
111749
111805
|
const {
|
|
111750
111806
|
transcript: transcript2,
|
|
111751
111807
|
messages: tailMessages,
|
|
111752
111808
|
headBytes,
|
|
111753
111809
|
liveInContextIds
|
|
111754
|
-
} = readLocalTranscriptTailWindow(metadata.messagesPath, metadata.messageFormat,
|
|
111810
|
+
} = readLocalTranscriptTailWindow(metadata.messagesPath, metadata.messageFormat, activeMessageIds, this.residentMessageTailLimit, this.storageDir ?? "", metadata.conversationDir, localTranscriptTailByteBudget(conversation, this.agents.get(agentId)?.model_settings));
|
|
111755
111811
|
const toolResultClip = clipOversizedLocalToolResults(tailMessages);
|
|
111756
111812
|
const messages = toolResultClip.messages;
|
|
111757
111813
|
if (toolResultClip.clippedToolResultIds.length > 0) {
|
|
@@ -111760,8 +111816,9 @@ class LocalStore {
|
|
|
111760
111816
|
this.localMessagesByConversationKey.set(key, messages);
|
|
111761
111817
|
if (conversation)
|
|
111762
111818
|
conversation.in_context_message_ids = liveInContextIds;
|
|
111819
|
+
const head = activeMessageIds.length === 0 ? -headBytes : headBytes;
|
|
111763
111820
|
if (headBytes > 0)
|
|
111764
|
-
this.unreadTranscriptHeadBytesByKey.set(key,
|
|
111821
|
+
this.unreadTranscriptHeadBytesByKey.set(key, head);
|
|
111765
111822
|
else
|
|
111766
111823
|
this.unreadTranscriptHeadBytesByKey.delete(key);
|
|
111767
111824
|
this.loadedConversationKeys.delete(key);
|
|
@@ -111836,12 +111893,13 @@ class LocalStore {
|
|
|
111836
111893
|
});
|
|
111837
111894
|
}
|
|
111838
111895
|
validateUnreadTranscriptHeadOnce(key) {
|
|
111839
|
-
const
|
|
111840
|
-
if (
|
|
111896
|
+
const storedHeadBytes = this.unreadTranscriptHeadBytesByKey.get(key);
|
|
111897
|
+
if (storedHeadBytes === undefined)
|
|
111841
111898
|
return;
|
|
111899
|
+
const headBytes = Math.abs(storedHeadBytes);
|
|
111842
111900
|
const metadata = this.transcriptMetadataByConversationKey.get(key);
|
|
111843
111901
|
if (metadata) {
|
|
111844
|
-
validateUnreadTranscriptHead(metadata.messagesPath, headBytes, this.storageDir ?? "", metadata.conversationDir, this.conversations.get(key)?.in_context_message_ids ?? []);
|
|
111902
|
+
validateUnreadTranscriptHead(metadata.messagesPath, headBytes, this.storageDir ?? "", metadata.conversationDir, storedHeadBytes < 0 ? [] : this.conversations.get(key)?.in_context_message_ids ?? []);
|
|
111845
111903
|
}
|
|
111846
111904
|
this.unreadTranscriptHeadBytesByKey.delete(key);
|
|
111847
111905
|
}
|
|
@@ -112434,7 +112492,7 @@ class LocalStore {
|
|
|
112434
112492
|
return conversationId === "default" ? `default:${agentId}` : `conversation:${conversationId}`;
|
|
112435
112493
|
}
|
|
112436
112494
|
}
|
|
112437
|
-
var DEFAULT_LOCAL_AGENT_NAME = "Letta Code", DEFAULT_LOCAL_MODEL = "local/default",
|
|
112495
|
+
var DEFAULT_LOCAL_AGENT_NAME = "Letta Code", DEFAULT_LOCAL_MODEL = "local/default", LEGACY_LOCAL_CONTEXT_WINDOW_LIMIT2 = 128000, DEFAULT_LOCAL_CONVERSATION_ID_PREFIX = "local-conv-", DEFAULT_LOCAL_STORED_MESSAGE_ID_PREFIX = "letta-msg-", DEFAULT_LOCAL_UI_MESSAGE_ID_PREFIX = "ui-msg-", DEFAULT_RESIDENT_MESSAGE_TAIL_LIMIT = 100, LocalBackendNotFoundError;
|
|
112438
112496
|
var init_local_store = __esm(() => {
|
|
112439
112497
|
init_constants2();
|
|
112440
112498
|
init_local_agent_record();
|
|
@@ -118372,6 +118430,7 @@ var init_local_backend = __esm(() => {
|
|
|
118372
118430
|
init_memory_git();
|
|
118373
118431
|
init_headless_backend();
|
|
118374
118432
|
init_pi_models_runtime();
|
|
118433
|
+
init_settings_manager();
|
|
118375
118434
|
init_compaction();
|
|
118376
118435
|
init_initial_memory();
|
|
118377
118436
|
init_local_executor_factory();
|
|
@@ -118472,7 +118531,8 @@ var init_local_backend = __esm(() => {
|
|
|
118472
118531
|
}
|
|
118473
118532
|
async createAgent(...args) {
|
|
118474
118533
|
let [body, ...restArgs] = args;
|
|
118475
|
-
|
|
118534
|
+
const memfsExplicitlyDisabled = isMemfsOptOutCreateTags(body.tags);
|
|
118535
|
+
if (this.isLocalMemfsEnabled() && !memfsExplicitlyDisabled) {
|
|
118476
118536
|
body = stampRootMemoryOnCreateBody(body);
|
|
118477
118537
|
const bodyRecord = body;
|
|
118478
118538
|
const existingTags = Array.isArray(bodyRecord.tags) ? bodyRecord.tags : [];
|
|
@@ -118489,10 +118549,13 @@ var init_local_backend = __esm(() => {
|
|
|
118489
118549
|
}
|
|
118490
118550
|
const compactionSettingsForStorage = localCompactionSettingsForStorage(requestedCompactionSettings);
|
|
118491
118551
|
let agent = await super.createAgent(body, ...restArgs);
|
|
118552
|
+
if (memfsExplicitlyDisabled) {
|
|
118553
|
+
settingsManager.setMemfsEnabled(agent.id, false);
|
|
118554
|
+
}
|
|
118492
118555
|
if (compactionSettingsForStorage !== undefined) {
|
|
118493
118556
|
agent = this.store.setAgentCompactionSettings(agent.id, compactionSettingsForStorage);
|
|
118494
118557
|
}
|
|
118495
|
-
if (this.
|
|
118558
|
+
if (this.isMemfsEnabledForAgent(agent.id)) {
|
|
118496
118559
|
await this.ensureLocalMemoryRepo(agent.id, initialMemoryFilesFromCreateBody(body), agent.name ?? undefined);
|
|
118497
118560
|
}
|
|
118498
118561
|
await this.compileAndMaybePersistSystemPrompt("default", agent.id, {
|
|
@@ -118560,6 +118623,10 @@ var init_local_backend = __esm(() => {
|
|
|
118560
118623
|
isLocalMemfsEnabled() {
|
|
118561
118624
|
return this.memfsEnabledOverride ?? !isLocalBackendMemfsDisabledForProcess();
|
|
118562
118625
|
}
|
|
118626
|
+
isMemfsEnabledForAgent(agentId) {
|
|
118627
|
+
const { tags } = this.store.retrieveAgentRecord(agentId);
|
|
118628
|
+
return this.isLocalMemfsEnabled() && !isMemfsOptOutCreateTags(tags);
|
|
118629
|
+
}
|
|
118563
118630
|
async ensureLocalMemoryRepo(agentId, files = [], authorName) {
|
|
118564
118631
|
await initializeLocalMemoryRepo({
|
|
118565
118632
|
memoryDir: this.memoryDirForAgent(agentId),
|
|
@@ -118752,7 +118819,7 @@ var init_local_backend = __esm(() => {
|
|
|
118752
118819
|
async getOrCompileSystemPrompt(conversationId, agentId, agent = this.store.retrieveAgentRecord(agentId), previousMessageCount = 0) {
|
|
118753
118820
|
const existing = this.store.getCompiledSystemPrompt(conversationId, agentId);
|
|
118754
118821
|
const rawSystemHash = hashRawSystemPrompt(agent.system);
|
|
118755
|
-
const memfsRevision = this.
|
|
118822
|
+
const memfsRevision = this.isMemfsEnabledForAgent(agentId) ? getCommittedMemfsRevision(this.memoryDirForAgent(agentId)) : undefined;
|
|
118756
118823
|
if (existing?.rawSystemHash === rawSystemHash && existing.memfsRevision === memfsRevision) {
|
|
118757
118824
|
return existing;
|
|
118758
118825
|
}
|
|
@@ -118780,7 +118847,7 @@ var init_local_backend = __esm(() => {
|
|
|
118780
118847
|
}
|
|
118781
118848
|
async compileAndMaybePersistSystemPrompt(conversationId, agentId, options) {
|
|
118782
118849
|
const agent = this.store.retrieveAgentRecord(agentId);
|
|
118783
|
-
const memfsEnabled = this.
|
|
118850
|
+
const memfsEnabled = this.isMemfsEnabledForAgent(agentId);
|
|
118784
118851
|
if (memfsEnabled) {
|
|
118785
118852
|
await this.ensureLocalMemoryRepo(agentId, [], agent.name);
|
|
118786
118853
|
}
|
|
@@ -210764,7 +210831,7 @@ var init_mcp_client = __esm(() => {
|
|
|
210764
210831
|
init_streamableHttp();
|
|
210765
210832
|
DEFAULT_CLIENT_INFO = {
|
|
210766
210833
|
name: "letta-code",
|
|
210767
|
-
version: "0.34.
|
|
210834
|
+
version: "0.34.14"
|
|
210768
210835
|
};
|
|
210769
210836
|
});
|
|
210770
210837
|
|
|
@@ -210795,17 +210862,17 @@ async function startOAuthCallbackServerOnPort(port) {
|
|
|
210795
210862
|
let completed = false;
|
|
210796
210863
|
let settle;
|
|
210797
210864
|
let reject2;
|
|
210798
|
-
const
|
|
210799
|
-
settle = (
|
|
210865
|
+
const callbackPromise = new Promise((resolve13, rejectPromise) => {
|
|
210866
|
+
settle = (result2) => {
|
|
210800
210867
|
completed = true;
|
|
210801
|
-
resolve13(
|
|
210868
|
+
resolve13(result2);
|
|
210802
210869
|
};
|
|
210803
210870
|
reject2 = (error5) => {
|
|
210804
210871
|
completed = true;
|
|
210805
210872
|
rejectPromise(error5);
|
|
210806
210873
|
};
|
|
210807
210874
|
});
|
|
210808
|
-
|
|
210875
|
+
callbackPromise.catch(() => {
|
|
210809
210876
|
return;
|
|
210810
210877
|
});
|
|
210811
210878
|
server2 = createServer4((request, response) => {
|
|
@@ -210836,6 +210903,7 @@ async function startOAuthCallbackServerOnPort(port) {
|
|
|
210836
210903
|
const error5 = url2.searchParams.get("error");
|
|
210837
210904
|
const code2 = url2.searchParams.get("code");
|
|
210838
210905
|
const state2 = url2.searchParams.get("state");
|
|
210906
|
+
const domain = url2.searchParams.get("domain");
|
|
210839
210907
|
if (!state2 || state2 !== expectedState.value) {
|
|
210840
210908
|
response.writeHead(400, { "Content-Type": "text/html" });
|
|
210841
210909
|
response.end(callbackPage("Authorization failed", "Invalid OAuth callback"));
|
|
@@ -210855,7 +210923,7 @@ async function startOAuthCallbackServerOnPort(port) {
|
|
|
210855
210923
|
return;
|
|
210856
210924
|
}
|
|
210857
210925
|
response.writeHead(200, { "Content-Type": "text/html" });
|
|
210858
|
-
settle?.(code2);
|
|
210926
|
+
settle?.(domain ? { code: code2, domain } : { code: code2 });
|
|
210859
210927
|
response.end(callbackPage("Authorization complete", "You can close this tab and return to Letta Code."), () => {
|
|
210860
210928
|
closeServer2(true);
|
|
210861
210929
|
});
|
|
@@ -210896,7 +210964,7 @@ Content-Length: 0\r
|
|
|
210896
210964
|
return {
|
|
210897
210965
|
redirectUrl: `http://127.0.0.1:${address.port}/callback`,
|
|
210898
210966
|
expectedState,
|
|
210899
|
-
|
|
210967
|
+
waitForCallback: () => callbackPromise.finally(() => clearTimeout(timeout)),
|
|
210900
210968
|
close: () => {
|
|
210901
210969
|
clearTimeout(timeout);
|
|
210902
210970
|
if (!completed)
|
|
@@ -210925,6 +210993,20 @@ var init_mcp_oauth_callback = __esm(() => {
|
|
|
210925
210993
|
CALLBACK_TIMEOUT_MS = 5 * 60 * 1000;
|
|
210926
210994
|
});
|
|
210927
210995
|
|
|
210996
|
+
// src/mcp-oauth-client-name.ts
|
|
210997
|
+
function resolveMcpOAuthClientName(clientName) {
|
|
210998
|
+
if (clientName === undefined)
|
|
210999
|
+
return DEFAULT_MCP_OAUTH_CLIENT_NAME;
|
|
211000
|
+
const trimmed = clientName.trim();
|
|
211001
|
+
if (!trimmed)
|
|
211002
|
+
throw new Error("MCP OAuth client name must not be empty");
|
|
211003
|
+
if (trimmed.length > MAX_MCP_OAUTH_CLIENT_NAME_LENGTH) {
|
|
211004
|
+
throw new Error(`MCP OAuth client name must be at most ${MAX_MCP_OAUTH_CLIENT_NAME_LENGTH} characters`);
|
|
211005
|
+
}
|
|
211006
|
+
return trimmed;
|
|
211007
|
+
}
|
|
211008
|
+
var DEFAULT_MCP_OAUTH_CLIENT_NAME = "Letta Code", MAX_MCP_OAUTH_CLIENT_NAME_LENGTH = 64;
|
|
211009
|
+
|
|
210928
211010
|
// src/mcp-oauth-identity.ts
|
|
210929
211011
|
import { createHash as createHash4 } from "node:crypto";
|
|
210930
211012
|
function mcpOAuthCredentialKey(agentId, serverName, serverUrl) {
|
|
@@ -210999,10 +211081,12 @@ async function createMcpOAuthSession(agentId, serverName, serverUrl, options) {
|
|
|
210999
211081
|
storage: bunSecretStorage,
|
|
211000
211082
|
interactive: options.interactive,
|
|
211001
211083
|
onStatus: options.onStatus,
|
|
211002
|
-
openBrowser: options.openBrowser ?? openSystemBrowser
|
|
211084
|
+
openBrowser: options.openBrowser ?? openSystemBrowser,
|
|
211085
|
+
clientName: options.clientName
|
|
211003
211086
|
});
|
|
211004
211087
|
}
|
|
211005
211088
|
async function createMcpOAuthSessionWithStorage(options) {
|
|
211089
|
+
const clientName = resolveMcpOAuthClientName(options.clientName);
|
|
211006
211090
|
const coordinationKey = storageCoordinationKey(options.storage, options.credentialKey, options.storageNamespace);
|
|
211007
211091
|
retainCredentialCoordinator(coordinationKey);
|
|
211008
211092
|
let provider;
|
|
@@ -211030,13 +211114,20 @@ async function createMcpOAuthSessionWithStorage(options) {
|
|
|
211030
211114
|
onStatus: options.onStatus,
|
|
211031
211115
|
openBrowser: options.openBrowser ?? openSystemBrowser,
|
|
211032
211116
|
expectedState: callback?.expectedState,
|
|
211033
|
-
generation: loaded.generation
|
|
211117
|
+
generation: loaded.generation,
|
|
211118
|
+
clientName
|
|
211034
211119
|
});
|
|
211035
211120
|
const activeProvider = provider;
|
|
211036
211121
|
const activeCallback = callback;
|
|
211037
211122
|
return {
|
|
211038
211123
|
authProvider: activeProvider,
|
|
211039
|
-
...activeCallback ? {
|
|
211124
|
+
...activeCallback ? {
|
|
211125
|
+
waitForAuthorizationCode: async () => {
|
|
211126
|
+
const { code: code2, domain } = await activeCallback.waitForCallback();
|
|
211127
|
+
options.onAuthorizationCallback?.({ domain });
|
|
211128
|
+
return code2;
|
|
211129
|
+
}
|
|
211130
|
+
} : {},
|
|
211040
211131
|
exportCredentials: () => activeProvider.exportCredentials(),
|
|
211041
211132
|
closeCallback: async () => activeCallback?.close(),
|
|
211042
211133
|
close: async () => {
|
|
@@ -211073,6 +211164,7 @@ class PersistentMcpOAuthProvider {
|
|
|
211073
211164
|
onStatus;
|
|
211074
211165
|
openBrowser;
|
|
211075
211166
|
expectedState;
|
|
211167
|
+
clientName;
|
|
211076
211168
|
closed = false;
|
|
211077
211169
|
constructor(options) {
|
|
211078
211170
|
this.credentialKey = options.credentialKey;
|
|
@@ -211082,6 +211174,7 @@ class PersistentMcpOAuthProvider {
|
|
|
211082
211174
|
this.onStatus = options.onStatus;
|
|
211083
211175
|
this.openBrowser = options.openBrowser;
|
|
211084
211176
|
this.expectedState = options.expectedState;
|
|
211177
|
+
this.clientName = options.clientName;
|
|
211085
211178
|
this.generation = options.generation;
|
|
211086
211179
|
const coordinator = getCredentialCoordinator(options.coordinationKey);
|
|
211087
211180
|
this.coordinatorValue = coordinator;
|
|
@@ -211101,7 +211194,7 @@ class PersistentMcpOAuthProvider {
|
|
|
211101
211194
|
}
|
|
211102
211195
|
get clientMetadata() {
|
|
211103
211196
|
return {
|
|
211104
|
-
client_name:
|
|
211197
|
+
client_name: this.clientName,
|
|
211105
211198
|
redirect_uris: [this.redirectUrl],
|
|
211106
211199
|
grant_types: ["authorization_code", "refresh_token"],
|
|
211107
211200
|
response_types: ["code"],
|
|
@@ -211596,7 +211689,7 @@ async function authorizeMcpServerWithStorage(options) {
|
|
|
211596
211689
|
throw new Error("MCP OAuth storage namespace must be non-empty and contain no NUL bytes");
|
|
211597
211690
|
}
|
|
211598
211691
|
const credentialKey = mcpOAuthCredentialKey(options.agentId, options.serverName, options.serverUrl);
|
|
211599
|
-
const flightKey = `${options.storageNamespace}\x00${credentialKey}\x00${fetchIdentity(options.fetch)}`;
|
|
211692
|
+
const flightKey = `${options.storageNamespace}\x00${credentialKey}\x00${fetchIdentity(options.fetch)}\x00${options.clientName ?? ""}`;
|
|
211600
211693
|
let flight = inFlightAuthorizations.get(flightKey);
|
|
211601
211694
|
if (!flight) {
|
|
211602
211695
|
const controller = new AbortController;
|
|
@@ -211626,7 +211719,9 @@ async function runAuthorization(options, credentialKey, signal) {
|
|
|
211626
211719
|
storage,
|
|
211627
211720
|
interactive: true,
|
|
211628
211721
|
openBrowser: options.openBrowser,
|
|
211629
|
-
onStatus: options.onStatus
|
|
211722
|
+
onStatus: options.onStatus,
|
|
211723
|
+
onAuthorizationCallback: options.onAuthorizationCallback,
|
|
211724
|
+
clientName: options.clientName
|
|
211630
211725
|
});
|
|
211631
211726
|
let oauth;
|
|
211632
211727
|
try {
|
|
@@ -211763,11 +211858,18 @@ async function connectBrowserDeviceMcpOAuth(request, dependencies4 = {
|
|
|
211763
211858
|
try {
|
|
211764
211859
|
const credentials = await dependencies4.authorize({
|
|
211765
211860
|
agentId: handoffNamespace(request.handoffKey),
|
|
211861
|
+
clientName: request.clientName,
|
|
211766
211862
|
openBrowser: async (value) => {
|
|
211767
211863
|
const url2 = allowedAuthorizationUrl(value, definition.authorizationOrigins);
|
|
211768
211864
|
await dependencies4.openBrowser(url2.href);
|
|
211769
211865
|
},
|
|
211770
211866
|
fetch: createProviderFetch(definition, dependencies4.providerFetch ?? globalThis.fetch),
|
|
211867
|
+
onAuthorizationCallback: ({ domain }) => {
|
|
211868
|
+
const reported = definitionForCallbackDomain(request.service, domain);
|
|
211869
|
+
if (reported?.site && reported !== definition) {
|
|
211870
|
+
throw new BrowserDeviceMcpOAuthSiteMismatchError(reported.site, reported.serverUrl);
|
|
211871
|
+
}
|
|
211872
|
+
},
|
|
211771
211873
|
serverName: definition.serverName,
|
|
211772
211874
|
serverUrl: definition.serverUrl,
|
|
211773
211875
|
signal: authorizationSignal,
|
|
@@ -211852,6 +211954,13 @@ function findDefinition(service, normalizedServerUrl) {
|
|
|
211852
211954
|
}
|
|
211853
211955
|
return BROWSER_DEVICE_MCP_OAUTH_SERVICES[service]?.find((candidate) => normalizeServerUrl(candidate.serverUrl) === normalizedServerUrl);
|
|
211854
211956
|
}
|
|
211957
|
+
function definitionForCallbackDomain(service, domain) {
|
|
211958
|
+
if (!domain || !Object.hasOwn(BROWSER_DEVICE_MCP_OAUTH_SERVICES, service)) {
|
|
211959
|
+
return;
|
|
211960
|
+
}
|
|
211961
|
+
const site = domain.trim().toLowerCase().replace(/^https:\/\//, "").replace(/\/+$/, "").replace(/^(?:app|api)\./, "");
|
|
211962
|
+
return BROWSER_DEVICE_MCP_OAUTH_SERVICES[service]?.find((candidate) => candidate.site !== undefined && candidate.site === site);
|
|
211963
|
+
}
|
|
211855
211964
|
function browserDeviceMcpOAuthServerUrls() {
|
|
211856
211965
|
return Object.fromEntries(Object.entries(BROWSER_DEVICE_MCP_OAUTH_SERVICES).map(([service, definitions]) => [
|
|
211857
211966
|
service,
|
|
@@ -212004,7 +212113,8 @@ function datadogDefinition(mcpHost, appHost) {
|
|
|
212004
212113
|
return {
|
|
212005
212114
|
authorizationOrigins: [`https://${appHost}`],
|
|
212006
212115
|
serverName: "Datadog",
|
|
212007
|
-
serverUrl: `https://mcp.${mcpHost}/v1/mcp
|
|
212116
|
+
serverUrl: `https://mcp.${mcpHost}/v1/mcp`,
|
|
212117
|
+
site: mcpHost
|
|
212008
212118
|
};
|
|
212009
212119
|
}
|
|
212010
212120
|
function handoffNamespace(handoffKey) {
|
|
@@ -212018,7 +212128,7 @@ async function openSystemBrowser2(url2) {
|
|
|
212018
212128
|
return;
|
|
212019
212129
|
});
|
|
212020
212130
|
}
|
|
212021
|
-
var HANDOFF_KEY_PATTERN, BROWSER_DEVICE_HANDOFF_SUBMIT_TIMEOUT_MS = 90000, HANDOFF_ATTEMPT_TIMEOUT_MS = 1e4, PROVIDER_AUTHORIZATION_TIMEOUT_MS = 190000, HANDOFF_RETRY_BASE_DELAY_MS = 1000, HANDOFF_RETRY_MAX_DELAY_MS = 1e4, HANDOFF_RETRY_AFTER_MAX_DELAY_MS = 60000, BROWSER_DEVICE_MCP_OAUTH_SERVICES, BrowserDeviceMcpOAuthRequestError;
|
|
212131
|
+
var HANDOFF_KEY_PATTERN, BROWSER_DEVICE_HANDOFF_SUBMIT_TIMEOUT_MS = 90000, HANDOFF_ATTEMPT_TIMEOUT_MS = 1e4, PROVIDER_AUTHORIZATION_TIMEOUT_MS = 190000, HANDOFF_RETRY_BASE_DELAY_MS = 1000, HANDOFF_RETRY_MAX_DELAY_MS = 1e4, HANDOFF_RETRY_AFTER_MAX_DELAY_MS = 60000, BROWSER_DEVICE_MCP_OAUTH_SERVICES, BrowserDeviceMcpOAuthRequestError, BrowserDeviceMcpOAuthSiteMismatchError;
|
|
212022
212132
|
var init_browser_device_mcp_oauth = __esm(() => {
|
|
212023
212133
|
init_oauth();
|
|
212024
212134
|
init_request();
|
|
@@ -212048,6 +212158,16 @@ var init_browser_device_mcp_oauth = __esm(() => {
|
|
|
212048
212158
|
this.name = "BrowserDeviceMcpOAuthRequestError";
|
|
212049
212159
|
}
|
|
212050
212160
|
};
|
|
212161
|
+
BrowserDeviceMcpOAuthSiteMismatchError = class BrowserDeviceMcpOAuthSiteMismatchError extends Error {
|
|
212162
|
+
site;
|
|
212163
|
+
serverUrl;
|
|
212164
|
+
constructor(site, serverUrl) {
|
|
212165
|
+
super(`OAuth provider authorized on ${site}; use ${serverUrl}`);
|
|
212166
|
+
this.site = site;
|
|
212167
|
+
this.serverUrl = serverUrl;
|
|
212168
|
+
this.name = "BrowserDeviceMcpOAuthSiteMismatchError";
|
|
212169
|
+
}
|
|
212170
|
+
};
|
|
212051
212171
|
});
|
|
212052
212172
|
|
|
212053
212173
|
// src/websocket/listener/commands/browser-device-mcp-oauth.ts
|
|
@@ -218150,6 +218270,7 @@ function wrapManagedWorkloadLauncher(launcher, options = {}) {
|
|
|
218150
218270
|
"--quiet",
|
|
218151
218271
|
"--collect",
|
|
218152
218272
|
"--property=TimeoutStopSec=5s",
|
|
218273
|
+
"--property=OOMPolicy=continue",
|
|
218153
218274
|
`--slice=${slice2}`,
|
|
218154
218275
|
"--",
|
|
218155
218276
|
...launcher
|
|
@@ -239425,9 +239546,7 @@ function buildClaudeStreamArgs(options) {
|
|
|
239425
239546
|
"stream-json",
|
|
239426
239547
|
"--include-partial-messages",
|
|
239427
239548
|
"--permission-mode",
|
|
239428
|
-
"
|
|
239429
|
-
"--allowed-tools",
|
|
239430
|
-
"Bash,Edit,Write,Read,Glob,Grep,WebFetch,WebSearch"
|
|
239549
|
+
"bypassPermissions"
|
|
239431
239550
|
];
|
|
239432
239551
|
if (options.model)
|
|
239433
239552
|
args.push("--model", options.model);
|
|
@@ -239625,7 +239744,8 @@ async function launchSession(options, deps) {
|
|
|
239625
239744
|
const env6 = {
|
|
239626
239745
|
...deps.env ?? process.env,
|
|
239627
239746
|
AGENT_ID: options.parentAgentId,
|
|
239628
|
-
LETTA_AGENT_ID: options.parentAgentId
|
|
239747
|
+
LETTA_AGENT_ID: options.parentAgentId,
|
|
239748
|
+
IS_SANDBOX: "1"
|
|
239629
239749
|
};
|
|
239630
239750
|
const abortController = new AbortController;
|
|
239631
239751
|
const abortFromUpstream = () => abortController.abort(options.signal?.reason ?? "Claude Code turn cancelled");
|
|
@@ -239707,7 +239827,8 @@ async function launchSession(options, deps) {
|
|
|
239707
239827
|
return;
|
|
239708
239828
|
const detail = session3.stderr.trim();
|
|
239709
239829
|
const protocolDetail = session3.protocolError ? `; protocol error: ${session3.protocolError}` : "";
|
|
239710
|
-
const
|
|
239830
|
+
const oomDetail = exitCode === 143 || exitSignal === "SIGTERM" || exitSignal === "SIGKILL" ? "; possibly out of memory" : "";
|
|
239831
|
+
const error5 = transport3.wasAborted() ? abortController.signal.reason ?? "Claude Code turn cancelled" : `Claude Code exited before a final result with ${exitCode ?? exitSignal ?? "unknown status"}${oomDetail}${detail ? `: ${detail}` : ""}${protocolDetail}`;
|
|
239711
239832
|
rejectControls(session3, new Error(errorMessage(error5)));
|
|
239712
239833
|
settle(session3, failResult(session3, error5));
|
|
239713
239834
|
}).catch((error5) => {
|
|
@@ -239860,7 +239981,10 @@ function spawnTransport(options) {
|
|
|
239860
239981
|
stdin: child.stdin,
|
|
239861
239982
|
stdout: child.stdout,
|
|
239862
239983
|
stderr: child.stderr,
|
|
239863
|
-
kill: () => child.kill()
|
|
239984
|
+
kill: () => child.kill(),
|
|
239985
|
+
exited: new Promise((resolve35) => {
|
|
239986
|
+
child.once("close", (code2, signal) => resolve35({ code: code2, signal }));
|
|
239987
|
+
})
|
|
239864
239988
|
};
|
|
239865
239989
|
}
|
|
239866
239990
|
function asRecord9(value) {
|
|
@@ -239900,6 +240024,7 @@ class CodexAppServerClient {
|
|
|
239900
240024
|
this.onNotification = onNotification;
|
|
239901
240025
|
this.onClose = onClose;
|
|
239902
240026
|
const stdout = createInterface9({ input: transport3.stdout });
|
|
240027
|
+
stdout.once("error", () => void this.close());
|
|
239903
240028
|
stdout.on("line", (line) => {
|
|
239904
240029
|
if (!line.trim())
|
|
239905
240030
|
return;
|
|
@@ -239928,7 +240053,7 @@ class CodexAppServerClient {
|
|
|
239928
240053
|
transport3.stderr?.on("data", (chunk2) => {
|
|
239929
240054
|
this.stderr += chunk2;
|
|
239930
240055
|
});
|
|
239931
|
-
const close = () => this.close();
|
|
240056
|
+
const close = () => void this.close();
|
|
239932
240057
|
transport3.stdout.once("close", close);
|
|
239933
240058
|
transport3.stdout.once("error", close);
|
|
239934
240059
|
}
|
|
@@ -239936,7 +240061,7 @@ class CodexAppServerClient {
|
|
|
239936
240061
|
await this.request("initialize", {
|
|
239937
240062
|
clientInfo: {
|
|
239938
240063
|
name: "letta-code",
|
|
239939
|
-
version: "0.34.
|
|
240064
|
+
version: "0.34.14"
|
|
239940
240065
|
},
|
|
239941
240066
|
capabilities: null
|
|
239942
240067
|
});
|
|
@@ -239967,12 +240092,20 @@ class CodexAppServerClient {
|
|
|
239967
240092
|
this.transport.kill?.();
|
|
239968
240093
|
this.close();
|
|
239969
240094
|
}
|
|
239970
|
-
close() {
|
|
240095
|
+
async close() {
|
|
239971
240096
|
if (this.closed)
|
|
239972
240097
|
return;
|
|
239973
240098
|
this.closed = true;
|
|
239974
|
-
|
|
239975
|
-
const
|
|
240099
|
+
let exitTimeout;
|
|
240100
|
+
const exit = this.transport.exited ? await Promise.race([
|
|
240101
|
+
this.transport.exited,
|
|
240102
|
+
new Promise((resolve35) => {
|
|
240103
|
+
exitTimeout = setTimeout(() => resolve35(undefined), 2000);
|
|
240104
|
+
})
|
|
240105
|
+
]).finally(() => clearTimeout(exitTimeout)) : undefined;
|
|
240106
|
+
const detail = this.stderr.trim().slice(-300);
|
|
240107
|
+
const exitDetail = exit?.signal ? ` (signal ${exit.signal}${exit.signal === "SIGKILL" || exit.signal === "SIGTERM" ? "; possibly out of memory" : ""})` : exit?.code != null ? ` (exit code ${exit.code}${exit.code === 143 ? "; possibly out of memory" : ""})` : "";
|
|
240108
|
+
const error5 = new Error(`Codex app-server closed${exitDetail}${detail ? `: ${detail}` : ""}`);
|
|
239976
240109
|
for (const pending2 of this.pending.values())
|
|
239977
240110
|
pending2.reject(error5);
|
|
239978
240111
|
this.pending.clear();
|
|
@@ -240164,7 +240297,7 @@ async function createSession(options, deps) {
|
|
|
240164
240297
|
cwd: options.cwd,
|
|
240165
240298
|
model: options.model,
|
|
240166
240299
|
approvalPolicy: "never",
|
|
240167
|
-
sandbox: "
|
|
240300
|
+
sandbox: "danger-full-access",
|
|
240168
240301
|
developerInstructions: options.mcpReminder
|
|
240169
240302
|
};
|
|
240170
240303
|
response = await client.request(method2, params);
|
|
@@ -240215,11 +240348,7 @@ async function startTurnUnlocked(session3, prompt, signal, onStarted, onToolCall
|
|
|
240215
240348
|
cwd: session3.cwd,
|
|
240216
240349
|
model: session3.model,
|
|
240217
240350
|
approvalPolicy: "never",
|
|
240218
|
-
sandboxPolicy: {
|
|
240219
|
-
type: "workspaceWrite",
|
|
240220
|
-
writableRoots: [session3.cwd],
|
|
240221
|
-
networkAccess: true
|
|
240222
|
-
}
|
|
240351
|
+
sandboxPolicy: { type: "dangerFullAccess" }
|
|
240223
240352
|
});
|
|
240224
240353
|
const turn = asRecord9(response.turn);
|
|
240225
240354
|
const turnId = readString3(turn, "id");
|
|
@@ -246106,9 +246235,14 @@ function formatOutdatedComputerError(type3, computer) {
|
|
|
246106
246235
|
return `${computer} is running an older Letta Code that can't run ${DISPLAY_NAMES[type3]} subagents remotely. Update Letta Code on ${computer}.`;
|
|
246107
246236
|
}
|
|
246108
246237
|
async function defaultResolveComputer(computer, scope) {
|
|
246109
|
-
|
|
246110
|
-
|
|
246111
|
-
|
|
246238
|
+
if (!isCloudEnvironmentSelector(computer))
|
|
246239
|
+
return resolveEnvironmentConnectionId(computer);
|
|
246240
|
+
const client = await getClient();
|
|
246241
|
+
const createParams = { agent_id: scope.agentId, hidden: true };
|
|
246242
|
+
const conversation = await client.conversations.create(createParams);
|
|
246243
|
+
return resolveAgentSandboxConnectionId(scope.agentId, {
|
|
246244
|
+
conversationId: conversation.id
|
|
246245
|
+
});
|
|
246112
246246
|
}
|
|
246113
246247
|
async function defaultConnect(connectionId, scope) {
|
|
246114
246248
|
const auth2 = await getApiRequestConfig();
|
|
@@ -246345,6 +246479,7 @@ var DISPLAY_NAMES, RemoteWorkerLostError;
|
|
|
246345
246479
|
var init_remote_external_coding_agent = __esm(() => {
|
|
246346
246480
|
init_subagent_state();
|
|
246347
246481
|
init_app_server_client();
|
|
246482
|
+
init_client4();
|
|
246348
246483
|
init_environments3();
|
|
246349
246484
|
init_request();
|
|
246350
246485
|
init_headless_environment_response();
|
|
@@ -250461,7 +250596,7 @@ Usage:
|
|
|
250461
250596
|
letta mcp schema <tool-name> [--agent <id>]
|
|
250462
250597
|
letta mcp search <query> [--mode <hybrid|vector|fts>] [--limit <n>] [--agent <id>]
|
|
250463
250598
|
letta mcp call <tool-name> [--args '<json>' | --args-file <path|->] [--agent <id>]
|
|
250464
|
-
letta mcp connect <service> [--server-url <url>] [--agent <id>]
|
|
250599
|
+
letta mcp connect <service> [--server-url <url>] [--client-name <name>] [--agent <id>]
|
|
250465
250600
|
|
|
250466
250601
|
Commands:
|
|
250467
250602
|
list List MCP servers available to the agent
|
|
@@ -250482,7 +250617,11 @@ Options:
|
|
|
250482
250617
|
--args <json> JSON object passed to a tool
|
|
250483
250618
|
--args-file <path> Read tool arguments from a file; use - for stdin
|
|
250484
250619
|
--server-url <url> MCP server for connect, e.g. a Datadog site's URL
|
|
250485
|
-
(default: the service's first supported URL
|
|
250620
|
+
(default: the service's first supported URL; non-US1
|
|
250621
|
+
Datadog orgs can pass https://mcp.<site>/v1/mcp)
|
|
250622
|
+
--client-name <name>
|
|
250623
|
+
Application name shown on the provider's consent screen
|
|
250624
|
+
during connect, 1 to 64 characters (default: Letta Code)
|
|
250486
250625
|
-h, --help Show this help
|
|
250487
250626
|
|
|
250488
250627
|
Output is JSON. Server placement and agent/server/tool IDs are internal.
|
|
@@ -250563,11 +250702,19 @@ function resolveConnectServer(service, serverUrl) {
|
|
|
250563
250702
|
}
|
|
250564
250703
|
return { service, serverUrl: matched };
|
|
250565
250704
|
}
|
|
250705
|
+
function resolveConnectClientName(clientName) {
|
|
250706
|
+
if (clientName === undefined)
|
|
250707
|
+
return;
|
|
250708
|
+
try {
|
|
250709
|
+
return resolveMcpOAuthClientName(clientName);
|
|
250710
|
+
} catch (error5) {
|
|
250711
|
+
throw new McpCliError("invalid_client_name", error5 instanceof Error ? error5.message : String(error5), "Pass --client-name with 1 to 64 non-blank characters.");
|
|
250712
|
+
}
|
|
250713
|
+
}
|
|
250566
250714
|
function isTimeout(error5) {
|
|
250567
250715
|
return error5 instanceof Error && (error5.name === "TimeoutError" || error5.name === "AbortError");
|
|
250568
250716
|
}
|
|
250569
|
-
async function
|
|
250570
|
-
const { service, serverUrl } = resolveConnectServer(serviceArg, serverUrlArg);
|
|
250717
|
+
async function authorizeAndSubmit(deps, agentId, service, serverUrl, clientName) {
|
|
250571
250718
|
let handoff;
|
|
250572
250719
|
try {
|
|
250573
250720
|
handoff = await (deps.mintMcpOAuthHandoff ?? defaultMintMcpOAuthHandoff)(agentId, service, serverUrl);
|
|
@@ -250586,10 +250733,18 @@ async function runMcpConnect(deps, agentId, serviceArg, serverUrlArg, stdout) {
|
|
|
250586
250733
|
return;
|
|
250587
250734
|
}, 60000);
|
|
250588
250735
|
try {
|
|
250589
|
-
await (deps.connectMcpOAuth ?? defaultConnectMcpOAuth)({
|
|
250736
|
+
await (deps.connectMcpOAuth ?? defaultConnectMcpOAuth)({
|
|
250737
|
+
handoffKey: handoff.handoff_key,
|
|
250738
|
+
service,
|
|
250739
|
+
serverUrl,
|
|
250740
|
+
...clientName === undefined ? {} : { clientName }
|
|
250741
|
+
}, () => {
|
|
250590
250742
|
submitting = true;
|
|
250591
250743
|
});
|
|
250592
250744
|
} catch (error5) {
|
|
250745
|
+
if (error5 instanceof BrowserDeviceMcpOAuthSiteMismatchError && !submitting) {
|
|
250746
|
+
throw error5;
|
|
250747
|
+
}
|
|
250593
250748
|
const message2 = error5 instanceof Error ? error5.message : String(error5);
|
|
250594
250749
|
if (submitting) {
|
|
250595
250750
|
throw new McpCliError("handoff_submit_failed", `Authorization succeeded but saving the connection to the agent failed: ${message2}`, `Re-run \`letta mcp connect ${service}\` to try again.`);
|
|
@@ -250601,10 +250756,31 @@ async function runMcpConnect(deps, agentId, serviceArg, serverUrlArg, stdout) {
|
|
|
250601
250756
|
} finally {
|
|
250602
250757
|
clearInterval(keepAlive);
|
|
250603
250758
|
}
|
|
250759
|
+
}
|
|
250760
|
+
async function runMcpConnect(deps, agentId, serviceArg, serverUrlArg, clientNameArg, stdout) {
|
|
250761
|
+
const resolved2 = resolveConnectServer(serviceArg, serverUrlArg);
|
|
250762
|
+
const clientName = resolveConnectClientName(clientNameArg);
|
|
250763
|
+
const { service } = resolved2;
|
|
250764
|
+
let { serverUrl } = resolved2;
|
|
250765
|
+
for (let attempt2 = 0;; attempt2 += 1) {
|
|
250766
|
+
try {
|
|
250767
|
+
await authorizeAndSubmit(deps, agentId, service, serverUrl, clientName);
|
|
250768
|
+
break;
|
|
250769
|
+
} catch (error5) {
|
|
250770
|
+
if (!(error5 instanceof BrowserDeviceMcpOAuthSiteMismatchError)) {
|
|
250771
|
+
throw error5;
|
|
250772
|
+
}
|
|
250773
|
+
if (attempt2 > 0) {
|
|
250774
|
+
throw new McpCliError("datadog_site_mismatch", `Your Datadog org is on ${error5.site}. Re-run: letta mcp connect ${service} --server-url ${error5.serverUrl}`);
|
|
250775
|
+
}
|
|
250776
|
+
serverUrl = error5.serverUrl;
|
|
250777
|
+
await deps.stderr(`Your Datadog org is on ${error5.site}. Restarting authorization against ${serverUrl}; approve the second browser prompt.`);
|
|
250778
|
+
}
|
|
250779
|
+
}
|
|
250604
250780
|
await stdout(JSON.stringify({ connected: true, service, server_url: serverUrl }, null, 2));
|
|
250605
250781
|
return 0;
|
|
250606
250782
|
}
|
|
250607
|
-
var CONNECT_USAGE = "Usage: letta mcp connect <service> [--server-url <url>] [--agent <id>]";
|
|
250783
|
+
var CONNECT_USAGE = "Usage: letta mcp connect <service> [--server-url <url>] [--client-name <name>] [--agent <id>]";
|
|
250608
250784
|
var init_mcp_connect = __esm(() => {
|
|
250609
250785
|
init_request();
|
|
250610
250786
|
init_browser_device_mcp_oauth();
|
|
@@ -250786,7 +250962,8 @@ function parseMcpArgs(argv) {
|
|
|
250786
250962
|
full: { type: "boolean" },
|
|
250787
250963
|
args: { type: "string" },
|
|
250788
250964
|
"args-file": { type: "string" },
|
|
250789
|
-
"server-url": { type: "string" }
|
|
250965
|
+
"server-url": { type: "string" },
|
|
250966
|
+
"client-name": { type: "string" }
|
|
250790
250967
|
},
|
|
250791
250968
|
strict: true,
|
|
250792
250969
|
allowPositionals: true
|
|
@@ -251316,7 +251493,7 @@ async function runMcpSubcommand(argv, deps = {}) {
|
|
|
251316
251493
|
case "run_tool":
|
|
251317
251494
|
return await runCall(parsed, deps, agentId, stdout);
|
|
251318
251495
|
case "connect":
|
|
251319
|
-
return await runMcpConnect({ ...deps, stderr }, agentId, parsed.target, stringValue3(parsed.values["server-url"]), stdout);
|
|
251496
|
+
return await runMcpConnect({ ...deps, stderr }, agentId, parsed.target, stringValue3(parsed.values["server-url"]), stringValue3(parsed.values["client-name"]), stdout);
|
|
251320
251497
|
default:
|
|
251321
251498
|
throw new McpCliError("unknown_command", `Unknown mcp command '${parsed.action}'`);
|
|
251322
251499
|
}
|
|
@@ -440147,8 +440324,18 @@ async function resolveRuntimeStartAgent(parsed, created) {
|
|
|
440147
440324
|
const withMemfs = parsed.create_agent.memfs !== false;
|
|
440148
440325
|
const { prepareRawCreateAgentBodyForMemfs: prepareRawCreateAgentBodyForMemfs2, enableMemfsIfCloud: enableMemfsIfCloud2 } = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
440149
440326
|
const requestedBody = applyCreatedAgentServerToolDefaults(parsed.create_agent.body);
|
|
440327
|
+
const createBody = withMemfs ? requestedBody : {
|
|
440328
|
+
...requestedBody,
|
|
440329
|
+
tags: buildCreatedAgentTags({
|
|
440330
|
+
enableMemfs: false,
|
|
440331
|
+
tags: [
|
|
440332
|
+
...Array.isArray(requestedBody.tags) ? requestedBody.tags : [],
|
|
440333
|
+
MEMFS_DISABLED_TAG
|
|
440334
|
+
]
|
|
440335
|
+
})
|
|
440336
|
+
};
|
|
440150
440337
|
const appliedHarnessToolDefaults = requestedBody !== parsed.create_agent.body;
|
|
440151
|
-
const body3 = withMemfs ? await prepareRawCreateAgentBodyForMemfs2(
|
|
440338
|
+
const body3 = withMemfs ? await prepareRawCreateAgentBodyForMemfs2(createBody) : createBody;
|
|
440152
440339
|
const agent = appliedHarnessToolDefaults ? await createAgentWithBaseToolsRecovery((tools) => backend3.createAgent({ ...body3, tools }), [...DEFAULT_CREATED_AGENT_BASE_TOOLS]) : await backend3.createAgent(body3);
|
|
440153
440340
|
if (withMemfs) {
|
|
440154
440341
|
enableMemfsIfCloud2(agent.id);
|
|
@@ -450819,12 +451006,12 @@ function rowToolCalls(row, index, diagnostics2) {
|
|
|
450819
451006
|
}
|
|
450820
451007
|
return calls;
|
|
450821
451008
|
}
|
|
450822
|
-
function
|
|
451009
|
+
function contentText2(content) {
|
|
450823
451010
|
if (typeof content === "string") {
|
|
450824
451011
|
if (content.startsWith(CONTENT_JSON_PREFIX)) {
|
|
450825
451012
|
const encoded = content.slice(CONTENT_JSON_PREFIX.length);
|
|
450826
451013
|
try {
|
|
450827
|
-
return
|
|
451014
|
+
return contentText2(JSON.parse(encoded));
|
|
450828
451015
|
} catch {
|
|
450829
451016
|
return encoded;
|
|
450830
451017
|
}
|
|
@@ -450910,7 +451097,7 @@ var init_hermes = __esm(() => {
|
|
|
450910
451097
|
});
|
|
450911
451098
|
};
|
|
450912
451099
|
if (row.role === "user") {
|
|
450913
|
-
const content =
|
|
451100
|
+
const content = contentText2(row.content);
|
|
450914
451101
|
if (content) {
|
|
450915
451102
|
emit({
|
|
450916
451103
|
type: "message",
|
|
@@ -450930,7 +451117,7 @@ var init_hermes = __esm(() => {
|
|
|
450930
451117
|
...timestamp ? { timestamp } : {}
|
|
450931
451118
|
});
|
|
450932
451119
|
}
|
|
450933
|
-
const content =
|
|
451120
|
+
const content = contentText2(row.content);
|
|
450934
451121
|
if (content) {
|
|
450935
451122
|
emit({
|
|
450936
451123
|
type: "message",
|
|
@@ -450953,7 +451140,7 @@ var init_hermes = __esm(() => {
|
|
|
450953
451140
|
if (row.role === "tool") {
|
|
450954
451141
|
emit({
|
|
450955
451142
|
type: "tool_result",
|
|
450956
|
-
content:
|
|
451143
|
+
content: contentText2(row.content),
|
|
450957
451144
|
...typeof row.tool_call_id === "string" && row.tool_call_id ? { callId: row.tool_call_id } : {},
|
|
450958
451145
|
...timestamp ? { timestamp } : {}
|
|
450959
451146
|
});
|
|
@@ -467915,16 +468102,6 @@ function readJsonFile3(path46) {
|
|
|
467915
468102
|
return;
|
|
467916
468103
|
}
|
|
467917
468104
|
}
|
|
467918
|
-
function readJsonlFile2(path46) {
|
|
467919
|
-
if (!existsSync65(path46))
|
|
467920
|
-
return [];
|
|
467921
|
-
try {
|
|
467922
|
-
return readFileSync48(path46, "utf8").split(`
|
|
467923
|
-
`).filter((line) => line.trim().length > 0).map((line) => JSON.parse(line));
|
|
467924
|
-
} catch {
|
|
467925
|
-
return [];
|
|
467926
|
-
}
|
|
467927
|
-
}
|
|
467928
468105
|
function conversationSearchRecord(value) {
|
|
467929
468106
|
if (!isRecord2(value))
|
|
467930
468107
|
return;
|
|
@@ -468161,7 +468338,12 @@ function collectConversationMessages(input) {
|
|
|
468161
468338
|
if (input.conversationId && conversation.id !== input.conversationId)
|
|
468162
468339
|
return [];
|
|
468163
468340
|
const messagesPath = join94(conversationDir, "messages.jsonl");
|
|
468164
|
-
|
|
468341
|
+
let rows;
|
|
468342
|
+
try {
|
|
468343
|
+
rows = readJsonlFile(messagesPath);
|
|
468344
|
+
} catch {
|
|
468345
|
+
rows = [];
|
|
468346
|
+
}
|
|
468165
468347
|
if (rows.length === 0)
|
|
468166
468348
|
return [];
|
|
468167
468349
|
const manifest2 = readJsonFile3(join94(conversationDir, "manifest.json"));
|
|
@@ -474333,7 +474515,7 @@ Read step metadata and an available provider trace with CLI authentication. Loca
|
|
|
474333
474515
|
throw new Error("Step does not belong to the requested agent.");
|
|
474334
474516
|
}
|
|
474335
474517
|
const trace = await (deps.retrieveTrace ?? (async (id2) => (await getClient()).steps.trace.retrieve(id2)))(values4.step);
|
|
474336
|
-
if (trace && (trace.agent_id !== values4.agent || trace.step_id !== step.id)) {
|
|
474518
|
+
if (trace && (trace.agent_id != null && trace.agent_id !== values4.agent || trace.step_id != null && trace.step_id !== step.id)) {
|
|
474337
474519
|
throw new Error("Provider trace does not match the requested agent and step.");
|
|
474338
474520
|
}
|
|
474339
474521
|
console.log(JSON.stringify({ status: trace ? "available" : "unavailable", step, trace }, null, 2));
|
|
@@ -533726,4 +533908,4 @@ function registerBunOAuthFlows() {
|
|
|
533726
533908
|
registerBunOAuthFlows();
|
|
533727
533909
|
await init_src5().then(() => exports_src2);
|
|
533728
533910
|
|
|
533729
|
-
//# debugId=
|
|
533911
|
+
//# debugId=10AC316A829B737364756E2164756E21
|