@letta-ai/letta-code 0.15.2 → 0.15.3
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/letta.js +1503 -1008
- package/package.json +3 -1
package/letta.js
CHANGED
|
@@ -3122,7 +3122,7 @@ var package_default;
|
|
|
3122
3122
|
var init_package = __esm(() => {
|
|
3123
3123
|
package_default = {
|
|
3124
3124
|
name: "@letta-ai/letta-code",
|
|
3125
|
-
version: "0.15.
|
|
3125
|
+
version: "0.15.3",
|
|
3126
3126
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
3127
3127
|
type: "module",
|
|
3128
3128
|
bin: {
|
|
@@ -3184,6 +3184,8 @@ var init_package = __esm(() => {
|
|
|
3184
3184
|
check: "bun run scripts/check.js",
|
|
3185
3185
|
dev: "bun --loader:.md=text --loader:.mdx=text --loader:.txt=text run src/index.ts",
|
|
3186
3186
|
build: "node scripts/postinstall-patches.js && bun run build.js",
|
|
3187
|
+
"test:update-chain:manual": "bun run src/tests/update-chain-smoke.ts --mode manual",
|
|
3188
|
+
"test:update-chain:startup": "bun run src/tests/update-chain-smoke.ts --mode startup",
|
|
3187
3189
|
prepublishOnly: "bun run build",
|
|
3188
3190
|
postinstall: "node scripts/postinstall-patches.js"
|
|
3189
3191
|
},
|
|
@@ -5635,13 +5637,15 @@ If the user asks for help or wants to give feedback inform them of the following
|
|
|
5635
5637
|
|
|
5636
5638
|
When the user directly asks about Letta Code (eg 'can Letta Code do...', 'does Letta Code have...') or asks in second person (eg 'are you able...', 'can you do...'), first use the WebFetch tool to gather information to answer the question from the Letta Code repository at https://github.com/letta-ai/letta-code.
|
|
5637
5639
|
|
|
5640
|
+
When running in Letta Code, shell tools provide \`AGENT_ID\`: your current agent ID.
|
|
5641
|
+
|
|
5638
5642
|
# Skills
|
|
5639
5643
|
- /<skill-name> (e.g., /commit) is shorthand for users to invoke a skill. When executed, the skill gets expanded to a full prompt. Use the Skill tool to execute them. IMPORTANT: Only use Skill for skills listed in system-reminder messages in the conversation - do not guess or use built-in CLI commands.
|
|
5640
5644
|
`;
|
|
5641
5645
|
var init_system_prompt = () => {};
|
|
5642
5646
|
|
|
5643
5647
|
// src/agent/prompts/system_prompt_memfs.txt
|
|
5644
|
-
var system_prompt_memfs_default = "\n# Memory\n\nYou have an advanced memory system that enables you to remember past interactions and continuously improve your own capabilities.\n\n## Memory Filesystem\nYour memory is stored in a git repository at `~/.letta/agents
|
|
5648
|
+
var system_prompt_memfs_default = "\n# Memory\n\nYou have an advanced memory system that enables you to remember past interactions and continuously improve your own capabilities.\n\n## Memory Filesystem\nYour memory is stored in a git repository at `$MEMORY_DIR` (absolute path provided by Letta Code shell tools; usually `~/.letta/agents/$AGENT_ID/memory/`). This provides full version control, sync with the server, and create worktrees for parallel edits.\nEach file contains metadata frontmatter include a `description` (the description of the file's contents), `limit` (the character limit), and optional `metadata`.\nThe filesystem tree is always available in your system prompt, along with the contents of files in the `system/` folder.\nYou also have additional external memory (e.g. your message history) that is accessible and that you can bring into context with tools when needed.\n\n## How It Works\n1. Each `.md` file in `memory/system/` is pinned to your system prompt with tags <system/context/{name}.md></system/context/{name}.md>\n2. The `memory_filesystem` block renders the current tree view of all available memory files\n2. Changes pushed to git sync to the API server within seconds\n3. API server changes sync to git automatically\n4. The system prompt is only recompiled with the latest memory on the API on compactions or message resets: your local copy may diverge\n\n## Syncing\n```bash\ncd \"$MEMORY_DIR\"\n\n# See what changed\ngit status\n\n# Commit and push your changes\ngit add system/\ngit commit -m \"<type>: <what changed>\" # e.g. \"fix: update user prefs\", \"refactor: reorganize persona blocks\"\ngit push\n\n# Get latest from server\ngit pull\n```\nThe system will remind you when your memory has uncommitted changes. Sync when convenient.\n\n## History\n```bash\ngit -C \"$MEMORY_DIR\" log --oneline\n```\n";
|
|
5645
5649
|
var init_system_prompt_memfs = () => {};
|
|
5646
5650
|
|
|
5647
5651
|
// src/agent/prompts/system_prompt_memory.txt
|
|
@@ -37549,6 +37553,926 @@ var init_process_manager = __esm(() => {
|
|
|
37549
37553
|
backgroundTasks = new Map;
|
|
37550
37554
|
});
|
|
37551
37555
|
|
|
37556
|
+
// src/providers/openai-codex-provider.ts
|
|
37557
|
+
var exports_openai_codex_provider = {};
|
|
37558
|
+
__export(exports_openai_codex_provider, {
|
|
37559
|
+
updateOpenAICodexProvider: () => updateOpenAICodexProvider,
|
|
37560
|
+
removeOpenAICodexProvider: () => removeOpenAICodexProvider,
|
|
37561
|
+
listProviders: () => listProviders,
|
|
37562
|
+
getOpenAICodexProvider: () => getOpenAICodexProvider,
|
|
37563
|
+
deleteOpenAICodexProvider: () => deleteOpenAICodexProvider,
|
|
37564
|
+
createOrUpdateOpenAICodexProvider: () => createOrUpdateOpenAICodexProvider,
|
|
37565
|
+
createOpenAICodexProvider: () => createOpenAICodexProvider,
|
|
37566
|
+
checkOpenAICodexEligibility: () => checkOpenAICodexEligibility,
|
|
37567
|
+
OPENAI_CODEX_PROVIDER_NAME: () => OPENAI_CODEX_PROVIDER_NAME,
|
|
37568
|
+
CHATGPT_OAUTH_PROVIDER_TYPE: () => CHATGPT_OAUTH_PROVIDER_TYPE
|
|
37569
|
+
});
|
|
37570
|
+
async function getLettaConfig() {
|
|
37571
|
+
const settings = await settingsManager.getSettingsWithSecureTokens();
|
|
37572
|
+
const baseUrl = process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
|
|
37573
|
+
const apiKey = process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY || "";
|
|
37574
|
+
return { baseUrl, apiKey };
|
|
37575
|
+
}
|
|
37576
|
+
async function providersRequest(method, path3, body) {
|
|
37577
|
+
const { baseUrl, apiKey } = await getLettaConfig();
|
|
37578
|
+
const url = `${baseUrl}${path3}`;
|
|
37579
|
+
const response = await fetch(url, {
|
|
37580
|
+
method,
|
|
37581
|
+
headers: getLettaCodeHeaders2(apiKey),
|
|
37582
|
+
...body && { body: JSON.stringify(body) }
|
|
37583
|
+
});
|
|
37584
|
+
if (!response.ok) {
|
|
37585
|
+
const errorText = await response.text();
|
|
37586
|
+
if (response.status === 403) {
|
|
37587
|
+
try {
|
|
37588
|
+
const errorData = JSON.parse(errorText);
|
|
37589
|
+
if (errorData.error && typeof errorData.error === "string" && errorData.error.includes("only available for pro or enterprise")) {
|
|
37590
|
+
throw new Error("PLAN_UPGRADE_REQUIRED");
|
|
37591
|
+
}
|
|
37592
|
+
} catch (parseError) {
|
|
37593
|
+
if (parseError instanceof Error && parseError.message === "PLAN_UPGRADE_REQUIRED") {
|
|
37594
|
+
throw parseError;
|
|
37595
|
+
}
|
|
37596
|
+
}
|
|
37597
|
+
}
|
|
37598
|
+
throw new Error(`Provider API error (${response.status}): ${errorText}`);
|
|
37599
|
+
}
|
|
37600
|
+
const text = await response.text();
|
|
37601
|
+
if (!text) {
|
|
37602
|
+
return {};
|
|
37603
|
+
}
|
|
37604
|
+
return JSON.parse(text);
|
|
37605
|
+
}
|
|
37606
|
+
async function listProviders() {
|
|
37607
|
+
try {
|
|
37608
|
+
const response = await providersRequest("GET", "/v1/providers");
|
|
37609
|
+
return response;
|
|
37610
|
+
} catch {
|
|
37611
|
+
return [];
|
|
37612
|
+
}
|
|
37613
|
+
}
|
|
37614
|
+
async function getOpenAICodexProvider() {
|
|
37615
|
+
const providers = await listProviders();
|
|
37616
|
+
return providers.find((p) => p.name === OPENAI_CODEX_PROVIDER_NAME) || null;
|
|
37617
|
+
}
|
|
37618
|
+
async function createOpenAICodexProvider(config) {
|
|
37619
|
+
const apiKeyJson = JSON.stringify({
|
|
37620
|
+
access_token: config.access_token,
|
|
37621
|
+
id_token: config.id_token,
|
|
37622
|
+
refresh_token: config.refresh_token,
|
|
37623
|
+
account_id: config.account_id,
|
|
37624
|
+
expires_at: config.expires_at
|
|
37625
|
+
});
|
|
37626
|
+
return providersRequest("POST", "/v1/providers", {
|
|
37627
|
+
name: OPENAI_CODEX_PROVIDER_NAME,
|
|
37628
|
+
provider_type: CHATGPT_OAUTH_PROVIDER_TYPE,
|
|
37629
|
+
api_key: apiKeyJson
|
|
37630
|
+
});
|
|
37631
|
+
}
|
|
37632
|
+
async function updateOpenAICodexProvider(providerId, config) {
|
|
37633
|
+
const apiKeyJson = JSON.stringify({
|
|
37634
|
+
access_token: config.access_token,
|
|
37635
|
+
id_token: config.id_token,
|
|
37636
|
+
refresh_token: config.refresh_token,
|
|
37637
|
+
account_id: config.account_id,
|
|
37638
|
+
expires_at: config.expires_at
|
|
37639
|
+
});
|
|
37640
|
+
return providersRequest("PATCH", `/v1/providers/${providerId}`, {
|
|
37641
|
+
api_key: apiKeyJson
|
|
37642
|
+
});
|
|
37643
|
+
}
|
|
37644
|
+
async function deleteOpenAICodexProvider(providerId) {
|
|
37645
|
+
await providersRequest("DELETE", `/v1/providers/${providerId}`);
|
|
37646
|
+
}
|
|
37647
|
+
async function createOrUpdateOpenAICodexProvider(config) {
|
|
37648
|
+
const existing = await getOpenAICodexProvider();
|
|
37649
|
+
if (existing) {
|
|
37650
|
+
return updateOpenAICodexProvider(existing.id, config);
|
|
37651
|
+
} else {
|
|
37652
|
+
return createOpenAICodexProvider(config);
|
|
37653
|
+
}
|
|
37654
|
+
}
|
|
37655
|
+
async function removeOpenAICodexProvider() {
|
|
37656
|
+
const existing = await getOpenAICodexProvider();
|
|
37657
|
+
if (existing) {
|
|
37658
|
+
await deleteOpenAICodexProvider(existing.id);
|
|
37659
|
+
}
|
|
37660
|
+
}
|
|
37661
|
+
async function checkOpenAICodexEligibility() {
|
|
37662
|
+
try {
|
|
37663
|
+
const balance = await providersRequest("GET", "/v1/metadata/balance");
|
|
37664
|
+
const billingTier = balance.billing_tier.toLowerCase();
|
|
37665
|
+
if (billingTier === "pro" || billingTier === "enterprise") {
|
|
37666
|
+
return {
|
|
37667
|
+
eligible: true,
|
|
37668
|
+
billing_tier: balance.billing_tier
|
|
37669
|
+
};
|
|
37670
|
+
}
|
|
37671
|
+
return {
|
|
37672
|
+
eligible: false,
|
|
37673
|
+
billing_tier: balance.billing_tier,
|
|
37674
|
+
reason: `ChatGPT OAuth requires a Pro or Enterprise plan. Current plan: ${balance.billing_tier}`
|
|
37675
|
+
};
|
|
37676
|
+
} catch (error) {
|
|
37677
|
+
console.warn("Failed to check ChatGPT OAuth eligibility:", error);
|
|
37678
|
+
return {
|
|
37679
|
+
eligible: true,
|
|
37680
|
+
billing_tier: "unknown"
|
|
37681
|
+
};
|
|
37682
|
+
}
|
|
37683
|
+
}
|
|
37684
|
+
var OPENAI_CODEX_PROVIDER_NAME = "chatgpt-plus-pro", CHATGPT_OAUTH_PROVIDER_TYPE = "chatgpt_oauth";
|
|
37685
|
+
var init_openai_codex_provider = __esm(async () => {
|
|
37686
|
+
init_http_headers();
|
|
37687
|
+
init_oauth();
|
|
37688
|
+
await init_settings_manager();
|
|
37689
|
+
});
|
|
37690
|
+
|
|
37691
|
+
// src/agent/available-models.ts
|
|
37692
|
+
var exports_available_models = {};
|
|
37693
|
+
__export(exports_available_models, {
|
|
37694
|
+
prefetchAvailableModelHandles: () => prefetchAvailableModelHandles,
|
|
37695
|
+
getModelContextWindow: () => getModelContextWindow,
|
|
37696
|
+
getAvailableModelsCacheInfo: () => getAvailableModelsCacheInfo,
|
|
37697
|
+
getAvailableModelHandles: () => getAvailableModelHandles,
|
|
37698
|
+
clearAvailableModelsCache: () => clearAvailableModelsCache
|
|
37699
|
+
});
|
|
37700
|
+
function isFresh(now = Date.now()) {
|
|
37701
|
+
return cache4 !== null && now - cache4.fetchedAt < CACHE_TTL_MS;
|
|
37702
|
+
}
|
|
37703
|
+
function clearAvailableModelsCache() {
|
|
37704
|
+
cache4 = null;
|
|
37705
|
+
}
|
|
37706
|
+
function getAvailableModelsCacheInfo() {
|
|
37707
|
+
const now = Date.now();
|
|
37708
|
+
return {
|
|
37709
|
+
hasCache: cache4 !== null,
|
|
37710
|
+
isFresh: isFresh(now),
|
|
37711
|
+
fetchedAt: cache4?.fetchedAt ?? null,
|
|
37712
|
+
ageMs: cache4 ? now - cache4.fetchedAt : null,
|
|
37713
|
+
ttlMs: CACHE_TTL_MS
|
|
37714
|
+
};
|
|
37715
|
+
}
|
|
37716
|
+
async function refreshByokProviders() {
|
|
37717
|
+
const client = await getClient2();
|
|
37718
|
+
try {
|
|
37719
|
+
const providers = await client.get("/v1/providers/");
|
|
37720
|
+
const byokProviders = providers.filter((p) => p.provider_category === "byok");
|
|
37721
|
+
await Promise.allSettled(byokProviders.map(async (provider) => {
|
|
37722
|
+
try {
|
|
37723
|
+
await client.patch(`/v1/providers/${provider.id}/refresh`);
|
|
37724
|
+
} catch (error) {
|
|
37725
|
+
debugWarn("available-models", `Failed to refresh provider ${provider.name} (${provider.id}):`, error);
|
|
37726
|
+
}
|
|
37727
|
+
}));
|
|
37728
|
+
} catch (error) {
|
|
37729
|
+
debugWarn("available-models", "Failed to list providers for refresh:", error);
|
|
37730
|
+
}
|
|
37731
|
+
}
|
|
37732
|
+
async function fetchFromNetwork() {
|
|
37733
|
+
const client = await getClient2();
|
|
37734
|
+
const modelsList = await client.models.list();
|
|
37735
|
+
const handles = new Set(modelsList.map((m) => m.handle).filter((h) => !!h));
|
|
37736
|
+
const contextWindows = new Map;
|
|
37737
|
+
for (const model of modelsList) {
|
|
37738
|
+
if (model.handle && model.max_context_window) {
|
|
37739
|
+
contextWindows.set(model.handle, model.max_context_window);
|
|
37740
|
+
}
|
|
37741
|
+
}
|
|
37742
|
+
return { handles, contextWindows, fetchedAt: Date.now() };
|
|
37743
|
+
}
|
|
37744
|
+
async function getAvailableModelHandles(options) {
|
|
37745
|
+
const forceRefresh = options?.forceRefresh === true;
|
|
37746
|
+
const now = Date.now();
|
|
37747
|
+
if (!forceRefresh && isFresh(now) && cache4) {
|
|
37748
|
+
return {
|
|
37749
|
+
handles: cache4.handles,
|
|
37750
|
+
source: "cache",
|
|
37751
|
+
fetchedAt: cache4.fetchedAt
|
|
37752
|
+
};
|
|
37753
|
+
}
|
|
37754
|
+
if (!forceRefresh && inflight) {
|
|
37755
|
+
const entry2 = await inflight;
|
|
37756
|
+
return {
|
|
37757
|
+
handles: entry2.handles,
|
|
37758
|
+
source: "network",
|
|
37759
|
+
fetchedAt: entry2.fetchedAt
|
|
37760
|
+
};
|
|
37761
|
+
}
|
|
37762
|
+
if (forceRefresh) {
|
|
37763
|
+
await refreshByokProviders();
|
|
37764
|
+
}
|
|
37765
|
+
inflight = fetchFromNetwork().then((entry2) => {
|
|
37766
|
+
cache4 = entry2;
|
|
37767
|
+
return entry2;
|
|
37768
|
+
}).finally(() => {
|
|
37769
|
+
inflight = null;
|
|
37770
|
+
});
|
|
37771
|
+
const entry = await inflight;
|
|
37772
|
+
return {
|
|
37773
|
+
handles: entry.handles,
|
|
37774
|
+
source: "network",
|
|
37775
|
+
fetchedAt: entry.fetchedAt
|
|
37776
|
+
};
|
|
37777
|
+
}
|
|
37778
|
+
function prefetchAvailableModelHandles() {
|
|
37779
|
+
getAvailableModelHandles().catch(() => {});
|
|
37780
|
+
}
|
|
37781
|
+
async function getModelContextWindow(handle) {
|
|
37782
|
+
if (!cache4) {
|
|
37783
|
+
await getAvailableModelHandles();
|
|
37784
|
+
}
|
|
37785
|
+
return cache4?.contextWindows.get(handle);
|
|
37786
|
+
}
|
|
37787
|
+
var CACHE_TTL_MS, cache4 = null, inflight = null;
|
|
37788
|
+
var init_available_models = __esm(async () => {
|
|
37789
|
+
init_debug();
|
|
37790
|
+
await init_client2();
|
|
37791
|
+
CACHE_TTL_MS = 5 * 60 * 1000;
|
|
37792
|
+
});
|
|
37793
|
+
|
|
37794
|
+
// src/agent/memoryPrompt.ts
|
|
37795
|
+
var exports_memoryPrompt = {};
|
|
37796
|
+
__export(exports_memoryPrompt, {
|
|
37797
|
+
stripManagedMemorySections: () => stripManagedMemorySections,
|
|
37798
|
+
reconcileMemoryPrompt: () => reconcileMemoryPrompt,
|
|
37799
|
+
detectMemoryPromptDrift: () => detectMemoryPromptDrift
|
|
37800
|
+
});
|
|
37801
|
+
function normalizeNewlines(text) {
|
|
37802
|
+
return text.replace(/\r\n/g, `
|
|
37803
|
+
`);
|
|
37804
|
+
}
|
|
37805
|
+
function scanHeadingsOutsideFences(text) {
|
|
37806
|
+
const lines = text.split(`
|
|
37807
|
+
`);
|
|
37808
|
+
const headings = [];
|
|
37809
|
+
let inFence = false;
|
|
37810
|
+
let fenceToken = "";
|
|
37811
|
+
let offset = 0;
|
|
37812
|
+
for (const line of lines) {
|
|
37813
|
+
const trimmed = line.trimStart();
|
|
37814
|
+
const fenceMatch = trimmed.match(/^(```+|~~~+)/);
|
|
37815
|
+
if (fenceMatch) {
|
|
37816
|
+
const token = fenceMatch[1] ?? fenceMatch[0] ?? "";
|
|
37817
|
+
const tokenChar = token.startsWith("`") ? "`" : "~";
|
|
37818
|
+
if (!inFence) {
|
|
37819
|
+
inFence = true;
|
|
37820
|
+
fenceToken = tokenChar;
|
|
37821
|
+
} else if (fenceToken === tokenChar) {
|
|
37822
|
+
inFence = false;
|
|
37823
|
+
fenceToken = "";
|
|
37824
|
+
}
|
|
37825
|
+
}
|
|
37826
|
+
if (!inFence) {
|
|
37827
|
+
const headingMatch = line.match(/^\s*(#{1,6})\s+(.+?)\s*$/);
|
|
37828
|
+
if (headingMatch) {
|
|
37829
|
+
const hashes = headingMatch[1] ?? "";
|
|
37830
|
+
const rawTitle = headingMatch[2] ?? "";
|
|
37831
|
+
if (hashes && rawTitle) {
|
|
37832
|
+
const level = hashes.length;
|
|
37833
|
+
const title = rawTitle.replace(/\s+#*$/, "").trim();
|
|
37834
|
+
headings.push({
|
|
37835
|
+
level,
|
|
37836
|
+
title,
|
|
37837
|
+
startOffset: offset
|
|
37838
|
+
});
|
|
37839
|
+
}
|
|
37840
|
+
}
|
|
37841
|
+
}
|
|
37842
|
+
offset += line.length + 1;
|
|
37843
|
+
}
|
|
37844
|
+
return headings;
|
|
37845
|
+
}
|
|
37846
|
+
function stripHeadingSections(text, shouldStrip) {
|
|
37847
|
+
let current = text;
|
|
37848
|
+
while (true) {
|
|
37849
|
+
const headings = scanHeadingsOutsideFences(current);
|
|
37850
|
+
const target = headings.find(shouldStrip);
|
|
37851
|
+
if (!target) {
|
|
37852
|
+
return current;
|
|
37853
|
+
}
|
|
37854
|
+
const nextHeading = headings.find((heading) => heading.startOffset > target.startOffset && heading.level <= target.level);
|
|
37855
|
+
const end = nextHeading ? nextHeading.startOffset : current.length;
|
|
37856
|
+
current = `${current.slice(0, target.startOffset)}${current.slice(end)}`;
|
|
37857
|
+
}
|
|
37858
|
+
}
|
|
37859
|
+
function getMemfsTailFragment() {
|
|
37860
|
+
const tailAnchor = "# See what changed";
|
|
37861
|
+
const start = SYSTEM_PROMPT_MEMFS_ADDON.indexOf(tailAnchor);
|
|
37862
|
+
if (start === -1)
|
|
37863
|
+
return "";
|
|
37864
|
+
return SYSTEM_PROMPT_MEMFS_ADDON.slice(start).trim();
|
|
37865
|
+
}
|
|
37866
|
+
function stripExactAddon(text, addon) {
|
|
37867
|
+
const trimmedAddon = addon.trim();
|
|
37868
|
+
if (!trimmedAddon)
|
|
37869
|
+
return text;
|
|
37870
|
+
let current = text;
|
|
37871
|
+
while (current.includes(trimmedAddon)) {
|
|
37872
|
+
current = current.replace(trimmedAddon, "");
|
|
37873
|
+
}
|
|
37874
|
+
return current;
|
|
37875
|
+
}
|
|
37876
|
+
function stripOrphanMemfsTail(text) {
|
|
37877
|
+
const tail = getMemfsTailFragment();
|
|
37878
|
+
if (!tail)
|
|
37879
|
+
return text;
|
|
37880
|
+
let current = text;
|
|
37881
|
+
while (current.includes(tail)) {
|
|
37882
|
+
current = current.replace(tail, "");
|
|
37883
|
+
}
|
|
37884
|
+
return current;
|
|
37885
|
+
}
|
|
37886
|
+
function compactBlankLines(text) {
|
|
37887
|
+
return text.replace(/\n{3,}/g, `
|
|
37888
|
+
|
|
37889
|
+
`).trimEnd();
|
|
37890
|
+
}
|
|
37891
|
+
function stripManagedMemorySections(systemPrompt) {
|
|
37892
|
+
let current = normalizeNewlines(systemPrompt);
|
|
37893
|
+
current = stripExactAddon(current, SYSTEM_PROMPT_MEMORY_ADDON);
|
|
37894
|
+
current = stripExactAddon(current, SYSTEM_PROMPT_MEMFS_ADDON);
|
|
37895
|
+
current = stripOrphanMemfsTail(current);
|
|
37896
|
+
current = stripHeadingSections(current, (heading) => heading.title === "Memory");
|
|
37897
|
+
current = stripHeadingSections(current, (heading) => heading.title.startsWith("Memory Filesystem"));
|
|
37898
|
+
return compactBlankLines(current);
|
|
37899
|
+
}
|
|
37900
|
+
function reconcileMemoryPrompt(systemPrompt, mode) {
|
|
37901
|
+
const base2 = stripManagedMemorySections(systemPrompt).trimEnd();
|
|
37902
|
+
const addon = mode === "memfs" ? SYSTEM_PROMPT_MEMFS_ADDON.trimStart() : SYSTEM_PROMPT_MEMORY_ADDON.trimStart();
|
|
37903
|
+
return `${base2}
|
|
37904
|
+
|
|
37905
|
+
${addon}`.trim();
|
|
37906
|
+
}
|
|
37907
|
+
function detectMemoryPromptDrift(systemPrompt, expectedMode) {
|
|
37908
|
+
const prompt = normalizeNewlines(systemPrompt);
|
|
37909
|
+
const drifts = [];
|
|
37910
|
+
const hasLegacyMemoryLanguage = prompt.includes("Your memory consists of core memory (composed of memory blocks)");
|
|
37911
|
+
const hasMemfsLanguage = prompt.includes("## Memory Filesystem") || prompt.includes("Your memory is stored in a git repository at");
|
|
37912
|
+
const hasOrphanFragment = prompt.includes("# See what changed") && prompt.includes("git add system/") && prompt.includes('git commit -m "<type>: <what changed>"');
|
|
37913
|
+
if (expectedMode === "memfs" && hasLegacyMemoryLanguage) {
|
|
37914
|
+
drifts.push({
|
|
37915
|
+
code: "legacy_memory_language_with_memfs",
|
|
37916
|
+
message: "System prompt contains legacy memory-block language while memfs is enabled."
|
|
37917
|
+
});
|
|
37918
|
+
}
|
|
37919
|
+
if (expectedMode === "standard" && hasMemfsLanguage) {
|
|
37920
|
+
drifts.push({
|
|
37921
|
+
code: "memfs_language_with_standard_mode",
|
|
37922
|
+
message: "System prompt contains Memory Filesystem language while memfs is disabled."
|
|
37923
|
+
});
|
|
37924
|
+
}
|
|
37925
|
+
if (hasOrphanFragment && !hasMemfsLanguage) {
|
|
37926
|
+
drifts.push({
|
|
37927
|
+
code: "orphan_memfs_fragment",
|
|
37928
|
+
message: "System prompt contains orphaned memfs sync fragment without a full memfs section."
|
|
37929
|
+
});
|
|
37930
|
+
}
|
|
37931
|
+
return drifts;
|
|
37932
|
+
}
|
|
37933
|
+
var init_memoryPrompt = __esm(() => {
|
|
37934
|
+
init_promptAssets();
|
|
37935
|
+
});
|
|
37936
|
+
|
|
37937
|
+
// src/agent/modify.ts
|
|
37938
|
+
var exports_modify = {};
|
|
37939
|
+
__export(exports_modify, {
|
|
37940
|
+
updateAgentSystemPromptRaw: () => updateAgentSystemPromptRaw,
|
|
37941
|
+
updateAgentSystemPromptMemfs: () => updateAgentSystemPromptMemfs,
|
|
37942
|
+
updateAgentSystemPrompt: () => updateAgentSystemPrompt,
|
|
37943
|
+
updateAgentLLMConfig: () => updateAgentLLMConfig
|
|
37944
|
+
});
|
|
37945
|
+
function buildModelSettings(modelHandle, updateArgs) {
|
|
37946
|
+
const isOpenAI = modelHandle.startsWith("openai/") || modelHandle.startsWith(`${OPENAI_CODEX_PROVIDER_NAME}/`);
|
|
37947
|
+
const isAnthropic = modelHandle.startsWith("anthropic/") || modelHandle.startsWith("claude-pro-max/");
|
|
37948
|
+
const isZai = modelHandle.startsWith("zai/");
|
|
37949
|
+
const isGoogleAI = modelHandle.startsWith("google_ai/");
|
|
37950
|
+
const isGoogleVertex = modelHandle.startsWith("google_vertex/");
|
|
37951
|
+
const isOpenRouter = modelHandle.startsWith("openrouter/");
|
|
37952
|
+
const isBedrock = modelHandle.startsWith("bedrock/");
|
|
37953
|
+
let settings;
|
|
37954
|
+
if (isOpenAI || isOpenRouter) {
|
|
37955
|
+
const openaiSettings = {
|
|
37956
|
+
provider_type: "openai",
|
|
37957
|
+
parallel_tool_calls: true
|
|
37958
|
+
};
|
|
37959
|
+
if (updateArgs?.reasoning_effort) {
|
|
37960
|
+
openaiSettings.reasoning = {
|
|
37961
|
+
reasoning_effort: updateArgs.reasoning_effort
|
|
37962
|
+
};
|
|
37963
|
+
}
|
|
37964
|
+
settings = openaiSettings;
|
|
37965
|
+
} else if (isAnthropic) {
|
|
37966
|
+
const anthropicSettings = {
|
|
37967
|
+
provider_type: "anthropic",
|
|
37968
|
+
parallel_tool_calls: true
|
|
37969
|
+
};
|
|
37970
|
+
if (updateArgs?.enable_reasoner !== undefined || typeof updateArgs?.max_reasoning_tokens === "number") {
|
|
37971
|
+
anthropicSettings.thinking = {
|
|
37972
|
+
type: updateArgs?.enable_reasoner === false ? "disabled" : "enabled",
|
|
37973
|
+
...typeof updateArgs?.max_reasoning_tokens === "number" && {
|
|
37974
|
+
budget_tokens: updateArgs.max_reasoning_tokens
|
|
37975
|
+
}
|
|
37976
|
+
};
|
|
37977
|
+
}
|
|
37978
|
+
settings = anthropicSettings;
|
|
37979
|
+
} else if (isZai) {
|
|
37980
|
+
settings = {
|
|
37981
|
+
provider_type: "zai",
|
|
37982
|
+
parallel_tool_calls: true
|
|
37983
|
+
};
|
|
37984
|
+
} else if (isGoogleAI) {
|
|
37985
|
+
const googleSettings = {
|
|
37986
|
+
provider_type: "google_ai",
|
|
37987
|
+
parallel_tool_calls: true
|
|
37988
|
+
};
|
|
37989
|
+
if (updateArgs?.thinking_budget !== undefined) {
|
|
37990
|
+
googleSettings.thinking_config = {
|
|
37991
|
+
thinking_budget: updateArgs.thinking_budget
|
|
37992
|
+
};
|
|
37993
|
+
}
|
|
37994
|
+
if (typeof updateArgs?.temperature === "number") {
|
|
37995
|
+
googleSettings.temperature = updateArgs.temperature;
|
|
37996
|
+
}
|
|
37997
|
+
settings = googleSettings;
|
|
37998
|
+
} else if (isGoogleVertex) {
|
|
37999
|
+
const googleVertexSettings = {
|
|
38000
|
+
provider_type: "google_vertex",
|
|
38001
|
+
parallel_tool_calls: true
|
|
38002
|
+
};
|
|
38003
|
+
if (updateArgs?.thinking_budget !== undefined) {
|
|
38004
|
+
googleVertexSettings.thinking_config = {
|
|
38005
|
+
thinking_budget: updateArgs.thinking_budget
|
|
38006
|
+
};
|
|
38007
|
+
}
|
|
38008
|
+
if (typeof updateArgs?.temperature === "number") {
|
|
38009
|
+
googleVertexSettings.temperature = updateArgs.temperature;
|
|
38010
|
+
}
|
|
38011
|
+
settings = googleVertexSettings;
|
|
38012
|
+
} else if (isBedrock) {
|
|
38013
|
+
const bedrockSettings = {
|
|
38014
|
+
provider_type: "bedrock",
|
|
38015
|
+
parallel_tool_calls: true
|
|
38016
|
+
};
|
|
38017
|
+
if (updateArgs?.enable_reasoner !== undefined || typeof updateArgs?.max_reasoning_tokens === "number") {
|
|
38018
|
+
bedrockSettings.thinking = {
|
|
38019
|
+
type: updateArgs?.enable_reasoner === false ? "disabled" : "enabled",
|
|
38020
|
+
...typeof updateArgs?.max_reasoning_tokens === "number" && {
|
|
38021
|
+
budget_tokens: updateArgs.max_reasoning_tokens
|
|
38022
|
+
}
|
|
38023
|
+
};
|
|
38024
|
+
}
|
|
38025
|
+
settings = bedrockSettings;
|
|
38026
|
+
} else {
|
|
38027
|
+
settings = {};
|
|
38028
|
+
}
|
|
38029
|
+
if (typeof updateArgs?.max_output_tokens === "number" && "provider_type" in settings) {
|
|
38030
|
+
settings.max_output_tokens = updateArgs.max_output_tokens;
|
|
38031
|
+
}
|
|
38032
|
+
return settings;
|
|
38033
|
+
}
|
|
38034
|
+
async function updateAgentLLMConfig(agentId, modelHandle, updateArgs) {
|
|
38035
|
+
const client = await getClient2();
|
|
38036
|
+
const modelSettings = buildModelSettings(modelHandle, updateArgs);
|
|
38037
|
+
const contextWindow = updateArgs?.context_window ?? await getModelContextWindow(modelHandle);
|
|
38038
|
+
const hasModelSettings = Object.keys(modelSettings).length > 0;
|
|
38039
|
+
await client.agents.update(agentId, {
|
|
38040
|
+
model: modelHandle,
|
|
38041
|
+
...hasModelSettings && { model_settings: modelSettings },
|
|
38042
|
+
...contextWindow && { context_window_limit: contextWindow },
|
|
38043
|
+
...typeof updateArgs?.max_output_tokens === "number" && {
|
|
38044
|
+
max_tokens: updateArgs.max_output_tokens
|
|
38045
|
+
}
|
|
38046
|
+
});
|
|
38047
|
+
const finalAgent = await client.agents.retrieve(agentId);
|
|
38048
|
+
return finalAgent.llm_config;
|
|
38049
|
+
}
|
|
38050
|
+
async function updateAgentSystemPromptRaw(agentId, systemPromptContent) {
|
|
38051
|
+
try {
|
|
38052
|
+
const client = await getClient2();
|
|
38053
|
+
await client.agents.update(agentId, {
|
|
38054
|
+
system: systemPromptContent
|
|
38055
|
+
});
|
|
38056
|
+
return {
|
|
38057
|
+
success: true,
|
|
38058
|
+
message: "System prompt updated successfully"
|
|
38059
|
+
};
|
|
38060
|
+
} catch (error) {
|
|
38061
|
+
return {
|
|
38062
|
+
success: false,
|
|
38063
|
+
message: `Failed to update system prompt: ${error instanceof Error ? error.message : String(error)}`
|
|
38064
|
+
};
|
|
38065
|
+
}
|
|
38066
|
+
}
|
|
38067
|
+
async function updateAgentSystemPrompt(agentId, systemPromptId) {
|
|
38068
|
+
try {
|
|
38069
|
+
const { resolveSystemPrompt: resolveSystemPrompt2 } = await Promise.resolve().then(() => (init_promptAssets(), exports_promptAssets));
|
|
38070
|
+
const { detectMemoryPromptDrift: detectMemoryPromptDrift2, reconcileMemoryPrompt: reconcileMemoryPrompt2 } = await Promise.resolve().then(() => (init_memoryPrompt(), exports_memoryPrompt));
|
|
38071
|
+
const { settingsManager: settingsManager3 } = await init_settings_manager().then(() => exports_settings_manager);
|
|
38072
|
+
const client = await getClient2();
|
|
38073
|
+
const currentAgent = await client.agents.retrieve(agentId);
|
|
38074
|
+
const baseContent = await resolveSystemPrompt2(systemPromptId);
|
|
38075
|
+
const settingIndicatesMemfs = settingsManager3.isMemfsEnabled(agentId);
|
|
38076
|
+
const promptIndicatesMemfs = detectMemoryPromptDrift2(currentAgent.system || "", "standard").some((drift) => drift.code === "memfs_language_with_standard_mode");
|
|
38077
|
+
const memoryMode = settingIndicatesMemfs || promptIndicatesMemfs ? "memfs" : "standard";
|
|
38078
|
+
const systemPromptContent = reconcileMemoryPrompt2(baseContent, memoryMode);
|
|
38079
|
+
const updateResult = await updateAgentSystemPromptRaw(agentId, systemPromptContent);
|
|
38080
|
+
if (!updateResult.success) {
|
|
38081
|
+
return {
|
|
38082
|
+
success: false,
|
|
38083
|
+
message: updateResult.message,
|
|
38084
|
+
agent: null
|
|
38085
|
+
};
|
|
38086
|
+
}
|
|
38087
|
+
const agent = await client.agents.retrieve(agentId);
|
|
38088
|
+
return {
|
|
38089
|
+
success: true,
|
|
38090
|
+
message: "System prompt applied successfully",
|
|
38091
|
+
agent
|
|
38092
|
+
};
|
|
38093
|
+
} catch (error) {
|
|
38094
|
+
return {
|
|
38095
|
+
success: false,
|
|
38096
|
+
message: `Failed to apply system prompt: ${error instanceof Error ? error.message : String(error)}`,
|
|
38097
|
+
agent: null
|
|
38098
|
+
};
|
|
38099
|
+
}
|
|
38100
|
+
}
|
|
38101
|
+
async function updateAgentSystemPromptMemfs(agentId, enableMemfs) {
|
|
38102
|
+
try {
|
|
38103
|
+
const client = await getClient2();
|
|
38104
|
+
const agent = await client.agents.retrieve(agentId);
|
|
38105
|
+
const { reconcileMemoryPrompt: reconcileMemoryPrompt2 } = await Promise.resolve().then(() => (init_memoryPrompt(), exports_memoryPrompt));
|
|
38106
|
+
const nextSystemPrompt = reconcileMemoryPrompt2(agent.system || "", enableMemfs ? "memfs" : "standard");
|
|
38107
|
+
await client.agents.update(agentId, {
|
|
38108
|
+
system: nextSystemPrompt
|
|
38109
|
+
});
|
|
38110
|
+
return {
|
|
38111
|
+
success: true,
|
|
38112
|
+
message: enableMemfs ? "System prompt updated to include Memory Filesystem section" : "System prompt updated to include standard Memory section"
|
|
38113
|
+
};
|
|
38114
|
+
} catch (error) {
|
|
38115
|
+
return {
|
|
38116
|
+
success: false,
|
|
38117
|
+
message: `Failed to update system prompt memfs: ${error instanceof Error ? error.message : String(error)}`
|
|
38118
|
+
};
|
|
38119
|
+
}
|
|
38120
|
+
}
|
|
38121
|
+
var init_modify = __esm(async () => {
|
|
38122
|
+
await __promiseAll([
|
|
38123
|
+
init_openai_codex_provider(),
|
|
38124
|
+
init_available_models(),
|
|
38125
|
+
init_client2()
|
|
38126
|
+
]);
|
|
38127
|
+
});
|
|
38128
|
+
|
|
38129
|
+
// src/tools/filter.ts
|
|
38130
|
+
var exports_filter = {};
|
|
38131
|
+
__export(exports_filter, {
|
|
38132
|
+
toolFilter: () => toolFilter
|
|
38133
|
+
});
|
|
38134
|
+
|
|
38135
|
+
class ToolFilterManager {
|
|
38136
|
+
enabledTools = null;
|
|
38137
|
+
setEnabledTools(toolsString) {
|
|
38138
|
+
if (toolsString === "") {
|
|
38139
|
+
this.enabledTools = [];
|
|
38140
|
+
} else {
|
|
38141
|
+
this.enabledTools = toolsString.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
38142
|
+
}
|
|
38143
|
+
}
|
|
38144
|
+
isEnabled(toolName) {
|
|
38145
|
+
if (this.enabledTools === null) {
|
|
38146
|
+
return true;
|
|
38147
|
+
}
|
|
38148
|
+
return this.enabledTools.includes(toolName);
|
|
38149
|
+
}
|
|
38150
|
+
getEnabledTools() {
|
|
38151
|
+
return this.enabledTools ? [...this.enabledTools] : null;
|
|
38152
|
+
}
|
|
38153
|
+
isActive() {
|
|
38154
|
+
return this.enabledTools !== null;
|
|
38155
|
+
}
|
|
38156
|
+
reset() {
|
|
38157
|
+
this.enabledTools = null;
|
|
38158
|
+
}
|
|
38159
|
+
}
|
|
38160
|
+
function getFilter() {
|
|
38161
|
+
const global2 = globalThis;
|
|
38162
|
+
if (!global2[FILTER_KEY]) {
|
|
38163
|
+
global2[FILTER_KEY] = new ToolFilterManager;
|
|
38164
|
+
}
|
|
38165
|
+
return global2[FILTER_KEY];
|
|
38166
|
+
}
|
|
38167
|
+
var FILTER_KEY, toolFilter;
|
|
38168
|
+
var init_filter = __esm(() => {
|
|
38169
|
+
FILTER_KEY = Symbol.for("@letta/toolFilter");
|
|
38170
|
+
toolFilter = getFilter();
|
|
38171
|
+
});
|
|
38172
|
+
|
|
38173
|
+
// src/tools/toolset.ts
|
|
38174
|
+
var exports_toolset = {};
|
|
38175
|
+
__export(exports_toolset, {
|
|
38176
|
+
switchToolsetForModel: () => switchToolsetForModel,
|
|
38177
|
+
reattachMemoryTool: () => reattachMemoryTool,
|
|
38178
|
+
forceToolsetSwitch: () => forceToolsetSwitch,
|
|
38179
|
+
ensureCorrectMemoryTool: () => ensureCorrectMemoryTool,
|
|
38180
|
+
detachMemoryTools: () => detachMemoryTools,
|
|
38181
|
+
MEMORY_TOOL_NAMES: () => MEMORY_TOOL_NAMES
|
|
38182
|
+
});
|
|
38183
|
+
async function ensureCorrectMemoryTool(agentId, modelIdentifier, useMemoryPatch) {
|
|
38184
|
+
const resolvedModel = resolveModel(modelIdentifier) ?? modelIdentifier;
|
|
38185
|
+
const client = await getClient2();
|
|
38186
|
+
const shouldUsePatch = useMemoryPatch !== undefined ? useMemoryPatch : isOpenAIModel(resolvedModel);
|
|
38187
|
+
try {
|
|
38188
|
+
const agentWithTools = await client.agents.retrieve(agentId, {
|
|
38189
|
+
include: ["agent.tools"]
|
|
38190
|
+
});
|
|
38191
|
+
const currentTools = agentWithTools.tools || [];
|
|
38192
|
+
const mapByName = new Map(currentTools.map((t) => [t.name, t.id]));
|
|
38193
|
+
const hasAnyMemoryTool = mapByName.has("memory") || mapByName.has("memory_apply_patch");
|
|
38194
|
+
if (!hasAnyMemoryTool) {
|
|
38195
|
+
return;
|
|
38196
|
+
}
|
|
38197
|
+
const desiredMemoryTool = shouldUsePatch ? "memory_apply_patch" : "memory";
|
|
38198
|
+
const otherMemoryTool = desiredMemoryTool === "memory" ? "memory_apply_patch" : "memory";
|
|
38199
|
+
let desiredId = mapByName.get(desiredMemoryTool);
|
|
38200
|
+
if (!desiredId) {
|
|
38201
|
+
const resp = await client.tools.list({ name: desiredMemoryTool });
|
|
38202
|
+
desiredId = resp.items[0]?.id;
|
|
38203
|
+
}
|
|
38204
|
+
if (!desiredId) {
|
|
38205
|
+
return;
|
|
38206
|
+
}
|
|
38207
|
+
const otherId = mapByName.get(otherMemoryTool);
|
|
38208
|
+
if (mapByName.has(desiredMemoryTool) && !otherId) {
|
|
38209
|
+
return;
|
|
38210
|
+
}
|
|
38211
|
+
const currentIds = currentTools.map((t) => t.id).filter((id) => typeof id === "string");
|
|
38212
|
+
const newIds = new Set(currentIds);
|
|
38213
|
+
if (otherId)
|
|
38214
|
+
newIds.delete(otherId);
|
|
38215
|
+
newIds.add(desiredId);
|
|
38216
|
+
const updatedRules = (agentWithTools.tool_rules || []).map((r) => r.tool_name === otherMemoryTool ? { ...r, tool_name: desiredMemoryTool } : r);
|
|
38217
|
+
await client.agents.update(agentId, {
|
|
38218
|
+
tool_ids: Array.from(newIds),
|
|
38219
|
+
tool_rules: updatedRules
|
|
38220
|
+
});
|
|
38221
|
+
} catch (err) {
|
|
38222
|
+
console.warn(`Warning: Failed to sync memory tool: ${err instanceof Error ? err.message : String(err)}`);
|
|
38223
|
+
}
|
|
38224
|
+
}
|
|
38225
|
+
async function detachMemoryTools(agentId) {
|
|
38226
|
+
const client = await getClient2();
|
|
38227
|
+
try {
|
|
38228
|
+
const agentWithTools = await client.agents.retrieve(agentId, {
|
|
38229
|
+
include: ["agent.tools"]
|
|
38230
|
+
});
|
|
38231
|
+
const currentTools = agentWithTools.tools || [];
|
|
38232
|
+
let detachedAny = false;
|
|
38233
|
+
for (const tool of currentTools) {
|
|
38234
|
+
if (tool.name && MEMORY_TOOL_NAMES.has(tool.name)) {
|
|
38235
|
+
if (tool.id) {
|
|
38236
|
+
await client.agents.tools.detach(tool.id, { agent_id: agentId });
|
|
38237
|
+
detachedAny = true;
|
|
38238
|
+
}
|
|
38239
|
+
}
|
|
38240
|
+
}
|
|
38241
|
+
return detachedAny;
|
|
38242
|
+
} catch (err) {
|
|
38243
|
+
console.warn(`Warning: Failed to detach memory tools: ${err instanceof Error ? err.message : String(err)}`);
|
|
38244
|
+
return false;
|
|
38245
|
+
}
|
|
38246
|
+
}
|
|
38247
|
+
async function reattachMemoryTool(agentId, modelIdentifier) {
|
|
38248
|
+
const resolvedModel = resolveModel(modelIdentifier) ?? modelIdentifier;
|
|
38249
|
+
const client = await getClient2();
|
|
38250
|
+
const shouldUsePatch = isOpenAIModel(resolvedModel);
|
|
38251
|
+
try {
|
|
38252
|
+
const agentWithTools = await client.agents.retrieve(agentId, {
|
|
38253
|
+
include: ["agent.tools"]
|
|
38254
|
+
});
|
|
38255
|
+
const currentTools = agentWithTools.tools || [];
|
|
38256
|
+
const mapByName = new Map(currentTools.map((t) => [t.name, t.id]));
|
|
38257
|
+
const desiredMemoryTool = shouldUsePatch ? "memory_apply_patch" : "memory";
|
|
38258
|
+
if (mapByName.has(desiredMemoryTool)) {
|
|
38259
|
+
return;
|
|
38260
|
+
}
|
|
38261
|
+
const resp = await client.tools.list({ name: desiredMemoryTool });
|
|
38262
|
+
const toolId = resp.items[0]?.id;
|
|
38263
|
+
if (!toolId) {
|
|
38264
|
+
console.warn(`Memory tool "${desiredMemoryTool}" not found on server`);
|
|
38265
|
+
return;
|
|
38266
|
+
}
|
|
38267
|
+
await client.agents.tools.attach(toolId, { agent_id: agentId });
|
|
38268
|
+
} catch (err) {
|
|
38269
|
+
console.warn(`Warning: Failed to reattach memory tool: ${err instanceof Error ? err.message : String(err)}`);
|
|
38270
|
+
}
|
|
38271
|
+
}
|
|
38272
|
+
async function forceToolsetSwitch(toolsetName, agentId) {
|
|
38273
|
+
let modelForLoading;
|
|
38274
|
+
if (toolsetName === "none") {
|
|
38275
|
+
clearToolsWithLock();
|
|
38276
|
+
return;
|
|
38277
|
+
} else if (toolsetName === "codex") {
|
|
38278
|
+
await loadSpecificTools([...CODEX_TOOLS]);
|
|
38279
|
+
modelForLoading = "openai/gpt-4";
|
|
38280
|
+
} else if (toolsetName === "codex_snake") {
|
|
38281
|
+
await loadTools("openai/gpt-4");
|
|
38282
|
+
modelForLoading = "openai/gpt-4";
|
|
38283
|
+
} else if (toolsetName === "gemini") {
|
|
38284
|
+
await loadSpecificTools([...GEMINI_TOOLS]);
|
|
38285
|
+
modelForLoading = "google_ai/gemini-3-pro-preview";
|
|
38286
|
+
} else if (toolsetName === "gemini_snake") {
|
|
38287
|
+
await loadTools("google_ai/gemini-3-pro-preview");
|
|
38288
|
+
modelForLoading = "google_ai/gemini-3-pro-preview";
|
|
38289
|
+
} else {
|
|
38290
|
+
await loadTools("anthropic/claude-sonnet-4");
|
|
38291
|
+
modelForLoading = "anthropic/claude-sonnet-4";
|
|
38292
|
+
}
|
|
38293
|
+
const useMemoryPatch = toolsetName === "codex" || toolsetName === "codex_snake";
|
|
38294
|
+
await ensureCorrectMemoryTool(agentId, modelForLoading, useMemoryPatch);
|
|
38295
|
+
}
|
|
38296
|
+
async function switchToolsetForModel(modelIdentifier, agentId) {
|
|
38297
|
+
const resolvedModel = resolveModel(modelIdentifier) ?? modelIdentifier;
|
|
38298
|
+
await loadTools(resolvedModel);
|
|
38299
|
+
const loadedAfterPrimary = getToolNames().length;
|
|
38300
|
+
if (loadedAfterPrimary === 0 && !toolFilter.isActive()) {
|
|
38301
|
+
await loadTools();
|
|
38302
|
+
if (getToolNames().length === 0) {
|
|
38303
|
+
throw new Error(`Failed to load any Letta tools for model "${resolvedModel}".`);
|
|
38304
|
+
}
|
|
38305
|
+
}
|
|
38306
|
+
await ensureCorrectMemoryTool(agentId, resolvedModel);
|
|
38307
|
+
const { isGeminiModel } = await init_manager3().then(() => exports_manager2);
|
|
38308
|
+
const toolsetName = isOpenAIModel(resolvedModel) ? "codex" : isGeminiModel(resolvedModel) ? "gemini" : "default";
|
|
38309
|
+
return toolsetName;
|
|
38310
|
+
}
|
|
38311
|
+
var CODEX_TOOLS, GEMINI_TOOLS, MEMORY_TOOL_NAMES;
|
|
38312
|
+
var init_toolset = __esm(async () => {
|
|
38313
|
+
init_model();
|
|
38314
|
+
init_filter();
|
|
38315
|
+
await __promiseAll([
|
|
38316
|
+
init_client2(),
|
|
38317
|
+
init_manager3()
|
|
38318
|
+
]);
|
|
38319
|
+
CODEX_TOOLS = OPENAI_PASCAL_TOOLS;
|
|
38320
|
+
GEMINI_TOOLS = GEMINI_PASCAL_TOOLS;
|
|
38321
|
+
MEMORY_TOOL_NAMES = new Set([
|
|
38322
|
+
"memory",
|
|
38323
|
+
"memory_apply_patch",
|
|
38324
|
+
"memory_insert",
|
|
38325
|
+
"memory_replace",
|
|
38326
|
+
"memory_rethink"
|
|
38327
|
+
]);
|
|
38328
|
+
});
|
|
38329
|
+
|
|
38330
|
+
// src/agent/memoryFilesystem.ts
|
|
38331
|
+
var exports_memoryFilesystem = {};
|
|
38332
|
+
__export(exports_memoryFilesystem, {
|
|
38333
|
+
renderMemoryFilesystemTree: () => renderMemoryFilesystemTree,
|
|
38334
|
+
labelFromRelativePath: () => labelFromRelativePath,
|
|
38335
|
+
getMemorySystemDir: () => getMemorySystemDir,
|
|
38336
|
+
getMemoryFilesystemRoot: () => getMemoryFilesystemRoot,
|
|
38337
|
+
ensureMemoryFilesystemDirs: () => ensureMemoryFilesystemDirs,
|
|
38338
|
+
enableMemfsIfCloud: () => enableMemfsIfCloud,
|
|
38339
|
+
applyMemfsFlags: () => applyMemfsFlags,
|
|
38340
|
+
MEMORY_SYSTEM_DIR: () => MEMORY_SYSTEM_DIR,
|
|
38341
|
+
MEMORY_FS_ROOT: () => MEMORY_FS_ROOT,
|
|
38342
|
+
MEMORY_FS_MEMORY_DIR: () => MEMORY_FS_MEMORY_DIR,
|
|
38343
|
+
MEMORY_FS_AGENTS_DIR: () => MEMORY_FS_AGENTS_DIR
|
|
38344
|
+
});
|
|
38345
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync4 } from "node:fs";
|
|
38346
|
+
import { homedir as homedir8 } from "node:os";
|
|
38347
|
+
import { join as join7 } from "node:path";
|
|
38348
|
+
function getMemoryFilesystemRoot(agentId, homeDir = homedir8()) {
|
|
38349
|
+
return join7(homeDir, MEMORY_FS_ROOT, MEMORY_FS_AGENTS_DIR, agentId, MEMORY_FS_MEMORY_DIR);
|
|
38350
|
+
}
|
|
38351
|
+
function getMemorySystemDir(agentId, homeDir = homedir8()) {
|
|
38352
|
+
return join7(getMemoryFilesystemRoot(agentId, homeDir), MEMORY_SYSTEM_DIR);
|
|
38353
|
+
}
|
|
38354
|
+
function ensureMemoryFilesystemDirs(agentId, homeDir = homedir8()) {
|
|
38355
|
+
const root = getMemoryFilesystemRoot(agentId, homeDir);
|
|
38356
|
+
const systemDir = getMemorySystemDir(agentId, homeDir);
|
|
38357
|
+
if (!existsSync6(root)) {
|
|
38358
|
+
mkdirSync4(root, { recursive: true });
|
|
38359
|
+
}
|
|
38360
|
+
if (!existsSync6(systemDir)) {
|
|
38361
|
+
mkdirSync4(systemDir, { recursive: true });
|
|
38362
|
+
}
|
|
38363
|
+
}
|
|
38364
|
+
function labelFromRelativePath(relativePath) {
|
|
38365
|
+
const normalized = relativePath.replace(/\\/g, "/");
|
|
38366
|
+
return normalized.replace(/\.md$/, "");
|
|
38367
|
+
}
|
|
38368
|
+
function renderMemoryFilesystemTree(systemLabels, detachedLabels) {
|
|
38369
|
+
const makeNode = () => ({ children: new Map, isFile: false });
|
|
38370
|
+
const root = makeNode();
|
|
38371
|
+
const insertPath = (base2, label) => {
|
|
38372
|
+
const parts = base2 ? [base2, ...label.split("/")] : label.split("/");
|
|
38373
|
+
let current = root;
|
|
38374
|
+
for (const [i, partName] of parts.entries()) {
|
|
38375
|
+
const part = i === parts.length - 1 ? `${partName}.md` : partName;
|
|
38376
|
+
if (!current.children.has(part)) {
|
|
38377
|
+
current.children.set(part, makeNode());
|
|
38378
|
+
}
|
|
38379
|
+
current = current.children.get(part);
|
|
38380
|
+
if (i === parts.length - 1) {
|
|
38381
|
+
current.isFile = true;
|
|
38382
|
+
}
|
|
38383
|
+
}
|
|
38384
|
+
};
|
|
38385
|
+
for (const label of systemLabels) {
|
|
38386
|
+
insertPath(MEMORY_SYSTEM_DIR, label);
|
|
38387
|
+
}
|
|
38388
|
+
for (const label of detachedLabels) {
|
|
38389
|
+
insertPath(null, label);
|
|
38390
|
+
}
|
|
38391
|
+
if (!root.children.has(MEMORY_SYSTEM_DIR)) {
|
|
38392
|
+
root.children.set(MEMORY_SYSTEM_DIR, makeNode());
|
|
38393
|
+
}
|
|
38394
|
+
const sortedEntries = (node) => {
|
|
38395
|
+
const entries = Array.from(node.children.entries());
|
|
38396
|
+
return entries.sort(([nameA, nodeA], [nameB, nodeB]) => {
|
|
38397
|
+
if (nodeA.isFile !== nodeB.isFile) {
|
|
38398
|
+
return nodeA.isFile ? 1 : -1;
|
|
38399
|
+
}
|
|
38400
|
+
return nameA.localeCompare(nameB);
|
|
38401
|
+
});
|
|
38402
|
+
};
|
|
38403
|
+
const lines = ["/memory/"];
|
|
38404
|
+
const render2 = (node, prefix) => {
|
|
38405
|
+
const entries = sortedEntries(node);
|
|
38406
|
+
entries.forEach(([name, child], index) => {
|
|
38407
|
+
const isLast = index === entries.length - 1;
|
|
38408
|
+
const branch = isLast ? "└──" : "├──";
|
|
38409
|
+
lines.push(`${prefix}${branch} ${name}${child.isFile ? "" : "/"}`);
|
|
38410
|
+
if (child.children.size > 0) {
|
|
38411
|
+
const nextPrefix = `${prefix}${isLast ? " " : "│ "}`;
|
|
38412
|
+
render2(child, nextPrefix);
|
|
38413
|
+
}
|
|
38414
|
+
});
|
|
38415
|
+
};
|
|
38416
|
+
render2(root, "");
|
|
38417
|
+
return lines.join(`
|
|
38418
|
+
`);
|
|
38419
|
+
}
|
|
38420
|
+
async function applyMemfsFlags(agentId, memfsFlag, noMemfsFlag, options) {
|
|
38421
|
+
const { getServerUrl: getServerUrl2 } = await init_client2().then(() => exports_client);
|
|
38422
|
+
const { settingsManager: settingsManager3 } = await init_settings_manager().then(() => exports_settings_manager);
|
|
38423
|
+
if (memfsFlag) {
|
|
38424
|
+
const serverUrl = getServerUrl2();
|
|
38425
|
+
if (!serverUrl.includes("api.letta.com")) {
|
|
38426
|
+
throw new Error("--memfs is only available on Letta Cloud (api.letta.com).");
|
|
38427
|
+
}
|
|
38428
|
+
}
|
|
38429
|
+
const hasExplicitToggle = Boolean(memfsFlag || noMemfsFlag);
|
|
38430
|
+
const targetEnabled = memfsFlag ? true : noMemfsFlag ? false : settingsManager3.isMemfsEnabled(agentId);
|
|
38431
|
+
if (hasExplicitToggle) {
|
|
38432
|
+
const { updateAgentSystemPromptMemfs: updateAgentSystemPromptMemfs2 } = await init_modify().then(() => exports_modify);
|
|
38433
|
+
const promptUpdate = await updateAgentSystemPromptMemfs2(agentId, targetEnabled);
|
|
38434
|
+
if (!promptUpdate.success) {
|
|
38435
|
+
throw new Error(promptUpdate.message);
|
|
38436
|
+
}
|
|
38437
|
+
settingsManager3.setMemfsEnabled(agentId, targetEnabled);
|
|
38438
|
+
}
|
|
38439
|
+
const isEnabled = hasExplicitToggle ? targetEnabled : settingsManager3.isMemfsEnabled(agentId);
|
|
38440
|
+
if (isEnabled && memfsFlag) {
|
|
38441
|
+
const { detachMemoryTools: detachMemoryTools2 } = await init_toolset().then(() => exports_toolset);
|
|
38442
|
+
await detachMemoryTools2(agentId);
|
|
38443
|
+
}
|
|
38444
|
+
let pullSummary;
|
|
38445
|
+
if (isEnabled) {
|
|
38446
|
+
const { addGitMemoryTag: addGitMemoryTag2, isGitRepo: isGitRepo2, cloneMemoryRepo: cloneMemoryRepo2, pullMemory: pullMemory2 } = await init_memoryGit().then(() => exports_memoryGit);
|
|
38447
|
+
await addGitMemoryTag2(agentId);
|
|
38448
|
+
if (!isGitRepo2(agentId)) {
|
|
38449
|
+
await cloneMemoryRepo2(agentId);
|
|
38450
|
+
} else if (options?.pullOnExistingRepo) {
|
|
38451
|
+
const result = await pullMemory2(agentId);
|
|
38452
|
+
pullSummary = result.summary;
|
|
38453
|
+
}
|
|
38454
|
+
}
|
|
38455
|
+
const action = memfsFlag ? "enabled" : noMemfsFlag ? "disabled" : "unchanged";
|
|
38456
|
+
return {
|
|
38457
|
+
action,
|
|
38458
|
+
memoryDir: isEnabled ? getMemoryFilesystemRoot(agentId) : undefined,
|
|
38459
|
+
pullSummary
|
|
38460
|
+
};
|
|
38461
|
+
}
|
|
38462
|
+
async function enableMemfsIfCloud(agentId) {
|
|
38463
|
+
const { getServerUrl: getServerUrl2 } = await init_client2().then(() => exports_client);
|
|
38464
|
+
const serverUrl = getServerUrl2();
|
|
38465
|
+
if (!serverUrl.includes("api.letta.com"))
|
|
38466
|
+
return;
|
|
38467
|
+
try {
|
|
38468
|
+
await applyMemfsFlags(agentId, true, undefined);
|
|
38469
|
+
} catch (error) {
|
|
38470
|
+
console.warn(`Warning: Could not enable memfs for new agent: ${error instanceof Error ? error.message : String(error)}`);
|
|
38471
|
+
}
|
|
38472
|
+
}
|
|
38473
|
+
var MEMORY_FS_ROOT = ".letta", MEMORY_FS_AGENTS_DIR = "agents", MEMORY_FS_MEMORY_DIR = "memory", MEMORY_SYSTEM_DIR = "system";
|
|
38474
|
+
var init_memoryFilesystem = () => {};
|
|
38475
|
+
|
|
37552
38476
|
// src/tools/impl/shellEnv.ts
|
|
37553
38477
|
var exports_shellEnv = {};
|
|
37554
38478
|
__export(exports_shellEnv, {
|
|
@@ -37556,7 +38480,7 @@ __export(exports_shellEnv, {
|
|
|
37556
38480
|
getShellEnv: () => getShellEnv,
|
|
37557
38481
|
ensureLettaShimDir: () => ensureLettaShimDir
|
|
37558
38482
|
});
|
|
37559
|
-
import { mkdirSync as
|
|
38483
|
+
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync2 } from "node:fs";
|
|
37560
38484
|
import { createRequire as createRequire2 } from "node:module";
|
|
37561
38485
|
import { tmpdir } from "node:os";
|
|
37562
38486
|
import * as path3 from "node:path";
|
|
@@ -37629,7 +38553,7 @@ function ensureLettaShimDir(invocation) {
|
|
|
37629
38553
|
if (!invocation.command)
|
|
37630
38554
|
return null;
|
|
37631
38555
|
const shimDir = path3.join(tmpdir(), "letta-code-shell-shim");
|
|
37632
|
-
|
|
38556
|
+
mkdirSync5(shimDir, { recursive: true });
|
|
37633
38557
|
if (process.platform === "win32") {
|
|
37634
38558
|
const cmdPath = path3.join(shimDir, "letta.cmd");
|
|
37635
38559
|
const quotedCommand = `"${invocation.command.replaceAll('"', '""')}"`;
|
|
@@ -37669,9 +38593,33 @@ function getShellEnv() {
|
|
|
37669
38593
|
const existingPath = env3[pathKey] || "";
|
|
37670
38594
|
env3[pathKey] = existingPath ? `${pathPrefixes.join(path3.delimiter)}${path3.delimiter}${existingPath}` : pathPrefixes.join(path3.delimiter);
|
|
37671
38595
|
}
|
|
38596
|
+
let agentId;
|
|
37672
38597
|
try {
|
|
37673
|
-
|
|
38598
|
+
const resolvedAgentId = getCurrentAgentId();
|
|
38599
|
+
if (typeof resolvedAgentId === "string" && resolvedAgentId.trim()) {
|
|
38600
|
+
agentId = resolvedAgentId.trim();
|
|
38601
|
+
}
|
|
37674
38602
|
} catch {}
|
|
38603
|
+
if (!agentId) {
|
|
38604
|
+
const fallbackAgentId = env3.AGENT_ID || env3.LETTA_AGENT_ID;
|
|
38605
|
+
if (typeof fallbackAgentId === "string" && fallbackAgentId.trim()) {
|
|
38606
|
+
agentId = fallbackAgentId.trim();
|
|
38607
|
+
}
|
|
38608
|
+
}
|
|
38609
|
+
if (agentId) {
|
|
38610
|
+
env3.LETTA_AGENT_ID = agentId;
|
|
38611
|
+
env3.AGENT_ID = agentId;
|
|
38612
|
+
try {
|
|
38613
|
+
if (settingsManager.isMemfsEnabled(agentId)) {
|
|
38614
|
+
const memoryDir = getMemoryFilesystemRoot(agentId);
|
|
38615
|
+
env3.LETTA_MEMORY_DIR = memoryDir;
|
|
38616
|
+
env3.MEMORY_DIR = memoryDir;
|
|
38617
|
+
} else {
|
|
38618
|
+
delete env3.LETTA_MEMORY_DIR;
|
|
38619
|
+
delete env3.MEMORY_DIR;
|
|
38620
|
+
}
|
|
38621
|
+
} catch {}
|
|
38622
|
+
}
|
|
37675
38623
|
if (!env3.LETTA_API_KEY || !env3.LETTA_BASE_URL) {
|
|
37676
38624
|
try {
|
|
37677
38625
|
const settings = settingsManager.getSettings();
|
|
@@ -37699,6 +38647,7 @@ function getShellEnv() {
|
|
|
37699
38647
|
var LETTA_BIN_ARGS_ENV = "LETTA_CODE_BIN_ARGS_JSON";
|
|
37700
38648
|
var init_shellEnv = __esm(async () => {
|
|
37701
38649
|
init_context();
|
|
38650
|
+
init_memoryFilesystem();
|
|
37702
38651
|
await __promiseAll([
|
|
37703
38652
|
init_client2(),
|
|
37704
38653
|
init_settings_manager()
|
|
@@ -38472,8 +39421,8 @@ async function edit(args) {
|
|
|
38472
39421
|
var init_Edit2 = () => {};
|
|
38473
39422
|
|
|
38474
39423
|
// src/cli/helpers/planName.ts
|
|
38475
|
-
import { homedir as
|
|
38476
|
-
import { join as
|
|
39424
|
+
import { homedir as homedir10 } from "node:os";
|
|
39425
|
+
import { join as join10 } from "node:path";
|
|
38477
39426
|
function randomElement(arr) {
|
|
38478
39427
|
return arr[Math.floor(Math.random() * arr.length)];
|
|
38479
39428
|
}
|
|
@@ -38485,7 +39434,7 @@ function generatePlanName() {
|
|
|
38485
39434
|
}
|
|
38486
39435
|
function generatePlanFilePath() {
|
|
38487
39436
|
const name = generatePlanName();
|
|
38488
|
-
return
|
|
39437
|
+
return join10(homedir10(), ".letta", "plans", `${name}.md`);
|
|
38489
39438
|
}
|
|
38490
39439
|
var adjectives, nouns;
|
|
38491
39440
|
var init_planName = __esm(() => {
|
|
@@ -38594,8 +39543,8 @@ var exports_mode = {};
|
|
|
38594
39543
|
__export(exports_mode, {
|
|
38595
39544
|
permissionMode: () => permissionMode2
|
|
38596
39545
|
});
|
|
38597
|
-
import { homedir as
|
|
38598
|
-
import { join as
|
|
39546
|
+
import { homedir as homedir11 } from "node:os";
|
|
39547
|
+
import { join as join11 } from "node:path";
|
|
38599
39548
|
function getGlobalMode2() {
|
|
38600
39549
|
const global2 = globalThis;
|
|
38601
39550
|
if (!global2[MODE_KEY2]) {
|
|
@@ -38716,7 +39665,7 @@ class PermissionModeManager2 {
|
|
|
38716
39665
|
return "allow";
|
|
38717
39666
|
}
|
|
38718
39667
|
if (writeTools.includes(toolName)) {
|
|
38719
|
-
const plansDir =
|
|
39668
|
+
const plansDir = join11(homedir11(), ".letta", "plans");
|
|
38720
39669
|
let targetPath = toolArgs?.file_path || toolArgs?.path;
|
|
38721
39670
|
if ((toolName === "ApplyPatch" || toolName === "apply_patch") && toolArgs?.input) {
|
|
38722
39671
|
const input = toolArgs.input;
|
|
@@ -40744,7 +41693,7 @@ var init_LS2 = __esm(() => {
|
|
|
40744
41693
|
|
|
40745
41694
|
// src/tools/impl/LS.ts
|
|
40746
41695
|
import { readdir as readdir3, stat } from "node:fs/promises";
|
|
40747
|
-
import { join as
|
|
41696
|
+
import { join as join13, resolve as resolve7 } from "node:path";
|
|
40748
41697
|
async function ls(args) {
|
|
40749
41698
|
validateRequiredParams(args, ["path"], "LS");
|
|
40750
41699
|
validateParamTypes(args, LS_default2, "LS");
|
|
@@ -40754,7 +41703,7 @@ async function ls(args) {
|
|
|
40754
41703
|
const items = await readdir3(dirPath);
|
|
40755
41704
|
const filteredItems = items.filter((item) => !ignore.some((pattern) => import_picomatch.default.isMatch(item, pattern)));
|
|
40756
41705
|
const fileInfos = await Promise.all(filteredItems.map(async (item) => {
|
|
40757
|
-
const fullPath =
|
|
41706
|
+
const fullPath = join13(dirPath, item);
|
|
40758
41707
|
try {
|
|
40759
41708
|
const stats = await stat(fullPath);
|
|
40760
41709
|
return {
|
|
@@ -40917,9 +41866,9 @@ __export(exports_imageResize_magick, {
|
|
|
40917
41866
|
import { execSync } from "node:child_process";
|
|
40918
41867
|
import { readFileSync as readFileSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
40919
41868
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
40920
|
-
import { join as
|
|
41869
|
+
import { join as join14 } from "node:path";
|
|
40921
41870
|
async function getImageDimensions(buffer) {
|
|
40922
|
-
const tempInput =
|
|
41871
|
+
const tempInput = join14(tmpdir2(), `image-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);
|
|
40923
41872
|
writeFileSync4(tempInput, buffer);
|
|
40924
41873
|
try {
|
|
40925
41874
|
const output = execSync(`magick identify -format "%w %h %m" "${tempInput}"`, {
|
|
@@ -40942,12 +41891,12 @@ async function compressToFitByteLimit(buffer, currentWidth, currentHeight) {
|
|
|
40942
41891
|
if (buffer.length <= MAX_IMAGE_BYTES) {
|
|
40943
41892
|
return null;
|
|
40944
41893
|
}
|
|
40945
|
-
const tempInput =
|
|
41894
|
+
const tempInput = join14(tmpdir2(), `compress-input-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);
|
|
40946
41895
|
writeFileSync4(tempInput, buffer);
|
|
40947
41896
|
try {
|
|
40948
41897
|
const qualities = [85, 70, 55, 40];
|
|
40949
41898
|
for (const quality of qualities) {
|
|
40950
|
-
const tempOutput =
|
|
41899
|
+
const tempOutput = join14(tmpdir2(), `compress-output-${Date.now()}-${Math.random().toString(36).slice(2)}.jpg`);
|
|
40951
41900
|
try {
|
|
40952
41901
|
execSync(`magick "${tempInput}" -quality ${quality} "${tempOutput}"`, {
|
|
40953
41902
|
stdio: "ignore"
|
|
@@ -40973,7 +41922,7 @@ async function compressToFitByteLimit(buffer, currentWidth, currentHeight) {
|
|
|
40973
41922
|
for (const scale of scales) {
|
|
40974
41923
|
const scaledWidth = Math.floor(currentWidth * scale);
|
|
40975
41924
|
const scaledHeight = Math.floor(currentHeight * scale);
|
|
40976
|
-
const tempOutput =
|
|
41925
|
+
const tempOutput = join14(tmpdir2(), `compress-output-${Date.now()}-${Math.random().toString(36).slice(2)}.jpg`);
|
|
40977
41926
|
try {
|
|
40978
41927
|
execSync(`magick "${tempInput}" -resize ${scaledWidth}x${scaledHeight} -quality 70 "${tempOutput}"`, {
|
|
40979
41928
|
stdio: "ignore"
|
|
@@ -41017,11 +41966,11 @@ async function resizeImageIfNeeded(buffer, inputMediaType) {
|
|
|
41017
41966
|
resized: false
|
|
41018
41967
|
};
|
|
41019
41968
|
}
|
|
41020
|
-
const tempInput =
|
|
41969
|
+
const tempInput = join14(tmpdir2(), `resize-input-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);
|
|
41021
41970
|
writeFileSync4(tempInput, buffer);
|
|
41022
41971
|
try {
|
|
41023
41972
|
if (needsResize) {
|
|
41024
|
-
const tempOutput2 =
|
|
41973
|
+
const tempOutput2 = join14(tmpdir2(), `resize-output-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
41025
41974
|
let outputBuffer2;
|
|
41026
41975
|
let outputMediaType;
|
|
41027
41976
|
if (format2 === "jpeg" || format2 === "jpg") {
|
|
@@ -41052,7 +42001,7 @@ async function resizeImageIfNeeded(buffer, inputMediaType) {
|
|
|
41052
42001
|
resized: true
|
|
41053
42002
|
};
|
|
41054
42003
|
}
|
|
41055
|
-
const tempOutput =
|
|
42004
|
+
const tempOutput = join14(tmpdir2(), `convert-output-${Date.now()}-${Math.random().toString(36).slice(2)}.png`);
|
|
41056
42005
|
execSync(`magick "${tempInput}" "${tempOutput}"`, {
|
|
41057
42006
|
stdio: "ignore"
|
|
41058
42007
|
});
|
|
@@ -42272,7 +43221,7 @@ var require_range = __commonJS((exports, module) => {
|
|
|
42272
43221
|
parseRange(range) {
|
|
42273
43222
|
const memoOpts = (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | (this.options.loose && FLAG_LOOSE);
|
|
42274
43223
|
const memoKey = memoOpts + ":" + range;
|
|
42275
|
-
const cached =
|
|
43224
|
+
const cached = cache5.get(memoKey);
|
|
42276
43225
|
if (cached) {
|
|
42277
43226
|
return cached;
|
|
42278
43227
|
}
|
|
@@ -42306,7 +43255,7 @@ var require_range = __commonJS((exports, module) => {
|
|
|
42306
43255
|
rangeMap.delete("");
|
|
42307
43256
|
}
|
|
42308
43257
|
const result = [...rangeMap.values()];
|
|
42309
|
-
|
|
43258
|
+
cache5.set(memoKey, result);
|
|
42310
43259
|
return result;
|
|
42311
43260
|
}
|
|
42312
43261
|
intersects(range, options) {
|
|
@@ -42344,7 +43293,7 @@ var require_range = __commonJS((exports, module) => {
|
|
|
42344
43293
|
}
|
|
42345
43294
|
module.exports = Range;
|
|
42346
43295
|
var LRU = require_lrucache();
|
|
42347
|
-
var
|
|
43296
|
+
var cache5 = new LRU;
|
|
42348
43297
|
var parseOptions = require_parse_options();
|
|
42349
43298
|
var Comparator = require_comparator();
|
|
42350
43299
|
var debug = require_debug();
|
|
@@ -47387,7 +48336,7 @@ var require_utility = __commonJS((exports, module) => {
|
|
|
47387
48336
|
format2.heif.input.fileSuffix = [".avif"];
|
|
47388
48337
|
format2.heif.output.alias = ["avif"];
|
|
47389
48338
|
}
|
|
47390
|
-
function
|
|
48339
|
+
function cache5(options) {
|
|
47391
48340
|
if (is.bool(options)) {
|
|
47392
48341
|
if (options) {
|
|
47393
48342
|
return sharp.cache(50, 20, 100);
|
|
@@ -47400,7 +48349,7 @@ var require_utility = __commonJS((exports, module) => {
|
|
|
47400
48349
|
return sharp.cache();
|
|
47401
48350
|
}
|
|
47402
48351
|
}
|
|
47403
|
-
|
|
48352
|
+
cache5(true);
|
|
47404
48353
|
function concurrency(concurrency2) {
|
|
47405
48354
|
return sharp.concurrency(is.integer(concurrency2) ? concurrency2 : null);
|
|
47406
48355
|
}
|
|
@@ -47439,7 +48388,7 @@ var require_utility = __commonJS((exports, module) => {
|
|
|
47439
48388
|
}
|
|
47440
48389
|
}
|
|
47441
48390
|
module.exports = (Sharp) => {
|
|
47442
|
-
Sharp.cache =
|
|
48391
|
+
Sharp.cache = cache5;
|
|
47443
48392
|
Sharp.concurrency = concurrency;
|
|
47444
48393
|
Sharp.counters = counters;
|
|
47445
48394
|
Sharp.simd = simd;
|
|
@@ -54321,19 +55270,19 @@ __export(exports_skills, {
|
|
|
54321
55270
|
SKILLS_DIR: () => SKILLS_DIR,
|
|
54322
55271
|
GLOBAL_SKILLS_DIR: () => GLOBAL_SKILLS_DIR
|
|
54323
55272
|
});
|
|
54324
|
-
import { existsSync as
|
|
55273
|
+
import { existsSync as existsSync8 } from "node:fs";
|
|
54325
55274
|
import { readdir as readdir5, readFile as readFile3 } from "node:fs/promises";
|
|
54326
|
-
import { dirname as dirname4, join as
|
|
55275
|
+
import { dirname as dirname4, join as join15 } from "node:path";
|
|
54327
55276
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
54328
55277
|
function getBundledSkillsPath() {
|
|
54329
55278
|
const thisDir = dirname4(fileURLToPath6(import.meta.url));
|
|
54330
55279
|
if (thisDir.includes("src/agent") || thisDir.includes("src\\agent")) {
|
|
54331
|
-
return
|
|
55280
|
+
return join15(thisDir, "../skills/builtin");
|
|
54332
55281
|
}
|
|
54333
|
-
return
|
|
55282
|
+
return join15(thisDir, "skills");
|
|
54334
55283
|
}
|
|
54335
55284
|
function getAgentSkillsDir(agentId) {
|
|
54336
|
-
return
|
|
55285
|
+
return join15(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents", agentId, "skills");
|
|
54337
55286
|
}
|
|
54338
55287
|
async function getBundledSkills() {
|
|
54339
55288
|
const bundledPath = getBundledSkillsPath();
|
|
@@ -54342,7 +55291,7 @@ async function getBundledSkills() {
|
|
|
54342
55291
|
}
|
|
54343
55292
|
async function discoverSkillsFromDir(skillsPath, source) {
|
|
54344
55293
|
const errors = [];
|
|
54345
|
-
if (!
|
|
55294
|
+
if (!existsSync8(skillsPath)) {
|
|
54346
55295
|
return { skills: [], errors: [] };
|
|
54347
55296
|
}
|
|
54348
55297
|
const skills = [];
|
|
@@ -54356,7 +55305,7 @@ async function discoverSkillsFromDir(skillsPath, source) {
|
|
|
54356
55305
|
}
|
|
54357
55306
|
return { skills, errors };
|
|
54358
55307
|
}
|
|
54359
|
-
async function discoverSkills(projectSkillsPath =
|
|
55308
|
+
async function discoverSkills(projectSkillsPath = join15(process.cwd(), SKILLS_DIR), agentId, options) {
|
|
54360
55309
|
const allErrors = [];
|
|
54361
55310
|
const skillsById = new Map;
|
|
54362
55311
|
if (!options?.skipBundled) {
|
|
@@ -54392,7 +55341,7 @@ async function findSkillFiles(currentPath, rootPath, skills, errors, source) {
|
|
|
54392
55341
|
try {
|
|
54393
55342
|
const entries = await readdir5(currentPath, { withFileTypes: true });
|
|
54394
55343
|
for (const entry of entries) {
|
|
54395
|
-
const fullPath =
|
|
55344
|
+
const fullPath = join15(currentPath, entry.name);
|
|
54396
55345
|
if (entry.isDirectory()) {
|
|
54397
55346
|
await findSkillFiles(fullPath, rootPath, skills, errors, source);
|
|
54398
55347
|
} else if (entry.isFile() && entry.name.toUpperCase() === "SKILL.MD") {
|
|
@@ -54466,7 +55415,7 @@ ${lines.join(`
|
|
|
54466
55415
|
}
|
|
54467
55416
|
var SKILLS_DIR = ".skills", GLOBAL_SKILLS_DIR;
|
|
54468
55417
|
var init_skills = __esm(() => {
|
|
54469
|
-
GLOBAL_SKILLS_DIR =
|
|
55418
|
+
GLOBAL_SKILLS_DIR = join15(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
|
|
54470
55419
|
});
|
|
54471
55420
|
|
|
54472
55421
|
// src/tools/impl/skillContentRegistry.ts
|
|
@@ -54491,7 +55440,7 @@ var init_skillContentRegistry = __esm(() => {
|
|
|
54491
55440
|
// src/tools/impl/Skill.ts
|
|
54492
55441
|
import { readdirSync as readdirSync3 } from "node:fs";
|
|
54493
55442
|
import { readFile as readFile4 } from "node:fs/promises";
|
|
54494
|
-
import { dirname as dirname5, join as
|
|
55443
|
+
import { dirname as dirname5, join as join16 } from "node:path";
|
|
54495
55444
|
function hasAdditionalFiles(skillMdPath) {
|
|
54496
55445
|
try {
|
|
54497
55446
|
const skillDir = dirname5(skillMdPath);
|
|
@@ -54502,19 +55451,19 @@ function hasAdditionalFiles(skillMdPath) {
|
|
|
54502
55451
|
}
|
|
54503
55452
|
}
|
|
54504
55453
|
async function readSkillContent(skillId, skillsDir, agentId) {
|
|
54505
|
-
const projectSkillPath =
|
|
55454
|
+
const projectSkillPath = join16(skillsDir, skillId, "SKILL.md");
|
|
54506
55455
|
try {
|
|
54507
55456
|
const content = await readFile4(projectSkillPath, "utf-8");
|
|
54508
55457
|
return { content, path: projectSkillPath };
|
|
54509
55458
|
} catch {}
|
|
54510
55459
|
if (agentId) {
|
|
54511
|
-
const agentSkillPath =
|
|
55460
|
+
const agentSkillPath = join16(getAgentSkillsDir(agentId), skillId, "SKILL.md");
|
|
54512
55461
|
try {
|
|
54513
55462
|
const content = await readFile4(agentSkillPath, "utf-8");
|
|
54514
55463
|
return { content, path: agentSkillPath };
|
|
54515
55464
|
} catch {}
|
|
54516
55465
|
}
|
|
54517
|
-
const globalSkillPath =
|
|
55466
|
+
const globalSkillPath = join16(GLOBAL_SKILLS_DIR, skillId, "SKILL.md");
|
|
54518
55467
|
try {
|
|
54519
55468
|
const content = await readFile4(globalSkillPath, "utf-8");
|
|
54520
55469
|
return { content, path: globalSkillPath };
|
|
@@ -54528,8 +55477,8 @@ async function readSkillContent(skillId, skillsDir, agentId) {
|
|
|
54528
55477
|
} catch {}
|
|
54529
55478
|
}
|
|
54530
55479
|
try {
|
|
54531
|
-
const bundledSkillsDir =
|
|
54532
|
-
const bundledSkillPath =
|
|
55480
|
+
const bundledSkillsDir = join16(process.cwd(), "skills", "skills");
|
|
55481
|
+
const bundledSkillPath = join16(bundledSkillsDir, skillId, "SKILL.md");
|
|
54533
55482
|
const content = await readFile4(bundledSkillPath, "utf-8");
|
|
54534
55483
|
return { content, path: bundledSkillPath };
|
|
54535
55484
|
} catch {
|
|
@@ -54541,7 +55490,7 @@ async function getResolvedSkillsDir() {
|
|
|
54541
55490
|
if (skillsDir) {
|
|
54542
55491
|
return skillsDir;
|
|
54543
55492
|
}
|
|
54544
|
-
return
|
|
55493
|
+
return join16(process.cwd(), SKILLS_DIR);
|
|
54545
55494
|
}
|
|
54546
55495
|
async function skill(args) {
|
|
54547
55496
|
validateRequiredParams(args, ["skill"], "Skill");
|
|
@@ -54806,109 +55755,6 @@ var init_cli = __esm(() => {
|
|
|
54806
55755
|
cliPermissions = new CliPermissions;
|
|
54807
55756
|
});
|
|
54808
55757
|
|
|
54809
|
-
// src/agent/available-models.ts
|
|
54810
|
-
var exports_available_models = {};
|
|
54811
|
-
__export(exports_available_models, {
|
|
54812
|
-
prefetchAvailableModelHandles: () => prefetchAvailableModelHandles,
|
|
54813
|
-
getModelContextWindow: () => getModelContextWindow,
|
|
54814
|
-
getAvailableModelsCacheInfo: () => getAvailableModelsCacheInfo,
|
|
54815
|
-
getAvailableModelHandles: () => getAvailableModelHandles,
|
|
54816
|
-
clearAvailableModelsCache: () => clearAvailableModelsCache
|
|
54817
|
-
});
|
|
54818
|
-
function isFresh(now = Date.now()) {
|
|
54819
|
-
return cache4 !== null && now - cache4.fetchedAt < CACHE_TTL_MS;
|
|
54820
|
-
}
|
|
54821
|
-
function clearAvailableModelsCache() {
|
|
54822
|
-
cache4 = null;
|
|
54823
|
-
}
|
|
54824
|
-
function getAvailableModelsCacheInfo() {
|
|
54825
|
-
const now = Date.now();
|
|
54826
|
-
return {
|
|
54827
|
-
hasCache: cache4 !== null,
|
|
54828
|
-
isFresh: isFresh(now),
|
|
54829
|
-
fetchedAt: cache4?.fetchedAt ?? null,
|
|
54830
|
-
ageMs: cache4 ? now - cache4.fetchedAt : null,
|
|
54831
|
-
ttlMs: CACHE_TTL_MS
|
|
54832
|
-
};
|
|
54833
|
-
}
|
|
54834
|
-
async function refreshByokProviders() {
|
|
54835
|
-
const client = await getClient2();
|
|
54836
|
-
try {
|
|
54837
|
-
const providers = await client.get("/v1/providers/");
|
|
54838
|
-
const byokProviders = providers.filter((p) => p.provider_category === "byok");
|
|
54839
|
-
await Promise.allSettled(byokProviders.map(async (provider) => {
|
|
54840
|
-
try {
|
|
54841
|
-
await client.patch(`/v1/providers/${provider.id}/refresh`);
|
|
54842
|
-
} catch (error) {
|
|
54843
|
-
debugWarn("available-models", `Failed to refresh provider ${provider.name} (${provider.id}):`, error);
|
|
54844
|
-
}
|
|
54845
|
-
}));
|
|
54846
|
-
} catch (error) {
|
|
54847
|
-
debugWarn("available-models", "Failed to list providers for refresh:", error);
|
|
54848
|
-
}
|
|
54849
|
-
}
|
|
54850
|
-
async function fetchFromNetwork() {
|
|
54851
|
-
const client = await getClient2();
|
|
54852
|
-
const modelsList = await client.models.list();
|
|
54853
|
-
const handles = new Set(modelsList.map((m) => m.handle).filter((h) => !!h));
|
|
54854
|
-
const contextWindows = new Map;
|
|
54855
|
-
for (const model of modelsList) {
|
|
54856
|
-
if (model.handle && model.max_context_window) {
|
|
54857
|
-
contextWindows.set(model.handle, model.max_context_window);
|
|
54858
|
-
}
|
|
54859
|
-
}
|
|
54860
|
-
return { handles, contextWindows, fetchedAt: Date.now() };
|
|
54861
|
-
}
|
|
54862
|
-
async function getAvailableModelHandles(options) {
|
|
54863
|
-
const forceRefresh = options?.forceRefresh === true;
|
|
54864
|
-
const now = Date.now();
|
|
54865
|
-
if (!forceRefresh && isFresh(now) && cache4) {
|
|
54866
|
-
return {
|
|
54867
|
-
handles: cache4.handles,
|
|
54868
|
-
source: "cache",
|
|
54869
|
-
fetchedAt: cache4.fetchedAt
|
|
54870
|
-
};
|
|
54871
|
-
}
|
|
54872
|
-
if (!forceRefresh && inflight) {
|
|
54873
|
-
const entry2 = await inflight;
|
|
54874
|
-
return {
|
|
54875
|
-
handles: entry2.handles,
|
|
54876
|
-
source: "network",
|
|
54877
|
-
fetchedAt: entry2.fetchedAt
|
|
54878
|
-
};
|
|
54879
|
-
}
|
|
54880
|
-
if (forceRefresh) {
|
|
54881
|
-
await refreshByokProviders();
|
|
54882
|
-
}
|
|
54883
|
-
inflight = fetchFromNetwork().then((entry2) => {
|
|
54884
|
-
cache4 = entry2;
|
|
54885
|
-
return entry2;
|
|
54886
|
-
}).finally(() => {
|
|
54887
|
-
inflight = null;
|
|
54888
|
-
});
|
|
54889
|
-
const entry = await inflight;
|
|
54890
|
-
return {
|
|
54891
|
-
handles: entry.handles,
|
|
54892
|
-
source: "network",
|
|
54893
|
-
fetchedAt: entry.fetchedAt
|
|
54894
|
-
};
|
|
54895
|
-
}
|
|
54896
|
-
function prefetchAvailableModelHandles() {
|
|
54897
|
-
getAvailableModelHandles().catch(() => {});
|
|
54898
|
-
}
|
|
54899
|
-
async function getModelContextWindow(handle) {
|
|
54900
|
-
if (!cache4) {
|
|
54901
|
-
await getAvailableModelHandles();
|
|
54902
|
-
}
|
|
54903
|
-
return cache4?.contextWindows.get(handle);
|
|
54904
|
-
}
|
|
54905
|
-
var CACHE_TTL_MS, cache4 = null, inflight = null;
|
|
54906
|
-
var init_available_models = __esm(async () => {
|
|
54907
|
-
init_debug();
|
|
54908
|
-
await init_client2();
|
|
54909
|
-
CACHE_TTL_MS = 5 * 60 * 1000;
|
|
54910
|
-
});
|
|
54911
|
-
|
|
54912
55758
|
// src/agent/subagents/manager.ts
|
|
54913
55759
|
import { spawn as spawn4 } from "node:child_process";
|
|
54914
55760
|
import { createInterface } from "node:readline";
|
|
@@ -56798,11 +57644,6 @@ var init_Task3 = __esm(() => {
|
|
|
56798
57644
|
conversation_id: {
|
|
56799
57645
|
type: "string",
|
|
56800
57646
|
description: "Resume from an existing conversation. Does NOT require agent_id (conversation IDs are unique and encode the agent)."
|
|
56801
|
-
},
|
|
56802
|
-
max_turns: {
|
|
56803
|
-
type: "integer",
|
|
56804
|
-
exclusiveMinimum: 0,
|
|
56805
|
-
description: "Maximum number of agentic turns (API round-trips) before stopping. Defaults to unlimited (recommended for most use cases)."
|
|
56806
57647
|
}
|
|
56807
57648
|
},
|
|
56808
57649
|
required: ["description", "prompt", "subagent_type"],
|
|
@@ -58665,8 +59506,8 @@ function matchesFilePattern(query, pattern, workingDirectory) {
|
|
|
58665
59506
|
globPattern = globPattern.slice(2);
|
|
58666
59507
|
}
|
|
58667
59508
|
if (globPattern.startsWith("~/")) {
|
|
58668
|
-
const
|
|
58669
|
-
globPattern = globPattern.replace(/^~/,
|
|
59509
|
+
const homedir12 = __require("node:os").homedir();
|
|
59510
|
+
globPattern = globPattern.replace(/^~/, homedir12);
|
|
58670
59511
|
}
|
|
58671
59512
|
globPattern = normalizeAbsolutePattern(globPattern, workingDirectory);
|
|
58672
59513
|
const windowsContext = isWindowsContext(workingDirectory);
|
|
@@ -59088,8 +59929,8 @@ __export(exports_loader, {
|
|
|
59088
59929
|
savePermissionRule: () => savePermissionRule,
|
|
59089
59930
|
loadPermissions: () => loadPermissions
|
|
59090
59931
|
});
|
|
59091
|
-
import { homedir as
|
|
59092
|
-
import { join as
|
|
59932
|
+
import { homedir as homedir12 } from "node:os";
|
|
59933
|
+
import { join as join17 } from "node:path";
|
|
59093
59934
|
async function loadPermissions(workingDirectory = process.cwd()) {
|
|
59094
59935
|
const merged = {
|
|
59095
59936
|
allow: [],
|
|
@@ -59098,10 +59939,10 @@ async function loadPermissions(workingDirectory = process.cwd()) {
|
|
|
59098
59939
|
additionalDirectories: []
|
|
59099
59940
|
};
|
|
59100
59941
|
const sources = [
|
|
59101
|
-
|
|
59102
|
-
|
|
59103
|
-
|
|
59104
|
-
|
|
59942
|
+
join17(process.env.XDG_CONFIG_HOME || join17(homedir12(), ".config"), "letta", "settings.json"),
|
|
59943
|
+
join17(homedir12(), ".letta", "settings.json"),
|
|
59944
|
+
join17(workingDirectory, ".letta", "settings.json"),
|
|
59945
|
+
join17(workingDirectory, ".letta", "settings.local.json")
|
|
59105
59946
|
];
|
|
59106
59947
|
for (const settingsPath of sources) {
|
|
59107
59948
|
try {
|
|
@@ -59137,13 +59978,13 @@ async function savePermissionRule(rule, ruleType, scope, workingDirectory = proc
|
|
|
59137
59978
|
let settingsPath;
|
|
59138
59979
|
switch (scope) {
|
|
59139
59980
|
case "user":
|
|
59140
|
-
settingsPath =
|
|
59981
|
+
settingsPath = join17(process.env.XDG_CONFIG_HOME || join17(homedir12(), ".config"), "letta", "settings.json");
|
|
59141
59982
|
break;
|
|
59142
59983
|
case "project":
|
|
59143
|
-
settingsPath =
|
|
59984
|
+
settingsPath = join17(workingDirectory, ".letta", "settings.json");
|
|
59144
59985
|
break;
|
|
59145
59986
|
case "local":
|
|
59146
|
-
settingsPath =
|
|
59987
|
+
settingsPath = join17(workingDirectory, ".letta", "settings.local.json");
|
|
59147
59988
|
break;
|
|
59148
59989
|
}
|
|
59149
59990
|
let settings = {};
|
|
@@ -59168,7 +60009,7 @@ async function savePermissionRule(rule, ruleType, scope, workingDirectory = proc
|
|
|
59168
60009
|
}
|
|
59169
60010
|
}
|
|
59170
60011
|
async function ensureLocalSettingsIgnored(workingDirectory) {
|
|
59171
|
-
const gitignorePath =
|
|
60012
|
+
const gitignorePath = join17(workingDirectory, ".gitignore");
|
|
59172
60013
|
const pattern = ".letta/settings.local.json";
|
|
59173
60014
|
try {
|
|
59174
60015
|
let content = "";
|
|
@@ -59193,7 +60034,7 @@ var exports_analyzer = {};
|
|
|
59193
60034
|
__export(exports_analyzer, {
|
|
59194
60035
|
analyzeApprovalContext: () => analyzeApprovalContext
|
|
59195
60036
|
});
|
|
59196
|
-
import { homedir as
|
|
60037
|
+
import { homedir as homedir13 } from "node:os";
|
|
59197
60038
|
import { dirname as dirname7, relative, resolve as resolve16, win32 as win322 } from "node:path";
|
|
59198
60039
|
function normalizeOsPath(path18) {
|
|
59199
60040
|
return path18.replace(/\\/g, "/");
|
|
@@ -59230,7 +60071,7 @@ function formatAbsoluteRulePath(path18) {
|
|
|
59230
60071
|
return `//${normalized.replace(/^\/+/, "")}`;
|
|
59231
60072
|
}
|
|
59232
60073
|
function formatDisplayPath(path18) {
|
|
59233
|
-
return normalizeOsPath(path18).replace(normalizeOsPath(
|
|
60074
|
+
return normalizeOsPath(path18).replace(normalizeOsPath(homedir13()), "~");
|
|
59234
60075
|
}
|
|
59235
60076
|
function analyzeApprovalContext(toolName, toolArgs, workingDirectory) {
|
|
59236
60077
|
const resolveFilePath = () => {
|
|
@@ -59373,7 +60214,7 @@ function detectSkillScript(command, workingDir) {
|
|
|
59373
60214
|
return null;
|
|
59374
60215
|
}
|
|
59375
60216
|
const normalizedWorkingDir = normalizePathSeparators(workingDir).replace(/\/$/, "");
|
|
59376
|
-
const normalizedHomeDir = normalizePathSeparators(
|
|
60217
|
+
const normalizedHomeDir = normalizePathSeparators(homedir13()).replace(/\/$/, "");
|
|
59377
60218
|
const detect = (source, regex2) => {
|
|
59378
60219
|
for (const candidate of pathCandidates) {
|
|
59379
60220
|
const match3 = candidate.match(regex2);
|
|
@@ -59687,50 +60528,6 @@ var init_analyzer = __esm(() => {
|
|
|
59687
60528
|
];
|
|
59688
60529
|
});
|
|
59689
60530
|
|
|
59690
|
-
// src/tools/filter.ts
|
|
59691
|
-
var exports_filter = {};
|
|
59692
|
-
__export(exports_filter, {
|
|
59693
|
-
toolFilter: () => toolFilter
|
|
59694
|
-
});
|
|
59695
|
-
|
|
59696
|
-
class ToolFilterManager {
|
|
59697
|
-
enabledTools = null;
|
|
59698
|
-
setEnabledTools(toolsString) {
|
|
59699
|
-
if (toolsString === "") {
|
|
59700
|
-
this.enabledTools = [];
|
|
59701
|
-
} else {
|
|
59702
|
-
this.enabledTools = toolsString.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
59703
|
-
}
|
|
59704
|
-
}
|
|
59705
|
-
isEnabled(toolName) {
|
|
59706
|
-
if (this.enabledTools === null) {
|
|
59707
|
-
return true;
|
|
59708
|
-
}
|
|
59709
|
-
return this.enabledTools.includes(toolName);
|
|
59710
|
-
}
|
|
59711
|
-
getEnabledTools() {
|
|
59712
|
-
return this.enabledTools ? [...this.enabledTools] : null;
|
|
59713
|
-
}
|
|
59714
|
-
isActive() {
|
|
59715
|
-
return this.enabledTools !== null;
|
|
59716
|
-
}
|
|
59717
|
-
reset() {
|
|
59718
|
-
this.enabledTools = null;
|
|
59719
|
-
}
|
|
59720
|
-
}
|
|
59721
|
-
function getFilter() {
|
|
59722
|
-
const global2 = globalThis;
|
|
59723
|
-
if (!global2[FILTER_KEY]) {
|
|
59724
|
-
global2[FILTER_KEY] = new ToolFilterManager;
|
|
59725
|
-
}
|
|
59726
|
-
return global2[FILTER_KEY];
|
|
59727
|
-
}
|
|
59728
|
-
var FILTER_KEY, toolFilter;
|
|
59729
|
-
var init_filter = __esm(() => {
|
|
59730
|
-
FILTER_KEY = Symbol.for("@letta/toolFilter");
|
|
59731
|
-
toolFilter = getFilter();
|
|
59732
|
-
});
|
|
59733
|
-
|
|
59734
60531
|
// src/tools/manager.ts
|
|
59735
60532
|
var exports_manager2 = {};
|
|
59736
60533
|
__export(exports_manager2, {
|
|
@@ -60778,19 +61575,19 @@ __export(exports_skills2, {
|
|
|
60778
61575
|
SKILLS_DIR: () => SKILLS_DIR2,
|
|
60779
61576
|
GLOBAL_SKILLS_DIR: () => GLOBAL_SKILLS_DIR2
|
|
60780
61577
|
});
|
|
60781
|
-
import { existsSync as
|
|
61578
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
60782
61579
|
import { readdir as readdir6, readFile as readFile5 } from "node:fs/promises";
|
|
60783
|
-
import { dirname as dirname8, join as
|
|
61580
|
+
import { dirname as dirname8, join as join18 } from "node:path";
|
|
60784
61581
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
60785
61582
|
function getBundledSkillsPath2() {
|
|
60786
61583
|
const thisDir = dirname8(fileURLToPath7(import.meta.url));
|
|
60787
61584
|
if (thisDir.includes("src/agent") || thisDir.includes("src\\agent")) {
|
|
60788
|
-
return
|
|
61585
|
+
return join18(thisDir, "../skills/builtin");
|
|
60789
61586
|
}
|
|
60790
|
-
return
|
|
61587
|
+
return join18(thisDir, "skills");
|
|
60791
61588
|
}
|
|
60792
61589
|
function getAgentSkillsDir2(agentId) {
|
|
60793
|
-
return
|
|
61590
|
+
return join18(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents", agentId, "skills");
|
|
60794
61591
|
}
|
|
60795
61592
|
async function getBundledSkills2() {
|
|
60796
61593
|
const bundledPath = getBundledSkillsPath2();
|
|
@@ -60799,7 +61596,7 @@ async function getBundledSkills2() {
|
|
|
60799
61596
|
}
|
|
60800
61597
|
async function discoverSkillsFromDir2(skillsPath, source) {
|
|
60801
61598
|
const errors = [];
|
|
60802
|
-
if (!
|
|
61599
|
+
if (!existsSync9(skillsPath)) {
|
|
60803
61600
|
return { skills: [], errors: [] };
|
|
60804
61601
|
}
|
|
60805
61602
|
const skills = [];
|
|
@@ -60813,7 +61610,7 @@ async function discoverSkillsFromDir2(skillsPath, source) {
|
|
|
60813
61610
|
}
|
|
60814
61611
|
return { skills, errors };
|
|
60815
61612
|
}
|
|
60816
|
-
async function discoverSkills2(projectSkillsPath =
|
|
61613
|
+
async function discoverSkills2(projectSkillsPath = join18(process.cwd(), SKILLS_DIR2), agentId, options) {
|
|
60817
61614
|
const allErrors = [];
|
|
60818
61615
|
const skillsById = new Map;
|
|
60819
61616
|
if (!options?.skipBundled) {
|
|
@@ -60849,7 +61646,7 @@ async function findSkillFiles2(currentPath, rootPath, skills, errors, source) {
|
|
|
60849
61646
|
try {
|
|
60850
61647
|
const entries = await readdir6(currentPath, { withFileTypes: true });
|
|
60851
61648
|
for (const entry of entries) {
|
|
60852
|
-
const fullPath =
|
|
61649
|
+
const fullPath = join18(currentPath, entry.name);
|
|
60853
61650
|
if (entry.isDirectory()) {
|
|
60854
61651
|
await findSkillFiles2(fullPath, rootPath, skills, errors, source);
|
|
60855
61652
|
} else if (entry.isFile() && entry.name.toUpperCase() === "SKILL.MD") {
|
|
@@ -60923,7 +61720,7 @@ ${lines.join(`
|
|
|
60923
61720
|
}
|
|
60924
61721
|
var SKILLS_DIR2 = ".skills", GLOBAL_SKILLS_DIR2;
|
|
60925
61722
|
var init_skills2 = __esm(() => {
|
|
60926
|
-
GLOBAL_SKILLS_DIR2 =
|
|
61723
|
+
GLOBAL_SKILLS_DIR2 = join18(process.env.HOME || process.env.USERPROFILE || "~", ".letta/skills");
|
|
60927
61724
|
});
|
|
60928
61725
|
|
|
60929
61726
|
// src/utils/fs.ts
|
|
@@ -60937,10 +61734,10 @@ __export(exports_fs, {
|
|
|
60937
61734
|
exists: () => exists2
|
|
60938
61735
|
});
|
|
60939
61736
|
import {
|
|
60940
|
-
existsSync as
|
|
61737
|
+
existsSync as existsSync10,
|
|
60941
61738
|
readFileSync as fsReadFileSync2,
|
|
60942
61739
|
writeFileSync as fsWriteFileSync2,
|
|
60943
|
-
mkdirSync as
|
|
61740
|
+
mkdirSync as mkdirSync7
|
|
60944
61741
|
} from "node:fs";
|
|
60945
61742
|
import { dirname as dirname9 } from "node:path";
|
|
60946
61743
|
async function readFile6(path19) {
|
|
@@ -60948,16 +61745,16 @@ async function readFile6(path19) {
|
|
|
60948
61745
|
}
|
|
60949
61746
|
async function writeFile2(path19, content) {
|
|
60950
61747
|
const dir = dirname9(path19);
|
|
60951
|
-
if (!
|
|
60952
|
-
|
|
61748
|
+
if (!existsSync10(dir)) {
|
|
61749
|
+
mkdirSync7(dir, { recursive: true });
|
|
60953
61750
|
}
|
|
60954
61751
|
fsWriteFileSync2(path19, content, { encoding: "utf-8", flush: true });
|
|
60955
61752
|
}
|
|
60956
61753
|
function exists2(path19) {
|
|
60957
|
-
return
|
|
61754
|
+
return existsSync10(path19);
|
|
60958
61755
|
}
|
|
60959
61756
|
async function mkdir2(path19, options) {
|
|
60960
|
-
|
|
61757
|
+
mkdirSync7(path19, options);
|
|
60961
61758
|
}
|
|
60962
61759
|
async function readJsonFile(path19) {
|
|
60963
61760
|
const text = await readFile6(path19);
|
|
@@ -61263,21 +62060,85 @@ var init_manager4 = __esm(() => {
|
|
|
61263
62060
|
// src/updater/auto-update.ts
|
|
61264
62061
|
var exports_auto_update = {};
|
|
61265
62062
|
__export(exports_auto_update, {
|
|
62063
|
+
resolveUpdateRegistryBaseUrl: () => resolveUpdateRegistryBaseUrl,
|
|
62064
|
+
resolveUpdatePackageName: () => resolveUpdatePackageName,
|
|
62065
|
+
resolveUpdateInstallRegistryUrl: () => resolveUpdateInstallRegistryUrl,
|
|
61266
62066
|
manualUpdate: () => manualUpdate,
|
|
61267
62067
|
detectPackageManager: () => detectPackageManager,
|
|
61268
62068
|
checkForUpdate: () => checkForUpdate,
|
|
61269
|
-
checkAndAutoUpdate: () => checkAndAutoUpdate
|
|
62069
|
+
checkAndAutoUpdate: () => checkAndAutoUpdate,
|
|
62070
|
+
buildLatestVersionUrl: () => buildLatestVersionUrl,
|
|
62071
|
+
buildInstallCommand: () => buildInstallCommand,
|
|
62072
|
+
buildInstallArgs: () => buildInstallArgs
|
|
61270
62073
|
});
|
|
61271
|
-
import {
|
|
62074
|
+
import { execFile as execFile4 } from "node:child_process";
|
|
61272
62075
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
61273
62076
|
import { readdir as readdir7, rm } from "node:fs/promises";
|
|
61274
|
-
import { join as
|
|
62077
|
+
import { join as join19 } from "node:path";
|
|
61275
62078
|
import { promisify as promisify4 } from "node:util";
|
|
61276
62079
|
function debugLog2(...args) {
|
|
61277
62080
|
if (DEBUG) {
|
|
61278
62081
|
console.error("[auto-update]", ...args);
|
|
61279
62082
|
}
|
|
61280
62083
|
}
|
|
62084
|
+
function normalizeUpdatePackageName(raw) {
|
|
62085
|
+
if (!raw)
|
|
62086
|
+
return null;
|
|
62087
|
+
const value = raw.trim();
|
|
62088
|
+
if (!value)
|
|
62089
|
+
return null;
|
|
62090
|
+
if (/\s/.test(value) || /["'`;|&$]/.test(value))
|
|
62091
|
+
return null;
|
|
62092
|
+
return value;
|
|
62093
|
+
}
|
|
62094
|
+
function normalizeRegistryUrl(raw) {
|
|
62095
|
+
if (!raw)
|
|
62096
|
+
return null;
|
|
62097
|
+
const value = raw.trim();
|
|
62098
|
+
if (!value || /\s/.test(value) || /["'`;|&$]/.test(value))
|
|
62099
|
+
return null;
|
|
62100
|
+
try {
|
|
62101
|
+
const url = new URL(value);
|
|
62102
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
62103
|
+
return null;
|
|
62104
|
+
}
|
|
62105
|
+
return value.replace(/\/+$/, "");
|
|
62106
|
+
} catch {
|
|
62107
|
+
return null;
|
|
62108
|
+
}
|
|
62109
|
+
}
|
|
62110
|
+
function resolveUpdatePackageName(env3 = process.env) {
|
|
62111
|
+
const custom = normalizeUpdatePackageName(env3[UPDATE_PACKAGE_NAME_ENV]);
|
|
62112
|
+
if (custom) {
|
|
62113
|
+
return custom;
|
|
62114
|
+
}
|
|
62115
|
+
return DEFAULT_UPDATE_PACKAGE_NAME;
|
|
62116
|
+
}
|
|
62117
|
+
function resolveUpdateRegistryBaseUrl(env3 = process.env) {
|
|
62118
|
+
const custom = normalizeRegistryUrl(env3[UPDATE_REGISTRY_BASE_URL_ENV]);
|
|
62119
|
+
if (custom) {
|
|
62120
|
+
return custom;
|
|
62121
|
+
}
|
|
62122
|
+
return DEFAULT_UPDATE_REGISTRY_BASE_URL;
|
|
62123
|
+
}
|
|
62124
|
+
function resolveUpdateInstallRegistryUrl(env3 = process.env) {
|
|
62125
|
+
return normalizeRegistryUrl(env3[UPDATE_INSTALL_REGISTRY_URL_ENV]);
|
|
62126
|
+
}
|
|
62127
|
+
function buildLatestVersionUrl(packageName, registryBaseUrl) {
|
|
62128
|
+
return `${registryBaseUrl.replace(/\/+$/, "")}/${packageName}/latest`;
|
|
62129
|
+
}
|
|
62130
|
+
function buildInstallCommand(pm, env3 = process.env) {
|
|
62131
|
+
return `${pm} ${buildInstallArgs(pm, env3).join(" ")}`;
|
|
62132
|
+
}
|
|
62133
|
+
function buildInstallArgs(pm, env3 = process.env) {
|
|
62134
|
+
const packageName = resolveUpdatePackageName(env3);
|
|
62135
|
+
const installRegistry = resolveUpdateInstallRegistryUrl(env3);
|
|
62136
|
+
const args = [...INSTALL_ARG_PREFIX[pm], `${packageName}@latest`];
|
|
62137
|
+
if (installRegistry) {
|
|
62138
|
+
args.push("--registry", installRegistry);
|
|
62139
|
+
}
|
|
62140
|
+
return args;
|
|
62141
|
+
}
|
|
61281
62142
|
function detectPackageManager() {
|
|
61282
62143
|
const envOverride = process.env.LETTA_PACKAGE_MANAGER;
|
|
61283
62144
|
if (envOverride) {
|
|
@@ -61323,9 +62184,14 @@ async function checkForUpdate() {
|
|
|
61323
62184
|
debugLog2("Prerelease version detected, skipping auto-update check");
|
|
61324
62185
|
return { updateAvailable: false, currentVersion };
|
|
61325
62186
|
}
|
|
62187
|
+
const packageName = resolveUpdatePackageName();
|
|
62188
|
+
const registryBaseUrl = resolveUpdateRegistryBaseUrl();
|
|
62189
|
+
const latestUrl = buildLatestVersionUrl(packageName, registryBaseUrl);
|
|
61326
62190
|
try {
|
|
61327
|
-
debugLog2("Checking registry for latest version
|
|
61328
|
-
const res = await fetch(
|
|
62191
|
+
debugLog2("Checking registry for latest version:", latestUrl);
|
|
62192
|
+
const res = await fetch(latestUrl, {
|
|
62193
|
+
signal: AbortSignal.timeout(5000)
|
|
62194
|
+
});
|
|
61329
62195
|
if (!res.ok) {
|
|
61330
62196
|
throw new Error(`Registry returned ${res.status}`);
|
|
61331
62197
|
}
|
|
@@ -61359,19 +62225,21 @@ async function checkForUpdate() {
|
|
|
61359
62225
|
}
|
|
61360
62226
|
async function getNpmGlobalPath() {
|
|
61361
62227
|
try {
|
|
61362
|
-
const { stdout } = await
|
|
62228
|
+
const { stdout } = await execFileAsync3("npm", ["prefix", "-g"], {
|
|
62229
|
+
timeout: 5000
|
|
62230
|
+
});
|
|
61363
62231
|
return stdout.trim();
|
|
61364
62232
|
} catch {
|
|
61365
62233
|
return null;
|
|
61366
62234
|
}
|
|
61367
62235
|
}
|
|
61368
62236
|
async function cleanupOrphanedDirs(globalPath) {
|
|
61369
|
-
const lettaAiDir =
|
|
62237
|
+
const lettaAiDir = join19(globalPath, "lib/node_modules/@letta-ai");
|
|
61370
62238
|
try {
|
|
61371
62239
|
const entries = await readdir7(lettaAiDir);
|
|
61372
62240
|
for (const entry of entries) {
|
|
61373
62241
|
if (entry.startsWith(".letta-code-")) {
|
|
61374
|
-
const orphanPath =
|
|
62242
|
+
const orphanPath = join19(lettaAiDir, entry);
|
|
61375
62243
|
debugLog2("Cleaning orphaned temp directory:", orphanPath);
|
|
61376
62244
|
await rm(orphanPath, { recursive: true, force: true });
|
|
61377
62245
|
}
|
|
@@ -61380,7 +62248,8 @@ async function cleanupOrphanedDirs(globalPath) {
|
|
|
61380
62248
|
}
|
|
61381
62249
|
async function performUpdate() {
|
|
61382
62250
|
const pm = detectPackageManager();
|
|
61383
|
-
const installCmd =
|
|
62251
|
+
const installCmd = buildInstallCommand(pm);
|
|
62252
|
+
const installArgs = buildInstallArgs(pm);
|
|
61384
62253
|
debugLog2("Detected package manager:", pm);
|
|
61385
62254
|
debugLog2("Install command:", installCmd);
|
|
61386
62255
|
let globalPath = null;
|
|
@@ -61393,7 +62262,7 @@ async function performUpdate() {
|
|
|
61393
62262
|
}
|
|
61394
62263
|
try {
|
|
61395
62264
|
debugLog2(`Running ${installCmd}...`);
|
|
61396
|
-
await
|
|
62265
|
+
await execFileAsync3(pm, installArgs, { timeout: 60000 });
|
|
61397
62266
|
debugLog2("Update completed successfully");
|
|
61398
62267
|
return { success: true };
|
|
61399
62268
|
} catch (error) {
|
|
@@ -61402,7 +62271,7 @@ async function performUpdate() {
|
|
|
61402
62271
|
debugLog2("ENOTEMPTY detected, attempting cleanup and retry...");
|
|
61403
62272
|
await cleanupOrphanedDirs(globalPath);
|
|
61404
62273
|
try {
|
|
61405
|
-
await
|
|
62274
|
+
await execFileAsync3(pm, installArgs, { timeout: 60000 });
|
|
61406
62275
|
debugLog2("Update succeeded after cleanup retry");
|
|
61407
62276
|
return { success: true };
|
|
61408
62277
|
} catch (retryError) {
|
|
@@ -61476,17 +62345,17 @@ async function manualUpdate() {
|
|
|
61476
62345
|
message: `Update failed: ${updateResult.error}`
|
|
61477
62346
|
};
|
|
61478
62347
|
}
|
|
61479
|
-
var
|
|
62348
|
+
var execFileAsync3, DEBUG, DEFAULT_UPDATE_PACKAGE_NAME = "@letta-ai/letta-code", DEFAULT_UPDATE_REGISTRY_BASE_URL = "https://registry.npmjs.org", UPDATE_PACKAGE_NAME_ENV = "LETTA_UPDATE_PACKAGE_NAME", UPDATE_REGISTRY_BASE_URL_ENV = "LETTA_UPDATE_REGISTRY_BASE_URL", UPDATE_INSTALL_REGISTRY_URL_ENV = "LETTA_UPDATE_INSTALL_REGISTRY_URL", INSTALL_ARG_PREFIX, VALID_PACKAGE_MANAGERS;
|
|
61480
62349
|
var init_auto_update = __esm(() => {
|
|
61481
62350
|
init_version();
|
|
61482
|
-
|
|
62351
|
+
execFileAsync3 = promisify4(execFile4);
|
|
61483
62352
|
DEBUG = process.env.LETTA_DEBUG_AUTOUPDATE === "1";
|
|
61484
|
-
|
|
61485
|
-
npm: "
|
|
61486
|
-
bun: "
|
|
61487
|
-
pnpm: "
|
|
62353
|
+
INSTALL_ARG_PREFIX = {
|
|
62354
|
+
npm: ["install", "-g"],
|
|
62355
|
+
bun: ["add", "-g"],
|
|
62356
|
+
pnpm: ["add", "-g"]
|
|
61488
62357
|
};
|
|
61489
|
-
VALID_PACKAGE_MANAGERS = new Set(Object.keys(
|
|
62358
|
+
VALID_PACKAGE_MANAGERS = new Set(Object.keys(INSTALL_ARG_PREFIX));
|
|
61490
62359
|
});
|
|
61491
62360
|
|
|
61492
62361
|
// src/tools/impl/overflow.ts
|
|
@@ -61726,9 +62595,9 @@ __export(exports_subagents2, {
|
|
|
61726
62595
|
GLOBAL_AGENTS_DIR: () => GLOBAL_AGENTS_DIR2,
|
|
61727
62596
|
AGENTS_DIR: () => AGENTS_DIR2
|
|
61728
62597
|
});
|
|
61729
|
-
import { existsSync as
|
|
62598
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
61730
62599
|
import { readdir as readdir8, readFile as readFile7 } from "node:fs/promises";
|
|
61731
|
-
import { join as
|
|
62600
|
+
import { join as join21 } from "node:path";
|
|
61732
62601
|
function isValidName2(name) {
|
|
61733
62602
|
return /^[a-z][a-z0-9-]*$/.test(name);
|
|
61734
62603
|
}
|
|
@@ -61810,7 +62679,7 @@ function getBuiltinSubagentNames2() {
|
|
|
61810
62679
|
return new Set(Object.keys(getBuiltinSubagents2()));
|
|
61811
62680
|
}
|
|
61812
62681
|
async function discoverSubagentsFromDir2(agentsDir, seenNames, subagents, errors) {
|
|
61813
|
-
if (!
|
|
62682
|
+
if (!existsSync12(agentsDir)) {
|
|
61814
62683
|
return;
|
|
61815
62684
|
}
|
|
61816
62685
|
try {
|
|
@@ -61819,7 +62688,7 @@ async function discoverSubagentsFromDir2(agentsDir, seenNames, subagents, errors
|
|
|
61819
62688
|
if (!entry.isFile() || !entry.name.endsWith(".md")) {
|
|
61820
62689
|
continue;
|
|
61821
62690
|
}
|
|
61822
|
-
const filePath =
|
|
62691
|
+
const filePath = join21(agentsDir, entry.name);
|
|
61823
62692
|
try {
|
|
61824
62693
|
const config = await parseSubagentFile2(filePath);
|
|
61825
62694
|
if (config) {
|
|
@@ -61851,7 +62720,7 @@ async function discoverSubagents2(workingDirectory = process.cwd()) {
|
|
|
61851
62720
|
const subagents = [];
|
|
61852
62721
|
const seenNames = new Set;
|
|
61853
62722
|
await discoverSubagentsFromDir2(GLOBAL_AGENTS_DIR2, seenNames, subagents, errors);
|
|
61854
|
-
const projectAgentsDir =
|
|
62723
|
+
const projectAgentsDir = join21(workingDirectory, AGENTS_DIR2);
|
|
61855
62724
|
await discoverSubagentsFromDir2(projectAgentsDir, seenNames, subagents, errors);
|
|
61856
62725
|
return { subagents, errors };
|
|
61857
62726
|
}
|
|
@@ -61894,7 +62763,7 @@ var init_subagents2 = __esm(() => {
|
|
|
61894
62763
|
recall_default,
|
|
61895
62764
|
reflection_default
|
|
61896
62765
|
];
|
|
61897
|
-
GLOBAL_AGENTS_DIR2 =
|
|
62766
|
+
GLOBAL_AGENTS_DIR2 = join21(process.env.HOME || process.env.USERPROFILE || "~", ".letta/agents");
|
|
61898
62767
|
VALID_MEMORY_BLOCKS2 = new Set(MEMORY_BLOCK_LABELS);
|
|
61899
62768
|
cache5 = {
|
|
61900
62769
|
builtins: null,
|
|
@@ -62038,24 +62907,24 @@ function defineLazyProperty(object, propertyName, valueGetter) {
|
|
|
62038
62907
|
// node_modules/default-browser-id/index.js
|
|
62039
62908
|
import { promisify as promisify5 } from "node:util";
|
|
62040
62909
|
import process15 from "node:process";
|
|
62041
|
-
import { execFile as
|
|
62910
|
+
import { execFile as execFile5 } from "node:child_process";
|
|
62042
62911
|
async function defaultBrowserId() {
|
|
62043
62912
|
if (process15.platform !== "darwin") {
|
|
62044
62913
|
throw new Error("macOS only");
|
|
62045
62914
|
}
|
|
62046
|
-
const { stdout } = await
|
|
62915
|
+
const { stdout } = await execFileAsync4("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
|
|
62047
62916
|
const match3 = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
|
|
62048
62917
|
return match3?.groups.id ?? "com.apple.Safari";
|
|
62049
62918
|
}
|
|
62050
|
-
var
|
|
62919
|
+
var execFileAsync4;
|
|
62051
62920
|
var init_default_browser_id = __esm(() => {
|
|
62052
|
-
|
|
62921
|
+
execFileAsync4 = promisify5(execFile5);
|
|
62053
62922
|
});
|
|
62054
62923
|
|
|
62055
62924
|
// node_modules/run-applescript/index.js
|
|
62056
62925
|
import process16 from "node:process";
|
|
62057
62926
|
import { promisify as promisify6 } from "node:util";
|
|
62058
|
-
import { execFile as
|
|
62927
|
+
import { execFile as execFile6, execFileSync } from "node:child_process";
|
|
62059
62928
|
async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
|
|
62060
62929
|
if (process16.platform !== "darwin") {
|
|
62061
62930
|
throw new Error("macOS only");
|
|
@@ -62065,12 +62934,12 @@ async function runAppleScript(script, { humanReadableOutput = true, signal } = {
|
|
|
62065
62934
|
if (signal) {
|
|
62066
62935
|
execOptions.signal = signal;
|
|
62067
62936
|
}
|
|
62068
|
-
const { stdout } = await
|
|
62937
|
+
const { stdout } = await execFileAsync5("osascript", ["-e", script, outputArguments], execOptions);
|
|
62069
62938
|
return stdout.trim();
|
|
62070
62939
|
}
|
|
62071
|
-
var
|
|
62940
|
+
var execFileAsync5;
|
|
62072
62941
|
var init_run_applescript = __esm(() => {
|
|
62073
|
-
|
|
62942
|
+
execFileAsync5 = promisify6(execFile6);
|
|
62074
62943
|
});
|
|
62075
62944
|
|
|
62076
62945
|
// node_modules/bundle-name/index.js
|
|
@@ -62084,8 +62953,8 @@ var init_bundle_name = __esm(() => {
|
|
|
62084
62953
|
|
|
62085
62954
|
// node_modules/default-browser/windows.js
|
|
62086
62955
|
import { promisify as promisify7 } from "node:util";
|
|
62087
|
-
import { execFile as
|
|
62088
|
-
async function defaultBrowser(_execFileAsync =
|
|
62956
|
+
import { execFile as execFile7 } from "node:child_process";
|
|
62957
|
+
async function defaultBrowser(_execFileAsync = execFileAsync6) {
|
|
62089
62958
|
const { stdout } = await _execFileAsync("reg", [
|
|
62090
62959
|
"QUERY",
|
|
62091
62960
|
" HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
|
|
@@ -62103,9 +62972,9 @@ async function defaultBrowser(_execFileAsync = execFileAsync5) {
|
|
|
62103
62972
|
}
|
|
62104
62973
|
return browser;
|
|
62105
62974
|
}
|
|
62106
|
-
var
|
|
62975
|
+
var execFileAsync6, windowsBrowserProgIds, UnknownBrowserError;
|
|
62107
62976
|
var init_windows = __esm(() => {
|
|
62108
|
-
|
|
62977
|
+
execFileAsync6 = promisify7(execFile7);
|
|
62109
62978
|
windowsBrowserProgIds = {
|
|
62110
62979
|
AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
|
|
62111
62980
|
MSEdgeDHTML: { name: "Edge", id: "com.microsoft.edge" },
|
|
@@ -62124,7 +62993,7 @@ var init_windows = __esm(() => {
|
|
|
62124
62993
|
// node_modules/default-browser/index.js
|
|
62125
62994
|
import { promisify as promisify8 } from "node:util";
|
|
62126
62995
|
import process17 from "node:process";
|
|
62127
|
-
import { execFile as
|
|
62996
|
+
import { execFile as execFile8 } from "node:child_process";
|
|
62128
62997
|
async function defaultBrowser2() {
|
|
62129
62998
|
if (process17.platform === "darwin") {
|
|
62130
62999
|
const id = await defaultBrowserId();
|
|
@@ -62132,7 +63001,7 @@ async function defaultBrowser2() {
|
|
|
62132
63001
|
return { name, id };
|
|
62133
63002
|
}
|
|
62134
63003
|
if (process17.platform === "linux") {
|
|
62135
|
-
const { stdout } = await
|
|
63004
|
+
const { stdout } = await execFileAsync7("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
|
|
62136
63005
|
const id = stdout.trim();
|
|
62137
63006
|
const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
|
|
62138
63007
|
return { name, id };
|
|
@@ -62142,12 +63011,12 @@ async function defaultBrowser2() {
|
|
|
62142
63011
|
}
|
|
62143
63012
|
throw new Error("Only macOS, Linux, and Windows are supported");
|
|
62144
63013
|
}
|
|
62145
|
-
var
|
|
63014
|
+
var execFileAsync7, titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
|
|
62146
63015
|
var init_default_browser = __esm(() => {
|
|
62147
63016
|
init_default_browser_id();
|
|
62148
63017
|
init_bundle_name();
|
|
62149
63018
|
init_windows();
|
|
62150
|
-
|
|
63019
|
+
execFileAsync7 = promisify8(execFile8);
|
|
62151
63020
|
});
|
|
62152
63021
|
|
|
62153
63022
|
// node_modules/open/index.js
|
|
@@ -62168,7 +63037,7 @@ async function getWindowsDefaultBrowserFromWsl() {
|
|
|
62168
63037
|
const powershellPath = await powerShellPath();
|
|
62169
63038
|
const rawCommand = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
|
|
62170
63039
|
const encodedCommand = Buffer3.from(rawCommand, "utf16le").toString("base64");
|
|
62171
|
-
const { stdout } = await
|
|
63040
|
+
const { stdout } = await execFile9(powershellPath, [
|
|
62172
63041
|
"-NoProfile",
|
|
62173
63042
|
"-NonInteractive",
|
|
62174
63043
|
"-ExecutionPolicy",
|
|
@@ -62204,7 +63073,7 @@ function detectPlatformBinary({ [platform2]: platformBinary }, { wsl }) {
|
|
|
62204
63073
|
}
|
|
62205
63074
|
return detectArchBinary(platformBinary);
|
|
62206
63075
|
}
|
|
62207
|
-
var
|
|
63076
|
+
var execFile9, __dirname2, localXdgOpenPath, platform2, arch, pTryEach = async (array, mapper) => {
|
|
62208
63077
|
let latestError;
|
|
62209
63078
|
for (const item of array) {
|
|
62210
63079
|
try {
|
|
@@ -62383,7 +63252,7 @@ var init_open = __esm(() => {
|
|
|
62383
63252
|
init_wsl_utils();
|
|
62384
63253
|
init_default_browser();
|
|
62385
63254
|
init_is_inside_container();
|
|
62386
|
-
|
|
63255
|
+
execFile9 = promisify9(childProcess.execFile);
|
|
62387
63256
|
__dirname2 = path21.dirname(fileURLToPath8(import.meta.url));
|
|
62388
63257
|
localXdgOpenPath = path21.join(__dirname2, "xdg-open");
|
|
62389
63258
|
({ platform: platform2, arch } = process18);
|
|
@@ -62803,6 +63672,58 @@ function isConversationBusyError(detail) {
|
|
|
62803
63672
|
return false;
|
|
62804
63673
|
return detail.toLowerCase().includes(CONVERSATION_BUSY_DETAIL_FRAGMENT);
|
|
62805
63674
|
}
|
|
63675
|
+
function isRetryableProviderErrorDetail(detail) {
|
|
63676
|
+
if (typeof detail !== "string")
|
|
63677
|
+
return false;
|
|
63678
|
+
return RETRYABLE_PROVIDER_DETAIL_PATTERNS.some((pattern) => detail.includes(pattern));
|
|
63679
|
+
}
|
|
63680
|
+
function isNonRetryableProviderErrorDetail(detail) {
|
|
63681
|
+
if (typeof detail !== "string")
|
|
63682
|
+
return false;
|
|
63683
|
+
const normalized = detail.toLowerCase();
|
|
63684
|
+
if (NON_RETRYABLE_4XX_PATTERN.test(detail))
|
|
63685
|
+
return true;
|
|
63686
|
+
return NON_RETRYABLE_PROVIDER_DETAIL_PATTERNS.some((pattern) => normalized.includes(pattern));
|
|
63687
|
+
}
|
|
63688
|
+
function shouldRetryRunMetadataError(errorType, detail) {
|
|
63689
|
+
const explicitLlmError = errorType === "llm_error";
|
|
63690
|
+
const retryable429Detail = typeof detail === "string" && RETRYABLE_429_PATTERN.test(detail);
|
|
63691
|
+
const retryableDetail = isRetryableProviderErrorDetail(detail);
|
|
63692
|
+
const nonRetryableDetail = isNonRetryableProviderErrorDetail(detail);
|
|
63693
|
+
if (nonRetryableDetail && !retryable429Detail)
|
|
63694
|
+
return false;
|
|
63695
|
+
if (explicitLlmError)
|
|
63696
|
+
return true;
|
|
63697
|
+
return retryable429Detail || retryableDetail;
|
|
63698
|
+
}
|
|
63699
|
+
function shouldRetryPreStreamTransientError(opts) {
|
|
63700
|
+
const { status, detail } = opts;
|
|
63701
|
+
if (status === 429)
|
|
63702
|
+
return true;
|
|
63703
|
+
if (status !== undefined && status >= 500)
|
|
63704
|
+
return true;
|
|
63705
|
+
if (status !== undefined && status >= 400)
|
|
63706
|
+
return false;
|
|
63707
|
+
const retryable429Detail = typeof detail === "string" && RETRYABLE_429_PATTERN.test(detail);
|
|
63708
|
+
if (retryable429Detail)
|
|
63709
|
+
return true;
|
|
63710
|
+
if (isNonRetryableProviderErrorDetail(detail))
|
|
63711
|
+
return false;
|
|
63712
|
+
return isRetryableProviderErrorDetail(detail);
|
|
63713
|
+
}
|
|
63714
|
+
function parseRetryAfterHeaderMs(retryAfterValue) {
|
|
63715
|
+
if (!retryAfterValue)
|
|
63716
|
+
return null;
|
|
63717
|
+
const seconds = Number(retryAfterValue);
|
|
63718
|
+
if (Number.isFinite(seconds) && seconds >= 0) {
|
|
63719
|
+
return Math.round(seconds * 1000);
|
|
63720
|
+
}
|
|
63721
|
+
const retryAtMs = Date.parse(retryAfterValue);
|
|
63722
|
+
if (Number.isNaN(retryAtMs))
|
|
63723
|
+
return null;
|
|
63724
|
+
const delayMs = retryAtMs - Date.now();
|
|
63725
|
+
return delayMs > 0 ? delayMs : 0;
|
|
63726
|
+
}
|
|
62806
63727
|
function classifyPreStreamConflict(detail) {
|
|
62807
63728
|
if (isApprovalPendingError(detail))
|
|
62808
63729
|
return "approval_pending";
|
|
@@ -62810,7 +63731,7 @@ function classifyPreStreamConflict(detail) {
|
|
|
62810
63731
|
return "conversation_busy";
|
|
62811
63732
|
return null;
|
|
62812
63733
|
}
|
|
62813
|
-
function getPreStreamErrorAction(detail, conversationBusyRetries, maxConversationBusyRetries) {
|
|
63734
|
+
function getPreStreamErrorAction(detail, conversationBusyRetries, maxConversationBusyRetries, opts) {
|
|
62814
63735
|
const kind = classifyPreStreamConflict(detail);
|
|
62815
63736
|
if (kind === "approval_pending") {
|
|
62816
63737
|
return "resolve_approval_pending";
|
|
@@ -62818,6 +63739,9 @@ function getPreStreamErrorAction(detail, conversationBusyRetries, maxConversatio
|
|
|
62818
63739
|
if (kind === "conversation_busy" && conversationBusyRetries < maxConversationBusyRetries) {
|
|
62819
63740
|
return "retry_conversation_busy";
|
|
62820
63741
|
}
|
|
63742
|
+
if (opts && shouldRetryPreStreamTransientError({ status: opts.status, detail }) && (opts.transientRetries ?? 0) < (opts.maxTransientRetries ?? 0)) {
|
|
63743
|
+
return "retry_transient";
|
|
63744
|
+
}
|
|
62821
63745
|
return "rethrow";
|
|
62822
63746
|
}
|
|
62823
63747
|
function extractConflictDetail(error) {
|
|
@@ -62861,7 +63785,42 @@ function rebuildInputWithFreshDenials(currentInput, serverApprovals, denialReaso
|
|
|
62861
63785
|
function shouldAttemptApprovalRecovery(opts) {
|
|
62862
63786
|
return opts.approvalPendingDetected && opts.retries < opts.maxRetries;
|
|
62863
63787
|
}
|
|
62864
|
-
var INVALID_TOOL_CALL_IDS_FRAGMENT = "invalid tool call ids", APPROVAL_PENDING_DETAIL_FRAGMENT = "waiting for approval", CONVERSATION_BUSY_DETAIL_FRAGMENT = "another request is currently being processed";
|
|
63788
|
+
var INVALID_TOOL_CALL_IDS_FRAGMENT = "invalid tool call ids", APPROVAL_PENDING_DETAIL_FRAGMENT = "waiting for approval", CONVERSATION_BUSY_DETAIL_FRAGMENT = "another request is currently being processed", RETRYABLE_PROVIDER_DETAIL_PATTERNS, NON_RETRYABLE_PROVIDER_DETAIL_PATTERNS, NON_RETRYABLE_4XX_PATTERN, RETRYABLE_429_PATTERN;
|
|
63789
|
+
var init_turn_recovery_policy = __esm(() => {
|
|
63790
|
+
RETRYABLE_PROVIDER_DETAIL_PATTERNS = [
|
|
63791
|
+
"Anthropic API error",
|
|
63792
|
+
"OpenAI API error",
|
|
63793
|
+
"Google Vertex API error",
|
|
63794
|
+
"ChatGPT API error",
|
|
63795
|
+
"ChatGPT server error",
|
|
63796
|
+
"Connection error during Anthropic streaming",
|
|
63797
|
+
"Connection error during streaming",
|
|
63798
|
+
"upstream connect error",
|
|
63799
|
+
"connection termination",
|
|
63800
|
+
"peer closed connection",
|
|
63801
|
+
"incomplete chunked read",
|
|
63802
|
+
"Network error",
|
|
63803
|
+
"Connection error",
|
|
63804
|
+
"Request timed out",
|
|
63805
|
+
"overloaded",
|
|
63806
|
+
"api_error"
|
|
63807
|
+
];
|
|
63808
|
+
NON_RETRYABLE_PROVIDER_DETAIL_PATTERNS = [
|
|
63809
|
+
"invalid api key",
|
|
63810
|
+
"incorrect api key",
|
|
63811
|
+
"authentication error",
|
|
63812
|
+
"unauthorized",
|
|
63813
|
+
"permission denied",
|
|
63814
|
+
"forbidden",
|
|
63815
|
+
"invalid_request_error",
|
|
63816
|
+
"invalid model",
|
|
63817
|
+
"model_not_found",
|
|
63818
|
+
"context_length_exceeded",
|
|
63819
|
+
"invalid_encrypted_content"
|
|
63820
|
+
];
|
|
63821
|
+
NON_RETRYABLE_4XX_PATTERN = /Error code:\s*4(0[0-8]|1\d|2\d|3\d|4\d|51)/i;
|
|
63822
|
+
RETRYABLE_429_PATTERN = /Error code:\s*429|rate limit|too many requests/i;
|
|
63823
|
+
});
|
|
62865
63824
|
|
|
62866
63825
|
// src/agent/approval-recovery.ts
|
|
62867
63826
|
async function fetchRunErrorDetail(runId) {
|
|
@@ -62877,336 +63836,10 @@ async function fetchRunErrorDetail(runId) {
|
|
|
62877
63836
|
}
|
|
62878
63837
|
}
|
|
62879
63838
|
var init_approval_recovery = __esm(async () => {
|
|
63839
|
+
init_turn_recovery_policy();
|
|
62880
63840
|
await init_client2();
|
|
62881
63841
|
});
|
|
62882
63842
|
|
|
62883
|
-
// src/providers/openai-codex-provider.ts
|
|
62884
|
-
var exports_openai_codex_provider = {};
|
|
62885
|
-
__export(exports_openai_codex_provider, {
|
|
62886
|
-
updateOpenAICodexProvider: () => updateOpenAICodexProvider,
|
|
62887
|
-
removeOpenAICodexProvider: () => removeOpenAICodexProvider,
|
|
62888
|
-
listProviders: () => listProviders,
|
|
62889
|
-
getOpenAICodexProvider: () => getOpenAICodexProvider,
|
|
62890
|
-
deleteOpenAICodexProvider: () => deleteOpenAICodexProvider,
|
|
62891
|
-
createOrUpdateOpenAICodexProvider: () => createOrUpdateOpenAICodexProvider,
|
|
62892
|
-
createOpenAICodexProvider: () => createOpenAICodexProvider,
|
|
62893
|
-
checkOpenAICodexEligibility: () => checkOpenAICodexEligibility,
|
|
62894
|
-
OPENAI_CODEX_PROVIDER_NAME: () => OPENAI_CODEX_PROVIDER_NAME,
|
|
62895
|
-
CHATGPT_OAUTH_PROVIDER_TYPE: () => CHATGPT_OAUTH_PROVIDER_TYPE
|
|
62896
|
-
});
|
|
62897
|
-
async function getLettaConfig() {
|
|
62898
|
-
const settings = await settingsManager.getSettingsWithSecureTokens();
|
|
62899
|
-
const baseUrl = process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
|
|
62900
|
-
const apiKey = process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY || "";
|
|
62901
|
-
return { baseUrl, apiKey };
|
|
62902
|
-
}
|
|
62903
|
-
async function providersRequest(method, path22, body) {
|
|
62904
|
-
const { baseUrl, apiKey } = await getLettaConfig();
|
|
62905
|
-
const url = `${baseUrl}${path22}`;
|
|
62906
|
-
const response = await fetch(url, {
|
|
62907
|
-
method,
|
|
62908
|
-
headers: getLettaCodeHeaders2(apiKey),
|
|
62909
|
-
...body && { body: JSON.stringify(body) }
|
|
62910
|
-
});
|
|
62911
|
-
if (!response.ok) {
|
|
62912
|
-
const errorText = await response.text();
|
|
62913
|
-
if (response.status === 403) {
|
|
62914
|
-
try {
|
|
62915
|
-
const errorData = JSON.parse(errorText);
|
|
62916
|
-
if (errorData.error && typeof errorData.error === "string" && errorData.error.includes("only available for pro or enterprise")) {
|
|
62917
|
-
throw new Error("PLAN_UPGRADE_REQUIRED");
|
|
62918
|
-
}
|
|
62919
|
-
} catch (parseError) {
|
|
62920
|
-
if (parseError instanceof Error && parseError.message === "PLAN_UPGRADE_REQUIRED") {
|
|
62921
|
-
throw parseError;
|
|
62922
|
-
}
|
|
62923
|
-
}
|
|
62924
|
-
}
|
|
62925
|
-
throw new Error(`Provider API error (${response.status}): ${errorText}`);
|
|
62926
|
-
}
|
|
62927
|
-
const text = await response.text();
|
|
62928
|
-
if (!text) {
|
|
62929
|
-
return {};
|
|
62930
|
-
}
|
|
62931
|
-
return JSON.parse(text);
|
|
62932
|
-
}
|
|
62933
|
-
async function listProviders() {
|
|
62934
|
-
try {
|
|
62935
|
-
const response = await providersRequest("GET", "/v1/providers");
|
|
62936
|
-
return response;
|
|
62937
|
-
} catch {
|
|
62938
|
-
return [];
|
|
62939
|
-
}
|
|
62940
|
-
}
|
|
62941
|
-
async function getOpenAICodexProvider() {
|
|
62942
|
-
const providers = await listProviders();
|
|
62943
|
-
return providers.find((p) => p.name === OPENAI_CODEX_PROVIDER_NAME) || null;
|
|
62944
|
-
}
|
|
62945
|
-
async function createOpenAICodexProvider(config) {
|
|
62946
|
-
const apiKeyJson = JSON.stringify({
|
|
62947
|
-
access_token: config.access_token,
|
|
62948
|
-
id_token: config.id_token,
|
|
62949
|
-
refresh_token: config.refresh_token,
|
|
62950
|
-
account_id: config.account_id,
|
|
62951
|
-
expires_at: config.expires_at
|
|
62952
|
-
});
|
|
62953
|
-
return providersRequest("POST", "/v1/providers", {
|
|
62954
|
-
name: OPENAI_CODEX_PROVIDER_NAME,
|
|
62955
|
-
provider_type: CHATGPT_OAUTH_PROVIDER_TYPE,
|
|
62956
|
-
api_key: apiKeyJson
|
|
62957
|
-
});
|
|
62958
|
-
}
|
|
62959
|
-
async function updateOpenAICodexProvider(providerId, config) {
|
|
62960
|
-
const apiKeyJson = JSON.stringify({
|
|
62961
|
-
access_token: config.access_token,
|
|
62962
|
-
id_token: config.id_token,
|
|
62963
|
-
refresh_token: config.refresh_token,
|
|
62964
|
-
account_id: config.account_id,
|
|
62965
|
-
expires_at: config.expires_at
|
|
62966
|
-
});
|
|
62967
|
-
return providersRequest("PATCH", `/v1/providers/${providerId}`, {
|
|
62968
|
-
api_key: apiKeyJson
|
|
62969
|
-
});
|
|
62970
|
-
}
|
|
62971
|
-
async function deleteOpenAICodexProvider(providerId) {
|
|
62972
|
-
await providersRequest("DELETE", `/v1/providers/${providerId}`);
|
|
62973
|
-
}
|
|
62974
|
-
async function createOrUpdateOpenAICodexProvider(config) {
|
|
62975
|
-
const existing = await getOpenAICodexProvider();
|
|
62976
|
-
if (existing) {
|
|
62977
|
-
return updateOpenAICodexProvider(existing.id, config);
|
|
62978
|
-
} else {
|
|
62979
|
-
return createOpenAICodexProvider(config);
|
|
62980
|
-
}
|
|
62981
|
-
}
|
|
62982
|
-
async function removeOpenAICodexProvider() {
|
|
62983
|
-
const existing = await getOpenAICodexProvider();
|
|
62984
|
-
if (existing) {
|
|
62985
|
-
await deleteOpenAICodexProvider(existing.id);
|
|
62986
|
-
}
|
|
62987
|
-
}
|
|
62988
|
-
async function checkOpenAICodexEligibility() {
|
|
62989
|
-
try {
|
|
62990
|
-
const balance = await providersRequest("GET", "/v1/metadata/balance");
|
|
62991
|
-
const billingTier = balance.billing_tier.toLowerCase();
|
|
62992
|
-
if (billingTier === "pro" || billingTier === "enterprise") {
|
|
62993
|
-
return {
|
|
62994
|
-
eligible: true,
|
|
62995
|
-
billing_tier: balance.billing_tier
|
|
62996
|
-
};
|
|
62997
|
-
}
|
|
62998
|
-
return {
|
|
62999
|
-
eligible: false,
|
|
63000
|
-
billing_tier: balance.billing_tier,
|
|
63001
|
-
reason: `ChatGPT OAuth requires a Pro or Enterprise plan. Current plan: ${balance.billing_tier}`
|
|
63002
|
-
};
|
|
63003
|
-
} catch (error) {
|
|
63004
|
-
console.warn("Failed to check ChatGPT OAuth eligibility:", error);
|
|
63005
|
-
return {
|
|
63006
|
-
eligible: true,
|
|
63007
|
-
billing_tier: "unknown"
|
|
63008
|
-
};
|
|
63009
|
-
}
|
|
63010
|
-
}
|
|
63011
|
-
var OPENAI_CODEX_PROVIDER_NAME = "chatgpt-plus-pro", CHATGPT_OAUTH_PROVIDER_TYPE = "chatgpt_oauth";
|
|
63012
|
-
var init_openai_codex_provider = __esm(async () => {
|
|
63013
|
-
init_http_headers();
|
|
63014
|
-
init_oauth();
|
|
63015
|
-
await init_settings_manager();
|
|
63016
|
-
});
|
|
63017
|
-
|
|
63018
|
-
// src/agent/modify.ts
|
|
63019
|
-
var exports_modify = {};
|
|
63020
|
-
__export(exports_modify, {
|
|
63021
|
-
updateAgentSystemPromptRaw: () => updateAgentSystemPromptRaw,
|
|
63022
|
-
updateAgentSystemPromptMemfs: () => updateAgentSystemPromptMemfs,
|
|
63023
|
-
updateAgentSystemPrompt: () => updateAgentSystemPrompt,
|
|
63024
|
-
updateAgentLLMConfig: () => updateAgentLLMConfig
|
|
63025
|
-
});
|
|
63026
|
-
function buildModelSettings(modelHandle, updateArgs) {
|
|
63027
|
-
const isOpenAI = modelHandle.startsWith("openai/") || modelHandle.startsWith(`${OPENAI_CODEX_PROVIDER_NAME}/`);
|
|
63028
|
-
const isAnthropic = modelHandle.startsWith("anthropic/") || modelHandle.startsWith("claude-pro-max/");
|
|
63029
|
-
const isZai = modelHandle.startsWith("zai/");
|
|
63030
|
-
const isGoogleAI = modelHandle.startsWith("google_ai/");
|
|
63031
|
-
const isGoogleVertex = modelHandle.startsWith("google_vertex/");
|
|
63032
|
-
const isOpenRouter = modelHandle.startsWith("openrouter/");
|
|
63033
|
-
const isBedrock = modelHandle.startsWith("bedrock/");
|
|
63034
|
-
let settings;
|
|
63035
|
-
if (isOpenAI || isOpenRouter) {
|
|
63036
|
-
const openaiSettings = {
|
|
63037
|
-
provider_type: "openai",
|
|
63038
|
-
parallel_tool_calls: true
|
|
63039
|
-
};
|
|
63040
|
-
if (updateArgs?.reasoning_effort) {
|
|
63041
|
-
openaiSettings.reasoning = {
|
|
63042
|
-
reasoning_effort: updateArgs.reasoning_effort
|
|
63043
|
-
};
|
|
63044
|
-
}
|
|
63045
|
-
settings = openaiSettings;
|
|
63046
|
-
} else if (isAnthropic) {
|
|
63047
|
-
const anthropicSettings = {
|
|
63048
|
-
provider_type: "anthropic",
|
|
63049
|
-
parallel_tool_calls: true
|
|
63050
|
-
};
|
|
63051
|
-
if (updateArgs?.enable_reasoner !== undefined || typeof updateArgs?.max_reasoning_tokens === "number") {
|
|
63052
|
-
anthropicSettings.thinking = {
|
|
63053
|
-
type: updateArgs?.enable_reasoner === false ? "disabled" : "enabled",
|
|
63054
|
-
...typeof updateArgs?.max_reasoning_tokens === "number" && {
|
|
63055
|
-
budget_tokens: updateArgs.max_reasoning_tokens
|
|
63056
|
-
}
|
|
63057
|
-
};
|
|
63058
|
-
}
|
|
63059
|
-
settings = anthropicSettings;
|
|
63060
|
-
} else if (isZai) {
|
|
63061
|
-
settings = {
|
|
63062
|
-
provider_type: "zai",
|
|
63063
|
-
parallel_tool_calls: true
|
|
63064
|
-
};
|
|
63065
|
-
} else if (isGoogleAI) {
|
|
63066
|
-
const googleSettings = {
|
|
63067
|
-
provider_type: "google_ai",
|
|
63068
|
-
parallel_tool_calls: true
|
|
63069
|
-
};
|
|
63070
|
-
if (updateArgs?.thinking_budget !== undefined) {
|
|
63071
|
-
googleSettings.thinking_config = {
|
|
63072
|
-
thinking_budget: updateArgs.thinking_budget
|
|
63073
|
-
};
|
|
63074
|
-
}
|
|
63075
|
-
if (typeof updateArgs?.temperature === "number") {
|
|
63076
|
-
googleSettings.temperature = updateArgs.temperature;
|
|
63077
|
-
}
|
|
63078
|
-
settings = googleSettings;
|
|
63079
|
-
} else if (isGoogleVertex) {
|
|
63080
|
-
const googleVertexSettings = {
|
|
63081
|
-
provider_type: "google_vertex",
|
|
63082
|
-
parallel_tool_calls: true
|
|
63083
|
-
};
|
|
63084
|
-
if (updateArgs?.thinking_budget !== undefined) {
|
|
63085
|
-
googleVertexSettings.thinking_config = {
|
|
63086
|
-
thinking_budget: updateArgs.thinking_budget
|
|
63087
|
-
};
|
|
63088
|
-
}
|
|
63089
|
-
if (typeof updateArgs?.temperature === "number") {
|
|
63090
|
-
googleVertexSettings.temperature = updateArgs.temperature;
|
|
63091
|
-
}
|
|
63092
|
-
settings = googleVertexSettings;
|
|
63093
|
-
} else if (isBedrock) {
|
|
63094
|
-
const bedrockSettings = {
|
|
63095
|
-
provider_type: "bedrock",
|
|
63096
|
-
parallel_tool_calls: true
|
|
63097
|
-
};
|
|
63098
|
-
if (updateArgs?.enable_reasoner !== undefined || typeof updateArgs?.max_reasoning_tokens === "number") {
|
|
63099
|
-
bedrockSettings.thinking = {
|
|
63100
|
-
type: updateArgs?.enable_reasoner === false ? "disabled" : "enabled",
|
|
63101
|
-
...typeof updateArgs?.max_reasoning_tokens === "number" && {
|
|
63102
|
-
budget_tokens: updateArgs.max_reasoning_tokens
|
|
63103
|
-
}
|
|
63104
|
-
};
|
|
63105
|
-
}
|
|
63106
|
-
settings = bedrockSettings;
|
|
63107
|
-
} else {
|
|
63108
|
-
settings = {};
|
|
63109
|
-
}
|
|
63110
|
-
if (typeof updateArgs?.max_output_tokens === "number" && "provider_type" in settings) {
|
|
63111
|
-
settings.max_output_tokens = updateArgs.max_output_tokens;
|
|
63112
|
-
}
|
|
63113
|
-
return settings;
|
|
63114
|
-
}
|
|
63115
|
-
async function updateAgentLLMConfig(agentId, modelHandle, updateArgs) {
|
|
63116
|
-
const client = await getClient2();
|
|
63117
|
-
const modelSettings = buildModelSettings(modelHandle, updateArgs);
|
|
63118
|
-
const contextWindow = updateArgs?.context_window ?? await getModelContextWindow(modelHandle);
|
|
63119
|
-
const hasModelSettings = Object.keys(modelSettings).length > 0;
|
|
63120
|
-
await client.agents.update(agentId, {
|
|
63121
|
-
model: modelHandle,
|
|
63122
|
-
...hasModelSettings && { model_settings: modelSettings },
|
|
63123
|
-
...contextWindow && { context_window_limit: contextWindow },
|
|
63124
|
-
...typeof updateArgs?.max_output_tokens === "number" && {
|
|
63125
|
-
max_tokens: updateArgs.max_output_tokens
|
|
63126
|
-
}
|
|
63127
|
-
});
|
|
63128
|
-
const finalAgent = await client.agents.retrieve(agentId);
|
|
63129
|
-
return finalAgent.llm_config;
|
|
63130
|
-
}
|
|
63131
|
-
async function updateAgentSystemPromptRaw(agentId, systemPromptContent) {
|
|
63132
|
-
try {
|
|
63133
|
-
const client = await getClient2();
|
|
63134
|
-
await client.agents.update(agentId, {
|
|
63135
|
-
system: systemPromptContent
|
|
63136
|
-
});
|
|
63137
|
-
return {
|
|
63138
|
-
success: true,
|
|
63139
|
-
message: "System prompt updated successfully"
|
|
63140
|
-
};
|
|
63141
|
-
} catch (error) {
|
|
63142
|
-
return {
|
|
63143
|
-
success: false,
|
|
63144
|
-
message: `Failed to update system prompt: ${error instanceof Error ? error.message : String(error)}`
|
|
63145
|
-
};
|
|
63146
|
-
}
|
|
63147
|
-
}
|
|
63148
|
-
async function updateAgentSystemPrompt(agentId, systemPromptId) {
|
|
63149
|
-
try {
|
|
63150
|
-
const { resolveSystemPrompt: resolveSystemPrompt3, SYSTEM_PROMPT_MEMORY_ADDON: SYSTEM_PROMPT_MEMORY_ADDON3 } = await Promise.resolve().then(() => (init_promptAssets(), exports_promptAssets));
|
|
63151
|
-
const baseContent = await resolveSystemPrompt3(systemPromptId);
|
|
63152
|
-
const systemPromptContent = `${baseContent}
|
|
63153
|
-
${SYSTEM_PROMPT_MEMORY_ADDON3}`;
|
|
63154
|
-
const updateResult = await updateAgentSystemPromptRaw(agentId, systemPromptContent);
|
|
63155
|
-
if (!updateResult.success) {
|
|
63156
|
-
return {
|
|
63157
|
-
success: false,
|
|
63158
|
-
message: updateResult.message,
|
|
63159
|
-
agent: null
|
|
63160
|
-
};
|
|
63161
|
-
}
|
|
63162
|
-
const client = await getClient2();
|
|
63163
|
-
const agent = await client.agents.retrieve(agentId);
|
|
63164
|
-
return {
|
|
63165
|
-
success: true,
|
|
63166
|
-
message: "System prompt applied successfully",
|
|
63167
|
-
agent
|
|
63168
|
-
};
|
|
63169
|
-
} catch (error) {
|
|
63170
|
-
return {
|
|
63171
|
-
success: false,
|
|
63172
|
-
message: `Failed to apply system prompt: ${error instanceof Error ? error.message : String(error)}`,
|
|
63173
|
-
agent: null
|
|
63174
|
-
};
|
|
63175
|
-
}
|
|
63176
|
-
}
|
|
63177
|
-
async function updateAgentSystemPromptMemfs(agentId, enableMemfs) {
|
|
63178
|
-
try {
|
|
63179
|
-
const client = await getClient2();
|
|
63180
|
-
const agent = await client.agents.retrieve(agentId);
|
|
63181
|
-
let currentSystemPrompt = agent.system || "";
|
|
63182
|
-
const { SYSTEM_PROMPT_MEMFS_ADDON: SYSTEM_PROMPT_MEMFS_ADDON3, SYSTEM_PROMPT_MEMORY_ADDON: SYSTEM_PROMPT_MEMORY_ADDON3 } = await Promise.resolve().then(() => (init_promptAssets(), exports_promptAssets));
|
|
63183
|
-
const memoryHeaderRegex = /\n#{1,2} Memory\b[\s\S]*?(?=\n#{1,2} (?!Memory|Filesystem|Structure|How It Works|Syncing|History)[^\n]|$)/;
|
|
63184
|
-
currentSystemPrompt = currentSystemPrompt.replace(memoryHeaderRegex, "");
|
|
63185
|
-
const addon = enableMemfs ? SYSTEM_PROMPT_MEMFS_ADDON3 : SYSTEM_PROMPT_MEMORY_ADDON3;
|
|
63186
|
-
currentSystemPrompt = `${currentSystemPrompt}
|
|
63187
|
-
${addon}`;
|
|
63188
|
-
await client.agents.update(agentId, {
|
|
63189
|
-
system: currentSystemPrompt
|
|
63190
|
-
});
|
|
63191
|
-
return {
|
|
63192
|
-
success: true,
|
|
63193
|
-
message: enableMemfs ? "System prompt updated to include Memory Filesystem section" : "System prompt updated to include standard Memory section"
|
|
63194
|
-
};
|
|
63195
|
-
} catch (error) {
|
|
63196
|
-
return {
|
|
63197
|
-
success: false,
|
|
63198
|
-
message: `Failed to update system prompt memfs: ${error instanceof Error ? error.message : String(error)}`
|
|
63199
|
-
};
|
|
63200
|
-
}
|
|
63201
|
-
}
|
|
63202
|
-
var init_modify = __esm(async () => {
|
|
63203
|
-
await __promiseAll([
|
|
63204
|
-
init_openai_codex_provider(),
|
|
63205
|
-
init_available_models(),
|
|
63206
|
-
init_client2()
|
|
63207
|
-
]);
|
|
63208
|
-
});
|
|
63209
|
-
|
|
63210
63843
|
// src/agent/prompts/sleeptime.ts
|
|
63211
63844
|
var SLEEPTIME_MEMORY_PERSONA = `I am a sleep-time memory management agent. I observe the conversation between the user and their primary agent, then actively maintain memory blocks to keep them accurate, concise, and useful.
|
|
63212
63845
|
|
|
@@ -63364,8 +63997,7 @@ async function createAgent(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingM
|
|
|
63364
63997
|
} else {
|
|
63365
63998
|
systemPromptContent = await resolveSystemPrompt(options.systemPromptPreset);
|
|
63366
63999
|
}
|
|
63367
|
-
systemPromptContent =
|
|
63368
|
-
${SYSTEM_PROMPT_MEMORY_ADDON}`;
|
|
64000
|
+
systemPromptContent = reconcileMemoryPrompt(systemPromptContent, options.memoryPromptMode ?? "standard");
|
|
63369
64001
|
if (options.systemPromptAppend) {
|
|
63370
64002
|
systemPromptContent = `${systemPromptContent}
|
|
63371
64003
|
|
|
@@ -63435,6 +64067,7 @@ ${options.systemPromptAppend}`;
|
|
|
63435
64067
|
var init_create = __esm(async () => {
|
|
63436
64068
|
init_constants();
|
|
63437
64069
|
init_memory();
|
|
64070
|
+
init_memoryPrompt();
|
|
63438
64071
|
init_model();
|
|
63439
64072
|
init_promptAssets();
|
|
63440
64073
|
await __promiseAll([
|
|
@@ -64025,163 +64658,6 @@ var init_interactivePolicy = __esm(() => {
|
|
|
64025
64658
|
HEADLESS_AUTO_ALLOW_TOOLS = new Set(["EnterPlanMode"]);
|
|
64026
64659
|
});
|
|
64027
64660
|
|
|
64028
|
-
// src/tools/toolset.ts
|
|
64029
|
-
var exports_toolset = {};
|
|
64030
|
-
__export(exports_toolset, {
|
|
64031
|
-
switchToolsetForModel: () => switchToolsetForModel,
|
|
64032
|
-
reattachMemoryTool: () => reattachMemoryTool,
|
|
64033
|
-
forceToolsetSwitch: () => forceToolsetSwitch,
|
|
64034
|
-
ensureCorrectMemoryTool: () => ensureCorrectMemoryTool,
|
|
64035
|
-
detachMemoryTools: () => detachMemoryTools,
|
|
64036
|
-
MEMORY_TOOL_NAMES: () => MEMORY_TOOL_NAMES
|
|
64037
|
-
});
|
|
64038
|
-
async function ensureCorrectMemoryTool(agentId, modelIdentifier, useMemoryPatch) {
|
|
64039
|
-
const resolvedModel = resolveModel(modelIdentifier) ?? modelIdentifier;
|
|
64040
|
-
const client = await getClient2();
|
|
64041
|
-
const shouldUsePatch = useMemoryPatch !== undefined ? useMemoryPatch : isOpenAIModel(resolvedModel);
|
|
64042
|
-
try {
|
|
64043
|
-
const agentWithTools = await client.agents.retrieve(agentId, {
|
|
64044
|
-
include: ["agent.tools"]
|
|
64045
|
-
});
|
|
64046
|
-
const currentTools = agentWithTools.tools || [];
|
|
64047
|
-
const mapByName = new Map(currentTools.map((t) => [t.name, t.id]));
|
|
64048
|
-
const hasAnyMemoryTool = mapByName.has("memory") || mapByName.has("memory_apply_patch");
|
|
64049
|
-
if (!hasAnyMemoryTool) {
|
|
64050
|
-
return;
|
|
64051
|
-
}
|
|
64052
|
-
const desiredMemoryTool = shouldUsePatch ? "memory_apply_patch" : "memory";
|
|
64053
|
-
const otherMemoryTool = desiredMemoryTool === "memory" ? "memory_apply_patch" : "memory";
|
|
64054
|
-
let desiredId = mapByName.get(desiredMemoryTool);
|
|
64055
|
-
if (!desiredId) {
|
|
64056
|
-
const resp = await client.tools.list({ name: desiredMemoryTool });
|
|
64057
|
-
desiredId = resp.items[0]?.id;
|
|
64058
|
-
}
|
|
64059
|
-
if (!desiredId) {
|
|
64060
|
-
return;
|
|
64061
|
-
}
|
|
64062
|
-
const otherId = mapByName.get(otherMemoryTool);
|
|
64063
|
-
if (mapByName.has(desiredMemoryTool) && !otherId) {
|
|
64064
|
-
return;
|
|
64065
|
-
}
|
|
64066
|
-
const currentIds = currentTools.map((t) => t.id).filter((id) => typeof id === "string");
|
|
64067
|
-
const newIds = new Set(currentIds);
|
|
64068
|
-
if (otherId)
|
|
64069
|
-
newIds.delete(otherId);
|
|
64070
|
-
newIds.add(desiredId);
|
|
64071
|
-
const updatedRules = (agentWithTools.tool_rules || []).map((r) => r.tool_name === otherMemoryTool ? { ...r, tool_name: desiredMemoryTool } : r);
|
|
64072
|
-
await client.agents.update(agentId, {
|
|
64073
|
-
tool_ids: Array.from(newIds),
|
|
64074
|
-
tool_rules: updatedRules
|
|
64075
|
-
});
|
|
64076
|
-
} catch (err) {
|
|
64077
|
-
console.warn(`Warning: Failed to sync memory tool: ${err instanceof Error ? err.message : String(err)}`);
|
|
64078
|
-
}
|
|
64079
|
-
}
|
|
64080
|
-
async function detachMemoryTools(agentId) {
|
|
64081
|
-
const client = await getClient2();
|
|
64082
|
-
try {
|
|
64083
|
-
const agentWithTools = await client.agents.retrieve(agentId, {
|
|
64084
|
-
include: ["agent.tools"]
|
|
64085
|
-
});
|
|
64086
|
-
const currentTools = agentWithTools.tools || [];
|
|
64087
|
-
let detachedAny = false;
|
|
64088
|
-
for (const tool of currentTools) {
|
|
64089
|
-
if (tool.name && MEMORY_TOOL_NAMES.has(tool.name)) {
|
|
64090
|
-
if (tool.id) {
|
|
64091
|
-
await client.agents.tools.detach(tool.id, { agent_id: agentId });
|
|
64092
|
-
detachedAny = true;
|
|
64093
|
-
}
|
|
64094
|
-
}
|
|
64095
|
-
}
|
|
64096
|
-
return detachedAny;
|
|
64097
|
-
} catch (err) {
|
|
64098
|
-
console.warn(`Warning: Failed to detach memory tools: ${err instanceof Error ? err.message : String(err)}`);
|
|
64099
|
-
return false;
|
|
64100
|
-
}
|
|
64101
|
-
}
|
|
64102
|
-
async function reattachMemoryTool(agentId, modelIdentifier) {
|
|
64103
|
-
const resolvedModel = resolveModel(modelIdentifier) ?? modelIdentifier;
|
|
64104
|
-
const client = await getClient2();
|
|
64105
|
-
const shouldUsePatch = isOpenAIModel(resolvedModel);
|
|
64106
|
-
try {
|
|
64107
|
-
const agentWithTools = await client.agents.retrieve(agentId, {
|
|
64108
|
-
include: ["agent.tools"]
|
|
64109
|
-
});
|
|
64110
|
-
const currentTools = agentWithTools.tools || [];
|
|
64111
|
-
const mapByName = new Map(currentTools.map((t) => [t.name, t.id]));
|
|
64112
|
-
const desiredMemoryTool = shouldUsePatch ? "memory_apply_patch" : "memory";
|
|
64113
|
-
if (mapByName.has(desiredMemoryTool)) {
|
|
64114
|
-
return;
|
|
64115
|
-
}
|
|
64116
|
-
const resp = await client.tools.list({ name: desiredMemoryTool });
|
|
64117
|
-
const toolId = resp.items[0]?.id;
|
|
64118
|
-
if (!toolId) {
|
|
64119
|
-
console.warn(`Memory tool "${desiredMemoryTool}" not found on server`);
|
|
64120
|
-
return;
|
|
64121
|
-
}
|
|
64122
|
-
await client.agents.tools.attach(toolId, { agent_id: agentId });
|
|
64123
|
-
} catch (err) {
|
|
64124
|
-
console.warn(`Warning: Failed to reattach memory tool: ${err instanceof Error ? err.message : String(err)}`);
|
|
64125
|
-
}
|
|
64126
|
-
}
|
|
64127
|
-
async function forceToolsetSwitch(toolsetName, agentId) {
|
|
64128
|
-
let modelForLoading;
|
|
64129
|
-
if (toolsetName === "none") {
|
|
64130
|
-
clearToolsWithLock();
|
|
64131
|
-
return;
|
|
64132
|
-
} else if (toolsetName === "codex") {
|
|
64133
|
-
await loadSpecificTools([...CODEX_TOOLS]);
|
|
64134
|
-
modelForLoading = "openai/gpt-4";
|
|
64135
|
-
} else if (toolsetName === "codex_snake") {
|
|
64136
|
-
await loadTools("openai/gpt-4");
|
|
64137
|
-
modelForLoading = "openai/gpt-4";
|
|
64138
|
-
} else if (toolsetName === "gemini") {
|
|
64139
|
-
await loadSpecificTools([...GEMINI_TOOLS]);
|
|
64140
|
-
modelForLoading = "google_ai/gemini-3-pro-preview";
|
|
64141
|
-
} else if (toolsetName === "gemini_snake") {
|
|
64142
|
-
await loadTools("google_ai/gemini-3-pro-preview");
|
|
64143
|
-
modelForLoading = "google_ai/gemini-3-pro-preview";
|
|
64144
|
-
} else {
|
|
64145
|
-
await loadTools("anthropic/claude-sonnet-4");
|
|
64146
|
-
modelForLoading = "anthropic/claude-sonnet-4";
|
|
64147
|
-
}
|
|
64148
|
-
const useMemoryPatch = toolsetName === "codex" || toolsetName === "codex_snake";
|
|
64149
|
-
await ensureCorrectMemoryTool(agentId, modelForLoading, useMemoryPatch);
|
|
64150
|
-
}
|
|
64151
|
-
async function switchToolsetForModel(modelIdentifier, agentId) {
|
|
64152
|
-
const resolvedModel = resolveModel(modelIdentifier) ?? modelIdentifier;
|
|
64153
|
-
await loadTools(resolvedModel);
|
|
64154
|
-
const loadedAfterPrimary = getToolNames().length;
|
|
64155
|
-
if (loadedAfterPrimary === 0 && !toolFilter.isActive()) {
|
|
64156
|
-
await loadTools();
|
|
64157
|
-
if (getToolNames().length === 0) {
|
|
64158
|
-
throw new Error(`Failed to load any Letta tools for model "${resolvedModel}".`);
|
|
64159
|
-
}
|
|
64160
|
-
}
|
|
64161
|
-
await ensureCorrectMemoryTool(agentId, resolvedModel);
|
|
64162
|
-
const { isGeminiModel: isGeminiModel3 } = await init_manager3().then(() => exports_manager2);
|
|
64163
|
-
const toolsetName = isOpenAIModel(resolvedModel) ? "codex" : isGeminiModel3(resolvedModel) ? "gemini" : "default";
|
|
64164
|
-
return toolsetName;
|
|
64165
|
-
}
|
|
64166
|
-
var CODEX_TOOLS, GEMINI_TOOLS, MEMORY_TOOL_NAMES;
|
|
64167
|
-
var init_toolset = __esm(async () => {
|
|
64168
|
-
init_model();
|
|
64169
|
-
init_filter();
|
|
64170
|
-
await __promiseAll([
|
|
64171
|
-
init_client2(),
|
|
64172
|
-
init_manager3()
|
|
64173
|
-
]);
|
|
64174
|
-
CODEX_TOOLS = OPENAI_PASCAL_TOOLS;
|
|
64175
|
-
GEMINI_TOOLS = GEMINI_PASCAL_TOOLS;
|
|
64176
|
-
MEMORY_TOOL_NAMES = new Set([
|
|
64177
|
-
"memory",
|
|
64178
|
-
"memory_apply_patch",
|
|
64179
|
-
"memory_insert",
|
|
64180
|
-
"memory_replace",
|
|
64181
|
-
"memory_rethink"
|
|
64182
|
-
]);
|
|
64183
|
-
});
|
|
64184
|
-
|
|
64185
64661
|
// src/cli/helpers/toolNameMapping.ts
|
|
64186
64662
|
function getDisplayToolName(rawName) {
|
|
64187
64663
|
if (rawName === "write")
|
|
@@ -65320,6 +65796,14 @@ function getRetryStatusMessage(errorDetail) {
|
|
|
65320
65796
|
return DEFAULT_RETRY_MESSAGE;
|
|
65321
65797
|
if (errorDetail.includes("Anthropic API is overloaded"))
|
|
65322
65798
|
return "Anthropic API is overloaded, retrying...";
|
|
65799
|
+
if (errorDetail.includes("ChatGPT API error") || errorDetail.includes("ChatGPT server error") || errorDetail.includes("upstream connect error")) {
|
|
65800
|
+
return "OpenAI ChatGPT backend connection failed, retrying...";
|
|
65801
|
+
}
|
|
65802
|
+
if (errorDetail.includes("Connection error during streaming") || errorDetail.includes("incomplete chunked read") || errorDetail.includes("connection termination")) {
|
|
65803
|
+
return "OpenAI ChatGPT streaming connection dropped, retrying...";
|
|
65804
|
+
}
|
|
65805
|
+
if (errorDetail.includes("OpenAI API error"))
|
|
65806
|
+
return "OpenAI API error, retrying...";
|
|
65323
65807
|
return DEFAULT_RETRY_MESSAGE;
|
|
65324
65808
|
}
|
|
65325
65809
|
function createAgentLink(runId, agentId, conversationId) {
|
|
@@ -65525,7 +66009,7 @@ async function drainStream(stream2, buffers, refresh, abortSignal, onFirstMessag
|
|
|
65525
66009
|
if (!streamProcessor.lastRunId) {
|
|
65526
66010
|
fallbackError = errorMessage;
|
|
65527
66011
|
}
|
|
65528
|
-
stopReason = "error";
|
|
66012
|
+
stopReason = streamProcessor.stopReason || "error";
|
|
65529
66013
|
markIncompleteToolsAsCancelled(buffers, true, "stream_error");
|
|
65530
66014
|
queueMicrotask(refresh);
|
|
65531
66015
|
} finally {
|
|
@@ -65763,7 +66247,7 @@ function parseRegistryHandle(handle) {
|
|
|
65763
66247
|
}
|
|
65764
66248
|
async function importAgentFromRegistry(options) {
|
|
65765
66249
|
const { tmpdir: tmpdir3 } = await import("node:os");
|
|
65766
|
-
const { join:
|
|
66250
|
+
const { join: join22 } = await import("node:path");
|
|
65767
66251
|
const { writeFile: writeFile4, unlink } = await import("node:fs/promises");
|
|
65768
66252
|
const { author, name } = parseRegistryHandle(options.handle);
|
|
65769
66253
|
const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER}/${AGENT_REGISTRY_REPO}/refs/heads/${AGENT_REGISTRY_BRANCH}/agents/@${author}/${name}/${name}.af`;
|
|
@@ -65775,7 +66259,7 @@ async function importAgentFromRegistry(options) {
|
|
|
65775
66259
|
throw new Error(`Failed to download agent @${author}/${name}: ${response.statusText}`);
|
|
65776
66260
|
}
|
|
65777
66261
|
const afContent = await response.text();
|
|
65778
|
-
const tempPath =
|
|
66262
|
+
const tempPath = join22(tmpdir3(), `letta-import-${author}-${name}-${Date.now()}.af`);
|
|
65779
66263
|
await writeFile4(tempPath, afContent, "utf-8");
|
|
65780
66264
|
try {
|
|
65781
66265
|
const result = await importAgentFromFile({
|
|
@@ -65800,149 +66284,6 @@ var init_import = __esm(async () => {
|
|
|
65800
66284
|
]);
|
|
65801
66285
|
});
|
|
65802
66286
|
|
|
65803
|
-
// src/agent/memoryFilesystem.ts
|
|
65804
|
-
var exports_memoryFilesystem = {};
|
|
65805
|
-
__export(exports_memoryFilesystem, {
|
|
65806
|
-
renderMemoryFilesystemTree: () => renderMemoryFilesystemTree,
|
|
65807
|
-
labelFromRelativePath: () => labelFromRelativePath,
|
|
65808
|
-
getMemorySystemDir: () => getMemorySystemDir,
|
|
65809
|
-
getMemoryFilesystemRoot: () => getMemoryFilesystemRoot,
|
|
65810
|
-
ensureMemoryFilesystemDirs: () => ensureMemoryFilesystemDirs,
|
|
65811
|
-
enableMemfsIfCloud: () => enableMemfsIfCloud,
|
|
65812
|
-
applyMemfsFlags: () => applyMemfsFlags,
|
|
65813
|
-
MEMORY_SYSTEM_DIR: () => MEMORY_SYSTEM_DIR,
|
|
65814
|
-
MEMORY_FS_ROOT: () => MEMORY_FS_ROOT,
|
|
65815
|
-
MEMORY_FS_MEMORY_DIR: () => MEMORY_FS_MEMORY_DIR,
|
|
65816
|
-
MEMORY_FS_AGENTS_DIR: () => MEMORY_FS_AGENTS_DIR
|
|
65817
|
-
});
|
|
65818
|
-
import { existsSync as existsSync12, mkdirSync as mkdirSync8 } from "node:fs";
|
|
65819
|
-
import { homedir as homedir14 } from "node:os";
|
|
65820
|
-
import { join as join21 } from "node:path";
|
|
65821
|
-
function getMemoryFilesystemRoot(agentId, homeDir = homedir14()) {
|
|
65822
|
-
return join21(homeDir, MEMORY_FS_ROOT, MEMORY_FS_AGENTS_DIR, agentId, MEMORY_FS_MEMORY_DIR);
|
|
65823
|
-
}
|
|
65824
|
-
function getMemorySystemDir(agentId, homeDir = homedir14()) {
|
|
65825
|
-
return join21(getMemoryFilesystemRoot(agentId, homeDir), MEMORY_SYSTEM_DIR);
|
|
65826
|
-
}
|
|
65827
|
-
function ensureMemoryFilesystemDirs(agentId, homeDir = homedir14()) {
|
|
65828
|
-
const root = getMemoryFilesystemRoot(agentId, homeDir);
|
|
65829
|
-
const systemDir = getMemorySystemDir(agentId, homeDir);
|
|
65830
|
-
if (!existsSync12(root)) {
|
|
65831
|
-
mkdirSync8(root, { recursive: true });
|
|
65832
|
-
}
|
|
65833
|
-
if (!existsSync12(systemDir)) {
|
|
65834
|
-
mkdirSync8(systemDir, { recursive: true });
|
|
65835
|
-
}
|
|
65836
|
-
}
|
|
65837
|
-
function labelFromRelativePath(relativePath) {
|
|
65838
|
-
const normalized = relativePath.replace(/\\/g, "/");
|
|
65839
|
-
return normalized.replace(/\.md$/, "");
|
|
65840
|
-
}
|
|
65841
|
-
function renderMemoryFilesystemTree(systemLabels, detachedLabels) {
|
|
65842
|
-
const makeNode = () => ({ children: new Map, isFile: false });
|
|
65843
|
-
const root = makeNode();
|
|
65844
|
-
const insertPath = (base2, label) => {
|
|
65845
|
-
const parts = base2 ? [base2, ...label.split("/")] : label.split("/");
|
|
65846
|
-
let current = root;
|
|
65847
|
-
for (const [i, partName] of parts.entries()) {
|
|
65848
|
-
const part = i === parts.length - 1 ? `${partName}.md` : partName;
|
|
65849
|
-
if (!current.children.has(part)) {
|
|
65850
|
-
current.children.set(part, makeNode());
|
|
65851
|
-
}
|
|
65852
|
-
current = current.children.get(part);
|
|
65853
|
-
if (i === parts.length - 1) {
|
|
65854
|
-
current.isFile = true;
|
|
65855
|
-
}
|
|
65856
|
-
}
|
|
65857
|
-
};
|
|
65858
|
-
for (const label of systemLabels) {
|
|
65859
|
-
insertPath(MEMORY_SYSTEM_DIR, label);
|
|
65860
|
-
}
|
|
65861
|
-
for (const label of detachedLabels) {
|
|
65862
|
-
insertPath(null, label);
|
|
65863
|
-
}
|
|
65864
|
-
if (!root.children.has(MEMORY_SYSTEM_DIR)) {
|
|
65865
|
-
root.children.set(MEMORY_SYSTEM_DIR, makeNode());
|
|
65866
|
-
}
|
|
65867
|
-
const sortedEntries = (node) => {
|
|
65868
|
-
const entries = Array.from(node.children.entries());
|
|
65869
|
-
return entries.sort(([nameA, nodeA], [nameB, nodeB]) => {
|
|
65870
|
-
if (nodeA.isFile !== nodeB.isFile) {
|
|
65871
|
-
return nodeA.isFile ? 1 : -1;
|
|
65872
|
-
}
|
|
65873
|
-
return nameA.localeCompare(nameB);
|
|
65874
|
-
});
|
|
65875
|
-
};
|
|
65876
|
-
const lines = ["/memory/"];
|
|
65877
|
-
const render2 = (node, prefix) => {
|
|
65878
|
-
const entries = sortedEntries(node);
|
|
65879
|
-
entries.forEach(([name, child], index) => {
|
|
65880
|
-
const isLast = index === entries.length - 1;
|
|
65881
|
-
const branch = isLast ? "└──" : "├──";
|
|
65882
|
-
lines.push(`${prefix}${branch} ${name}${child.isFile ? "" : "/"}`);
|
|
65883
|
-
if (child.children.size > 0) {
|
|
65884
|
-
const nextPrefix = `${prefix}${isLast ? " " : "│ "}`;
|
|
65885
|
-
render2(child, nextPrefix);
|
|
65886
|
-
}
|
|
65887
|
-
});
|
|
65888
|
-
};
|
|
65889
|
-
render2(root, "");
|
|
65890
|
-
return lines.join(`
|
|
65891
|
-
`);
|
|
65892
|
-
}
|
|
65893
|
-
async function applyMemfsFlags(agentId, memfsFlag, noMemfsFlag, options) {
|
|
65894
|
-
const { getServerUrl: getServerUrl2 } = await init_client2().then(() => exports_client);
|
|
65895
|
-
const { settingsManager: settingsManager3 } = await init_settings_manager().then(() => exports_settings_manager);
|
|
65896
|
-
if (memfsFlag) {
|
|
65897
|
-
const serverUrl = getServerUrl2();
|
|
65898
|
-
if (!serverUrl.includes("api.letta.com")) {
|
|
65899
|
-
throw new Error("--memfs is only available on Letta Cloud (api.letta.com).");
|
|
65900
|
-
}
|
|
65901
|
-
settingsManager3.setMemfsEnabled(agentId, true);
|
|
65902
|
-
} else if (noMemfsFlag) {
|
|
65903
|
-
settingsManager3.setMemfsEnabled(agentId, false);
|
|
65904
|
-
}
|
|
65905
|
-
const isEnabled = settingsManager3.isMemfsEnabled(agentId);
|
|
65906
|
-
if (isEnabled && memfsFlag) {
|
|
65907
|
-
const { detachMemoryTools: detachMemoryTools2 } = await init_toolset().then(() => exports_toolset);
|
|
65908
|
-
await detachMemoryTools2(agentId);
|
|
65909
|
-
}
|
|
65910
|
-
if (memfsFlag || noMemfsFlag) {
|
|
65911
|
-
const { updateAgentSystemPromptMemfs: updateAgentSystemPromptMemfs2 } = await init_modify().then(() => exports_modify);
|
|
65912
|
-
await updateAgentSystemPromptMemfs2(agentId, isEnabled);
|
|
65913
|
-
}
|
|
65914
|
-
let pullSummary;
|
|
65915
|
-
if (isEnabled) {
|
|
65916
|
-
const { addGitMemoryTag: addGitMemoryTag2, isGitRepo: isGitRepo2, cloneMemoryRepo: cloneMemoryRepo2, pullMemory: pullMemory2 } = await init_memoryGit().then(() => exports_memoryGit);
|
|
65917
|
-
await addGitMemoryTag2(agentId);
|
|
65918
|
-
if (!isGitRepo2(agentId)) {
|
|
65919
|
-
await cloneMemoryRepo2(agentId);
|
|
65920
|
-
} else if (options?.pullOnExistingRepo) {
|
|
65921
|
-
const result = await pullMemory2(agentId);
|
|
65922
|
-
pullSummary = result.summary;
|
|
65923
|
-
}
|
|
65924
|
-
}
|
|
65925
|
-
const action = memfsFlag ? "enabled" : noMemfsFlag ? "disabled" : "unchanged";
|
|
65926
|
-
return {
|
|
65927
|
-
action,
|
|
65928
|
-
memoryDir: isEnabled ? getMemoryFilesystemRoot(agentId) : undefined,
|
|
65929
|
-
pullSummary
|
|
65930
|
-
};
|
|
65931
|
-
}
|
|
65932
|
-
async function enableMemfsIfCloud(agentId) {
|
|
65933
|
-
const { getServerUrl: getServerUrl2 } = await init_client2().then(() => exports_client);
|
|
65934
|
-
const serverUrl = getServerUrl2();
|
|
65935
|
-
if (!serverUrl.includes("api.letta.com"))
|
|
65936
|
-
return;
|
|
65937
|
-
try {
|
|
65938
|
-
await applyMemfsFlags(agentId, true, undefined);
|
|
65939
|
-
} catch (error) {
|
|
65940
|
-
console.warn(`Warning: Could not enable memfs for new agent: ${error instanceof Error ? error.message : String(error)}`);
|
|
65941
|
-
}
|
|
65942
|
-
}
|
|
65943
|
-
var MEMORY_FS_ROOT = ".letta", MEMORY_FS_AGENTS_DIR = "agents", MEMORY_FS_MEMORY_DIR = "memory", MEMORY_SYSTEM_DIR = "system";
|
|
65944
|
-
var init_memoryFilesystem = () => {};
|
|
65945
|
-
|
|
65946
66287
|
// src/agent/defaults.ts
|
|
65947
66288
|
var exports_defaults = {};
|
|
65948
66289
|
__export(exports_defaults, {
|
|
@@ -66180,9 +66521,36 @@ var init_check_approval = __esm(() => {
|
|
|
66180
66521
|
// src/headless.ts
|
|
66181
66522
|
var exports_headless = {};
|
|
66182
66523
|
__export(exports_headless, {
|
|
66524
|
+
shouldReinjectSkillsAfterCompaction: () => shouldReinjectSkillsAfterCompaction,
|
|
66525
|
+
prependSkillsReminderToContent: () => prependSkillsReminderToContent,
|
|
66183
66526
|
handleHeadlessCommand: () => handleHeadlessCommand
|
|
66184
66527
|
});
|
|
66185
66528
|
import { parseArgs as parseArgs5 } from "node:util";
|
|
66529
|
+
function prependSkillsReminderToContent(content, skillsReminder) {
|
|
66530
|
+
if (!skillsReminder) {
|
|
66531
|
+
return content;
|
|
66532
|
+
}
|
|
66533
|
+
if (typeof content === "string") {
|
|
66534
|
+
return `${skillsReminder}
|
|
66535
|
+
|
|
66536
|
+
${content}`;
|
|
66537
|
+
}
|
|
66538
|
+
if (Array.isArray(content)) {
|
|
66539
|
+
return [
|
|
66540
|
+
{
|
|
66541
|
+
type: "text",
|
|
66542
|
+
text: `${skillsReminder}
|
|
66543
|
+
|
|
66544
|
+
`
|
|
66545
|
+
},
|
|
66546
|
+
...content
|
|
66547
|
+
];
|
|
66548
|
+
}
|
|
66549
|
+
return content;
|
|
66550
|
+
}
|
|
66551
|
+
function shouldReinjectSkillsAfterCompaction(lines) {
|
|
66552
|
+
return lines.some((line) => line.kind === "event" && line.eventType === "compaction" && line.phase === "finished" && (line.summary !== undefined || line.stats !== undefined));
|
|
66553
|
+
}
|
|
66186
66554
|
async function handleHeadlessCommand(argv, model, skillsDirectory, noSkills) {
|
|
66187
66555
|
const { values, positionals } = parseArgs5({
|
|
66188
66556
|
args: argv,
|
|
@@ -66317,10 +66685,12 @@ In headless mode, use:
|
|
|
66317
66685
|
const baseToolsRaw = values["base-tools"];
|
|
66318
66686
|
const memfsFlag = values.memfs;
|
|
66319
66687
|
const noMemfsFlag = values["no-memfs"];
|
|
66688
|
+
const requestedMemoryPromptMode = memfsFlag ? "memfs" : noMemfsFlag ? "standard" : undefined;
|
|
66689
|
+
const shouldAutoEnableMemfsForNewAgent = !memfsFlag && !noMemfsFlag;
|
|
66320
66690
|
const fromAfFile = values["from-af"];
|
|
66321
66691
|
const preLoadSkillsRaw = values["pre-load-skills"];
|
|
66322
66692
|
const maxTurnsRaw = values["max-turns"];
|
|
66323
|
-
const tagsRaw = values
|
|
66693
|
+
const tagsRaw = values.tags;
|
|
66324
66694
|
let tags;
|
|
66325
66695
|
if (tagsRaw !== undefined) {
|
|
66326
66696
|
const trimmed = tagsRaw.trim();
|
|
@@ -66547,6 +66917,7 @@ In headless mode, use:
|
|
|
66547
66917
|
systemPromptPreset,
|
|
66548
66918
|
systemPromptCustom: systemCustom,
|
|
66549
66919
|
systemPromptAppend: systemAppend,
|
|
66920
|
+
memoryPromptMode: requestedMemoryPromptMode,
|
|
66550
66921
|
initBlocks,
|
|
66551
66922
|
baseTools,
|
|
66552
66923
|
memoryBlocks,
|
|
@@ -66555,8 +66926,10 @@ In headless mode, use:
|
|
|
66555
66926
|
};
|
|
66556
66927
|
const result = await createAgent(createOptions);
|
|
66557
66928
|
agent = result.agent;
|
|
66558
|
-
|
|
66559
|
-
|
|
66929
|
+
if (shouldAutoEnableMemfsForNewAgent) {
|
|
66930
|
+
const { enableMemfsIfCloud: enableMemfsIfCloud2 } = await Promise.resolve().then(() => (init_memoryFilesystem(), exports_memoryFilesystem));
|
|
66931
|
+
await enableMemfsIfCloud2(agent.id);
|
|
66932
|
+
}
|
|
66560
66933
|
}
|
|
66561
66934
|
let resolvedLocalConvId = null;
|
|
66562
66935
|
if (!agent) {
|
|
@@ -66959,7 +67332,11 @@ ${loadedContents.join(`
|
|
|
66959
67332
|
});
|
|
66960
67333
|
} catch (preStreamError) {
|
|
66961
67334
|
const errorDetail = extractConflictDetail(preStreamError);
|
|
66962
|
-
const preStreamAction = getPreStreamErrorAction(errorDetail, conversationBusyRetries, CONVERSATION_BUSY_MAX_RETRIES
|
|
67335
|
+
const preStreamAction = getPreStreamErrorAction(errorDetail, conversationBusyRetries, CONVERSATION_BUSY_MAX_RETRIES, {
|
|
67336
|
+
status: preStreamError instanceof APIError2 ? preStreamError.status : undefined,
|
|
67337
|
+
transientRetries: llmApiErrorRetries,
|
|
67338
|
+
maxTransientRetries: LLM_API_ERROR_MAX_RETRIES
|
|
67339
|
+
});
|
|
66963
67340
|
if (preStreamAction === "resolve_approval_pending") {
|
|
66964
67341
|
if (outputFormat === "stream-json") {
|
|
66965
67342
|
const recoveryMsg = {
|
|
@@ -66995,6 +67372,30 @@ ${loadedContents.join(`
|
|
|
66995
67372
|
await new Promise((resolve20) => setTimeout(resolve20, CONVERSATION_BUSY_RETRY_DELAY_MS));
|
|
66996
67373
|
continue;
|
|
66997
67374
|
}
|
|
67375
|
+
if (preStreamAction === "retry_transient") {
|
|
67376
|
+
const attempt = llmApiErrorRetries + 1;
|
|
67377
|
+
const retryAfterMs = preStreamError instanceof APIError2 ? parseRetryAfterHeaderMs(preStreamError.headers?.get("retry-after")) : null;
|
|
67378
|
+
const delayMs = retryAfterMs ?? 1000 * 2 ** (attempt - 1);
|
|
67379
|
+
llmApiErrorRetries = attempt;
|
|
67380
|
+
if (outputFormat === "stream-json") {
|
|
67381
|
+
const retryMsg = {
|
|
67382
|
+
type: "retry",
|
|
67383
|
+
reason: "llm_api_error",
|
|
67384
|
+
attempt,
|
|
67385
|
+
max_attempts: LLM_API_ERROR_MAX_RETRIES,
|
|
67386
|
+
delay_ms: delayMs,
|
|
67387
|
+
session_id: sessionId,
|
|
67388
|
+
uuid: `retry-pre-stream-${crypto.randomUUID()}`
|
|
67389
|
+
};
|
|
67390
|
+
console.log(JSON.stringify(retryMsg));
|
|
67391
|
+
} else {
|
|
67392
|
+
const delaySeconds = Math.round(delayMs / 1000);
|
|
67393
|
+
console.error(`Transient API error before streaming (attempt ${attempt} of ${LLM_API_ERROR_MAX_RETRIES}), retrying in ${delaySeconds}s...`);
|
|
67394
|
+
}
|
|
67395
|
+
await new Promise((resolve20) => setTimeout(resolve20, delayMs));
|
|
67396
|
+
conversationBusyRetries = 0;
|
|
67397
|
+
continue;
|
|
67398
|
+
}
|
|
66998
67399
|
conversationBusyRetries = 0;
|
|
66999
67400
|
throw preStreamError;
|
|
67000
67401
|
}
|
|
@@ -67257,18 +67658,7 @@ ${loadedContents.join(`
|
|
|
67257
67658
|
const metaError = run.metadata?.error;
|
|
67258
67659
|
const errorType = metaError?.error_type ?? metaError?.error?.error_type;
|
|
67259
67660
|
const detail = metaError?.detail ?? metaError?.error?.detail ?? "";
|
|
67260
|
-
|
|
67261
|
-
const llmProviderPatterns = [
|
|
67262
|
-
"Anthropic API error",
|
|
67263
|
-
"OpenAI API error",
|
|
67264
|
-
"Google Vertex API error",
|
|
67265
|
-
"overloaded",
|
|
67266
|
-
"api_error",
|
|
67267
|
-
"Network error",
|
|
67268
|
-
"Connection error during Anthropic streaming"
|
|
67269
|
-
];
|
|
67270
|
-
const isLlmErrorFromDetail = llmProviderPatterns.some((pattern) => detail.includes(pattern));
|
|
67271
|
-
if ((errorType === "llm_error" || isLlmErrorFromDetail) && !is4xxError) {
|
|
67661
|
+
if (shouldRetryRunMetadataError(errorType, detail)) {
|
|
67272
67662
|
const attempt = llmApiErrorRetries + 1;
|
|
67273
67663
|
const baseDelayMs = 1000;
|
|
67274
67664
|
const delayMs = baseDelayMs * 2 ** (attempt - 1);
|
|
@@ -67433,6 +67823,9 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
|
|
|
67433
67823
|
};
|
|
67434
67824
|
console.log(JSON.stringify(initEvent));
|
|
67435
67825
|
let currentAbortController = null;
|
|
67826
|
+
let hasInjectedSkillsReminder = false;
|
|
67827
|
+
let pendingSkillsReinject = false;
|
|
67828
|
+
let cachedSkillsReminder = null;
|
|
67436
67829
|
const resolveAllPendingApprovals = async () => {
|
|
67437
67830
|
const { getResumeData: getResumeData3 } = await Promise.resolve().then(() => (init_check_approval(), exports_check_approval));
|
|
67438
67831
|
while (true) {
|
|
@@ -67699,7 +68092,7 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
|
|
|
67699
68092
|
}
|
|
67700
68093
|
continue;
|
|
67701
68094
|
}
|
|
67702
|
-
if (message.type === "user" && message.message?.content) {
|
|
68095
|
+
if (message.type === "user" && message.message?.content !== undefined) {
|
|
67703
68096
|
const userContent = message.message.content;
|
|
67704
68097
|
currentAbortController = new AbortController;
|
|
67705
68098
|
try {
|
|
@@ -67708,26 +68101,32 @@ async function runBidirectionalMode(agent, conversationId, client, _outputFormat
|
|
|
67708
68101
|
let numTurns = 0;
|
|
67709
68102
|
let lastStopReason = null;
|
|
67710
68103
|
let sawStreamError = false;
|
|
68104
|
+
let preStreamTransientRetries = 0;
|
|
67711
68105
|
let enrichedContent = userContent;
|
|
67712
|
-
|
|
67713
|
-
|
|
67714
|
-
|
|
67715
|
-
|
|
67716
|
-
|
|
67717
|
-
|
|
67718
|
-
|
|
67719
|
-
|
|
67720
|
-
|
|
67721
|
-
|
|
67722
|
-
|
|
67723
|
-
|
|
67724
|
-
|
|
67725
|
-
|
|
67726
|
-
|
|
67727
|
-
|
|
67728
|
-
|
|
67729
|
-
|
|
67730
|
-
|
|
68106
|
+
try {
|
|
68107
|
+
const {
|
|
68108
|
+
discoverSkills: discover,
|
|
68109
|
+
SKILLS_DIR: defaultDir,
|
|
68110
|
+
formatSkillsAsSystemReminder: formatSkillsAsSystemReminder3
|
|
68111
|
+
} = await Promise.resolve().then(() => (init_skills(), exports_skills));
|
|
68112
|
+
const { getSkillsDirectory: getSkillsDirectory2 } = await Promise.resolve().then(() => (init_context(), exports_context));
|
|
68113
|
+
const { join: join22 } = await import("node:path");
|
|
68114
|
+
const skillsDir = getSkillsDirectory2() || join22(process.cwd(), defaultDir);
|
|
68115
|
+
const { skills } = await discover(skillsDir, agent.id);
|
|
68116
|
+
const latestSkillsReminder = formatSkillsAsSystemReminder3(skills);
|
|
68117
|
+
if (cachedSkillsReminder !== null && latestSkillsReminder !== cachedSkillsReminder) {
|
|
68118
|
+
pendingSkillsReinject = true;
|
|
68119
|
+
}
|
|
68120
|
+
cachedSkillsReminder = latestSkillsReminder;
|
|
68121
|
+
const shouldInjectSkillsReminder = !hasInjectedSkillsReminder || pendingSkillsReinject;
|
|
68122
|
+
if (shouldInjectSkillsReminder && latestSkillsReminder) {
|
|
68123
|
+
enrichedContent = prependSkillsReminderToContent(enrichedContent, latestSkillsReminder);
|
|
68124
|
+
}
|
|
68125
|
+
if (shouldInjectSkillsReminder) {
|
|
68126
|
+
hasInjectedSkillsReminder = true;
|
|
68127
|
+
pendingSkillsReinject = false;
|
|
68128
|
+
}
|
|
68129
|
+
} catch {}
|
|
67731
68130
|
let currentInput = [
|
|
67732
68131
|
{ role: "user", content: enrichedContent }
|
|
67733
68132
|
];
|
|
@@ -67759,7 +68158,11 @@ ${enrichedContent}`;
|
|
|
67759
68158
|
});
|
|
67760
68159
|
} catch (preStreamError) {
|
|
67761
68160
|
const errorDetail = extractConflictDetail(preStreamError);
|
|
67762
|
-
const preStreamAction = getPreStreamErrorAction(errorDetail, 0, 0
|
|
68161
|
+
const preStreamAction = getPreStreamErrorAction(errorDetail, 0, 0, {
|
|
68162
|
+
status: preStreamError instanceof APIError2 ? preStreamError.status : undefined,
|
|
68163
|
+
transientRetries: preStreamTransientRetries,
|
|
68164
|
+
maxTransientRetries: LLM_API_ERROR_MAX_RETRIES
|
|
68165
|
+
});
|
|
67763
68166
|
if (preStreamAction === "resolve_approval_pending") {
|
|
67764
68167
|
const recoveryMsg = {
|
|
67765
68168
|
type: "recovery",
|
|
@@ -67772,8 +68175,27 @@ ${enrichedContent}`;
|
|
|
67772
68175
|
await resolveAllPendingApprovals();
|
|
67773
68176
|
continue;
|
|
67774
68177
|
}
|
|
68178
|
+
if (preStreamAction === "retry_transient") {
|
|
68179
|
+
const attempt = preStreamTransientRetries + 1;
|
|
68180
|
+
const retryAfterMs = preStreamError instanceof APIError2 ? parseRetryAfterHeaderMs(preStreamError.headers?.get("retry-after")) : null;
|
|
68181
|
+
const delayMs = retryAfterMs ?? 1000 * 2 ** (attempt - 1);
|
|
68182
|
+
preStreamTransientRetries = attempt;
|
|
68183
|
+
const retryMsg = {
|
|
68184
|
+
type: "retry",
|
|
68185
|
+
reason: "llm_api_error",
|
|
68186
|
+
attempt,
|
|
68187
|
+
max_attempts: LLM_API_ERROR_MAX_RETRIES,
|
|
68188
|
+
delay_ms: delayMs,
|
|
68189
|
+
session_id: sessionId,
|
|
68190
|
+
uuid: `retry-bidir-${crypto.randomUUID()}`
|
|
68191
|
+
};
|
|
68192
|
+
console.log(JSON.stringify(retryMsg));
|
|
68193
|
+
await new Promise((resolve20) => setTimeout(resolve20, delayMs));
|
|
68194
|
+
continue;
|
|
68195
|
+
}
|
|
67775
68196
|
throw preStreamError;
|
|
67776
68197
|
}
|
|
68198
|
+
preStreamTransientRetries = 0;
|
|
67777
68199
|
const streamJsonHook = ({
|
|
67778
68200
|
chunk,
|
|
67779
68201
|
shouldOutput,
|
|
@@ -67923,6 +68345,9 @@ ${enrichedContent}`;
|
|
|
67923
68345
|
}
|
|
67924
68346
|
const durationMs = performance.now() - startTime;
|
|
67925
68347
|
const lines = toLines(buffers);
|
|
68348
|
+
if (shouldReinjectSkillsAfterCompaction(lines)) {
|
|
68349
|
+
pendingSkillsReinject = true;
|
|
68350
|
+
}
|
|
67926
68351
|
const reversed = [...lines].reverse();
|
|
67927
68352
|
const lastAssistant = reversed.find((line2) => line2.kind === "assistant" && ("text" in line2) && typeof line2.text === "string" && line2.text.trim().length > 0);
|
|
67928
68353
|
const lastReasoning = reversed.find((line2) => line2.kind === "reasoning" && ("text" in line2) && typeof line2.text === "string" && line2.text.trim().length > 0);
|
|
@@ -92683,6 +93108,15 @@ function buildSessionContext(options) {
|
|
|
92683
93108
|
lastRunInfo = "(failed to parse last run time)";
|
|
92684
93109
|
}
|
|
92685
93110
|
}
|
|
93111
|
+
const showMemoryDir = (() => {
|
|
93112
|
+
try {
|
|
93113
|
+
return settingsManager.isMemfsEnabled(agentInfo.id);
|
|
93114
|
+
} catch {
|
|
93115
|
+
return false;
|
|
93116
|
+
}
|
|
93117
|
+
})();
|
|
93118
|
+
const memoryDirLine = showMemoryDir ? `
|
|
93119
|
+
- **Memory directory (also stored in \`MEMORY_DIR\` env var)**: \`${getMemoryFilesystemRoot(agentInfo.id)}\`` : "";
|
|
92686
93120
|
let context3 = `${SYSTEM_REMINDER_OPEN}
|
|
92687
93121
|
This is an automated message providing context about the user's environment.
|
|
92688
93122
|
The user has just initiated a new connection via the [Letta Code CLI client](https://docs.letta.com/letta-code/index.md).
|
|
@@ -92720,7 +93154,7 @@ ${gitInfo.status}
|
|
|
92720
93154
|
}
|
|
92721
93155
|
context3 += `
|
|
92722
93156
|
## Agent Information (i.e. information about you)
|
|
92723
|
-
- **Agent ID**: ${agentInfo.id}
|
|
93157
|
+
- **Agent ID (also stored in \`AGENT_ID\` env var)**: ${agentInfo.id}${memoryDirLine}
|
|
92724
93158
|
- **Agent name**: ${agentInfo.name || "(unnamed)"} (the user can change this with /rename)
|
|
92725
93159
|
- **Agent description**: ${agentInfo.description || "(no description)"} (the user can change this with /description)
|
|
92726
93160
|
- **Last message**: ${lastRunInfo}
|
|
@@ -92732,6 +93166,7 @@ ${SYSTEM_REMINDER_CLOSE}`;
|
|
|
92732
93166
|
}
|
|
92733
93167
|
}
|
|
92734
93168
|
var init_sessionContext = __esm(async () => {
|
|
93169
|
+
init_memoryFilesystem();
|
|
92735
93170
|
init_oauth();
|
|
92736
93171
|
init_constants();
|
|
92737
93172
|
init_version();
|
|
@@ -94835,19 +95270,7 @@ async function isRetriableError(stopReason, lastRunId) {
|
|
|
94835
95270
|
const metaError = run.metadata?.error;
|
|
94836
95271
|
const errorType = metaError?.error_type ?? metaError?.error?.error_type;
|
|
94837
95272
|
const detail = metaError?.detail ?? metaError?.error?.detail ?? "";
|
|
94838
|
-
|
|
94839
|
-
if (errorType === "llm_error" && !is4xxError)
|
|
94840
|
-
return true;
|
|
94841
|
-
const llmProviderPatterns = [
|
|
94842
|
-
"Anthropic API error",
|
|
94843
|
-
"OpenAI API error",
|
|
94844
|
-
"Google Vertex API error",
|
|
94845
|
-
"overloaded",
|
|
94846
|
-
"api_error",
|
|
94847
|
-
"Network error",
|
|
94848
|
-
"Connection error during Anthropic streaming"
|
|
94849
|
-
];
|
|
94850
|
-
if (llmProviderPatterns.some((pattern) => detail.includes(pattern)) && !is4xxError) {
|
|
95273
|
+
if (shouldRetryRunMetadataError(errorType, detail)) {
|
|
94851
95274
|
return true;
|
|
94852
95275
|
}
|
|
94853
95276
|
return false;
|
|
@@ -96407,7 +96830,11 @@ ${newState.originalPrompt}`
|
|
|
96407
96830
|
stream2 = await sendMessageStream(conversationIdRef.current, currentInput, { agentId: agentIdRef.current });
|
|
96408
96831
|
} catch (preStreamError) {
|
|
96409
96832
|
const errorDetail = extractConflictDetail(preStreamError);
|
|
96410
|
-
const preStreamAction = getPreStreamErrorAction(errorDetail, conversationBusyRetriesRef.current, CONVERSATION_BUSY_MAX_RETRIES2
|
|
96833
|
+
const preStreamAction = getPreStreamErrorAction(errorDetail, conversationBusyRetriesRef.current, CONVERSATION_BUSY_MAX_RETRIES2, {
|
|
96834
|
+
status: preStreamError instanceof APIError2 ? preStreamError.status : undefined,
|
|
96835
|
+
transientRetries: llmApiErrorRetriesRef.current,
|
|
96836
|
+
maxTransientRetries: LLM_API_ERROR_MAX_RETRIES2
|
|
96837
|
+
});
|
|
96411
96838
|
if (shouldAttemptApprovalRecovery({
|
|
96412
96839
|
approvalPendingDetected: preStreamAction === "resolve_approval_pending",
|
|
96413
96840
|
retries: llmApiErrorRetriesRef.current,
|
|
@@ -96453,6 +96880,37 @@ ${newState.originalPrompt}`
|
|
|
96453
96880
|
continue;
|
|
96454
96881
|
}
|
|
96455
96882
|
}
|
|
96883
|
+
if (preStreamAction === "retry_transient") {
|
|
96884
|
+
llmApiErrorRetriesRef.current += 1;
|
|
96885
|
+
const attempt = llmApiErrorRetriesRef.current;
|
|
96886
|
+
const retryAfterMs = preStreamError instanceof APIError2 ? parseRetryAfterHeaderMs(preStreamError.headers?.get("retry-after")) : null;
|
|
96887
|
+
const delayMs = retryAfterMs ?? 1000 * 2 ** (attempt - 1);
|
|
96888
|
+
const statusId = uid4("status");
|
|
96889
|
+
buffersRef.current.byId.set(statusId, {
|
|
96890
|
+
kind: "status",
|
|
96891
|
+
id: statusId,
|
|
96892
|
+
lines: [getRetryStatusMessage(errorDetail)]
|
|
96893
|
+
});
|
|
96894
|
+
buffersRef.current.order.push(statusId);
|
|
96895
|
+
refreshDerived();
|
|
96896
|
+
let cancelled = false;
|
|
96897
|
+
const startTime = Date.now();
|
|
96898
|
+
while (Date.now() - startTime < delayMs) {
|
|
96899
|
+
if (abortControllerRef.current?.signal.aborted || userCancelledRef.current) {
|
|
96900
|
+
cancelled = true;
|
|
96901
|
+
break;
|
|
96902
|
+
}
|
|
96903
|
+
await new Promise((resolve23) => setTimeout(resolve23, 100));
|
|
96904
|
+
}
|
|
96905
|
+
buffersRef.current.byId.delete(statusId);
|
|
96906
|
+
buffersRef.current.order = buffersRef.current.order.filter((id) => id !== statusId);
|
|
96907
|
+
refreshDerived();
|
|
96908
|
+
if (!cancelled) {
|
|
96909
|
+
buffersRef.current.interrupted = false;
|
|
96910
|
+
conversationBusyRetriesRef.current = 0;
|
|
96911
|
+
continue;
|
|
96912
|
+
}
|
|
96913
|
+
}
|
|
96456
96914
|
conversationBusyRetriesRef.current = 0;
|
|
96457
96915
|
const hasApprovalInPayload2 = currentInput.some((item) => item?.type === "approval");
|
|
96458
96916
|
if (hasApprovalInPayload2) {
|
|
@@ -97317,6 +97775,7 @@ ${feedback}
|
|
|
97317
97775
|
pendingInterruptRecoveryConversationIdRef.current = conversationIdRef.current;
|
|
97318
97776
|
userCancelledRef.current = true;
|
|
97319
97777
|
setStreaming(false);
|
|
97778
|
+
resetTrajectoryBases();
|
|
97320
97779
|
setIsExecutingTool(false);
|
|
97321
97780
|
toolResultsInFlightRef.current = false;
|
|
97322
97781
|
refreshDerived();
|
|
@@ -97351,6 +97810,7 @@ ${feedback}
|
|
|
97351
97810
|
conversationGenerationRef.current += 1;
|
|
97352
97811
|
processingConversationRef.current = 0;
|
|
97353
97812
|
setStreaming(false);
|
|
97813
|
+
resetTrajectoryBases();
|
|
97354
97814
|
toolResultsInFlightRef.current = false;
|
|
97355
97815
|
if (!toolsCancelled) {
|
|
97356
97816
|
appendError(INTERRUPT_MESSAGE, true);
|
|
@@ -97430,7 +97890,8 @@ ${feedback}
|
|
|
97430
97890
|
pendingApprovals,
|
|
97431
97891
|
autoHandledResults,
|
|
97432
97892
|
autoDeniedApprovals,
|
|
97433
|
-
queueApprovalResults
|
|
97893
|
+
queueApprovalResults,
|
|
97894
|
+
resetTrajectoryBases
|
|
97434
97895
|
]);
|
|
97435
97896
|
const processConversationRef = import_react94.useRef(processConversation);
|
|
97436
97897
|
import_react94.useEffect(() => {
|
|
@@ -97867,6 +98328,14 @@ ${SYSTEM_REMINDER_CLOSE}` : "";
|
|
|
97867
98328
|
debugLog("queue", `Bumping dequeueEpoch: userCancelledRef was reset, ${messageQueue.length} message(s) queued, agent not busy`);
|
|
97868
98329
|
setDequeueEpoch((e) => e + 1);
|
|
97869
98330
|
}
|
|
98331
|
+
const isSlashCommand = userTextForInput.startsWith("/");
|
|
98332
|
+
if (isAgentBusy() && isSlashCommand) {
|
|
98333
|
+
const attemptedCommand = userTextForInput.split(/\s+/)[0] || "/";
|
|
98334
|
+
const disabledMessage = `'${attemptedCommand}' is disabled while the agent is running.`;
|
|
98335
|
+
const cmd = commandRunner.start(userTextForInput, disabledMessage);
|
|
98336
|
+
cmd.fail(disabledMessage);
|
|
98337
|
+
return { submitted: true };
|
|
98338
|
+
}
|
|
97870
98339
|
const shouldBypassQueue = isInteractiveCommand(userTextForInput) || isNonStateCommand(userTextForInput);
|
|
97871
98340
|
if (isAgentBusy() && !shouldBypassQueue) {
|
|
97872
98341
|
setMessageQueue((prev) => {
|
|
@@ -99131,9 +99600,13 @@ ${recentCommits}
|
|
|
99131
99600
|
## Memory Filesystem Location
|
|
99132
99601
|
|
|
99133
99602
|
Your memory blocks are synchronized with the filesystem at:
|
|
99134
|
-
|
|
99603
|
+
\`${getMemoryFilesystemRoot(agentId)}\`
|
|
99135
99604
|
|
|
99136
|
-
|
|
99605
|
+
Environment variables available in Letta Code:
|
|
99606
|
+
- \`AGENT_ID=${agentId}\`
|
|
99607
|
+
- \`MEMORY_DIR=${getMemoryFilesystemRoot(agentId)}\`
|
|
99608
|
+
|
|
99609
|
+
Use \`$MEMORY_DIR\` when working with memory files during initialization.
|
|
99137
99610
|
` : "";
|
|
99138
99611
|
const initMessage = `${SYSTEM_REMINDER_OPEN}
|
|
99139
99612
|
The user has requested memory initialization via /init.
|
|
@@ -99353,25 +99826,30 @@ ${SYSTEM_REMINDER_CLOSE}
|
|
|
99353
99826
|
};
|
|
99354
99827
|
pushReminder(sessionContextReminder);
|
|
99355
99828
|
{
|
|
99356
|
-
|
|
99357
|
-
|
|
99358
|
-
|
|
99359
|
-
|
|
99360
|
-
|
|
99361
|
-
|
|
99362
|
-
|
|
99363
|
-
|
|
99364
|
-
|
|
99365
|
-
|
|
99366
|
-
|
|
99367
|
-
|
|
99829
|
+
const {
|
|
99830
|
+
discoverSkills: discover,
|
|
99831
|
+
SKILLS_DIR: defaultDir,
|
|
99832
|
+
formatSkillsAsSystemReminder: formatSkillsAsSystemReminder3
|
|
99833
|
+
} = await Promise.resolve().then(() => (init_skills(), exports_skills));
|
|
99834
|
+
const { getSkillsDirectory: getSkillsDirectory2, getNoSkills: getNoSkills2 } = await Promise.resolve().then(() => (init_context(), exports_context));
|
|
99835
|
+
const previousSkillsReminder = discoveredSkillsRef.current ? formatSkillsAsSystemReminder3(discoveredSkillsRef.current) : null;
|
|
99836
|
+
let latestSkills = discoveredSkillsRef.current ?? [];
|
|
99837
|
+
try {
|
|
99838
|
+
const skillsDir = getSkillsDirectory2() || join30(process.cwd(), defaultDir);
|
|
99839
|
+
const { skills } = await discover(skillsDir, agentId, {
|
|
99840
|
+
skipBundled: getNoSkills2()
|
|
99841
|
+
});
|
|
99842
|
+
latestSkills = skills;
|
|
99843
|
+
} catch {}
|
|
99844
|
+
discoveredSkillsRef.current = latestSkills;
|
|
99845
|
+
const latestSkillsReminder = formatSkillsAsSystemReminder3(discoveredSkillsRef.current);
|
|
99846
|
+
if (previousSkillsReminder !== null && previousSkillsReminder !== latestSkillsReminder) {
|
|
99847
|
+
contextTrackerRef.current.pendingSkillsReinject = true;
|
|
99368
99848
|
}
|
|
99369
99849
|
const needsSkillsReinject = contextTrackerRef.current.pendingSkillsReinject;
|
|
99370
99850
|
if (!hasInjectedSkillsRef.current || needsSkillsReinject) {
|
|
99371
|
-
|
|
99372
|
-
|
|
99373
|
-
if (skillsReminder) {
|
|
99374
|
-
pushReminder(skillsReminder);
|
|
99851
|
+
if (latestSkillsReminder) {
|
|
99852
|
+
pushReminder(latestSkillsReminder);
|
|
99375
99853
|
}
|
|
99376
99854
|
hasInjectedSkillsRef.current = true;
|
|
99377
99855
|
contextTrackerRef.current.pendingSkillsReinject = false;
|
|
@@ -100349,8 +100827,8 @@ ${guidance}`);
|
|
|
100349
100827
|
output: `Switching system prompt to ${prompt.label}...`,
|
|
100350
100828
|
phase: "running"
|
|
100351
100829
|
});
|
|
100352
|
-
const {
|
|
100353
|
-
const result = await
|
|
100830
|
+
const { updateAgentSystemPrompt: updateAgentSystemPrompt2 } = await init_modify().then(() => exports_modify);
|
|
100831
|
+
const result = await updateAgentSystemPrompt2(agentId, promptId);
|
|
100354
100832
|
if (result.success) {
|
|
100355
100833
|
setCurrentSystemPromptId(promptId);
|
|
100356
100834
|
cmd.finish(`Switched system prompt to ${prompt.label}`, true);
|
|
@@ -102747,8 +103225,7 @@ async function createAgent2(nameOrOptions = DEFAULT_AGENT_NAME, model, embedding
|
|
|
102747
103225
|
} else {
|
|
102748
103226
|
systemPromptContent = await resolveSystemPrompt(options.systemPromptPreset);
|
|
102749
103227
|
}
|
|
102750
|
-
systemPromptContent =
|
|
102751
|
-
${SYSTEM_PROMPT_MEMORY_ADDON}`;
|
|
103228
|
+
systemPromptContent = reconcileMemoryPrompt(systemPromptContent, options.memoryPromptMode ?? "standard");
|
|
102752
103229
|
if (options.systemPromptAppend) {
|
|
102753
103230
|
systemPromptContent = `${systemPromptContent}
|
|
102754
103231
|
|
|
@@ -102818,6 +103295,7 @@ ${options.systemPromptAppend}`;
|
|
|
102818
103295
|
var init_create3 = __esm(async () => {
|
|
102819
103296
|
init_constants();
|
|
102820
103297
|
init_memory();
|
|
103298
|
+
init_memoryPrompt();
|
|
102821
103299
|
init_model();
|
|
102822
103300
|
init_promptAssets();
|
|
102823
103301
|
await __promiseAll([
|
|
@@ -103117,10 +103595,16 @@ async function updateAgentSystemPromptRaw2(agentId, systemPromptContent) {
|
|
|
103117
103595
|
}
|
|
103118
103596
|
async function updateAgentSystemPrompt2(agentId, systemPromptId) {
|
|
103119
103597
|
try {
|
|
103120
|
-
const { resolveSystemPrompt: resolveSystemPrompt3
|
|
103598
|
+
const { resolveSystemPrompt: resolveSystemPrompt3 } = await Promise.resolve().then(() => (init_promptAssets(), exports_promptAssets));
|
|
103599
|
+
const { detectMemoryPromptDrift: detectMemoryPromptDrift2, reconcileMemoryPrompt: reconcileMemoryPrompt2 } = await Promise.resolve().then(() => (init_memoryPrompt(), exports_memoryPrompt));
|
|
103600
|
+
const { settingsManager: settingsManager3 } = await init_settings_manager().then(() => exports_settings_manager);
|
|
103601
|
+
const client = await getClient2();
|
|
103602
|
+
const currentAgent = await client.agents.retrieve(agentId);
|
|
103121
103603
|
const baseContent = await resolveSystemPrompt3(systemPromptId);
|
|
103122
|
-
const
|
|
103123
|
-
|
|
103604
|
+
const settingIndicatesMemfs = settingsManager3.isMemfsEnabled(agentId);
|
|
103605
|
+
const promptIndicatesMemfs = detectMemoryPromptDrift2(currentAgent.system || "", "standard").some((drift) => drift.code === "memfs_language_with_standard_mode");
|
|
103606
|
+
const memoryMode = settingIndicatesMemfs || promptIndicatesMemfs ? "memfs" : "standard";
|
|
103607
|
+
const systemPromptContent = reconcileMemoryPrompt2(baseContent, memoryMode);
|
|
103124
103608
|
const updateResult = await updateAgentSystemPromptRaw2(agentId, systemPromptContent);
|
|
103125
103609
|
if (!updateResult.success) {
|
|
103126
103610
|
return {
|
|
@@ -103129,7 +103613,6 @@ ${SYSTEM_PROMPT_MEMORY_ADDON3}`;
|
|
|
103129
103613
|
agent: null
|
|
103130
103614
|
};
|
|
103131
103615
|
}
|
|
103132
|
-
const client = await getClient2();
|
|
103133
103616
|
const agent = await client.agents.retrieve(agentId);
|
|
103134
103617
|
return {
|
|
103135
103618
|
success: true,
|
|
@@ -103148,15 +103631,10 @@ async function updateAgentSystemPromptMemfs2(agentId, enableMemfs) {
|
|
|
103148
103631
|
try {
|
|
103149
103632
|
const client = await getClient2();
|
|
103150
103633
|
const agent = await client.agents.retrieve(agentId);
|
|
103151
|
-
|
|
103152
|
-
const
|
|
103153
|
-
const memoryHeaderRegex = /\n#{1,2} Memory\b[\s\S]*?(?=\n#{1,2} (?!Memory|Filesystem|Structure|How It Works|Syncing|History)[^\n]|$)/;
|
|
103154
|
-
currentSystemPrompt = currentSystemPrompt.replace(memoryHeaderRegex, "");
|
|
103155
|
-
const addon = enableMemfs ? SYSTEM_PROMPT_MEMFS_ADDON3 : SYSTEM_PROMPT_MEMORY_ADDON3;
|
|
103156
|
-
currentSystemPrompt = `${currentSystemPrompt}
|
|
103157
|
-
${addon}`;
|
|
103634
|
+
const { reconcileMemoryPrompt: reconcileMemoryPrompt2 } = await Promise.resolve().then(() => (init_memoryPrompt(), exports_memoryPrompt));
|
|
103635
|
+
const nextSystemPrompt = reconcileMemoryPrompt2(agent.system || "", enableMemfs ? "memfs" : "standard");
|
|
103158
103636
|
await client.agents.update(agentId, {
|
|
103159
|
-
system:
|
|
103637
|
+
system: nextSystemPrompt
|
|
103160
103638
|
});
|
|
103161
103639
|
return {
|
|
103162
103640
|
success: true,
|
|
@@ -103275,19 +103753,22 @@ async function applyMemfsFlags2(agentId, memfsFlag, noMemfsFlag, options) {
|
|
|
103275
103753
|
if (!serverUrl.includes("api.letta.com")) {
|
|
103276
103754
|
throw new Error("--memfs is only available on Letta Cloud (api.letta.com).");
|
|
103277
103755
|
}
|
|
103278
|
-
settingsManager3.setMemfsEnabled(agentId, true);
|
|
103279
|
-
} else if (noMemfsFlag) {
|
|
103280
|
-
settingsManager3.setMemfsEnabled(agentId, false);
|
|
103281
103756
|
}
|
|
103282
|
-
const
|
|
103757
|
+
const hasExplicitToggle = Boolean(memfsFlag || noMemfsFlag);
|
|
103758
|
+
const targetEnabled = memfsFlag ? true : noMemfsFlag ? false : settingsManager3.isMemfsEnabled(agentId);
|
|
103759
|
+
if (hasExplicitToggle) {
|
|
103760
|
+
const { updateAgentSystemPromptMemfs: updateAgentSystemPromptMemfs3 } = await init_modify().then(() => exports_modify);
|
|
103761
|
+
const promptUpdate = await updateAgentSystemPromptMemfs3(agentId, targetEnabled);
|
|
103762
|
+
if (!promptUpdate.success) {
|
|
103763
|
+
throw new Error(promptUpdate.message);
|
|
103764
|
+
}
|
|
103765
|
+
settingsManager3.setMemfsEnabled(agentId, targetEnabled);
|
|
103766
|
+
}
|
|
103767
|
+
const isEnabled = hasExplicitToggle ? targetEnabled : settingsManager3.isMemfsEnabled(agentId);
|
|
103283
103768
|
if (isEnabled && memfsFlag) {
|
|
103284
103769
|
const { detachMemoryTools: detachMemoryTools2 } = await init_toolset().then(() => exports_toolset);
|
|
103285
103770
|
await detachMemoryTools2(agentId);
|
|
103286
103771
|
}
|
|
103287
|
-
if (memfsFlag || noMemfsFlag) {
|
|
103288
|
-
const { updateAgentSystemPromptMemfs: updateAgentSystemPromptMemfs3 } = await init_modify().then(() => exports_modify);
|
|
103289
|
-
await updateAgentSystemPromptMemfs3(agentId, isEnabled);
|
|
103290
|
-
}
|
|
103291
103772
|
let pullSummary;
|
|
103292
103773
|
if (isEnabled) {
|
|
103293
103774
|
const { addGitMemoryTag: addGitMemoryTag2, isGitRepo: isGitRepo2, cloneMemoryRepo: cloneMemoryRepo2, pullMemory: pullMemory2 } = await init_memoryGit().then(() => exports_memoryGit);
|
|
@@ -106382,6 +106863,18 @@ if (!globalThis.__lettaSettingsManager) {
|
|
|
106382
106863
|
}
|
|
106383
106864
|
var settingsManager2 = globalThis.__lettaSettingsManager;
|
|
106384
106865
|
|
|
106866
|
+
// src/startup-auto-update.ts
|
|
106867
|
+
function startStartupAutoUpdateCheck(checkAndAutoUpdate, logError = console.error) {
|
|
106868
|
+
checkAndAutoUpdate().then((result) => {
|
|
106869
|
+
if (result?.enotemptyFailed) {
|
|
106870
|
+
logError(`
|
|
106871
|
+
Auto-update failed due to filesystem issue (ENOTEMPTY).`);
|
|
106872
|
+
logError(`Fix: rm -rf $(npm prefix -g)/lib/node_modules/@letta-ai/letta-code && npm i -g @letta-ai/letta-code
|
|
106873
|
+
`);
|
|
106874
|
+
}
|
|
106875
|
+
}).catch(() => {});
|
|
106876
|
+
}
|
|
106877
|
+
|
|
106385
106878
|
// src/telemetry/index.ts
|
|
106386
106879
|
init_http_headers();
|
|
106387
106880
|
await init_settings_manager();
|
|
@@ -107095,14 +107588,7 @@ async function main() {
|
|
|
107095
107588
|
}
|
|
107096
107589
|
telemetry.init();
|
|
107097
107590
|
const { checkAndAutoUpdate: checkAndAutoUpdate2 } = await Promise.resolve().then(() => (init_auto_update(), exports_auto_update));
|
|
107098
|
-
checkAndAutoUpdate2
|
|
107099
|
-
if (result?.enotemptyFailed) {
|
|
107100
|
-
console.error(`
|
|
107101
|
-
Auto-update failed due to filesystem issue (ENOTEMPTY).`);
|
|
107102
|
-
console.error(`Fix: rm -rf $(npm prefix -g)/lib/node_modules/@letta-ai/letta-code && npm i -g @letta-ai/letta-code
|
|
107103
|
-
`);
|
|
107104
|
-
}
|
|
107105
|
-
}).catch(() => {});
|
|
107591
|
+
startStartupAutoUpdateCheck(checkAndAutoUpdate2);
|
|
107106
107592
|
const { cleanupOldOverflowFiles: cleanupOldOverflowFiles2 } = await Promise.resolve().then(() => (init_overflow2(), exports_overflow));
|
|
107107
107593
|
Promise.resolve().then(() => {
|
|
107108
107594
|
try {
|
|
@@ -107178,6 +107664,10 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
|
|
|
107178
107664
|
const command = positionals[2];
|
|
107179
107665
|
if (values.help) {
|
|
107180
107666
|
printHelp();
|
|
107667
|
+
const helpDelayMs = Number.parseInt(process.env.LETTA_TEST_HELP_EXIT_DELAY_MS ?? "", 10);
|
|
107668
|
+
if (Number.isFinite(helpDelayMs) && helpDelayMs > 0) {
|
|
107669
|
+
await new Promise((resolve24) => setTimeout(resolve24, helpDelayMs));
|
|
107670
|
+
}
|
|
107181
107671
|
process.exit(0);
|
|
107182
107672
|
}
|
|
107183
107673
|
if (values.version) {
|
|
@@ -107234,6 +107724,8 @@ Note: Flags should use double dashes for full names (e.g., --yolo, not -yolo)`);
|
|
|
107234
107724
|
const skillsDirectory = values.skills ?? undefined;
|
|
107235
107725
|
const memfsFlag = values.memfs;
|
|
107236
107726
|
const noMemfsFlag = values["no-memfs"];
|
|
107727
|
+
const requestedMemoryPromptMode = memfsFlag ? "memfs" : noMemfsFlag ? "standard" : undefined;
|
|
107728
|
+
const shouldAutoEnableMemfsForNewAgent = !memfsFlag && !noMemfsFlag;
|
|
107237
107729
|
const noSkillsFlag = values["no-skills"];
|
|
107238
107730
|
const fromAfFile = values.import ?? values["from-af"];
|
|
107239
107731
|
const isHeadless = values.prompt || values.run || !process.stdin.isTTY;
|
|
@@ -107927,13 +108419,16 @@ Error: ${message}`);
|
|
|
107927
108419
|
skillsDirectory: skillsDirectory2,
|
|
107928
108420
|
parallelToolCalls: true,
|
|
107929
108421
|
systemPromptPreset: systemPromptPreset2,
|
|
108422
|
+
memoryPromptMode: requestedMemoryPromptMode,
|
|
107930
108423
|
initBlocks: initBlocks2,
|
|
107931
108424
|
baseTools: baseTools2
|
|
107932
108425
|
});
|
|
107933
108426
|
agent = result.agent;
|
|
107934
108427
|
setAgentProvenance(result.provenance);
|
|
107935
|
-
|
|
107936
|
-
|
|
108428
|
+
if (shouldAutoEnableMemfsForNewAgent) {
|
|
108429
|
+
const { enableMemfsIfCloud: enableMemfsIfCloud3 } = await Promise.resolve().then(() => (init_memoryFilesystem2(), exports_memoryFilesystem2));
|
|
108430
|
+
await enableMemfsIfCloud3(agent.id);
|
|
108431
|
+
}
|
|
107937
108432
|
}
|
|
107938
108433
|
if (!agent && resumingAgentId) {
|
|
107939
108434
|
try {
|
|
@@ -108237,4 +108732,4 @@ Error during initialization: ${message}`);
|
|
|
108237
108732
|
}
|
|
108238
108733
|
main();
|
|
108239
108734
|
|
|
108240
|
-
//# debugId=
|
|
108735
|
+
//# debugId=28BAE9B7158D2B3E64756E2164756E21
|