@letta-ai/letta-code 0.27.2 → 0.27.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
CHANGED
|
@@ -3694,6 +3694,7 @@ class SettingsManager {
|
|
|
3694
3694
|
if (this.initialized)
|
|
3695
3695
|
return;
|
|
3696
3696
|
const settingsPath = this.getSettingsPath();
|
|
3697
|
+
let shouldRollbackAutoConversationTitles = false;
|
|
3697
3698
|
try {
|
|
3698
3699
|
if (!exists(settingsPath)) {
|
|
3699
3700
|
this.settings = { ...DEFAULT_SETTINGS };
|
|
@@ -3709,6 +3710,12 @@ class SettingsManager {
|
|
|
3709
3710
|
delete loadedSettingsRaw.reflectionBehavior;
|
|
3710
3711
|
this.markDirty("reflectionBehavior");
|
|
3711
3712
|
}
|
|
3713
|
+
shouldRollbackAutoConversationTitles = loadedSettingsRaw.autoConversationTitlesRollbackApplied !== true;
|
|
3714
|
+
if (shouldRollbackAutoConversationTitles) {
|
|
3715
|
+
loadedSettingsRaw.autoConversationTitles = false;
|
|
3716
|
+
loadedSettingsRaw.autoConversationTitlesRollbackApplied = true;
|
|
3717
|
+
this.markDirty("autoConversationTitles", "autoConversationTitlesRollbackApplied");
|
|
3718
|
+
}
|
|
3712
3719
|
this.settings = {
|
|
3713
3720
|
...DEFAULT_SETTINGS,
|
|
3714
3721
|
...loadedSettingsRaw
|
|
@@ -3718,6 +3725,11 @@ class SettingsManager {
|
|
|
3718
3725
|
}
|
|
3719
3726
|
}
|
|
3720
3727
|
this.initialized = true;
|
|
3728
|
+
if (shouldRollbackAutoConversationTitles) {
|
|
3729
|
+
try {
|
|
3730
|
+
await this.persistSettings();
|
|
3731
|
+
} catch {}
|
|
3732
|
+
}
|
|
3721
3733
|
await this.checkSecretsSupport();
|
|
3722
3734
|
if (!isSubagentProcess()) {
|
|
3723
3735
|
await this.migrateTokensToSecrets();
|
|
@@ -4787,7 +4799,9 @@ class SettingsManager {
|
|
|
4787
4799
|
pinned: updates.pinned !== undefined ? updates.pinned : existing.pinned,
|
|
4788
4800
|
memfs: updates.memfs !== undefined ? updates.memfs : existing.memfs,
|
|
4789
4801
|
toolset: updates.toolset !== undefined ? updates.toolset : existing.toolset,
|
|
4790
|
-
systemPromptPreset: updates.systemPromptPreset !== undefined ? updates.systemPromptPreset : existing.systemPromptPreset
|
|
4802
|
+
systemPromptPreset: updates.systemPromptPreset !== undefined ? updates.systemPromptPreset : existing.systemPromptPreset,
|
|
4803
|
+
systemPromptHash: updates.systemPromptHash !== undefined ? updates.systemPromptHash ?? undefined : existing.systemPromptHash,
|
|
4804
|
+
systemPromptVersion: updates.systemPromptVersion !== undefined ? updates.systemPromptVersion ?? undefined : existing.systemPromptVersion
|
|
4791
4805
|
};
|
|
4792
4806
|
if (!updated.pinned)
|
|
4793
4807
|
delete updated.pinned;
|
|
@@ -4797,6 +4811,10 @@ class SettingsManager {
|
|
|
4797
4811
|
delete updated.toolset;
|
|
4798
4812
|
if (!updated.systemPromptPreset)
|
|
4799
4813
|
delete updated.systemPromptPreset;
|
|
4814
|
+
if (!updated.systemPromptHash)
|
|
4815
|
+
delete updated.systemPromptHash;
|
|
4816
|
+
if (!updated.systemPromptVersion)
|
|
4817
|
+
delete updated.systemPromptVersion;
|
|
4800
4818
|
if (!updated.baseUrl)
|
|
4801
4819
|
delete updated.baseUrl;
|
|
4802
4820
|
agents[idx] = updated;
|
|
@@ -4804,7 +4822,9 @@ class SettingsManager {
|
|
|
4804
4822
|
const newAgent = {
|
|
4805
4823
|
agentId,
|
|
4806
4824
|
baseUrl: normalizedBaseUrl,
|
|
4807
|
-
...updates
|
|
4825
|
+
...updates,
|
|
4826
|
+
systemPromptHash: updates.systemPromptHash ?? undefined,
|
|
4827
|
+
systemPromptVersion: updates.systemPromptVersion ?? undefined
|
|
4808
4828
|
};
|
|
4809
4829
|
if (!newAgent.pinned)
|
|
4810
4830
|
delete newAgent.pinned;
|
|
@@ -4814,6 +4834,10 @@ class SettingsManager {
|
|
|
4814
4834
|
delete newAgent.toolset;
|
|
4815
4835
|
if (!newAgent.systemPromptPreset)
|
|
4816
4836
|
delete newAgent.systemPromptPreset;
|
|
4837
|
+
if (!newAgent.systemPromptHash)
|
|
4838
|
+
delete newAgent.systemPromptHash;
|
|
4839
|
+
if (!newAgent.systemPromptVersion)
|
|
4840
|
+
delete newAgent.systemPromptVersion;
|
|
4817
4841
|
if (!newAgent.baseUrl)
|
|
4818
4842
|
delete newAgent.baseUrl;
|
|
4819
4843
|
agents.push(newAgent);
|
|
@@ -4839,11 +4863,39 @@ class SettingsManager {
|
|
|
4839
4863
|
getSystemPromptPreset(agentId) {
|
|
4840
4864
|
return this.getAgentSettings(agentId)?.systemPromptPreset;
|
|
4841
4865
|
}
|
|
4866
|
+
getSystemPromptHash(agentId) {
|
|
4867
|
+
return this.getAgentSettings(agentId)?.systemPromptHash;
|
|
4868
|
+
}
|
|
4869
|
+
getSystemPromptVersion(agentId) {
|
|
4870
|
+
return this.getAgentSettings(agentId)?.systemPromptVersion;
|
|
4871
|
+
}
|
|
4842
4872
|
setSystemPromptPreset(agentId, preset) {
|
|
4843
|
-
this.upsertAgentSettings(agentId, {
|
|
4873
|
+
this.upsertAgentSettings(agentId, {
|
|
4874
|
+
systemPromptPreset: preset,
|
|
4875
|
+
systemPromptHash: null,
|
|
4876
|
+
systemPromptVersion: null
|
|
4877
|
+
});
|
|
4878
|
+
}
|
|
4879
|
+
setManagedSystemPrompt(agentId, prompt) {
|
|
4880
|
+
this.upsertAgentSettings(agentId, {
|
|
4881
|
+
systemPromptPreset: prompt.preset,
|
|
4882
|
+
systemPromptHash: prompt.hash,
|
|
4883
|
+
systemPromptVersion: prompt.version
|
|
4884
|
+
});
|
|
4885
|
+
}
|
|
4886
|
+
setSystemPromptCustom(agentId) {
|
|
4887
|
+
this.upsertAgentSettings(agentId, {
|
|
4888
|
+
systemPromptPreset: "custom",
|
|
4889
|
+
systemPromptHash: null,
|
|
4890
|
+
systemPromptVersion: null
|
|
4891
|
+
});
|
|
4844
4892
|
}
|
|
4845
4893
|
clearSystemPromptPreset(agentId) {
|
|
4846
|
-
this.upsertAgentSettings(agentId, {
|
|
4894
|
+
this.upsertAgentSettings(agentId, {
|
|
4895
|
+
systemPromptPreset: "",
|
|
4896
|
+
systemPromptHash: null,
|
|
4897
|
+
systemPromptVersion: null
|
|
4898
|
+
});
|
|
4847
4899
|
}
|
|
4848
4900
|
hasLocalLettaDir(workingDirectory = process.cwd()) {
|
|
4849
4901
|
const dirPath = join3(workingDirectory, ".letta");
|
|
@@ -5001,7 +5053,8 @@ var init_settings_manager = __esm(() => {
|
|
|
5001
5053
|
enableSleeptime: false,
|
|
5002
5054
|
conversationSwitchAlertEnabled: false,
|
|
5003
5055
|
sessionContextEnabled: true,
|
|
5004
|
-
autoConversationTitles:
|
|
5056
|
+
autoConversationTitles: false,
|
|
5057
|
+
autoConversationTitlesRollbackApplied: true,
|
|
5005
5058
|
autoSwapOnQuotaLimit: true,
|
|
5006
5059
|
includeWorktreeTool: true,
|
|
5007
5060
|
recentModels: [],
|
|
@@ -5024,7 +5077,7 @@ var package_default;
|
|
|
5024
5077
|
var init_package = __esm(() => {
|
|
5025
5078
|
package_default = {
|
|
5026
5079
|
name: "@letta-ai/letta-code",
|
|
5027
|
-
version: "0.27.
|
|
5080
|
+
version: "0.27.3",
|
|
5028
5081
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
5029
5082
|
type: "module",
|
|
5030
5083
|
packageManager: "bun@1.3.0",
|
|
@@ -5249,10 +5302,10 @@ var init_constants = __esm(() => {
|
|
|
5249
5302
|
function getConversationTitleSettings() {
|
|
5250
5303
|
try {
|
|
5251
5304
|
return {
|
|
5252
|
-
enabled: settingsManager.getSettings().autoConversationTitles
|
|
5305
|
+
enabled: settingsManager.getSettings().autoConversationTitles === true
|
|
5253
5306
|
};
|
|
5254
5307
|
} catch {
|
|
5255
|
-
return { enabled:
|
|
5308
|
+
return { enabled: false };
|
|
5256
5309
|
}
|
|
5257
5310
|
}
|
|
5258
5311
|
function setConversationTitleSettings(enabled) {
|
|
@@ -143845,6 +143898,177 @@ var init_prompt_assets = __esm(() => {
|
|
|
143845
143898
|
];
|
|
143846
143899
|
});
|
|
143847
143900
|
|
|
143901
|
+
// src/agent/system-prompt-versioning.ts
|
|
143902
|
+
var exports_system_prompt_versioning = {};
|
|
143903
|
+
__export(exports_system_prompt_versioning, {
|
|
143904
|
+
scheduleManagedSystemPromptUpdate: () => scheduleManagedSystemPromptUpdate,
|
|
143905
|
+
recordManagedSystemPrompt: () => recordManagedSystemPrompt,
|
|
143906
|
+
hashSystemPrompt: () => hashSystemPrompt,
|
|
143907
|
+
getMemoryPromptModeForAgent: () => getMemoryPromptModeForAgent,
|
|
143908
|
+
decideManagedSystemPromptUpdate: () => decideManagedSystemPromptUpdate
|
|
143909
|
+
});
|
|
143910
|
+
import { createHash } from "node:crypto";
|
|
143911
|
+
function hashSystemPrompt(content) {
|
|
143912
|
+
const digest = createHash("sha256").update(content).digest("base64url");
|
|
143913
|
+
return `${SYSTEM_PROMPT_HASH_PREFIX}${digest}`;
|
|
143914
|
+
}
|
|
143915
|
+
function managedPrompt(preset, memoryMode, content = buildSystemPrompt(preset, memoryMode)) {
|
|
143916
|
+
return {
|
|
143917
|
+
preset,
|
|
143918
|
+
hash: hashSystemPrompt(content),
|
|
143919
|
+
version: getVersion()
|
|
143920
|
+
};
|
|
143921
|
+
}
|
|
143922
|
+
function recordManagedSystemPrompt(agentId, preset, memoryMode, content) {
|
|
143923
|
+
if (!settingsManager.isReady) {
|
|
143924
|
+
return;
|
|
143925
|
+
}
|
|
143926
|
+
settingsManager.setManagedSystemPrompt(agentId, managedPrompt(preset, memoryMode, content));
|
|
143927
|
+
}
|
|
143928
|
+
function getMemoryPromptModeForAgent(agentId) {
|
|
143929
|
+
const backend = getBackend();
|
|
143930
|
+
if (backend.capabilities.localMemfs) {
|
|
143931
|
+
return "local-memfs";
|
|
143932
|
+
}
|
|
143933
|
+
return settingsManager.isReady && settingsManager.isMemfsEnabled(agentId) ? "memfs" : "standard";
|
|
143934
|
+
}
|
|
143935
|
+
function isLettaCodePrimaryAgent(agent2) {
|
|
143936
|
+
const tags = agent2.tags ?? [];
|
|
143937
|
+
return tags.includes("origin:letta-code") && !tags.includes("role:subagent");
|
|
143938
|
+
}
|
|
143939
|
+
function findMatchingCurrentPreset(systemPrompt, memoryMode) {
|
|
143940
|
+
for (const preset of SYSTEM_PROMPTS) {
|
|
143941
|
+
if (buildSystemPrompt(preset.id, memoryMode) === systemPrompt) {
|
|
143942
|
+
return preset.id;
|
|
143943
|
+
}
|
|
143944
|
+
}
|
|
143945
|
+
return;
|
|
143946
|
+
}
|
|
143947
|
+
function isValidHash(hash4) {
|
|
143948
|
+
return !!hash4 && hash4.startsWith(SYSTEM_PROMPT_HASH_PREFIX);
|
|
143949
|
+
}
|
|
143950
|
+
function decideManagedSystemPromptUpdate(input) {
|
|
143951
|
+
const { agent: agent2, memoryMode, storedPreset, storedHash, storedVersion } = input;
|
|
143952
|
+
const currentSystemPrompt = agent2.system ?? "";
|
|
143953
|
+
const currentHash = hashSystemPrompt(currentSystemPrompt);
|
|
143954
|
+
const currentVersion = getVersion();
|
|
143955
|
+
if (storedPreset === "custom") {
|
|
143956
|
+
return { kind: "noop", reason: "system prompt is marked custom" };
|
|
143957
|
+
}
|
|
143958
|
+
if (storedPreset) {
|
|
143959
|
+
if (!isKnownPreset(storedPreset)) {
|
|
143960
|
+
return { kind: "clear", reason: "stored preset is no longer known" };
|
|
143961
|
+
}
|
|
143962
|
+
if (storedHash) {
|
|
143963
|
+
if (!isValidHash(storedHash)) {
|
|
143964
|
+
return { kind: "clear", reason: "stored prompt hash is invalid" };
|
|
143965
|
+
}
|
|
143966
|
+
if (currentHash !== storedHash) {
|
|
143967
|
+
return {
|
|
143968
|
+
kind: "custom",
|
|
143969
|
+
reason: "agent prompt differs from stored managed prompt hash"
|
|
143970
|
+
};
|
|
143971
|
+
}
|
|
143972
|
+
const nextSystemPrompt = buildSystemPrompt(storedPreset, memoryMode);
|
|
143973
|
+
const nextPrompt = managedPrompt(storedPreset, memoryMode, nextSystemPrompt);
|
|
143974
|
+
if (nextPrompt.hash !== storedHash) {
|
|
143975
|
+
return {
|
|
143976
|
+
kind: "update",
|
|
143977
|
+
nextSystemPrompt,
|
|
143978
|
+
prompt: nextPrompt,
|
|
143979
|
+
reason: "managed prompt content changed for current Letta Code version"
|
|
143980
|
+
};
|
|
143981
|
+
}
|
|
143982
|
+
if (storedVersion !== currentVersion) {
|
|
143983
|
+
return { kind: "track", prompt: nextPrompt };
|
|
143984
|
+
}
|
|
143985
|
+
return { kind: "noop", reason: "managed prompt is current" };
|
|
143986
|
+
}
|
|
143987
|
+
const expectedCurrentPrompt = buildSystemPrompt(storedPreset, memoryMode);
|
|
143988
|
+
if (currentSystemPrompt === expectedCurrentPrompt) {
|
|
143989
|
+
return {
|
|
143990
|
+
kind: "track",
|
|
143991
|
+
prompt: managedPrompt(storedPreset, memoryMode, currentSystemPrompt)
|
|
143992
|
+
};
|
|
143993
|
+
}
|
|
143994
|
+
return {
|
|
143995
|
+
kind: "custom",
|
|
143996
|
+
reason: "legacy preset tracking exists but prompt content was modified"
|
|
143997
|
+
};
|
|
143998
|
+
}
|
|
143999
|
+
if (!isLettaCodePrimaryAgent(agent2)) {
|
|
144000
|
+
return { kind: "noop", reason: "agent is not a primary Letta Code agent" };
|
|
144001
|
+
}
|
|
144002
|
+
const matchingPreset = findMatchingCurrentPreset(currentSystemPrompt, memoryMode);
|
|
144003
|
+
if (!matchingPreset) {
|
|
144004
|
+
return {
|
|
144005
|
+
kind: "custom",
|
|
144006
|
+
reason: "legacy Letta Code agent prompt does not match a current preset"
|
|
144007
|
+
};
|
|
144008
|
+
}
|
|
144009
|
+
return {
|
|
144010
|
+
kind: "track",
|
|
144011
|
+
prompt: managedPrompt(matchingPreset, memoryMode, currentSystemPrompt)
|
|
144012
|
+
};
|
|
144013
|
+
}
|
|
144014
|
+
function scheduleManagedSystemPromptUpdate({
|
|
144015
|
+
agent: agent2,
|
|
144016
|
+
memoryMode,
|
|
144017
|
+
onUpdated
|
|
144018
|
+
}) {
|
|
144019
|
+
if (!settingsManager.isReady) {
|
|
144020
|
+
return;
|
|
144021
|
+
}
|
|
144022
|
+
const decision = decideManagedSystemPromptUpdate({
|
|
144023
|
+
agent: agent2,
|
|
144024
|
+
memoryMode,
|
|
144025
|
+
storedPreset: settingsManager.getSystemPromptPreset(agent2.id),
|
|
144026
|
+
storedHash: settingsManager.getSystemPromptHash(agent2.id),
|
|
144027
|
+
storedVersion: settingsManager.getSystemPromptVersion(agent2.id)
|
|
144028
|
+
});
|
|
144029
|
+
if (decision.kind === "noop") {
|
|
144030
|
+
debugLog("startup", `System prompt version check noop: ${decision.reason}`);
|
|
144031
|
+
return;
|
|
144032
|
+
}
|
|
144033
|
+
if (decision.kind === "track") {
|
|
144034
|
+
settingsManager.setManagedSystemPrompt(agent2.id, decision.prompt);
|
|
144035
|
+
debugLog("startup", `Tracking managed system prompt ${decision.prompt.preset}@${decision.prompt.version}`);
|
|
144036
|
+
return;
|
|
144037
|
+
}
|
|
144038
|
+
if (decision.kind === "custom") {
|
|
144039
|
+
settingsManager.setSystemPromptCustom(agent2.id);
|
|
144040
|
+
debugLog("startup", `Marked system prompt custom: ${decision.reason}`);
|
|
144041
|
+
return;
|
|
144042
|
+
}
|
|
144043
|
+
if (decision.kind === "clear") {
|
|
144044
|
+
settingsManager.clearSystemPromptPreset(agent2.id);
|
|
144045
|
+
debugLog("startup", `Cleared system prompt metadata: ${decision.reason}`);
|
|
144046
|
+
return;
|
|
144047
|
+
}
|
|
144048
|
+
getBackend().updateAgent(agent2.id, {
|
|
144049
|
+
system: decision.nextSystemPrompt
|
|
144050
|
+
}).then(async () => {
|
|
144051
|
+
settingsManager.setManagedSystemPrompt(agent2.id, decision.prompt);
|
|
144052
|
+
debugLog("startup", `Updated managed system prompt ${decision.prompt.preset}@${decision.prompt.version}: ${decision.reason}`);
|
|
144053
|
+
if (onUpdated) {
|
|
144054
|
+
const updatedAgent = await getBackend().retrieveAgent(agent2.id, {
|
|
144055
|
+
include: ["agent.secrets", "agent.tools", "agent.tags"]
|
|
144056
|
+
});
|
|
144057
|
+
onUpdated(updatedAgent);
|
|
144058
|
+
}
|
|
144059
|
+
}).catch((error54) => {
|
|
144060
|
+
debugWarn("startup", `Failed to update managed system prompt for ${agent2.id}: ${error54 instanceof Error ? error54.message : String(error54)}`);
|
|
144061
|
+
});
|
|
144062
|
+
}
|
|
144063
|
+
var SYSTEM_PROMPT_HASH_PREFIX = "sha256:";
|
|
144064
|
+
var init_system_prompt_versioning = __esm(() => {
|
|
144065
|
+
init_backend2();
|
|
144066
|
+
init_settings_manager();
|
|
144067
|
+
init_debug();
|
|
144068
|
+
init_version();
|
|
144069
|
+
init_prompt_assets();
|
|
144070
|
+
});
|
|
144071
|
+
|
|
143848
144072
|
// src/agent/modify.ts
|
|
143849
144073
|
var exports_modify = {};
|
|
143850
144074
|
__export(exports_modify, {
|
|
@@ -144070,6 +144294,7 @@ async function updateAgentSystemPromptRaw(agentId, systemPromptContent) {
|
|
|
144070
144294
|
async function updateAgentSystemPrompt(agentId, systemPromptId) {
|
|
144071
144295
|
try {
|
|
144072
144296
|
const { isKnownPreset: isKnownPreset2, resolveAndBuildSystemPrompt: resolveAndBuildSystemPrompt2 } = await Promise.resolve().then(() => (init_prompt_assets(), exports_prompt_assets));
|
|
144297
|
+
const { recordManagedSystemPrompt: recordManagedSystemPrompt2 } = await Promise.resolve().then(() => (init_system_prompt_versioning(), exports_system_prompt_versioning));
|
|
144073
144298
|
const { settingsManager: settingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), exports_settings_manager));
|
|
144074
144299
|
const backend = getBackend();
|
|
144075
144300
|
const memoryMode = backend.capabilities.localMemfs ? "local-memfs" : settingsManager2.isReady && settingsManager2.isMemfsEnabled(agentId) ? "memfs" : "standard";
|
|
@@ -144085,7 +144310,7 @@ async function updateAgentSystemPrompt(agentId, systemPromptId) {
|
|
|
144085
144310
|
}
|
|
144086
144311
|
if (settingsManager2.isReady) {
|
|
144087
144312
|
if (isKnownPreset2(systemPromptId)) {
|
|
144088
|
-
|
|
144313
|
+
recordManagedSystemPrompt2(agentId, systemPromptId, memoryMode, systemPromptContent);
|
|
144089
144314
|
} else {
|
|
144090
144315
|
settingsManager2.clearSystemPromptPreset(agentId);
|
|
144091
144316
|
}
|
|
@@ -144110,10 +144335,33 @@ async function updateAgentSystemPromptMemfs(agentId, enableMemfs) {
|
|
|
144110
144335
|
try {
|
|
144111
144336
|
const { settingsManager: settingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), exports_settings_manager));
|
|
144112
144337
|
const { isKnownPreset: isKnownPreset2, buildSystemPrompt: buildSystemPrompt2 } = await Promise.resolve().then(() => (init_prompt_assets(), exports_prompt_assets));
|
|
144338
|
+
const { hashSystemPrompt: hashSystemPrompt2, recordManagedSystemPrompt: recordManagedSystemPrompt2 } = await Promise.resolve().then(() => (init_system_prompt_versioning(), exports_system_prompt_versioning));
|
|
144113
144339
|
const newMode = enableMemfs ? getBackend().capabilities.localMemfs ? "local-memfs" : "memfs" : "standard";
|
|
144114
144340
|
const storedPreset = settingsManager2.isReady ? settingsManager2.getSystemPromptPreset(agentId) : undefined;
|
|
144341
|
+
const storedHash = settingsManager2.isReady ? settingsManager2.getSystemPromptHash(agentId) : undefined;
|
|
144115
144342
|
let nextSystemPrompt;
|
|
144116
144343
|
if (storedPreset && isKnownPreset2(storedPreset)) {
|
|
144344
|
+
const agent2 = await getBackend().retrieveAgent(agentId);
|
|
144345
|
+
const currentSystemPrompt = agent2.system || "";
|
|
144346
|
+
if (storedHash && hashSystemPrompt2(currentSystemPrompt) !== storedHash) {
|
|
144347
|
+
if (settingsManager2.isReady) {
|
|
144348
|
+
settingsManager2.setSystemPromptCustom(agentId);
|
|
144349
|
+
}
|
|
144350
|
+
return {
|
|
144351
|
+
success: true,
|
|
144352
|
+
message: "Custom system prompt left unchanged for memory mode"
|
|
144353
|
+
};
|
|
144354
|
+
}
|
|
144355
|
+
if (!storedHash && settingsManager2.isReady) {
|
|
144356
|
+
const currentMode = settingsManager2.isMemfsEnabled(agentId) ? getBackend().capabilities.localMemfs ? "local-memfs" : "memfs" : "standard";
|
|
144357
|
+
if (currentSystemPrompt !== buildSystemPrompt2(storedPreset, currentMode)) {
|
|
144358
|
+
settingsManager2.setSystemPromptCustom(agentId);
|
|
144359
|
+
return {
|
|
144360
|
+
success: true,
|
|
144361
|
+
message: "Custom system prompt left unchanged for memory mode"
|
|
144362
|
+
};
|
|
144363
|
+
}
|
|
144364
|
+
}
|
|
144117
144365
|
nextSystemPrompt = buildSystemPrompt2(storedPreset, newMode);
|
|
144118
144366
|
} else {
|
|
144119
144367
|
const agent2 = await getBackend().retrieveAgent(agentId);
|
|
@@ -144122,6 +144370,9 @@ async function updateAgentSystemPromptMemfs(agentId, enableMemfs) {
|
|
|
144122
144370
|
await getBackend().updateAgent(agentId, {
|
|
144123
144371
|
system: nextSystemPrompt
|
|
144124
144372
|
});
|
|
144373
|
+
if (storedPreset && isKnownPreset2(storedPreset)) {
|
|
144374
|
+
recordManagedSystemPrompt2(agentId, storedPreset, newMode, nextSystemPrompt);
|
|
144375
|
+
}
|
|
144125
144376
|
return {
|
|
144126
144377
|
success: true,
|
|
144127
144378
|
message: enableMemfs ? "System prompt updated for memfs memory mode" : "System prompt updated for standard memory mode"
|
|
@@ -161566,6 +161817,8 @@ var init_session2 = __esm(() => {
|
|
|
161566
161817
|
});
|
|
161567
161818
|
|
|
161568
161819
|
// src/tools/impl/shell-launchers.ts
|
|
161820
|
+
import { existsSync as existsSync13 } from "node:fs";
|
|
161821
|
+
import { delimiter, isAbsolute as isAbsolute3, join as join14 } from "node:path";
|
|
161569
161822
|
function isValidEnvAlias(name) {
|
|
161570
161823
|
return /^[A-Za-z_][A-Za-z0-9_]*$/.test(name);
|
|
161571
161824
|
}
|
|
@@ -161662,6 +161915,56 @@ function shellCommandFlag(shellName, login) {
|
|
|
161662
161915
|
}
|
|
161663
161916
|
return "-c";
|
|
161664
161917
|
}
|
|
161918
|
+
function pathEnvValue(env3) {
|
|
161919
|
+
return env3.PATH ?? env3.Path ?? env3.path ?? "";
|
|
161920
|
+
}
|
|
161921
|
+
function pathExtValue(env3) {
|
|
161922
|
+
return env3.PATHEXT ?? env3.PathExt ?? ".COM;.EXE;.BAT;.CMD";
|
|
161923
|
+
}
|
|
161924
|
+
function hasPathSeparator(executable) {
|
|
161925
|
+
return executable.includes("/") || executable.includes("\\");
|
|
161926
|
+
}
|
|
161927
|
+
function hasFileExtension(executable) {
|
|
161928
|
+
const basename11 = executable.split(/[\\/]/).pop() ?? executable;
|
|
161929
|
+
return /\.[^.]+$/.test(basename11);
|
|
161930
|
+
}
|
|
161931
|
+
function resolveExecutablePath(executable, env3) {
|
|
161932
|
+
if (isAbsolute3(executable) || hasPathSeparator(executable)) {
|
|
161933
|
+
return existsSync13(executable) ? executable : null;
|
|
161934
|
+
}
|
|
161935
|
+
const pathDelimiter = process.platform === "win32" ? ";" : delimiter;
|
|
161936
|
+
const pathEntries = pathEnvValue(env3).split(pathDelimiter).filter(Boolean);
|
|
161937
|
+
const executableNames = [executable];
|
|
161938
|
+
if (process.platform === "win32" && !hasFileExtension(executable)) {
|
|
161939
|
+
for (const extension of pathExtValue(env3).split(";").filter(Boolean)) {
|
|
161940
|
+
executableNames.push(`${executable}${extension}`);
|
|
161941
|
+
}
|
|
161942
|
+
}
|
|
161943
|
+
for (const entry of pathEntries) {
|
|
161944
|
+
for (const name of executableNames) {
|
|
161945
|
+
const candidate = join14(entry, name);
|
|
161946
|
+
if (existsSync13(candidate)) {
|
|
161947
|
+
return candidate;
|
|
161948
|
+
}
|
|
161949
|
+
}
|
|
161950
|
+
}
|
|
161951
|
+
return null;
|
|
161952
|
+
}
|
|
161953
|
+
function selectAvailableShellLauncher(launchers, env3 = process.env) {
|
|
161954
|
+
if (process.platform !== "win32") {
|
|
161955
|
+
return launchers[0];
|
|
161956
|
+
}
|
|
161957
|
+
for (const launcher of launchers) {
|
|
161958
|
+
const executable = launcher[0];
|
|
161959
|
+
if (!executable)
|
|
161960
|
+
continue;
|
|
161961
|
+
const resolvedExecutable = resolveExecutablePath(executable, env3);
|
|
161962
|
+
if (resolvedExecutable) {
|
|
161963
|
+
return [resolvedExecutable, ...launcher.slice(1)];
|
|
161964
|
+
}
|
|
161965
|
+
}
|
|
161966
|
+
return launchers.at(-1);
|
|
161967
|
+
}
|
|
161665
161968
|
function unixLaunchers(command, login) {
|
|
161666
161969
|
const trimmed = command.trim();
|
|
161667
161970
|
if (!trimmed)
|
|
@@ -166028,14 +166331,14 @@ function rebuildCachedLauncher(command, secretEnv) {
|
|
|
166028
166331
|
});
|
|
166029
166332
|
return launchers.find((launcher) => launcher[0]?.toLowerCase() === cachedExecutable) ?? null;
|
|
166030
166333
|
}
|
|
166031
|
-
function getBackgroundLauncher(command, secretEnv) {
|
|
166334
|
+
function getBackgroundLauncher(command, env3, secretEnv) {
|
|
166032
166335
|
const cachedLauncher = rebuildCachedLauncher(command, secretEnv);
|
|
166033
166336
|
if (cachedLauncher)
|
|
166034
166337
|
return cachedLauncher;
|
|
166035
166338
|
const launchers = buildShellLaunchers(command, {
|
|
166036
166339
|
powershellEnvAliases: secretEnv ? Object.keys(secretEnv) : undefined
|
|
166037
166340
|
});
|
|
166038
|
-
return launchers
|
|
166341
|
+
return selectAvailableShellLauncher(launchers, env3) || [];
|
|
166039
166342
|
}
|
|
166040
166343
|
async function spawnCommand(command, options3) {
|
|
166041
166344
|
const env3 = options3.secretEnv ? { ...options3.env, ...options3.secretEnv } : options3.env;
|
|
@@ -166153,7 +166456,7 @@ async function bash(args) {
|
|
|
166153
166456
|
const bgCommand = withStrictShellPrelude(command, bgEnv);
|
|
166154
166457
|
const bashId = getNextBashId();
|
|
166155
166458
|
const outputFile = createBackgroundOutputFile(bashId);
|
|
166156
|
-
const launcher = getBackgroundLauncher(bgCommand, secretEnv);
|
|
166459
|
+
const launcher = getBackgroundLauncher(bgCommand, bgEnv, secretEnv);
|
|
166157
166460
|
const [executable, ...launcherArgs] = launcher;
|
|
166158
166461
|
if (!executable) {
|
|
166159
166462
|
return {
|
|
@@ -166570,7 +166873,7 @@ var init_create_goal = __esm(() => {
|
|
|
166570
166873
|
});
|
|
166571
166874
|
|
|
166572
166875
|
// src/websocket/listener/remote-settings.ts
|
|
166573
|
-
import { existsSync as
|
|
166876
|
+
import { existsSync as existsSync15, readFileSync as readFileSync14 } from "node:fs";
|
|
166574
166877
|
import { mkdir as mkdir6, writeFile as writeFile9 } from "node:fs/promises";
|
|
166575
166878
|
import { homedir as homedir11 } from "node:os";
|
|
166576
166879
|
import path10 from "node:path";
|
|
@@ -166584,7 +166887,7 @@ function loadRemoteSettings() {
|
|
|
166584
166887
|
let loaded = {};
|
|
166585
166888
|
try {
|
|
166586
166889
|
const settingsPath = getRemoteSettingsPath();
|
|
166587
|
-
if (
|
|
166890
|
+
if (existsSync15(settingsPath)) {
|
|
166588
166891
|
const raw = readFileSync14(settingsPath, "utf-8");
|
|
166589
166892
|
const parsed = JSON.parse(raw);
|
|
166590
166893
|
loaded = parsed;
|
|
@@ -166593,7 +166896,7 @@ function loadRemoteSettings() {
|
|
|
166593
166896
|
if (loaded.cwdMap) {
|
|
166594
166897
|
const validCwdMap = {};
|
|
166595
166898
|
for (const [key, value] of Object.entries(loaded.cwdMap)) {
|
|
166596
|
-
if (typeof value === "string" &&
|
|
166899
|
+
if (typeof value === "string" && existsSync15(value)) {
|
|
166597
166900
|
validCwdMap[key] = value;
|
|
166598
166901
|
}
|
|
166599
166902
|
}
|
|
@@ -166620,13 +166923,13 @@ function saveRemoteSettings(updates) {
|
|
|
166620
166923
|
function loadLegacyCwdCache() {
|
|
166621
166924
|
try {
|
|
166622
166925
|
const legacyPath = path10.join(homedir11(), ".letta", "cwd-cache.json");
|
|
166623
|
-
if (!
|
|
166926
|
+
if (!existsSync15(legacyPath))
|
|
166624
166927
|
return {};
|
|
166625
166928
|
const raw = readFileSync14(legacyPath, "utf-8");
|
|
166626
166929
|
const parsed = JSON.parse(raw);
|
|
166627
166930
|
const result = {};
|
|
166628
166931
|
for (const [key, value] of Object.entries(parsed)) {
|
|
166629
|
-
if (typeof value === "string" &&
|
|
166932
|
+
if (typeof value === "string" && existsSync15(value)) {
|
|
166630
166933
|
result[key] = value;
|
|
166631
166934
|
}
|
|
166632
166935
|
}
|
|
@@ -167160,8 +167463,8 @@ var init_memory_runtime = __esm(() => {
|
|
|
167160
167463
|
});
|
|
167161
167464
|
|
|
167162
167465
|
// src/utils/system-prompt-size.ts
|
|
167163
|
-
import { existsSync as
|
|
167164
|
-
import { join as
|
|
167466
|
+
import { existsSync as existsSync16, readdirSync as readdirSync4, readFileSync as readFileSync15 } from "node:fs";
|
|
167467
|
+
import { join as join17 } from "node:path";
|
|
167165
167468
|
function estimateSystemTokens(text) {
|
|
167166
167469
|
return Math.ceil(Buffer.byteLength(text, "utf8") / SYSTEM_PROMPT_BYTES_PER_TOKEN);
|
|
167167
167470
|
}
|
|
@@ -167169,7 +167472,7 @@ function normalizePath(value) {
|
|
|
167169
167472
|
return value.replaceAll("\\", "/");
|
|
167170
167473
|
}
|
|
167171
167474
|
function walkMarkdownFiles(dir) {
|
|
167172
|
-
if (!
|
|
167475
|
+
if (!existsSync16(dir)) {
|
|
167173
167476
|
return [];
|
|
167174
167477
|
}
|
|
167175
167478
|
const out = [];
|
|
@@ -167178,7 +167481,7 @@ function walkMarkdownFiles(dir) {
|
|
|
167178
167481
|
if (entry.name.startsWith(".")) {
|
|
167179
167482
|
continue;
|
|
167180
167483
|
}
|
|
167181
|
-
const full =
|
|
167484
|
+
const full = join17(dir, entry.name);
|
|
167182
167485
|
if (entry.isDirectory()) {
|
|
167183
167486
|
out.push(...walkMarkdownFiles(full));
|
|
167184
167487
|
continue;
|
|
@@ -167190,8 +167493,8 @@ function walkMarkdownFiles(dir) {
|
|
|
167190
167493
|
return out;
|
|
167191
167494
|
}
|
|
167192
167495
|
function estimateSystemPromptSize(memoryDir) {
|
|
167193
|
-
const systemDir =
|
|
167194
|
-
if (!
|
|
167496
|
+
const systemDir = join17(memoryDir, "system");
|
|
167497
|
+
if (!existsSync16(systemDir)) {
|
|
167195
167498
|
return { total: 0, files: [] };
|
|
167196
167499
|
}
|
|
167197
167500
|
const files = walkMarkdownFiles(systemDir).sort();
|
|
@@ -168741,7 +169044,7 @@ var init_edit2 = __esm(() => {
|
|
|
168741
169044
|
});
|
|
168742
169045
|
|
|
168743
169046
|
// src/tools/impl/shell.ts
|
|
168744
|
-
import { existsSync as
|
|
169047
|
+
import { existsSync as existsSync17, statSync as statSync4 } from "node:fs";
|
|
168745
169048
|
import * as path14 from "node:path";
|
|
168746
169049
|
function resolveShellWorkdir(workdir) {
|
|
168747
169050
|
const defaultCwd = getCurrentWorkingDirectory();
|
|
@@ -168844,7 +169147,7 @@ function arraysEqual(a, b) {
|
|
|
168844
169147
|
}
|
|
168845
169148
|
function isUsableDirectory(candidate) {
|
|
168846
169149
|
try {
|
|
168847
|
-
return
|
|
169150
|
+
return existsSync17(candidate) && statSync4(candidate).isDirectory();
|
|
168848
169151
|
} catch {
|
|
168849
169152
|
return false;
|
|
168850
169153
|
}
|
|
@@ -168911,8 +169214,6 @@ var init_shell = __esm(() => {
|
|
|
168911
169214
|
|
|
168912
169215
|
// src/tools/impl/exec-command.ts
|
|
168913
169216
|
import { spawn as spawn6 } from "node:child_process";
|
|
168914
|
-
import { existsSync as existsSync17 } from "node:fs";
|
|
168915
|
-
import { delimiter as delimiter2, isAbsolute as isAbsolute6, join as join17 } from "node:path";
|
|
168916
169217
|
function createAbortError() {
|
|
168917
169218
|
const error54 = new Error("The operation was aborted");
|
|
168918
169219
|
error54.name = "AbortError";
|
|
@@ -169102,56 +169403,6 @@ function buildExecLaunchers(args) {
|
|
|
169102
169403
|
powershellEnvAliases: envAliases
|
|
169103
169404
|
});
|
|
169104
169405
|
}
|
|
169105
|
-
function pathEnvValue(env3) {
|
|
169106
|
-
return env3.PATH ?? env3.Path ?? env3.path ?? "";
|
|
169107
|
-
}
|
|
169108
|
-
function pathExtValue(env3) {
|
|
169109
|
-
return env3.PATHEXT ?? env3.PathExt ?? ".COM;.EXE;.BAT;.CMD";
|
|
169110
|
-
}
|
|
169111
|
-
function hasPathSeparator(executable) {
|
|
169112
|
-
return executable.includes("/") || executable.includes("\\");
|
|
169113
|
-
}
|
|
169114
|
-
function hasFileExtension(executable) {
|
|
169115
|
-
const basename12 = executable.split(/[\\/]/).pop() ?? executable;
|
|
169116
|
-
return /\.[^.]+$/.test(basename12);
|
|
169117
|
-
}
|
|
169118
|
-
function resolveExecutablePath(executable, env3) {
|
|
169119
|
-
if (isAbsolute6(executable) || hasPathSeparator(executable)) {
|
|
169120
|
-
return existsSync17(executable) ? executable : null;
|
|
169121
|
-
}
|
|
169122
|
-
const pathDelimiter = process.platform === "win32" ? ";" : delimiter2;
|
|
169123
|
-
const pathEntries = pathEnvValue(env3).split(pathDelimiter).filter(Boolean);
|
|
169124
|
-
const executableNames = [executable];
|
|
169125
|
-
if (process.platform === "win32" && !hasFileExtension(executable)) {
|
|
169126
|
-
for (const extension of pathExtValue(env3).split(";").filter(Boolean)) {
|
|
169127
|
-
executableNames.push(`${executable}${extension}`);
|
|
169128
|
-
}
|
|
169129
|
-
}
|
|
169130
|
-
for (const entry of pathEntries) {
|
|
169131
|
-
for (const name of executableNames) {
|
|
169132
|
-
const candidate = join17(entry, name);
|
|
169133
|
-
if (existsSync17(candidate)) {
|
|
169134
|
-
return candidate;
|
|
169135
|
-
}
|
|
169136
|
-
}
|
|
169137
|
-
}
|
|
169138
|
-
return null;
|
|
169139
|
-
}
|
|
169140
|
-
function selectExecLauncher(launchers, env3) {
|
|
169141
|
-
if (process.platform !== "win32") {
|
|
169142
|
-
return launchers[0];
|
|
169143
|
-
}
|
|
169144
|
-
for (const launcher of launchers) {
|
|
169145
|
-
const executable = launcher[0];
|
|
169146
|
-
if (!executable)
|
|
169147
|
-
continue;
|
|
169148
|
-
const resolvedExecutable = resolveExecutablePath(executable, env3);
|
|
169149
|
-
if (resolvedExecutable) {
|
|
169150
|
-
return [resolvedExecutable, ...launcher.slice(1)];
|
|
169151
|
-
}
|
|
169152
|
-
}
|
|
169153
|
-
return launchers.at(-1);
|
|
169154
|
-
}
|
|
169155
169406
|
function buildPtyEnv(env3) {
|
|
169156
169407
|
const ptyEnv = {};
|
|
169157
169408
|
for (const [key, value] of Object.entries(env3)) {
|
|
@@ -169336,7 +169587,7 @@ async function startExecSession(args) {
|
|
|
169336
169587
|
const cwd = resolveShellWorkdir(args.workdir);
|
|
169337
169588
|
const env3 = { ...getShellEnv(), ...args.secretEnv ?? {} };
|
|
169338
169589
|
const launchers = buildExecLaunchers(args);
|
|
169339
|
-
const launcher =
|
|
169590
|
+
const launcher = selectAvailableShellLauncher(launchers, env3);
|
|
169340
169591
|
if (!launcher) {
|
|
169341
169592
|
throw new Error("Command must be a non-empty string");
|
|
169342
169593
|
}
|
|
@@ -175071,7 +175322,7 @@ var require_libvips = __commonJS((exports, module3) => {
|
|
|
175071
175322
|
SPDX-License-Identifier: Apache-2.0
|
|
175072
175323
|
*/
|
|
175073
175324
|
var { spawnSync } = __require("node:child_process");
|
|
175074
|
-
var { createHash } = __require("node:crypto");
|
|
175325
|
+
var { createHash: createHash2 } = __require("node:crypto");
|
|
175075
175326
|
var semverCoerce = require_coerce();
|
|
175076
175327
|
var semverGreaterThanOrEqualTo = require_gte();
|
|
175077
175328
|
var semverSatisfies = require_satisfies();
|
|
@@ -175159,7 +175410,7 @@ var require_libvips = __commonJS((exports, module3) => {
|
|
|
175159
175410
|
}
|
|
175160
175411
|
return false;
|
|
175161
175412
|
};
|
|
175162
|
-
var sha512 = (s2) =>
|
|
175413
|
+
var sha512 = (s2) => createHash2("sha512").update(s2).digest("hex");
|
|
175163
175414
|
var yarnLocator = () => {
|
|
175164
175415
|
try {
|
|
175165
175416
|
const identHash = sha512(`imgsharp-libvips-${buildPlatformArch()}`);
|
|
@@ -192954,7 +193205,7 @@ __export(exports_loader, {
|
|
|
192954
193205
|
loadPermissions: () => loadPermissions,
|
|
192955
193206
|
getUserSettingsPaths: () => getUserSettingsPaths
|
|
192956
193207
|
});
|
|
192957
|
-
import { createHash } from "node:crypto";
|
|
193208
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
192958
193209
|
import { readFileSync as readFileSync17, statSync as statSync5, watch as watch2 } from "node:fs";
|
|
192959
193210
|
import { homedir as homedir12 } from "node:os";
|
|
192960
193211
|
import { dirname as dirname14, join as join24, resolve as resolve25 } from "node:path";
|
|
@@ -192985,7 +193236,7 @@ function getFileSignature(path26) {
|
|
|
192985
193236
|
exists: true,
|
|
192986
193237
|
mtimeMs: stat9.mtimeMs,
|
|
192987
193238
|
size: stat9.size,
|
|
192988
|
-
hash:
|
|
193239
|
+
hash: createHash2("sha256").update(readFileSync17(path26)).digest("hex")
|
|
192989
193240
|
};
|
|
192990
193241
|
} catch {
|
|
192991
193242
|
return { exists: false };
|
|
@@ -204098,11 +204349,11 @@ var init_local_model_config = __esm(() => {
|
|
|
204098
204349
|
|
|
204099
204350
|
// src/backend/local/system-prompt-compilation.ts
|
|
204100
204351
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
204101
|
-
import { createHash as
|
|
204352
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
204102
204353
|
import { existsSync as existsSync26 } from "node:fs";
|
|
204103
204354
|
import { basename as basename13, dirname as dirname17, relative as relative4 } from "node:path";
|
|
204104
204355
|
function hashString(value) {
|
|
204105
|
-
return
|
|
204356
|
+
return createHash3("sha256").update(value).digest("hex");
|
|
204106
204357
|
}
|
|
204107
204358
|
function hashRawSystemPrompt(systemPrompt) {
|
|
204108
204359
|
return hashString(systemPrompt);
|
|
@@ -243373,9 +243624,9 @@ async function createAgent(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingM
|
|
|
243373
243624
|
}
|
|
243374
243625
|
if (!isSubagent && settingsManager.isReady) {
|
|
243375
243626
|
if (options3.systemPromptCustom) {
|
|
243376
|
-
settingsManager.
|
|
243627
|
+
settingsManager.setSystemPromptCustom(fullAgent.id);
|
|
243377
243628
|
} else if (isKnownPreset(options3.systemPromptPreset ?? "default")) {
|
|
243378
|
-
|
|
243629
|
+
recordManagedSystemPrompt(fullAgent.id, options3.systemPromptPreset ?? "default", memMode, systemPromptContent);
|
|
243379
243630
|
}
|
|
243380
243631
|
}
|
|
243381
243632
|
const provenance = {
|
|
@@ -243395,6 +243646,7 @@ var init_create6 = __esm(() => {
|
|
|
243395
243646
|
init_model();
|
|
243396
243647
|
init_modify();
|
|
243397
243648
|
init_prompt_assets();
|
|
243649
|
+
init_system_prompt_versioning();
|
|
243398
243650
|
});
|
|
243399
243651
|
|
|
243400
243652
|
// src/agent/personality.ts
|
|
@@ -255134,6 +255386,7 @@ function markIncompleteToolsAsCancelled(b3, setInterruptedFlag = true, reason =
|
|
|
255134
255386
|
let anyToolsCancelled = false;
|
|
255135
255387
|
for (const [id2, line] of b3.byId.entries()) {
|
|
255136
255388
|
if (line.kind === "tool_call" && line.phase !== "finished") {
|
|
255389
|
+
debugLog("accumulator", `[ORPHANED_TOOL] name=${line.name ?? "?"} phase=${line.phase} diagnosis=${diagnoseOrphanedTool(line, b3)} reason=${reason}`);
|
|
255137
255390
|
const updatedLine = {
|
|
255138
255391
|
...line,
|
|
255139
255392
|
phase: "finished",
|
|
@@ -255149,6 +255402,33 @@ function markIncompleteToolsAsCancelled(b3, setInterruptedFlag = true, reason =
|
|
|
255149
255402
|
}
|
|
255150
255403
|
return anyToolsCancelled;
|
|
255151
255404
|
}
|
|
255405
|
+
function removeIncompleteTools(b3) {
|
|
255406
|
+
let anyToolsRemoved = false;
|
|
255407
|
+
for (const [id2, line] of b3.byId.entries()) {
|
|
255408
|
+
if (line.kind === "tool_call" && line.phase !== "finished") {
|
|
255409
|
+
debugLog("accumulator", `[REMOVED_ORPHANED_TOOL] name=${line.name ?? "?"} phase=${line.phase} diagnosis=${diagnoseOrphanedTool(line, b3)} toolCallId=${line.toolCallId ?? "?"}`);
|
|
255410
|
+
b3.byId.delete(id2);
|
|
255411
|
+
b3.order = b3.order.filter((oid) => oid !== id2);
|
|
255412
|
+
if (line.toolCallId) {
|
|
255413
|
+
b3.toolCallIdToLineId.delete(line.toolCallId);
|
|
255414
|
+
b3.serverToolCalls.delete(line.toolCallId);
|
|
255415
|
+
}
|
|
255416
|
+
anyToolsRemoved = true;
|
|
255417
|
+
}
|
|
255418
|
+
}
|
|
255419
|
+
return anyToolsRemoved;
|
|
255420
|
+
}
|
|
255421
|
+
function diagnoseOrphanedTool(line, b3) {
|
|
255422
|
+
const isTrackedAsServerTool = line.toolCallId ? b3.serverToolCalls.has(line.toolCallId) : false;
|
|
255423
|
+
if (line.phase === "streaming") {
|
|
255424
|
+
return isTrackedAsServerTool ? "server_tool_missing_return" : "client_tool_missing_approval_request";
|
|
255425
|
+
}
|
|
255426
|
+
if (line.phase === "ready")
|
|
255427
|
+
return "approval_pending_at_stream_end";
|
|
255428
|
+
if (line.phase === "running")
|
|
255429
|
+
return "execution_incomplete_at_stream_end";
|
|
255430
|
+
return "unknown_phase";
|
|
255431
|
+
}
|
|
255152
255432
|
function getStringProp(obj, key2) {
|
|
255153
255433
|
const v2 = obj[key2];
|
|
255154
255434
|
return typeof v2 === "string" ? v2 : undefined;
|
|
@@ -256340,7 +256620,15 @@ async function drainStream(stream5, buffers, refresh, abortSignal, onFirstMessag
|
|
|
256340
256620
|
stopReason = "error";
|
|
256341
256621
|
}
|
|
256342
256622
|
if (stopReason === "cancelled") {
|
|
256343
|
-
markIncompleteToolsAsCancelled(buffers, true, "user_interrupt");
|
|
256623
|
+
const hadOrphanedTools = markIncompleteToolsAsCancelled(buffers, true, "user_interrupt");
|
|
256624
|
+
if (hadOrphanedTools) {
|
|
256625
|
+
debugWarn("drainStream", "cancelled had orphaned tool calls (see [ORPHANED_TOOL] logs for diagnosis)");
|
|
256626
|
+
}
|
|
256627
|
+
} else if (stopReason === "end_turn") {
|
|
256628
|
+
const hadOrphanedTools = removeIncompleteTools(buffers);
|
|
256629
|
+
if (hadOrphanedTools) {
|
|
256630
|
+
debugWarn("drainStream", "end_turn had orphaned tool calls (see [REMOVED_ORPHANED_TOOL] logs)");
|
|
256631
|
+
}
|
|
256344
256632
|
}
|
|
256345
256633
|
if (stopReason !== "error") {
|
|
256346
256634
|
markCurrentLineAsFinished(buffers);
|
|
@@ -262322,6 +262610,45 @@ function trackListenerUserInput(messages, modelId) {
|
|
|
262322
262610
|
telemetry.trackUserInput(inputText, "user", modelId);
|
|
262323
262611
|
}
|
|
262324
262612
|
}
|
|
262613
|
+
function buildInboundUserTranscriptLines(messages) {
|
|
262614
|
+
const lines = [];
|
|
262615
|
+
for (const message of messages) {
|
|
262616
|
+
if (!("role" in message) || message.role !== "user") {
|
|
262617
|
+
continue;
|
|
262618
|
+
}
|
|
262619
|
+
if (!("content" in message)) {
|
|
262620
|
+
continue;
|
|
262621
|
+
}
|
|
262622
|
+
const text2 = extractTelemetryInputText(message.content);
|
|
262623
|
+
if (text2.length === 0) {
|
|
262624
|
+
continue;
|
|
262625
|
+
}
|
|
262626
|
+
const otid = "otid" in message && typeof message.otid === "string" ? message.otid : undefined;
|
|
262627
|
+
const id2 = otid ? `user-${otid}` : `user-${crypto.randomUUID()}`;
|
|
262628
|
+
lines.push({
|
|
262629
|
+
kind: "user",
|
|
262630
|
+
id: id2,
|
|
262631
|
+
text: text2,
|
|
262632
|
+
otid
|
|
262633
|
+
});
|
|
262634
|
+
}
|
|
262635
|
+
return lines;
|
|
262636
|
+
}
|
|
262637
|
+
function seedInboundUserTranscriptLines(buffers, lines) {
|
|
262638
|
+
for (const line of lines) {
|
|
262639
|
+
if (line.kind !== "user") {
|
|
262640
|
+
continue;
|
|
262641
|
+
}
|
|
262642
|
+
if (buffers.byId.has(line.id)) {
|
|
262643
|
+
continue;
|
|
262644
|
+
}
|
|
262645
|
+
buffers.byId.set(line.id, line);
|
|
262646
|
+
buffers.order.push(line.id);
|
|
262647
|
+
if (line.otid) {
|
|
262648
|
+
buffers.userLineIdByOtid.set(line.otid, line.id);
|
|
262649
|
+
}
|
|
262650
|
+
}
|
|
262651
|
+
}
|
|
262325
262652
|
function escapeTaskNotificationSummary(summary) {
|
|
262326
262653
|
return summary.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
262327
262654
|
}
|
|
@@ -262485,6 +262812,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
|
|
|
262485
262812
|
...m4,
|
|
262486
262813
|
otid: "client_message_id" in m4 && typeof m4.client_message_id === "string" ? m4.client_message_id : crypto.randomUUID()
|
|
262487
262814
|
} : m4));
|
|
262815
|
+
const inboundUserTranscriptLines = buildInboundUserTranscriptLines(messagesToSend);
|
|
262488
262816
|
const firstMessage = normalizedMessages[0];
|
|
262489
262817
|
const isApprovalMessage = firstMessage && "type" in firstMessage && firstMessage.type === "approval" && "approvals" in firstMessage;
|
|
262490
262818
|
let cachedAgent = null;
|
|
@@ -262590,6 +262918,7 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
|
|
|
262590
262918
|
let runIdSent = false;
|
|
262591
262919
|
let runId;
|
|
262592
262920
|
const buffers = createBuffers(agentId);
|
|
262921
|
+
seedInboundUserTranscriptLines(buffers, inboundUserTranscriptLines);
|
|
262593
262922
|
while (true) {
|
|
262594
262923
|
runIdSent = false;
|
|
262595
262924
|
let latestErrorText = null;
|
|
@@ -439966,7 +440295,7 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
|
|
|
439966
440295
|
});
|
|
439967
440296
|
|
|
439968
440297
|
// src/extensions/extension-engine.ts
|
|
439969
|
-
import { createHash as
|
|
440298
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
439970
440299
|
import {
|
|
439971
440300
|
existsSync as existsSync46,
|
|
439972
440301
|
mkdirSync as mkdirSync33,
|
|
@@ -440179,7 +440508,7 @@ function prepareExtensionForImport(extensionPath, source2) {
|
|
|
440179
440508
|
function createImportableExtensionPath(extensionPath, cacheDirectory) {
|
|
440180
440509
|
ensureExtensionCache(cacheDirectory);
|
|
440181
440510
|
const source2 = readFileSync32(extensionPath, "utf8");
|
|
440182
|
-
const hash4 =
|
|
440511
|
+
const hash4 = createHash4("sha256").update(source2).digest("hex").slice(0, 16);
|
|
440183
440512
|
const extension = path34.extname(extensionPath);
|
|
440184
440513
|
const importableSource = prepareExtensionForImport(extensionPath, source2);
|
|
440185
440514
|
const baseName = path34.basename(extensionPath, extension).replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
@@ -440937,17 +441266,19 @@ function hasExtensionSources(options3) {
|
|
|
440937
441266
|
return resolveLocalExtensionSources(options3).some((source2) => source2.files.length > 0);
|
|
440938
441267
|
}
|
|
440939
441268
|
function createExtensionAdapter(options3) {
|
|
440940
|
-
if (options3.disabled) {
|
|
440941
|
-
disableExtensionsForProcess();
|
|
440942
|
-
}
|
|
440943
|
-
if (options3.disabled || areExtensionsDisabled()) {
|
|
440944
|
-
return createDisabledExtensionAdapter(options3);
|
|
440945
|
-
}
|
|
440946
441269
|
const {
|
|
441270
|
+
disabled,
|
|
440947
441271
|
getBackend: resolveBackend,
|
|
440948
441272
|
initialContext,
|
|
440949
441273
|
...engineOptions
|
|
440950
441274
|
} = options3;
|
|
441275
|
+
const alreadyDisabled = areExtensionsDisabled();
|
|
441276
|
+
if (disabled || alreadyDisabled) {
|
|
441277
|
+
if (!alreadyDisabled) {
|
|
441278
|
+
disableExtensionsForProcess();
|
|
441279
|
+
}
|
|
441280
|
+
return createDisabledExtensionAdapter({ initialContext });
|
|
441281
|
+
}
|
|
440951
441282
|
let context3 = initialContext;
|
|
440952
441283
|
let disposed = false;
|
|
440953
441284
|
const initialHasExtensionSources = hasExtensionSources(engineOptions);
|
|
@@ -440961,7 +441292,7 @@ function createExtensionAdapter(options3) {
|
|
|
440961
441292
|
const getContext3 = () => context3;
|
|
440962
441293
|
const engine4 = createExtensionEngine({
|
|
440963
441294
|
...engineOptions,
|
|
440964
|
-
|
|
441295
|
+
getBackend: getBackend2,
|
|
440965
441296
|
getContext: getContext3
|
|
440966
441297
|
});
|
|
440967
441298
|
const events = {
|
|
@@ -441005,9 +441336,9 @@ function createExtensionAdapter(options3) {
|
|
|
441005
441336
|
debugLog("extensions", "failed to load %s: %s", loadError.path, loadError.error.message);
|
|
441006
441337
|
}
|
|
441007
441338
|
for (const diagnostic of nextRegistry.diagnostics) {
|
|
441008
|
-
if (diagnostic.phase
|
|
441009
|
-
|
|
441010
|
-
|
|
441339
|
+
if (diagnostic.phase === "command.override") {
|
|
441340
|
+
debugLog("extensions", "%s", diagnostic.error.message);
|
|
441341
|
+
}
|
|
441011
441342
|
}
|
|
441012
441343
|
loadState = {
|
|
441013
441344
|
hadStatuslineRenderer: Boolean(nextRegistry.ui.statuslineRenderer),
|
|
@@ -442086,7 +442417,7 @@ In headless mode, use:
|
|
|
442086
442417
|
}
|
|
442087
442418
|
agent2 = result.agent;
|
|
442088
442419
|
if (settingsManager.isReady) {
|
|
442089
|
-
settingsManager.
|
|
442420
|
+
settingsManager.setSystemPromptCustom(agent2.id);
|
|
442090
442421
|
}
|
|
442091
442422
|
if (result.skills && result.skills.length > 0) {
|
|
442092
442423
|
const { getAgentSkillsDir: getAgentSkillsDir3 } = await Promise.resolve().then(() => (init_skills3(), exports_skills2));
|
|
@@ -442295,26 +442626,11 @@ Current session AGENT_ID=${process.env.AGENT_ID}; --backend local switches to a
|
|
|
442295
442626
|
agent2 = result.agent;
|
|
442296
442627
|
}
|
|
442297
442628
|
if (isResumingAgent && !systemPromptPreset) {
|
|
442298
|
-
|
|
442299
|
-
|
|
442300
|
-
|
|
442301
|
-
|
|
442302
|
-
}
|
|
442303
|
-
if (storedPreset && storedPreset !== "custom") {
|
|
442304
|
-
const { buildSystemPrompt: rebuildPrompt, isKnownPreset: isKnown } = await Promise.resolve().then(() => (init_prompt_assets(), exports_prompt_assets));
|
|
442305
|
-
if (isKnown(storedPreset)) {
|
|
442306
|
-
const memoryMode = settingsManager.isMemfsEnabled(agent2.id) ? "memfs" : "standard";
|
|
442307
|
-
const expected = rebuildPrompt(storedPreset, memoryMode);
|
|
442308
|
-
if (agent2.system !== expected) {
|
|
442309
|
-
await backend4.updateAgent(agent2.id, { system: expected });
|
|
442310
|
-
agent2 = await backend4.retrieveAgent(agent2.id, {
|
|
442311
|
-
include: ["agent.secrets", "agent.tools", "agent.tags"]
|
|
442312
|
-
});
|
|
442313
|
-
}
|
|
442314
|
-
} else {
|
|
442315
|
-
settingsManager.clearSystemPromptPreset(agent2.id);
|
|
442316
|
-
}
|
|
442317
|
-
}
|
|
442629
|
+
const { getMemoryPromptModeForAgent: getMemoryPromptModeForAgent2, scheduleManagedSystemPromptUpdate: scheduleManagedSystemPromptUpdate2 } = await Promise.resolve().then(() => (init_system_prompt_versioning(), exports_system_prompt_versioning));
|
|
442630
|
+
scheduleManagedSystemPromptUpdate2({
|
|
442631
|
+
agent: agent2,
|
|
442632
|
+
memoryMode: getMemoryPromptModeForAgent2(agent2.id)
|
|
442633
|
+
});
|
|
442318
442634
|
}
|
|
442319
442635
|
const startupAgentId = agent2.id;
|
|
442320
442636
|
clearPersistedClientToolRules(startupAgentId, agent2).then((cleanup) => {
|
|
@@ -502285,9 +502601,9 @@ async function createAgent2(nameOrOptions = DEFAULT_AGENT_NAME, model, embedding
|
|
|
502285
502601
|
}
|
|
502286
502602
|
if (!isSubagent && settingsManager.isReady) {
|
|
502287
502603
|
if (options3.systemPromptCustom) {
|
|
502288
|
-
settingsManager.
|
|
502604
|
+
settingsManager.setSystemPromptCustom(fullAgent.id);
|
|
502289
502605
|
} else if (isKnownPreset(options3.systemPromptPreset ?? "default")) {
|
|
502290
|
-
|
|
502606
|
+
recordManagedSystemPrompt(fullAgent.id, options3.systemPromptPreset ?? "default", memMode, systemPromptContent);
|
|
502291
502607
|
}
|
|
502292
502608
|
}
|
|
502293
502609
|
const provenance = {
|
|
@@ -502307,6 +502623,7 @@ var init_create9 = __esm(() => {
|
|
|
502307
502623
|
init_model();
|
|
502308
502624
|
init_modify();
|
|
502309
502625
|
init_prompt_assets();
|
|
502626
|
+
init_system_prompt_versioning();
|
|
502310
502627
|
});
|
|
502311
502628
|
|
|
502312
502629
|
// src/agent/import.ts
|
|
@@ -502990,6 +503307,177 @@ var init_secrets_store2 = __esm(() => {
|
|
|
502990
503307
|
SECRETS_CACHE_KEY2 = Symbol.for("@letta/secretsCache");
|
|
502991
503308
|
});
|
|
502992
503309
|
|
|
503310
|
+
// src/agent/system-prompt-versioning.ts
|
|
503311
|
+
var exports_system_prompt_versioning2 = {};
|
|
503312
|
+
__export(exports_system_prompt_versioning2, {
|
|
503313
|
+
scheduleManagedSystemPromptUpdate: () => scheduleManagedSystemPromptUpdate2,
|
|
503314
|
+
recordManagedSystemPrompt: () => recordManagedSystemPrompt2,
|
|
503315
|
+
hashSystemPrompt: () => hashSystemPrompt2,
|
|
503316
|
+
getMemoryPromptModeForAgent: () => getMemoryPromptModeForAgent2,
|
|
503317
|
+
decideManagedSystemPromptUpdate: () => decideManagedSystemPromptUpdate2
|
|
503318
|
+
});
|
|
503319
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
503320
|
+
function hashSystemPrompt2(content) {
|
|
503321
|
+
const digest = createHash5("sha256").update(content).digest("base64url");
|
|
503322
|
+
return `${SYSTEM_PROMPT_HASH_PREFIX2}${digest}`;
|
|
503323
|
+
}
|
|
503324
|
+
function managedPrompt2(preset, memoryMode, content = buildSystemPrompt(preset, memoryMode)) {
|
|
503325
|
+
return {
|
|
503326
|
+
preset,
|
|
503327
|
+
hash: hashSystemPrompt2(content),
|
|
503328
|
+
version: getVersion()
|
|
503329
|
+
};
|
|
503330
|
+
}
|
|
503331
|
+
function recordManagedSystemPrompt2(agentId, preset, memoryMode, content) {
|
|
503332
|
+
if (!settingsManager.isReady) {
|
|
503333
|
+
return;
|
|
503334
|
+
}
|
|
503335
|
+
settingsManager.setManagedSystemPrompt(agentId, managedPrompt2(preset, memoryMode, content));
|
|
503336
|
+
}
|
|
503337
|
+
function getMemoryPromptModeForAgent2(agentId) {
|
|
503338
|
+
const backend4 = getBackend();
|
|
503339
|
+
if (backend4.capabilities.localMemfs) {
|
|
503340
|
+
return "local-memfs";
|
|
503341
|
+
}
|
|
503342
|
+
return settingsManager.isReady && settingsManager.isMemfsEnabled(agentId) ? "memfs" : "standard";
|
|
503343
|
+
}
|
|
503344
|
+
function isLettaCodePrimaryAgent2(agent2) {
|
|
503345
|
+
const tags = agent2.tags ?? [];
|
|
503346
|
+
return tags.includes("origin:letta-code") && !tags.includes("role:subagent");
|
|
503347
|
+
}
|
|
503348
|
+
function findMatchingCurrentPreset2(systemPrompt, memoryMode) {
|
|
503349
|
+
for (const preset of SYSTEM_PROMPTS) {
|
|
503350
|
+
if (buildSystemPrompt(preset.id, memoryMode) === systemPrompt) {
|
|
503351
|
+
return preset.id;
|
|
503352
|
+
}
|
|
503353
|
+
}
|
|
503354
|
+
return;
|
|
503355
|
+
}
|
|
503356
|
+
function isValidHash2(hash4) {
|
|
503357
|
+
return !!hash4 && hash4.startsWith(SYSTEM_PROMPT_HASH_PREFIX2);
|
|
503358
|
+
}
|
|
503359
|
+
function decideManagedSystemPromptUpdate2(input) {
|
|
503360
|
+
const { agent: agent2, memoryMode, storedPreset, storedHash, storedVersion } = input;
|
|
503361
|
+
const currentSystemPrompt = agent2.system ?? "";
|
|
503362
|
+
const currentHash = hashSystemPrompt2(currentSystemPrompt);
|
|
503363
|
+
const currentVersion = getVersion();
|
|
503364
|
+
if (storedPreset === "custom") {
|
|
503365
|
+
return { kind: "noop", reason: "system prompt is marked custom" };
|
|
503366
|
+
}
|
|
503367
|
+
if (storedPreset) {
|
|
503368
|
+
if (!isKnownPreset(storedPreset)) {
|
|
503369
|
+
return { kind: "clear", reason: "stored preset is no longer known" };
|
|
503370
|
+
}
|
|
503371
|
+
if (storedHash) {
|
|
503372
|
+
if (!isValidHash2(storedHash)) {
|
|
503373
|
+
return { kind: "clear", reason: "stored prompt hash is invalid" };
|
|
503374
|
+
}
|
|
503375
|
+
if (currentHash !== storedHash) {
|
|
503376
|
+
return {
|
|
503377
|
+
kind: "custom",
|
|
503378
|
+
reason: "agent prompt differs from stored managed prompt hash"
|
|
503379
|
+
};
|
|
503380
|
+
}
|
|
503381
|
+
const nextSystemPrompt = buildSystemPrompt(storedPreset, memoryMode);
|
|
503382
|
+
const nextPrompt = managedPrompt2(storedPreset, memoryMode, nextSystemPrompt);
|
|
503383
|
+
if (nextPrompt.hash !== storedHash) {
|
|
503384
|
+
return {
|
|
503385
|
+
kind: "update",
|
|
503386
|
+
nextSystemPrompt,
|
|
503387
|
+
prompt: nextPrompt,
|
|
503388
|
+
reason: "managed prompt content changed for current Letta Code version"
|
|
503389
|
+
};
|
|
503390
|
+
}
|
|
503391
|
+
if (storedVersion !== currentVersion) {
|
|
503392
|
+
return { kind: "track", prompt: nextPrompt };
|
|
503393
|
+
}
|
|
503394
|
+
return { kind: "noop", reason: "managed prompt is current" };
|
|
503395
|
+
}
|
|
503396
|
+
const expectedCurrentPrompt = buildSystemPrompt(storedPreset, memoryMode);
|
|
503397
|
+
if (currentSystemPrompt === expectedCurrentPrompt) {
|
|
503398
|
+
return {
|
|
503399
|
+
kind: "track",
|
|
503400
|
+
prompt: managedPrompt2(storedPreset, memoryMode, currentSystemPrompt)
|
|
503401
|
+
};
|
|
503402
|
+
}
|
|
503403
|
+
return {
|
|
503404
|
+
kind: "custom",
|
|
503405
|
+
reason: "legacy preset tracking exists but prompt content was modified"
|
|
503406
|
+
};
|
|
503407
|
+
}
|
|
503408
|
+
if (!isLettaCodePrimaryAgent2(agent2)) {
|
|
503409
|
+
return { kind: "noop", reason: "agent is not a primary Letta Code agent" };
|
|
503410
|
+
}
|
|
503411
|
+
const matchingPreset = findMatchingCurrentPreset2(currentSystemPrompt, memoryMode);
|
|
503412
|
+
if (!matchingPreset) {
|
|
503413
|
+
return {
|
|
503414
|
+
kind: "custom",
|
|
503415
|
+
reason: "legacy Letta Code agent prompt does not match a current preset"
|
|
503416
|
+
};
|
|
503417
|
+
}
|
|
503418
|
+
return {
|
|
503419
|
+
kind: "track",
|
|
503420
|
+
prompt: managedPrompt2(matchingPreset, memoryMode, currentSystemPrompt)
|
|
503421
|
+
};
|
|
503422
|
+
}
|
|
503423
|
+
function scheduleManagedSystemPromptUpdate2({
|
|
503424
|
+
agent: agent2,
|
|
503425
|
+
memoryMode,
|
|
503426
|
+
onUpdated
|
|
503427
|
+
}) {
|
|
503428
|
+
if (!settingsManager.isReady) {
|
|
503429
|
+
return;
|
|
503430
|
+
}
|
|
503431
|
+
const decision = decideManagedSystemPromptUpdate2({
|
|
503432
|
+
agent: agent2,
|
|
503433
|
+
memoryMode,
|
|
503434
|
+
storedPreset: settingsManager.getSystemPromptPreset(agent2.id),
|
|
503435
|
+
storedHash: settingsManager.getSystemPromptHash(agent2.id),
|
|
503436
|
+
storedVersion: settingsManager.getSystemPromptVersion(agent2.id)
|
|
503437
|
+
});
|
|
503438
|
+
if (decision.kind === "noop") {
|
|
503439
|
+
debugLog("startup", `System prompt version check noop: ${decision.reason}`);
|
|
503440
|
+
return;
|
|
503441
|
+
}
|
|
503442
|
+
if (decision.kind === "track") {
|
|
503443
|
+
settingsManager.setManagedSystemPrompt(agent2.id, decision.prompt);
|
|
503444
|
+
debugLog("startup", `Tracking managed system prompt ${decision.prompt.preset}@${decision.prompt.version}`);
|
|
503445
|
+
return;
|
|
503446
|
+
}
|
|
503447
|
+
if (decision.kind === "custom") {
|
|
503448
|
+
settingsManager.setSystemPromptCustom(agent2.id);
|
|
503449
|
+
debugLog("startup", `Marked system prompt custom: ${decision.reason}`);
|
|
503450
|
+
return;
|
|
503451
|
+
}
|
|
503452
|
+
if (decision.kind === "clear") {
|
|
503453
|
+
settingsManager.clearSystemPromptPreset(agent2.id);
|
|
503454
|
+
debugLog("startup", `Cleared system prompt metadata: ${decision.reason}`);
|
|
503455
|
+
return;
|
|
503456
|
+
}
|
|
503457
|
+
getBackend().updateAgent(agent2.id, {
|
|
503458
|
+
system: decision.nextSystemPrompt
|
|
503459
|
+
}).then(async () => {
|
|
503460
|
+
settingsManager.setManagedSystemPrompt(agent2.id, decision.prompt);
|
|
503461
|
+
debugLog("startup", `Updated managed system prompt ${decision.prompt.preset}@${decision.prompt.version}: ${decision.reason}`);
|
|
503462
|
+
if (onUpdated) {
|
|
503463
|
+
const updatedAgent = await getBackend().retrieveAgent(agent2.id, {
|
|
503464
|
+
include: ["agent.secrets", "agent.tools", "agent.tags"]
|
|
503465
|
+
});
|
|
503466
|
+
onUpdated(updatedAgent);
|
|
503467
|
+
}
|
|
503468
|
+
}).catch((error54) => {
|
|
503469
|
+
debugWarn("startup", `Failed to update managed system prompt for ${agent2.id}: ${error54 instanceof Error ? error54.message : String(error54)}`);
|
|
503470
|
+
});
|
|
503471
|
+
}
|
|
503472
|
+
var SYSTEM_PROMPT_HASH_PREFIX2 = "sha256:";
|
|
503473
|
+
var init_system_prompt_versioning2 = __esm(() => {
|
|
503474
|
+
init_backend2();
|
|
503475
|
+
init_settings_manager();
|
|
503476
|
+
init_debug();
|
|
503477
|
+
init_version();
|
|
503478
|
+
init_prompt_assets();
|
|
503479
|
+
});
|
|
503480
|
+
|
|
502993
503481
|
// src/index.ts
|
|
502994
503482
|
import { hostname as hostname7 } from "os";
|
|
502995
503483
|
|
|
@@ -504089,6 +504577,7 @@ async function updateAgentSystemPromptRaw2(agentId, systemPromptContent) {
|
|
|
504089
504577
|
async function updateAgentSystemPrompt2(agentId, systemPromptId) {
|
|
504090
504578
|
try {
|
|
504091
504579
|
const { isKnownPreset: isKnownPreset2, resolveAndBuildSystemPrompt: resolveAndBuildSystemPrompt2 } = await Promise.resolve().then(() => (init_prompt_assets(), exports_prompt_assets));
|
|
504580
|
+
const { recordManagedSystemPrompt: recordManagedSystemPrompt2 } = await Promise.resolve().then(() => (init_system_prompt_versioning(), exports_system_prompt_versioning));
|
|
504092
504581
|
const { settingsManager: settingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), exports_settings_manager));
|
|
504093
504582
|
const backend3 = getBackend();
|
|
504094
504583
|
const memoryMode = backend3.capabilities.localMemfs ? "local-memfs" : settingsManager2.isReady && settingsManager2.isMemfsEnabled(agentId) ? "memfs" : "standard";
|
|
@@ -504104,7 +504593,7 @@ async function updateAgentSystemPrompt2(agentId, systemPromptId) {
|
|
|
504104
504593
|
}
|
|
504105
504594
|
if (settingsManager2.isReady) {
|
|
504106
504595
|
if (isKnownPreset2(systemPromptId)) {
|
|
504107
|
-
|
|
504596
|
+
recordManagedSystemPrompt2(agentId, systemPromptId, memoryMode, systemPromptContent);
|
|
504108
504597
|
} else {
|
|
504109
504598
|
settingsManager2.clearSystemPromptPreset(agentId);
|
|
504110
504599
|
}
|
|
@@ -511590,7 +512079,8 @@ var DEFAULT_SETTINGS2 = {
|
|
|
511590
512079
|
enableSleeptime: false,
|
|
511591
512080
|
conversationSwitchAlertEnabled: false,
|
|
511592
512081
|
sessionContextEnabled: true,
|
|
511593
|
-
autoConversationTitles:
|
|
512082
|
+
autoConversationTitles: false,
|
|
512083
|
+
autoConversationTitlesRollbackApplied: true,
|
|
511594
512084
|
autoSwapOnQuotaLimit: true,
|
|
511595
512085
|
includeWorktreeTool: true,
|
|
511596
512086
|
recentModels: [],
|
|
@@ -511745,6 +512235,7 @@ class SettingsManager2 {
|
|
|
511745
512235
|
if (this.initialized)
|
|
511746
512236
|
return;
|
|
511747
512237
|
const settingsPath = this.getSettingsPath();
|
|
512238
|
+
let shouldRollbackAutoConversationTitles = false;
|
|
511748
512239
|
try {
|
|
511749
512240
|
if (!exists(settingsPath)) {
|
|
511750
512241
|
this.settings = { ...DEFAULT_SETTINGS2 };
|
|
@@ -511760,6 +512251,12 @@ class SettingsManager2 {
|
|
|
511760
512251
|
delete loadedSettingsRaw.reflectionBehavior;
|
|
511761
512252
|
this.markDirty("reflectionBehavior");
|
|
511762
512253
|
}
|
|
512254
|
+
shouldRollbackAutoConversationTitles = loadedSettingsRaw.autoConversationTitlesRollbackApplied !== true;
|
|
512255
|
+
if (shouldRollbackAutoConversationTitles) {
|
|
512256
|
+
loadedSettingsRaw.autoConversationTitles = false;
|
|
512257
|
+
loadedSettingsRaw.autoConversationTitlesRollbackApplied = true;
|
|
512258
|
+
this.markDirty("autoConversationTitles", "autoConversationTitlesRollbackApplied");
|
|
512259
|
+
}
|
|
511763
512260
|
this.settings = {
|
|
511764
512261
|
...DEFAULT_SETTINGS2,
|
|
511765
512262
|
...loadedSettingsRaw
|
|
@@ -511769,6 +512266,11 @@ class SettingsManager2 {
|
|
|
511769
512266
|
}
|
|
511770
512267
|
}
|
|
511771
512268
|
this.initialized = true;
|
|
512269
|
+
if (shouldRollbackAutoConversationTitles) {
|
|
512270
|
+
try {
|
|
512271
|
+
await this.persistSettings();
|
|
512272
|
+
} catch {}
|
|
512273
|
+
}
|
|
511772
512274
|
await this.checkSecretsSupport();
|
|
511773
512275
|
if (!isSubagentProcess3()) {
|
|
511774
512276
|
await this.migrateTokensToSecrets();
|
|
@@ -512838,7 +513340,9 @@ class SettingsManager2 {
|
|
|
512838
513340
|
pinned: updates.pinned !== undefined ? updates.pinned : existing.pinned,
|
|
512839
513341
|
memfs: updates.memfs !== undefined ? updates.memfs : existing.memfs,
|
|
512840
513342
|
toolset: updates.toolset !== undefined ? updates.toolset : existing.toolset,
|
|
512841
|
-
systemPromptPreset: updates.systemPromptPreset !== undefined ? updates.systemPromptPreset : existing.systemPromptPreset
|
|
513343
|
+
systemPromptPreset: updates.systemPromptPreset !== undefined ? updates.systemPromptPreset : existing.systemPromptPreset,
|
|
513344
|
+
systemPromptHash: updates.systemPromptHash !== undefined ? updates.systemPromptHash ?? undefined : existing.systemPromptHash,
|
|
513345
|
+
systemPromptVersion: updates.systemPromptVersion !== undefined ? updates.systemPromptVersion ?? undefined : existing.systemPromptVersion
|
|
512842
513346
|
};
|
|
512843
513347
|
if (!updated.pinned)
|
|
512844
513348
|
delete updated.pinned;
|
|
@@ -512848,6 +513352,10 @@ class SettingsManager2 {
|
|
|
512848
513352
|
delete updated.toolset;
|
|
512849
513353
|
if (!updated.systemPromptPreset)
|
|
512850
513354
|
delete updated.systemPromptPreset;
|
|
513355
|
+
if (!updated.systemPromptHash)
|
|
513356
|
+
delete updated.systemPromptHash;
|
|
513357
|
+
if (!updated.systemPromptVersion)
|
|
513358
|
+
delete updated.systemPromptVersion;
|
|
512851
513359
|
if (!updated.baseUrl)
|
|
512852
513360
|
delete updated.baseUrl;
|
|
512853
513361
|
agents[idx] = updated;
|
|
@@ -512855,7 +513363,9 @@ class SettingsManager2 {
|
|
|
512855
513363
|
const newAgent = {
|
|
512856
513364
|
agentId,
|
|
512857
513365
|
baseUrl: normalizedBaseUrl,
|
|
512858
|
-
...updates
|
|
513366
|
+
...updates,
|
|
513367
|
+
systemPromptHash: updates.systemPromptHash ?? undefined,
|
|
513368
|
+
systemPromptVersion: updates.systemPromptVersion ?? undefined
|
|
512859
513369
|
};
|
|
512860
513370
|
if (!newAgent.pinned)
|
|
512861
513371
|
delete newAgent.pinned;
|
|
@@ -512865,6 +513375,10 @@ class SettingsManager2 {
|
|
|
512865
513375
|
delete newAgent.toolset;
|
|
512866
513376
|
if (!newAgent.systemPromptPreset)
|
|
512867
513377
|
delete newAgent.systemPromptPreset;
|
|
513378
|
+
if (!newAgent.systemPromptHash)
|
|
513379
|
+
delete newAgent.systemPromptHash;
|
|
513380
|
+
if (!newAgent.systemPromptVersion)
|
|
513381
|
+
delete newAgent.systemPromptVersion;
|
|
512868
513382
|
if (!newAgent.baseUrl)
|
|
512869
513383
|
delete newAgent.baseUrl;
|
|
512870
513384
|
agents.push(newAgent);
|
|
@@ -512890,11 +513404,39 @@ class SettingsManager2 {
|
|
|
512890
513404
|
getSystemPromptPreset(agentId) {
|
|
512891
513405
|
return this.getAgentSettings(agentId)?.systemPromptPreset;
|
|
512892
513406
|
}
|
|
513407
|
+
getSystemPromptHash(agentId) {
|
|
513408
|
+
return this.getAgentSettings(agentId)?.systemPromptHash;
|
|
513409
|
+
}
|
|
513410
|
+
getSystemPromptVersion(agentId) {
|
|
513411
|
+
return this.getAgentSettings(agentId)?.systemPromptVersion;
|
|
513412
|
+
}
|
|
512893
513413
|
setSystemPromptPreset(agentId, preset) {
|
|
512894
|
-
this.upsertAgentSettings(agentId, {
|
|
513414
|
+
this.upsertAgentSettings(agentId, {
|
|
513415
|
+
systemPromptPreset: preset,
|
|
513416
|
+
systemPromptHash: null,
|
|
513417
|
+
systemPromptVersion: null
|
|
513418
|
+
});
|
|
513419
|
+
}
|
|
513420
|
+
setManagedSystemPrompt(agentId, prompt) {
|
|
513421
|
+
this.upsertAgentSettings(agentId, {
|
|
513422
|
+
systemPromptPreset: prompt.preset,
|
|
513423
|
+
systemPromptHash: prompt.hash,
|
|
513424
|
+
systemPromptVersion: prompt.version
|
|
513425
|
+
});
|
|
513426
|
+
}
|
|
513427
|
+
setSystemPromptCustom(agentId) {
|
|
513428
|
+
this.upsertAgentSettings(agentId, {
|
|
513429
|
+
systemPromptPreset: "custom",
|
|
513430
|
+
systemPromptHash: null,
|
|
513431
|
+
systemPromptVersion: null
|
|
513432
|
+
});
|
|
512895
513433
|
}
|
|
512896
513434
|
clearSystemPromptPreset(agentId) {
|
|
512897
|
-
this.upsertAgentSettings(agentId, {
|
|
513435
|
+
this.upsertAgentSettings(agentId, {
|
|
513436
|
+
systemPromptPreset: "",
|
|
513437
|
+
systemPromptHash: null,
|
|
513438
|
+
systemPromptVersion: null
|
|
513439
|
+
});
|
|
512898
513440
|
}
|
|
512899
513441
|
hasLocalLettaDir(workingDirectory = process.cwd()) {
|
|
512900
513442
|
const dirPath = join42(workingDirectory, ".letta");
|
|
@@ -514837,7 +515379,7 @@ Error: ${message}`);
|
|
|
514837
515379
|
blocks: []
|
|
514838
515380
|
});
|
|
514839
515381
|
if (settingsManager2.isReady) {
|
|
514840
|
-
settingsManager2.
|
|
515382
|
+
settingsManager2.setSystemPromptCustom(agent2.id);
|
|
514841
515383
|
}
|
|
514842
515384
|
if (result.skills && result.skills.length > 0) {
|
|
514843
515385
|
const { getAgentSkillsDir: getAgentSkillsDir3 } = await Promise.resolve().then(() => (init_skills4(), exports_skills3));
|
|
@@ -514890,6 +515432,7 @@ Error: ${message}`);
|
|
|
514890
515432
|
skillsDirectory: skillsDirectory2,
|
|
514891
515433
|
parallelToolCalls: true,
|
|
514892
515434
|
systemPromptPreset: systemPromptPreset2,
|
|
515435
|
+
systemPromptCustom: systemCustom,
|
|
514893
515436
|
memoryPromptMode: effectiveMemoryMode,
|
|
514894
515437
|
initBlocks: initBlocks2,
|
|
514895
515438
|
baseTools: baseTools2
|
|
@@ -515072,26 +515615,6 @@ Error: ${message}`);
|
|
|
515072
515615
|
} catch (error54) {
|
|
515073
515616
|
Promise.resolve().then(() => (init_debug2(), exports_debug2)).then(({ debugLog: debugLog5 }) => debugLog5("secrets", `Failed to init secrets: ${error54 instanceof Error ? error54.message : String(error54)}`));
|
|
515074
515617
|
}
|
|
515075
|
-
if (resuming && !systemPromptPreset2) {
|
|
515076
|
-
let storedPreset = settingsManager2.getSystemPromptPreset(agent2.id);
|
|
515077
|
-
if (!storedPreset && agent2.tags?.includes("origin:letta-code") && !agent2.tags?.includes("role:subagent")) {
|
|
515078
|
-
storedPreset = "custom";
|
|
515079
|
-
settingsManager2.setSystemPromptPreset(agent2.id, storedPreset);
|
|
515080
|
-
}
|
|
515081
|
-
if (storedPreset && storedPreset !== "custom") {
|
|
515082
|
-
const { buildSystemPrompt: rebuildPrompt, isKnownPreset: isKnown } = await Promise.resolve().then(() => (init_prompt_assets2(), exports_prompt_assets2));
|
|
515083
|
-
if (isKnown(storedPreset)) {
|
|
515084
|
-
const memoryMode = settingsManager2.isMemfsEnabled(agent2.id) ? "memfs" : "standard";
|
|
515085
|
-
const expected = rebuildPrompt(storedPreset, memoryMode);
|
|
515086
|
-
if (agent2.system !== expected) {
|
|
515087
|
-
await backend4.updateAgent(agent2.id, { system: expected });
|
|
515088
|
-
agent2 = await backend4.retrieveAgent(agent2.id);
|
|
515089
|
-
}
|
|
515090
|
-
} else {
|
|
515091
|
-
settingsManager2.clearSystemPromptPreset(agent2.id);
|
|
515092
|
-
}
|
|
515093
|
-
}
|
|
515094
|
-
}
|
|
515095
515618
|
if (shouldPersistSessionState2()) {
|
|
515096
515619
|
settingsManager2.persistSession(agent2.id, conversationIdToUse);
|
|
515097
515620
|
}
|
|
@@ -515101,6 +515624,19 @@ Error: ${message}`);
|
|
|
515101
515624
|
setConversationId2(conversationIdToUse);
|
|
515102
515625
|
markMilestone2("TUI_READY");
|
|
515103
515626
|
setLoadingState("ready");
|
|
515627
|
+
if (resuming && !systemPromptPreset2) {
|
|
515628
|
+
const {
|
|
515629
|
+
getMemoryPromptModeForAgent: getMemoryPromptModeForAgent3,
|
|
515630
|
+
scheduleManagedSystemPromptUpdate: scheduleManagedSystemPromptUpdate3
|
|
515631
|
+
} = await Promise.resolve().then(() => (init_system_prompt_versioning2(), exports_system_prompt_versioning2));
|
|
515632
|
+
scheduleManagedSystemPromptUpdate3({
|
|
515633
|
+
agent: agent2,
|
|
515634
|
+
memoryMode: getMemoryPromptModeForAgent3(agent2.id),
|
|
515635
|
+
onUpdated: (updatedAgent) => {
|
|
515636
|
+
setAgentState(updatedAgent);
|
|
515637
|
+
}
|
|
515638
|
+
});
|
|
515639
|
+
}
|
|
515104
515640
|
}
|
|
515105
515641
|
init().catch((err) => {
|
|
515106
515642
|
trackCliBoundaryError("tui_initialization_failed", err, "tui_app_initialization");
|
|
@@ -515250,4 +515786,4 @@ Error during initialization: ${message}`);
|
|
|
515250
515786
|
}
|
|
515251
515787
|
main2();
|
|
515252
515788
|
|
|
515253
|
-
//# debugId=
|
|
515789
|
+
//# debugId=1C963C23C659C5D164756E2164756E21
|