@letta-ai/letta-code 0.27.28 → 0.27.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/types/types/protocol_v2.d.ts +7 -1
- package/dist/types/types/protocol_v2.d.ts.map +1 -1
- package/letta.js +658 -576
- package/package.json +1 -1
package/letta.js
CHANGED
|
@@ -4719,12 +4719,98 @@ var init_settings_manager = __esm(() => {
|
|
|
4719
4719
|
settingsManager = globalThis.__lettaSettingsManager;
|
|
4720
4720
|
});
|
|
4721
4721
|
|
|
4722
|
+
// src/utils/timing.ts
|
|
4723
|
+
function isTimingsEnabled() {
|
|
4724
|
+
const val = process.env.LETTA_DEBUG_TIMINGS;
|
|
4725
|
+
return val === "1" || val === "true";
|
|
4726
|
+
}
|
|
4727
|
+
function formatDuration(ms) {
|
|
4728
|
+
if (ms < 1000)
|
|
4729
|
+
return `${Math.round(ms)}ms`;
|
|
4730
|
+
return `${(ms / 1000).toFixed(2)}s`;
|
|
4731
|
+
}
|
|
4732
|
+
function formatTimestamp(date) {
|
|
4733
|
+
return date.toISOString().slice(11, 23);
|
|
4734
|
+
}
|
|
4735
|
+
function logTiming(message) {
|
|
4736
|
+
if (isTimingsEnabled()) {
|
|
4737
|
+
console.error(`[timing] ${message}`);
|
|
4738
|
+
}
|
|
4739
|
+
}
|
|
4740
|
+
function markMilestone(name) {
|
|
4741
|
+
const now = performance.now();
|
|
4742
|
+
milestones.set(name, now);
|
|
4743
|
+
if (firstMilestoneTime === null) {
|
|
4744
|
+
firstMilestoneTime = now;
|
|
4745
|
+
}
|
|
4746
|
+
if (isTimingsEnabled()) {
|
|
4747
|
+
const relative = now - firstMilestoneTime;
|
|
4748
|
+
console.error(`[timing] MILESTONE ${name} at +${formatDuration(relative)} (${formatTimestamp(new Date)})`);
|
|
4749
|
+
}
|
|
4750
|
+
}
|
|
4751
|
+
function measureSinceMilestone(label, fromMilestone) {
|
|
4752
|
+
if (!isTimingsEnabled())
|
|
4753
|
+
return;
|
|
4754
|
+
const startTime = milestones.get(fromMilestone);
|
|
4755
|
+
if (startTime === undefined) {
|
|
4756
|
+
console.error(`[timing] WARNING: milestone "${fromMilestone}" not found for measurement "${label}"`);
|
|
4757
|
+
return;
|
|
4758
|
+
}
|
|
4759
|
+
const duration = performance.now() - startTime;
|
|
4760
|
+
console.error(`[timing] ${label}: ${formatDuration(duration)}`);
|
|
4761
|
+
}
|
|
4762
|
+
function reportAllMilestones() {
|
|
4763
|
+
if (!isTimingsEnabled() || milestones.size === 0)
|
|
4764
|
+
return;
|
|
4765
|
+
const first = firstMilestoneTime ?? 0;
|
|
4766
|
+
console.error(`[timing] ======== MILESTONE SUMMARY ========`);
|
|
4767
|
+
const sorted = [...milestones.entries()].sort((a, b) => a[1] - b[1]);
|
|
4768
|
+
let prevTime = first;
|
|
4769
|
+
for (const [name, time] of sorted) {
|
|
4770
|
+
const relativeToStart = time - first;
|
|
4771
|
+
const delta = time - prevTime;
|
|
4772
|
+
const deltaStr = prevTime === first ? "" : ` (+${formatDuration(delta)})`;
|
|
4773
|
+
console.error(`[timing] +${formatDuration(relativeToStart).padStart(8)} ${name}${deltaStr}`);
|
|
4774
|
+
prevTime = time;
|
|
4775
|
+
}
|
|
4776
|
+
console.error(`[timing] =====================================`);
|
|
4777
|
+
}
|
|
4778
|
+
function createTimingFetch(baseFetch) {
|
|
4779
|
+
return async (input, init) => {
|
|
4780
|
+
const start = performance.now();
|
|
4781
|
+
const startTime = formatTimestamp(new Date);
|
|
4782
|
+
const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
4783
|
+
const method = init?.method || "GET";
|
|
4784
|
+
let path2;
|
|
4785
|
+
try {
|
|
4786
|
+
path2 = new URL(url).pathname;
|
|
4787
|
+
} catch {
|
|
4788
|
+
path2 = url;
|
|
4789
|
+
}
|
|
4790
|
+
logTiming(`${method} ${path2} started at ${startTime}`);
|
|
4791
|
+
try {
|
|
4792
|
+
const response = await baseFetch(input, init);
|
|
4793
|
+
const duration = performance.now() - start;
|
|
4794
|
+
logTiming(`${method} ${path2} -> ${formatDuration(duration)} (status: ${response.status})`);
|
|
4795
|
+
return response;
|
|
4796
|
+
} catch (error) {
|
|
4797
|
+
const duration = performance.now() - start;
|
|
4798
|
+
logTiming(`${method} ${path2} -> FAILED after ${formatDuration(duration)}`);
|
|
4799
|
+
throw error;
|
|
4800
|
+
}
|
|
4801
|
+
};
|
|
4802
|
+
}
|
|
4803
|
+
var milestones, firstMilestoneTime = null;
|
|
4804
|
+
var init_timing = __esm(() => {
|
|
4805
|
+
milestones = new Map;
|
|
4806
|
+
});
|
|
4807
|
+
|
|
4722
4808
|
// package.json
|
|
4723
4809
|
var package_default;
|
|
4724
4810
|
var init_package = __esm(() => {
|
|
4725
4811
|
package_default = {
|
|
4726
4812
|
name: "@letta-ai/letta-code",
|
|
4727
|
-
version: "0.27.
|
|
4813
|
+
version: "0.27.29",
|
|
4728
4814
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
4729
4815
|
type: "module",
|
|
4730
4816
|
packageManager: "bun@1.3.0",
|
|
@@ -4856,474 +4942,6 @@ var init_package = __esm(() => {
|
|
|
4856
4942
|
};
|
|
4857
4943
|
});
|
|
4858
4944
|
|
|
4859
|
-
// src/backend/api/http-headers.ts
|
|
4860
|
-
function getLettaCodeHeaders(apiKey) {
|
|
4861
|
-
return {
|
|
4862
|
-
"Content-Type": "application/json",
|
|
4863
|
-
"User-Agent": `letta-code/${package_default.version}`,
|
|
4864
|
-
"X-Letta-Source": "letta-code",
|
|
4865
|
-
...apiKey ? { Authorization: `Bearer ${apiKey}` } : {}
|
|
4866
|
-
};
|
|
4867
|
-
}
|
|
4868
|
-
var init_http_headers = __esm(() => {
|
|
4869
|
-
init_package();
|
|
4870
|
-
});
|
|
4871
|
-
|
|
4872
|
-
// src/backend/api/request.ts
|
|
4873
|
-
async function getApiRequestConfig() {
|
|
4874
|
-
const settings = await settingsManager.getSettingsWithSecureTokens();
|
|
4875
|
-
return {
|
|
4876
|
-
baseUrl: process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL,
|
|
4877
|
-
apiKey: process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY || ""
|
|
4878
|
-
};
|
|
4879
|
-
}
|
|
4880
|
-
function maybeMapKnownApiError(status, responseText) {
|
|
4881
|
-
if (status !== 403) {
|
|
4882
|
-
return null;
|
|
4883
|
-
}
|
|
4884
|
-
try {
|
|
4885
|
-
const errorData = JSON.parse(responseText);
|
|
4886
|
-
if (typeof errorData.error === "string" && errorData.error.includes("only available for pro or enterprise")) {
|
|
4887
|
-
return new Error("PLAN_UPGRADE_REQUIRED");
|
|
4888
|
-
}
|
|
4889
|
-
} catch {}
|
|
4890
|
-
return null;
|
|
4891
|
-
}
|
|
4892
|
-
async function apiFetch(path2, options = {}) {
|
|
4893
|
-
const config = options.baseUrl === undefined || options.apiKey === undefined ? await getApiRequestConfig() : null;
|
|
4894
|
-
const baseUrl = options.baseUrl ?? config?.baseUrl;
|
|
4895
|
-
const apiKey = options.apiKey ?? config?.apiKey ?? "";
|
|
4896
|
-
if (!baseUrl) {
|
|
4897
|
-
throw new Error("Missing Letta API base URL");
|
|
4898
|
-
}
|
|
4899
|
-
const url = new URL(`${baseUrl}${path2}`);
|
|
4900
|
-
if (options.query) {
|
|
4901
|
-
for (const [key, value] of Object.entries(options.query)) {
|
|
4902
|
-
if (value !== undefined && value !== null) {
|
|
4903
|
-
url.searchParams.set(key, String(value));
|
|
4904
|
-
}
|
|
4905
|
-
}
|
|
4906
|
-
}
|
|
4907
|
-
return fetch(url, {
|
|
4908
|
-
method: options.method ?? "GET",
|
|
4909
|
-
headers: {
|
|
4910
|
-
...getLettaCodeHeaders(apiKey),
|
|
4911
|
-
...options.headers
|
|
4912
|
-
},
|
|
4913
|
-
...options.body && { body: JSON.stringify(options.body) },
|
|
4914
|
-
...options.signal && { signal: options.signal }
|
|
4915
|
-
});
|
|
4916
|
-
}
|
|
4917
|
-
async function apiRequest(method, path2, body, options = {}) {
|
|
4918
|
-
const response = await apiFetch(path2, {
|
|
4919
|
-
...options,
|
|
4920
|
-
method,
|
|
4921
|
-
body
|
|
4922
|
-
});
|
|
4923
|
-
const text = await response.text();
|
|
4924
|
-
if (!response.ok) {
|
|
4925
|
-
const mapped = maybeMapKnownApiError(response.status, text);
|
|
4926
|
-
if (mapped) {
|
|
4927
|
-
throw mapped;
|
|
4928
|
-
}
|
|
4929
|
-
throw new ApiRequestError(`API error (${response.status}): ${text}`, response.status, text);
|
|
4930
|
-
}
|
|
4931
|
-
if (!text) {
|
|
4932
|
-
return {};
|
|
4933
|
-
}
|
|
4934
|
-
return JSON.parse(text);
|
|
4935
|
-
}
|
|
4936
|
-
var ApiRequestError;
|
|
4937
|
-
var init_request = __esm(() => {
|
|
4938
|
-
init_oauth();
|
|
4939
|
-
init_settings_manager();
|
|
4940
|
-
init_http_headers();
|
|
4941
|
-
ApiRequestError = class ApiRequestError extends Error {
|
|
4942
|
-
status;
|
|
4943
|
-
responseText;
|
|
4944
|
-
constructor(message, status, responseText) {
|
|
4945
|
-
super(message);
|
|
4946
|
-
this.status = status;
|
|
4947
|
-
this.responseText = responseText;
|
|
4948
|
-
this.name = "ApiRequestError";
|
|
4949
|
-
}
|
|
4950
|
-
};
|
|
4951
|
-
});
|
|
4952
|
-
|
|
4953
|
-
// src/backend/api/conversations.ts
|
|
4954
|
-
var exports_conversations = {};
|
|
4955
|
-
__export(exports_conversations, {
|
|
4956
|
-
updateConversationDescription: () => updateConversationDescription,
|
|
4957
|
-
summarizeConversation: () => summarizeConversation,
|
|
4958
|
-
forkConversation: () => forkConversation
|
|
4959
|
-
});
|
|
4960
|
-
async function forkConversation(conversationId, options = {}) {
|
|
4961
|
-
const query = {
|
|
4962
|
-
...options.agentId ? { agent_id: options.agentId } : {},
|
|
4963
|
-
...options.hidden !== undefined ? { hidden: options.hidden } : {}
|
|
4964
|
-
};
|
|
4965
|
-
return apiRequest("POST", `/v1/conversations/${encodeURIComponent(conversationId)}/fork`, undefined, { query, ...options.headers ? { headers: options.headers } : {} });
|
|
4966
|
-
}
|
|
4967
|
-
async function updateConversationDescription(conversationId, body) {
|
|
4968
|
-
return apiRequest("PATCH", `/v1/conversations/${encodeURIComponent(conversationId)}`, body);
|
|
4969
|
-
}
|
|
4970
|
-
async function summarizeConversation(conversationId, body, options = {}) {
|
|
4971
|
-
return apiRequest("POST", `/v1/conversations/${encodeURIComponent(conversationId)}/summarize`, body, options);
|
|
4972
|
-
}
|
|
4973
|
-
var init_conversations2 = __esm(() => {
|
|
4974
|
-
init_request();
|
|
4975
|
-
});
|
|
4976
|
-
|
|
4977
|
-
// src/constants.ts
|
|
4978
|
-
var DEFAULT_SUMMARIZATION_MODEL = "letta/auto", DEFAULT_TITLE_SUMMARIZATION_MODEL = "letta/auto-fast", DEFAULT_AGENT_NAME = "Letta Code", INTERRUPTED_BY_USER = "Interrupted by user", TURN_DID_NOT_COMPLETE = "Turn did not complete", SYSTEM_REMINDER_TAG = "system-reminder", SYSTEM_REMINDER_OPEN, SYSTEM_REMINDER_CLOSE, SYSTEM_ALERT_TAG = "system-alert", SYSTEM_ALERT_OPEN, SYSTEM_ALERT_CLOSE, COMPACTION_SUMMARY_HEADER = "(Earlier messages in this conversation have been compacted to free up context, summarized below)", TOKEN_DISPLAY_THRESHOLD = 100, ELAPSED_DISPLAY_THRESHOLD_MS;
|
|
4979
|
-
var init_constants = __esm(() => {
|
|
4980
|
-
SYSTEM_REMINDER_OPEN = `<${SYSTEM_REMINDER_TAG}>`;
|
|
4981
|
-
SYSTEM_REMINDER_CLOSE = `</${SYSTEM_REMINDER_TAG}>`;
|
|
4982
|
-
SYSTEM_ALERT_OPEN = `<${SYSTEM_ALERT_TAG}>`;
|
|
4983
|
-
SYSTEM_ALERT_CLOSE = `</${SYSTEM_ALERT_TAG}>`;
|
|
4984
|
-
ELAPSED_DISPLAY_THRESHOLD_MS = 60 * 1000;
|
|
4985
|
-
});
|
|
4986
|
-
|
|
4987
|
-
// src/cli/helpers/conversation-title.ts
|
|
4988
|
-
function getConversationTitleSettings() {
|
|
4989
|
-
try {
|
|
4990
|
-
return {
|
|
4991
|
-
enabled: settingsManager.getSettings().autoConversationTitles === true
|
|
4992
|
-
};
|
|
4993
|
-
} catch {
|
|
4994
|
-
return { enabled: false };
|
|
4995
|
-
}
|
|
4996
|
-
}
|
|
4997
|
-
function setConversationTitleSettings(enabled) {
|
|
4998
|
-
settingsManager.updateSettings({ autoConversationTitles: enabled });
|
|
4999
|
-
return getConversationTitleSettings();
|
|
5000
|
-
}
|
|
5001
|
-
function normalizeConversationTitle(value) {
|
|
5002
|
-
let normalized = value.replace(/\s+/g, " ").trim();
|
|
5003
|
-
if (normalized.startsWith('"') && normalized.endsWith('"') || normalized.startsWith("'") && normalized.endsWith("'")) {
|
|
5004
|
-
normalized = normalized.slice(1, -1).trim();
|
|
5005
|
-
}
|
|
5006
|
-
if (!normalized || normalized.startsWith("/")) {
|
|
5007
|
-
return null;
|
|
5008
|
-
}
|
|
5009
|
-
return normalized.slice(0, CONVERSATION_TITLE_MAX_LENGTH);
|
|
5010
|
-
}
|
|
5011
|
-
function paginatedItems(value) {
|
|
5012
|
-
if (Array.isArray(value))
|
|
5013
|
-
return value;
|
|
5014
|
-
return value.getPaginatedItems?.() ?? [];
|
|
5015
|
-
}
|
|
5016
|
-
function extractAssistantText(content) {
|
|
5017
|
-
if (typeof content === "string") {
|
|
5018
|
-
return content;
|
|
5019
|
-
}
|
|
5020
|
-
if (Array.isArray(content)) {
|
|
5021
|
-
let collected = "";
|
|
5022
|
-
for (const part of content) {
|
|
5023
|
-
if (part && typeof part === "object" && "text" in part && typeof part.text === "string") {
|
|
5024
|
-
collected += part.text;
|
|
5025
|
-
}
|
|
5026
|
-
}
|
|
5027
|
-
return collected;
|
|
5028
|
-
}
|
|
5029
|
-
return "";
|
|
5030
|
-
}
|
|
5031
|
-
function stripSystemReminders(content) {
|
|
5032
|
-
return content.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g, "").trim();
|
|
5033
|
-
}
|
|
5034
|
-
function extractUserText(content) {
|
|
5035
|
-
if (typeof content === "string") {
|
|
5036
|
-
return stripSystemReminders(content);
|
|
5037
|
-
}
|
|
5038
|
-
if (Array.isArray(content)) {
|
|
5039
|
-
const parts = [];
|
|
5040
|
-
for (const part of content) {
|
|
5041
|
-
if (!part || typeof part !== "object")
|
|
5042
|
-
continue;
|
|
5043
|
-
const record = part;
|
|
5044
|
-
if (typeof record.text === "string") {
|
|
5045
|
-
parts.push(record.text);
|
|
5046
|
-
} else if (record.type === "image") {
|
|
5047
|
-
parts.push("[image]");
|
|
5048
|
-
}
|
|
5049
|
-
}
|
|
5050
|
-
return stripSystemReminders(parts.join(`
|
|
5051
|
-
`));
|
|
5052
|
-
}
|
|
5053
|
-
return "";
|
|
5054
|
-
}
|
|
5055
|
-
function messageToTitleMessage(message) {
|
|
5056
|
-
if (message.message_type === "user_message") {
|
|
5057
|
-
const content = extractUserText(message.content).trim();
|
|
5058
|
-
return content ? { role: "user", content } : null;
|
|
5059
|
-
}
|
|
5060
|
-
if (message.message_type === "assistant_message") {
|
|
5061
|
-
const content = extractAssistantText(message.content).trim();
|
|
5062
|
-
return content ? { role: "assistant", content } : null;
|
|
5063
|
-
}
|
|
5064
|
-
return null;
|
|
5065
|
-
}
|
|
5066
|
-
function buildConversationTitleMessages(messages) {
|
|
5067
|
-
const titleMessages = [];
|
|
5068
|
-
for (const message of messages) {
|
|
5069
|
-
const titleMessage = messageToTitleMessage(message);
|
|
5070
|
-
if (titleMessage) {
|
|
5071
|
-
titleMessages.push(titleMessage);
|
|
5072
|
-
}
|
|
5073
|
-
}
|
|
5074
|
-
return titleMessages;
|
|
5075
|
-
}
|
|
5076
|
-
async function listConversationTitleMessages(backend, conversationId) {
|
|
5077
|
-
const page = await backend.listConversationMessages(conversationId, {
|
|
5078
|
-
limit: CONVERSATION_TITLE_MESSAGE_LIMIT,
|
|
5079
|
-
order: "desc",
|
|
5080
|
-
include_return_message_types: ["user_message", "assistant_message"]
|
|
5081
|
-
});
|
|
5082
|
-
return buildConversationTitleMessages(paginatedItems(page).reverse());
|
|
5083
|
-
}
|
|
5084
|
-
async function generateConversationTitleFromSummary(conversationId, messages, model = DEFAULT_TITLE_SUMMARIZATION_MODEL) {
|
|
5085
|
-
if (messages.length === 0) {
|
|
5086
|
-
return null;
|
|
5087
|
-
}
|
|
5088
|
-
const abortController = new AbortController;
|
|
5089
|
-
const timeoutId = setTimeout(() => abortController.abort(), CONVERSATION_TITLE_TIMEOUT_MS);
|
|
5090
|
-
try {
|
|
5091
|
-
const response = await summarizeConversation(conversationId, {
|
|
5092
|
-
prompt: CONVERSATION_TITLE_SYSTEM_PROMPT,
|
|
5093
|
-
messages,
|
|
5094
|
-
model
|
|
5095
|
-
}, {
|
|
5096
|
-
signal: abortController.signal
|
|
5097
|
-
});
|
|
5098
|
-
return normalizeConversationTitle(response.summary);
|
|
5099
|
-
} catch (err) {
|
|
5100
|
-
if (isDebugEnabled()) {
|
|
5101
|
-
console.error("[DEBUG] generateConversationTitleFromSummary failed:", err);
|
|
5102
|
-
}
|
|
5103
|
-
return null;
|
|
5104
|
-
} finally {
|
|
5105
|
-
clearTimeout(timeoutId);
|
|
5106
|
-
}
|
|
5107
|
-
}
|
|
5108
|
-
var CONVERSATION_TITLE_MAX_LENGTH = 100, CONVERSATION_TITLE_TIMEOUT_MS = 30000, CONVERSATION_TITLE_SYSTEM_PROMPT = `You are a conversation title generator.
|
|
5109
|
-
|
|
5110
|
-
Output ONLY a short, descriptive title for the conversation above.
|
|
5111
|
-
Rules:
|
|
5112
|
-
- 2 to 7 words
|
|
5113
|
-
- describe the actual topic, not the mood
|
|
5114
|
-
- no quotes, markdown, prefixes, or trailing punctuation
|
|
5115
|
-
- never call any tools — reply with plain text only
|
|
5116
|
-
- avoid generic titles like "New conversation" or "Help request"`, CONVERSATION_TITLE_MESSAGE_LIMIT = 1e4;
|
|
5117
|
-
var init_conversation_title = __esm(() => {
|
|
5118
|
-
init_conversations2();
|
|
5119
|
-
init_constants();
|
|
5120
|
-
init_settings_manager();
|
|
5121
|
-
init_debug();
|
|
5122
|
-
});
|
|
5123
|
-
|
|
5124
|
-
// src/experiments/manager.ts
|
|
5125
|
-
function isEnabledToggle(value) {
|
|
5126
|
-
if (!value) {
|
|
5127
|
-
return false;
|
|
5128
|
-
}
|
|
5129
|
-
return ENABLED_TOGGLE_VALUES.has(value.trim().toLowerCase());
|
|
5130
|
-
}
|
|
5131
|
-
function getExperimentDefinition(id) {
|
|
5132
|
-
const definition = EXPERIMENT_DEFINITIONS.find((entry) => entry.id === id);
|
|
5133
|
-
if (!definition) {
|
|
5134
|
-
throw new Error(`Unknown experiment: ${id}`);
|
|
5135
|
-
}
|
|
5136
|
-
return definition;
|
|
5137
|
-
}
|
|
5138
|
-
|
|
5139
|
-
class ExperimentManager {
|
|
5140
|
-
getStoredOverrides() {
|
|
5141
|
-
try {
|
|
5142
|
-
return settingsManager.getSettings().experiments ?? {};
|
|
5143
|
-
} catch {
|
|
5144
|
-
return {};
|
|
5145
|
-
}
|
|
5146
|
-
}
|
|
5147
|
-
list() {
|
|
5148
|
-
return EXPERIMENT_DEFINITIONS.map((definition) => this.getSnapshot(definition.id));
|
|
5149
|
-
}
|
|
5150
|
-
getSnapshot(id) {
|
|
5151
|
-
const definition = getExperimentDefinition(id);
|
|
5152
|
-
if (id === "conversation_titles") {
|
|
5153
|
-
return {
|
|
5154
|
-
...definition,
|
|
5155
|
-
enabled: getConversationTitleSettings().enabled,
|
|
5156
|
-
source: "default",
|
|
5157
|
-
override: null
|
|
5158
|
-
};
|
|
5159
|
-
}
|
|
5160
|
-
const override = this.getStoredOverrides()[id];
|
|
5161
|
-
if (typeof override === "boolean") {
|
|
5162
|
-
return {
|
|
5163
|
-
...definition,
|
|
5164
|
-
enabled: override,
|
|
5165
|
-
source: "override",
|
|
5166
|
-
override
|
|
5167
|
-
};
|
|
5168
|
-
}
|
|
5169
|
-
const envEnabled = definition.envVar ? isEnabledToggle(process.env[definition.envVar]) : false;
|
|
5170
|
-
return {
|
|
5171
|
-
...definition,
|
|
5172
|
-
enabled: envEnabled,
|
|
5173
|
-
source: envEnabled ? "env" : "default",
|
|
5174
|
-
override: null
|
|
5175
|
-
};
|
|
5176
|
-
}
|
|
5177
|
-
isEnabled(id) {
|
|
5178
|
-
return this.getSnapshot(id).enabled;
|
|
5179
|
-
}
|
|
5180
|
-
set(id, enabled) {
|
|
5181
|
-
if (id === "conversation_titles") {
|
|
5182
|
-
setConversationTitleSettings(enabled);
|
|
5183
|
-
return this.getSnapshot(id);
|
|
5184
|
-
}
|
|
5185
|
-
const settings = settingsManager.getSettings();
|
|
5186
|
-
settingsManager.updateSettings({
|
|
5187
|
-
experiments: {
|
|
5188
|
-
...settings.experiments ?? {},
|
|
5189
|
-
[id]: enabled
|
|
5190
|
-
}
|
|
5191
|
-
});
|
|
5192
|
-
return this.getSnapshot(id);
|
|
5193
|
-
}
|
|
5194
|
-
toggle(id) {
|
|
5195
|
-
const snapshot = this.getSnapshot(id);
|
|
5196
|
-
return this.set(id, !snapshot.enabled);
|
|
5197
|
-
}
|
|
5198
|
-
}
|
|
5199
|
-
var ENABLED_TOGGLE_VALUES, EXPERIMENT_DEFINITIONS, experimentManager;
|
|
5200
|
-
var init_manager = __esm(() => {
|
|
5201
|
-
init_conversation_title();
|
|
5202
|
-
init_settings_manager();
|
|
5203
|
-
ENABLED_TOGGLE_VALUES = new Set(["1", "true", "yes"]);
|
|
5204
|
-
EXPERIMENT_DEFINITIONS = [
|
|
5205
|
-
{
|
|
5206
|
-
id: "artifacts",
|
|
5207
|
-
label: "artifacts",
|
|
5208
|
-
description: "Expose Letta Code Desktop artifact creation tools and artifact UI surfaces.",
|
|
5209
|
-
envVar: "LETTA_ARTIFACTS"
|
|
5210
|
-
},
|
|
5211
|
-
{
|
|
5212
|
-
id: "conversation_titles",
|
|
5213
|
-
label: "conversation titles",
|
|
5214
|
-
description: "Generate AI conversation titles automatically when possible."
|
|
5215
|
-
},
|
|
5216
|
-
{
|
|
5217
|
-
id: "desktop_conversation_bootstrap",
|
|
5218
|
-
label: "conversation bootstrap",
|
|
5219
|
-
description: "Inject lightweight prior-conversation context into the first turn of brand-new Letta Code conversations."
|
|
5220
|
-
},
|
|
5221
|
-
{
|
|
5222
|
-
id: "diffs",
|
|
5223
|
-
label: "diffs",
|
|
5224
|
-
description: "Open browser-based worktree diff previews powered by Diffs from Pierre."
|
|
5225
|
-
},
|
|
5226
|
-
{
|
|
5227
|
-
id: "node",
|
|
5228
|
-
label: "node",
|
|
5229
|
-
description: "Route API requests through the Letta Node / TS core path.",
|
|
5230
|
-
envVar: "LETTA_NODE"
|
|
5231
|
-
},
|
|
5232
|
-
{
|
|
5233
|
-
id: "tui_cron",
|
|
5234
|
-
label: "TUI cron scheduler",
|
|
5235
|
-
description: "Fire scheduled tasks from the CLI when the desktop app isn't running."
|
|
5236
|
-
}
|
|
5237
|
-
];
|
|
5238
|
-
experimentManager = new ExperimentManager;
|
|
5239
|
-
});
|
|
5240
|
-
|
|
5241
|
-
// src/utils/timing.ts
|
|
5242
|
-
function isTimingsEnabled() {
|
|
5243
|
-
const val = process.env.LETTA_DEBUG_TIMINGS;
|
|
5244
|
-
return val === "1" || val === "true";
|
|
5245
|
-
}
|
|
5246
|
-
function formatDuration(ms) {
|
|
5247
|
-
if (ms < 1000)
|
|
5248
|
-
return `${Math.round(ms)}ms`;
|
|
5249
|
-
return `${(ms / 1000).toFixed(2)}s`;
|
|
5250
|
-
}
|
|
5251
|
-
function formatTimestamp(date) {
|
|
5252
|
-
return date.toISOString().slice(11, 23);
|
|
5253
|
-
}
|
|
5254
|
-
function logTiming(message) {
|
|
5255
|
-
if (isTimingsEnabled()) {
|
|
5256
|
-
console.error(`[timing] ${message}`);
|
|
5257
|
-
}
|
|
5258
|
-
}
|
|
5259
|
-
function markMilestone(name) {
|
|
5260
|
-
const now = performance.now();
|
|
5261
|
-
milestones.set(name, now);
|
|
5262
|
-
if (firstMilestoneTime === null) {
|
|
5263
|
-
firstMilestoneTime = now;
|
|
5264
|
-
}
|
|
5265
|
-
if (isTimingsEnabled()) {
|
|
5266
|
-
const relative = now - firstMilestoneTime;
|
|
5267
|
-
console.error(`[timing] MILESTONE ${name} at +${formatDuration(relative)} (${formatTimestamp(new Date)})`);
|
|
5268
|
-
}
|
|
5269
|
-
}
|
|
5270
|
-
function measureSinceMilestone(label, fromMilestone) {
|
|
5271
|
-
if (!isTimingsEnabled())
|
|
5272
|
-
return;
|
|
5273
|
-
const startTime = milestones.get(fromMilestone);
|
|
5274
|
-
if (startTime === undefined) {
|
|
5275
|
-
console.error(`[timing] WARNING: milestone "${fromMilestone}" not found for measurement "${label}"`);
|
|
5276
|
-
return;
|
|
5277
|
-
}
|
|
5278
|
-
const duration = performance.now() - startTime;
|
|
5279
|
-
console.error(`[timing] ${label}: ${formatDuration(duration)}`);
|
|
5280
|
-
}
|
|
5281
|
-
function reportAllMilestones() {
|
|
5282
|
-
if (!isTimingsEnabled() || milestones.size === 0)
|
|
5283
|
-
return;
|
|
5284
|
-
const first = firstMilestoneTime ?? 0;
|
|
5285
|
-
console.error(`[timing] ======== MILESTONE SUMMARY ========`);
|
|
5286
|
-
const sorted = [...milestones.entries()].sort((a, b) => a[1] - b[1]);
|
|
5287
|
-
let prevTime = first;
|
|
5288
|
-
for (const [name, time] of sorted) {
|
|
5289
|
-
const relativeToStart = time - first;
|
|
5290
|
-
const delta = time - prevTime;
|
|
5291
|
-
const deltaStr = prevTime === first ? "" : ` (+${formatDuration(delta)})`;
|
|
5292
|
-
console.error(`[timing] +${formatDuration(relativeToStart).padStart(8)} ${name}${deltaStr}`);
|
|
5293
|
-
prevTime = time;
|
|
5294
|
-
}
|
|
5295
|
-
console.error(`[timing] =====================================`);
|
|
5296
|
-
}
|
|
5297
|
-
function createTimingFetch(baseFetch) {
|
|
5298
|
-
return async (input, init) => {
|
|
5299
|
-
const start = performance.now();
|
|
5300
|
-
const startTime = formatTimestamp(new Date);
|
|
5301
|
-
const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
5302
|
-
const method = init?.method || "GET";
|
|
5303
|
-
let path2;
|
|
5304
|
-
try {
|
|
5305
|
-
path2 = new URL(url).pathname;
|
|
5306
|
-
} catch {
|
|
5307
|
-
path2 = url;
|
|
5308
|
-
}
|
|
5309
|
-
logTiming(`${method} ${path2} started at ${startTime}`);
|
|
5310
|
-
try {
|
|
5311
|
-
const response = await baseFetch(input, init);
|
|
5312
|
-
const duration = performance.now() - start;
|
|
5313
|
-
logTiming(`${method} ${path2} -> ${formatDuration(duration)} (status: ${response.status})`);
|
|
5314
|
-
return response;
|
|
5315
|
-
} catch (error) {
|
|
5316
|
-
const duration = performance.now() - start;
|
|
5317
|
-
logTiming(`${method} ${path2} -> FAILED after ${formatDuration(duration)}`);
|
|
5318
|
-
throw error;
|
|
5319
|
-
}
|
|
5320
|
-
};
|
|
5321
|
-
}
|
|
5322
|
-
var milestones, firstMilestoneTime = null;
|
|
5323
|
-
var init_timing = __esm(() => {
|
|
5324
|
-
milestones = new Map;
|
|
5325
|
-
});
|
|
5326
|
-
|
|
5327
4945
|
// src/backend/api/memfs-git-proxy.ts
|
|
5328
4946
|
var exports_memfs_git_proxy = {};
|
|
5329
4947
|
__export(exports_memfs_git_proxy, {
|
|
@@ -5441,13 +5059,20 @@ function getServerUrl() {
|
|
|
5441
5059
|
const settings = settingsManager.getSettings();
|
|
5442
5060
|
return process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL;
|
|
5443
5061
|
}
|
|
5062
|
+
function getNodeRoutingHeader() {
|
|
5063
|
+
const raw = process.env.LETTA_NODE;
|
|
5064
|
+
if (raw === undefined || raw.trim() === "") {
|
|
5065
|
+
return {};
|
|
5066
|
+
}
|
|
5067
|
+
const enabled = NODE_HEADER_ENABLED_VALUES.has(raw.trim().toLowerCase());
|
|
5068
|
+
return { "x-letta-node": enabled ? "1" : "0" };
|
|
5069
|
+
}
|
|
5444
5070
|
function getClientDefaultHeaders() {
|
|
5445
|
-
const nodeExperiment = experimentManager.getSnapshot("node");
|
|
5446
5071
|
return {
|
|
5447
5072
|
"X-Letta-Source": "letta-code",
|
|
5448
5073
|
"User-Agent": `letta-code/${package_default.version}`,
|
|
5449
5074
|
"X-Letta-Environment-Device-Id": settingsManager.getOrCreateDeviceId(),
|
|
5450
|
-
...
|
|
5075
|
+
...getNodeRoutingHeader(),
|
|
5451
5076
|
...process.env.LETTA_MEMFS_BACKEND === "hosted" ? { "x-letta-memfs-backend": "hosted" } : {}
|
|
5452
5077
|
};
|
|
5453
5078
|
}
|
|
@@ -5540,11 +5165,10 @@ If you experience this issue multiple times, move ~/.letta to ~/.letta_backup, a
|
|
|
5540
5165
|
};
|
|
5541
5166
|
return client;
|
|
5542
5167
|
}
|
|
5543
|
-
var SDK_DIAGNOSTIC_MAX_LEN = 400, SDK_DIAGNOSTIC_MAX_LINES = 4, lastSDKDiagnostic = null, _cachedApiKey, _testClientOverride = null, sdkLogger;
|
|
5168
|
+
var SDK_DIAGNOSTIC_MAX_LEN = 400, SDK_DIAGNOSTIC_MAX_LINES = 4, lastSDKDiagnostic = null, _cachedApiKey, _testClientOverride = null, sdkLogger, NODE_HEADER_ENABLED_VALUES;
|
|
5544
5169
|
var init_client2 = __esm(() => {
|
|
5545
5170
|
init_letta_client();
|
|
5546
5171
|
init_oauth();
|
|
5547
|
-
init_manager();
|
|
5548
5172
|
init_settings_manager();
|
|
5549
5173
|
init_error_reporting();
|
|
5550
5174
|
init_debug();
|
|
@@ -5570,6 +5194,101 @@ var init_client2 = __esm(() => {
|
|
|
5570
5194
|
console.debug(...args);
|
|
5571
5195
|
}
|
|
5572
5196
|
};
|
|
5197
|
+
NODE_HEADER_ENABLED_VALUES = new Set(["1", "true", "yes"]);
|
|
5198
|
+
});
|
|
5199
|
+
|
|
5200
|
+
// src/backend/api/http-headers.ts
|
|
5201
|
+
function getLettaCodeHeaders(apiKey) {
|
|
5202
|
+
return {
|
|
5203
|
+
"Content-Type": "application/json",
|
|
5204
|
+
"User-Agent": `letta-code/${package_default.version}`,
|
|
5205
|
+
"X-Letta-Source": "letta-code",
|
|
5206
|
+
...apiKey ? { Authorization: `Bearer ${apiKey}` } : {}
|
|
5207
|
+
};
|
|
5208
|
+
}
|
|
5209
|
+
var init_http_headers = __esm(() => {
|
|
5210
|
+
init_package();
|
|
5211
|
+
});
|
|
5212
|
+
|
|
5213
|
+
// src/backend/api/request.ts
|
|
5214
|
+
async function getApiRequestConfig() {
|
|
5215
|
+
const settings = await settingsManager.getSettingsWithSecureTokens();
|
|
5216
|
+
return {
|
|
5217
|
+
baseUrl: process.env.LETTA_BASE_URL || settings.env?.LETTA_BASE_URL || LETTA_CLOUD_API_URL,
|
|
5218
|
+
apiKey: process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY || ""
|
|
5219
|
+
};
|
|
5220
|
+
}
|
|
5221
|
+
function maybeMapKnownApiError(status, responseText) {
|
|
5222
|
+
if (status !== 403) {
|
|
5223
|
+
return null;
|
|
5224
|
+
}
|
|
5225
|
+
try {
|
|
5226
|
+
const errorData = JSON.parse(responseText);
|
|
5227
|
+
if (typeof errorData.error === "string" && errorData.error.includes("only available for pro or enterprise")) {
|
|
5228
|
+
return new Error("PLAN_UPGRADE_REQUIRED");
|
|
5229
|
+
}
|
|
5230
|
+
} catch {}
|
|
5231
|
+
return null;
|
|
5232
|
+
}
|
|
5233
|
+
async function apiFetch(path2, options = {}) {
|
|
5234
|
+
const config = options.baseUrl === undefined || options.apiKey === undefined ? await getApiRequestConfig() : null;
|
|
5235
|
+
const baseUrl = options.baseUrl ?? config?.baseUrl;
|
|
5236
|
+
const apiKey = options.apiKey ?? config?.apiKey ?? "";
|
|
5237
|
+
if (!baseUrl) {
|
|
5238
|
+
throw new Error("Missing Letta API base URL");
|
|
5239
|
+
}
|
|
5240
|
+
const url = new URL(`${baseUrl}${path2}`);
|
|
5241
|
+
if (options.query) {
|
|
5242
|
+
for (const [key, value] of Object.entries(options.query)) {
|
|
5243
|
+
if (value !== undefined && value !== null) {
|
|
5244
|
+
url.searchParams.set(key, String(value));
|
|
5245
|
+
}
|
|
5246
|
+
}
|
|
5247
|
+
}
|
|
5248
|
+
return fetch(url, {
|
|
5249
|
+
method: options.method ?? "GET",
|
|
5250
|
+
headers: {
|
|
5251
|
+
...getLettaCodeHeaders(apiKey),
|
|
5252
|
+
...options.headers
|
|
5253
|
+
},
|
|
5254
|
+
...options.body && { body: JSON.stringify(options.body) },
|
|
5255
|
+
...options.signal && { signal: options.signal }
|
|
5256
|
+
});
|
|
5257
|
+
}
|
|
5258
|
+
async function apiRequest(method, path2, body, options = {}) {
|
|
5259
|
+
const response = await apiFetch(path2, {
|
|
5260
|
+
...options,
|
|
5261
|
+
method,
|
|
5262
|
+
body
|
|
5263
|
+
});
|
|
5264
|
+
const text = await response.text();
|
|
5265
|
+
if (!response.ok) {
|
|
5266
|
+
const mapped = maybeMapKnownApiError(response.status, text);
|
|
5267
|
+
if (mapped) {
|
|
5268
|
+
throw mapped;
|
|
5269
|
+
}
|
|
5270
|
+
throw new ApiRequestError(`API error (${response.status}): ${text}`, response.status, text);
|
|
5271
|
+
}
|
|
5272
|
+
if (!text) {
|
|
5273
|
+
return {};
|
|
5274
|
+
}
|
|
5275
|
+
return JSON.parse(text);
|
|
5276
|
+
}
|
|
5277
|
+
var ApiRequestError;
|
|
5278
|
+
var init_request = __esm(() => {
|
|
5279
|
+
init_oauth();
|
|
5280
|
+
init_settings_manager();
|
|
5281
|
+
init_http_headers();
|
|
5282
|
+
ApiRequestError = class ApiRequestError extends Error {
|
|
5283
|
+
status;
|
|
5284
|
+
responseText;
|
|
5285
|
+
constructor(message, status, responseText) {
|
|
5286
|
+
super(message);
|
|
5287
|
+
this.status = status;
|
|
5288
|
+
this.responseText = responseText;
|
|
5289
|
+
this.name = "ApiRequestError";
|
|
5290
|
+
}
|
|
5291
|
+
};
|
|
5573
5292
|
});
|
|
5574
5293
|
|
|
5575
5294
|
// src/backend/api/health.ts
|
|
@@ -18018,7 +17737,7 @@ var init_items = __esm(() => {
|
|
|
18018
17737
|
|
|
18019
17738
|
// node_modules/openai/resources/conversations/conversations.mjs
|
|
18020
17739
|
var Conversations2;
|
|
18021
|
-
var
|
|
17740
|
+
var init_conversations2 = __esm(() => {
|
|
18022
17741
|
init_items();
|
|
18023
17742
|
init_items();
|
|
18024
17743
|
init_path2();
|
|
@@ -19485,7 +19204,7 @@ var init_resources2 = __esm(() => {
|
|
|
19485
19204
|
init_beta();
|
|
19486
19205
|
init_completions3();
|
|
19487
19206
|
init_containers();
|
|
19488
|
-
|
|
19207
|
+
init_conversations2();
|
|
19489
19208
|
init_embeddings2();
|
|
19490
19209
|
init_evals();
|
|
19491
19210
|
init_files4();
|
|
@@ -19934,7 +19653,7 @@ var init_client3 = __esm(() => {
|
|
|
19934
19653
|
init_beta();
|
|
19935
19654
|
init_chat();
|
|
19936
19655
|
init_containers();
|
|
19937
|
-
|
|
19656
|
+
init_conversations2();
|
|
19938
19657
|
init_evals();
|
|
19939
19658
|
init_fine_tuning();
|
|
19940
19659
|
init_graders2();
|
|
@@ -39441,7 +39160,7 @@ var init_error5 = __esm(() => {
|
|
|
39441
39160
|
|
|
39442
39161
|
// node_modules/@anthropic-ai/sdk/internal/constants.mjs
|
|
39443
39162
|
var MODEL_NONSTREAMING_TOKENS;
|
|
39444
|
-
var
|
|
39163
|
+
var init_constants = __esm(() => {
|
|
39445
39164
|
MODEL_NONSTREAMING_TOKENS = {
|
|
39446
39165
|
"claude-opus-4-20250514": 8192,
|
|
39447
39166
|
"claude-opus-4-0": 8192,
|
|
@@ -40739,7 +40458,7 @@ function transformOutputFormat(params) {
|
|
|
40739
40458
|
var DEPRECATED_MODELS, MODELS_TO_WARN_WITH_THINKING_ENABLED, Messages8;
|
|
40740
40459
|
var init_messages8 = __esm(() => {
|
|
40741
40460
|
init_error5();
|
|
40742
|
-
|
|
40461
|
+
init_constants();
|
|
40743
40462
|
init_headers3();
|
|
40744
40463
|
init_stainless_helper_header();
|
|
40745
40464
|
init_beta_parser();
|
|
@@ -41979,7 +41698,7 @@ var init_messages9 = __esm(() => {
|
|
|
41979
41698
|
init_parser5();
|
|
41980
41699
|
init_batches3();
|
|
41981
41700
|
init_batches3();
|
|
41982
|
-
|
|
41701
|
+
init_constants();
|
|
41983
41702
|
Messages9 = class Messages9 extends APIResource3 {
|
|
41984
41703
|
constructor() {
|
|
41985
41704
|
super(...arguments);
|
|
@@ -114208,7 +113927,7 @@ var init_betaConversationsStartStream = __esm(() => {
|
|
|
114208
113927
|
|
|
114209
113928
|
// node_modules/@mistralai/mistralai/esm/sdk/conversations.js
|
|
114210
113929
|
var Conversations3;
|
|
114211
|
-
var
|
|
113930
|
+
var init_conversations3 = __esm(() => {
|
|
114212
113931
|
init_betaConversationsAppend();
|
|
114213
113932
|
init_betaConversationsAppendStream();
|
|
114214
113933
|
init_betaConversationsDelete();
|
|
@@ -119556,7 +119275,7 @@ var init_beta3 = __esm(() => {
|
|
|
119556
119275
|
init_sdks();
|
|
119557
119276
|
init_betaagents();
|
|
119558
119277
|
init_connectors();
|
|
119559
|
-
|
|
119278
|
+
init_conversations3();
|
|
119560
119279
|
init_libraries();
|
|
119561
119280
|
init_observability();
|
|
119562
119281
|
init_rag();
|
|
@@ -141070,6 +140789,8 @@ function isFresh(now = Date.now()) {
|
|
|
141070
140789
|
}
|
|
141071
140790
|
function clearAvailableModelsCache() {
|
|
141072
140791
|
cache = null;
|
|
140792
|
+
inflight = null;
|
|
140793
|
+
generation++;
|
|
141073
140794
|
}
|
|
141074
140795
|
function getAvailableModelsCacheInfo() {
|
|
141075
140796
|
const now = Date.now();
|
|
@@ -141133,13 +140854,19 @@ async function getAvailableModelHandles(options3) {
|
|
|
141133
140854
|
if (forceRefresh && backend.capabilities.byokProviderRefresh) {
|
|
141134
140855
|
await refreshByokProviders();
|
|
141135
140856
|
}
|
|
141136
|
-
|
|
141137
|
-
|
|
140857
|
+
const requestGeneration = generation;
|
|
140858
|
+
const request = fetchFromNetwork().then((entry2) => {
|
|
140859
|
+
if (generation === requestGeneration) {
|
|
140860
|
+
cache = entry2;
|
|
140861
|
+
}
|
|
141138
140862
|
return entry2;
|
|
141139
140863
|
}).finally(() => {
|
|
141140
|
-
inflight
|
|
140864
|
+
if (inflight === request) {
|
|
140865
|
+
inflight = null;
|
|
140866
|
+
}
|
|
141141
140867
|
});
|
|
141142
|
-
|
|
140868
|
+
inflight = request;
|
|
140869
|
+
const entry = await request;
|
|
141143
140870
|
return {
|
|
141144
140871
|
handles: entry.handles,
|
|
141145
140872
|
providerTypes: entry.providerTypes,
|
|
@@ -141162,7 +140889,7 @@ async function getModelProviderType(handle) {
|
|
|
141162
140889
|
}
|
|
141163
140890
|
return cache?.providerTypes.get(handle);
|
|
141164
140891
|
}
|
|
141165
|
-
var CACHE_TTL_MS, cache = null, inflight = null;
|
|
140892
|
+
var CACHE_TTL_MS, cache = null, inflight = null, generation = 0;
|
|
141166
140893
|
var init_available_models = __esm(() => {
|
|
141167
140894
|
init_backend2();
|
|
141168
140895
|
init_providers();
|
|
@@ -152980,7 +152707,7 @@ function createChannelTurnProgressBuilder(options3 = {}) {
|
|
|
152980
152707
|
namesByToolCallId.delete(summary.id);
|
|
152981
152708
|
}
|
|
152982
152709
|
const toolWithAccumulatedArgs = accumulatedArgs ? { ...summary, argumentsText: accumulatedArgs } : summary;
|
|
152983
|
-
const toolDetails =
|
|
152710
|
+
const toolDetails = formatToolProgressDetails(toolWithAccumulatedArgs, options3);
|
|
152984
152711
|
const toolTitle = formatToolProgressTitle(toolWithAccumulatedArgs, status);
|
|
152985
152712
|
updates.push(withRunId({
|
|
152986
152713
|
kind: "tool",
|
|
@@ -152989,6 +152716,7 @@ function createChannelTurnProgressBuilder(options3 = {}) {
|
|
|
152989
152716
|
...summary.id ? { toolCallId: summary.id } : {},
|
|
152990
152717
|
...summary.name ? { toolName: summary.name } : {},
|
|
152991
152718
|
...toolDetails ? { toolDetails } : {},
|
|
152719
|
+
...status === "error" && errorDetails ? { errorDetails } : {},
|
|
152992
152720
|
...toolTitle ? { toolTitle } : {}
|
|
152993
152721
|
}, runId));
|
|
152994
152722
|
}
|
|
@@ -153019,7 +152747,8 @@ function createChannelTurnProgressBuilder(options3 = {}) {
|
|
|
153019
152747
|
namesByToolCallId.delete(tool2.id);
|
|
153020
152748
|
}
|
|
153021
152749
|
const toolWithAccumulatedArgs = tool2 && accumulatedArgs ? { ...tool2, argumentsText: accumulatedArgs } : tool2;
|
|
153022
|
-
const toolDetails = toolWithAccumulatedArgs ?
|
|
152750
|
+
const toolDetails = toolWithAccumulatedArgs ? formatToolProgressDetails(toolWithAccumulatedArgs, options3) : undefined;
|
|
152751
|
+
const errorDetails = state === "error" ? formatToolErrorDetails(record5) : undefined;
|
|
153023
152752
|
const toolTitle = toolWithAccumulatedArgs ? formatToolProgressTitle(toolWithAccumulatedArgs, state) : undefined;
|
|
153024
152753
|
return [
|
|
153025
152754
|
withRunId({
|
|
@@ -153029,6 +152758,7 @@ function createChannelTurnProgressBuilder(options3 = {}) {
|
|
|
153029
152758
|
...tool2?.id ? { toolCallId: tool2.id } : {},
|
|
153030
152759
|
...tool2?.name ? { toolName: tool2.name } : {},
|
|
153031
152760
|
...toolDetails ? { toolDetails } : {},
|
|
152761
|
+
...errorDetails ? { errorDetails } : {},
|
|
153032
152762
|
...toolTitle ? { toolTitle } : {}
|
|
153033
152763
|
}, runId)
|
|
153034
152764
|
];
|
|
@@ -154177,7 +153907,7 @@ function formatSlackToolTaskTitle(toolName, status, details) {
|
|
|
154177
153907
|
if (details) {
|
|
154178
153908
|
return details;
|
|
154179
153909
|
}
|
|
154180
|
-
return status === "complete" ? "Ran" : "Running";
|
|
153910
|
+
return status === "complete" || status === "error" ? "Ran" : "Running";
|
|
154181
153911
|
}
|
|
154182
153912
|
if (toolName === "TaskOutput") {
|
|
154183
153913
|
return status === "complete" ? "Checked task output" : "Checking task output";
|
|
@@ -154272,7 +154002,7 @@ function resolveSlackToolActionDetails(entry, update2) {
|
|
|
154272
154002
|
return;
|
|
154273
154003
|
}
|
|
154274
154004
|
const rememberedDetails = update2.toolCallId ? entry.toolDetailsByCallId?.get(update2.toolCallId) : undefined;
|
|
154275
|
-
const details = update2.toolDetails ?? rememberedDetails;
|
|
154005
|
+
const details = (update2.state === "error" ? update2.errorDetails : undefined) ?? update2.toolDetails ?? rememberedDetails;
|
|
154276
154006
|
if (!details) {
|
|
154277
154007
|
return;
|
|
154278
154008
|
}
|
|
@@ -154407,7 +154137,7 @@ function buildSlackPlanUpdateChunk(entry) {
|
|
|
154407
154137
|
if (entry.status === "cancelled") {
|
|
154408
154138
|
return {
|
|
154409
154139
|
type: "plan_update",
|
|
154410
|
-
title: "
|
|
154140
|
+
title: "Interrupted"
|
|
154411
154141
|
};
|
|
154412
154142
|
}
|
|
154413
154143
|
if (entry.status === "completed") {
|
|
@@ -154547,7 +154277,8 @@ function buildSlackStreamProgressChunks(entry, update2) {
|
|
|
154547
154277
|
const resolvedDetails = resolveSlackToolActionDetails(entry, update2);
|
|
154548
154278
|
const sentDetails = entry.sentTaskDetailsById?.get(id2);
|
|
154549
154279
|
const details = sentDetails && resolvedDetails && sentDetails !== resolvedDetails ? sentDetails : resolvedDetails;
|
|
154550
|
-
const
|
|
154280
|
+
const titleDetails = update2.toolDetails ?? (update2.toolCallId ? entry.toolDetailsByCallId?.get(update2.toolCallId) : undefined);
|
|
154281
|
+
const title = resolveSlackToolActionName(entry, update2, titleDetails);
|
|
154551
154282
|
if (!title) {
|
|
154552
154283
|
return [];
|
|
154553
154284
|
}
|
|
@@ -154597,7 +154328,7 @@ function resolveSlackLifecycleProgressText(outcome) {
|
|
|
154597
154328
|
return { status: "completed", text: "Completed" };
|
|
154598
154329
|
}
|
|
154599
154330
|
if (outcome === "cancelled") {
|
|
154600
|
-
return { status: "cancelled", text: "
|
|
154331
|
+
return { status: "cancelled", text: "Interrupted" };
|
|
154601
154332
|
}
|
|
154602
154333
|
return { status: "error", text: "Failed" };
|
|
154603
154334
|
}
|
|
@@ -154801,6 +154532,7 @@ function createSlackAdapter(config3) {
|
|
|
154801
154532
|
const agentThreadTracker = createAgentThreadTracker();
|
|
154802
154533
|
const progressCardByReplyKey = new Map;
|
|
154803
154534
|
const activeProgressCardKeyByReplyKey = new Map;
|
|
154535
|
+
const orphanedStreamsByReplyKey = new Map;
|
|
154804
154536
|
const assistantStatusReplyKeys = new Set;
|
|
154805
154537
|
const assistantStatusTextByReplyKey = new Map;
|
|
154806
154538
|
const progressUpdateThrottleMs = resolveSlackProgressUpdateThrottleMs();
|
|
@@ -155127,6 +154859,59 @@ function createSlackAdapter(config3) {
|
|
|
155127
154859
|
}
|
|
155128
154860
|
return args;
|
|
155129
154861
|
}
|
|
154862
|
+
function rememberOrphanedSlackProgressStream(source2, streamTs, terminalPlanTitle) {
|
|
154863
|
+
const replyKey = getLifecycleReplyKey(source2);
|
|
154864
|
+
if (!replyKey) {
|
|
154865
|
+
return;
|
|
154866
|
+
}
|
|
154867
|
+
let orphans = orphanedStreamsByReplyKey.get(replyKey);
|
|
154868
|
+
if (!orphans) {
|
|
154869
|
+
if (orphanedStreamsByReplyKey.size >= SLACK_ORPHANED_STREAM_THREADS_MAX) {
|
|
154870
|
+
const oldestKey = orphanedStreamsByReplyKey.keys().next().value;
|
|
154871
|
+
if (oldestKey !== undefined) {
|
|
154872
|
+
orphanedStreamsByReplyKey.delete(oldestKey);
|
|
154873
|
+
}
|
|
154874
|
+
}
|
|
154875
|
+
orphans = new Map;
|
|
154876
|
+
orphanedStreamsByReplyKey.set(replyKey, orphans);
|
|
154877
|
+
}
|
|
154878
|
+
if (orphans.size >= SLACK_ORPHANED_STREAMS_PER_THREAD_MAX) {
|
|
154879
|
+
return;
|
|
154880
|
+
}
|
|
154881
|
+
orphans.set(streamTs, terminalPlanTitle);
|
|
154882
|
+
console.warn("[Slack] Progress stream stop failed; deferring close until the next stream in this thread:", streamTs);
|
|
154883
|
+
}
|
|
154884
|
+
async function sweepOrphanedSlackProgressStreams(source2, slackClient) {
|
|
154885
|
+
const replyKey = getLifecycleReplyKey(source2);
|
|
154886
|
+
if (!replyKey) {
|
|
154887
|
+
return;
|
|
154888
|
+
}
|
|
154889
|
+
const orphans = orphanedStreamsByReplyKey.get(replyKey);
|
|
154890
|
+
if (!orphans || orphans.size === 0) {
|
|
154891
|
+
return;
|
|
154892
|
+
}
|
|
154893
|
+
orphanedStreamsByReplyKey.delete(replyKey);
|
|
154894
|
+
const stopStream = slackClient.chat.stopStream;
|
|
154895
|
+
if (!stopStream) {
|
|
154896
|
+
return;
|
|
154897
|
+
}
|
|
154898
|
+
for (const [ts, terminalPlanTitle] of orphans) {
|
|
154899
|
+
try {
|
|
154900
|
+
const response = await stopStream.call(slackClient.chat, {
|
|
154901
|
+
channel: source2.chatId,
|
|
154902
|
+
ts,
|
|
154903
|
+
chunks: [{ type: "plan_update", title: terminalPlanTitle }]
|
|
154904
|
+
});
|
|
154905
|
+
if (response.ok === false && !isSlackMessageNotStreamingStateError(response.error)) {
|
|
154906
|
+
console.warn("[Slack] Failed to stop orphaned progress stream:", response.error ?? "unknown error");
|
|
154907
|
+
}
|
|
154908
|
+
} catch (error54) {
|
|
154909
|
+
if (!isSlackMessageNotStreamingStateError(error54)) {
|
|
154910
|
+
console.warn("[Slack] Failed to stop orphaned progress stream:", error54 instanceof Error ? error54.message : error54);
|
|
154911
|
+
}
|
|
154912
|
+
}
|
|
154913
|
+
}
|
|
154914
|
+
}
|
|
155130
154915
|
async function startSlackProgressStream(entry, replyToMessageId, rawChunks) {
|
|
155131
154916
|
if (!canStartSlackStream(entry.source)) {
|
|
155132
154917
|
return false;
|
|
@@ -155140,6 +154925,7 @@ function createSlackAdapter(config3) {
|
|
|
155140
154925
|
if (!startStream) {
|
|
155141
154926
|
return false;
|
|
155142
154927
|
}
|
|
154928
|
+
await sweepOrphanedSlackProgressStreams(entry.source, slackClient);
|
|
155143
154929
|
try {
|
|
155144
154930
|
const args = buildSlackStartStreamArgs(entry, replyToMessageId, rawChunks);
|
|
155145
154931
|
const response = await startStream.call(slackClient.chat, args);
|
|
@@ -155546,6 +155332,8 @@ function createSlackAdapter(config3) {
|
|
|
155546
155332
|
if (didStop) {
|
|
155547
155333
|
entry.lastSentText = formatSlackProgressCardText(entry.status, entry.latestText);
|
|
155548
155334
|
entry.lastSentAt = Date.now();
|
|
155335
|
+
} else if (!entry.streamDead && entry.streamTs) {
|
|
155336
|
+
rememberOrphanedSlackProgressStream(source2, entry.streamTs, entry.status === "completed" ? formatSlackCompletionPlanTitle(entry) : entry.status === "cancelled" ? "Interrupted" : "Failed");
|
|
155549
155337
|
}
|
|
155550
155338
|
} else {
|
|
155551
155339
|
await upsertSlackProgressCard(source2, progress.status, progress.text, {
|
|
@@ -156285,7 +156073,7 @@ function createSlackAdapter(config3) {
|
|
|
156285
156073
|
};
|
|
156286
156074
|
return adapter;
|
|
156287
156075
|
}
|
|
156288
|
-
var INITIAL_SLACK_THREAD_HISTORY_LIMIT = 20, SLACK_ASSISTANT_STATUS_VERBS, IGNORED_SLACK_MESSAGE_SUBTYPES, WRAPPER_SLACK_MESSAGE_SUBTYPES, SLACK_INGRESS_DEDUPE_TTL_MS = 60000, SLACK_INGRESS_DEDUPE_MAX = 2000, SLACK_LIFECYCLE_ERROR_TEXT_MAX = 3000, SLACK_DEAD_STREAM_REWRITE_TEXT_MAX = 2900, SLACK_PROGRESS_CARD_TEXT_MAX = 300, SLACK_PROGRESS_CARD_STATE_TTL_MS, SLACK_PROGRESS_CARD_STATE_MAX = 2000, SLACK_STREAM_CHUNK_TEXT_MAX = 256, SLACK_LIFECYCLE_ERROR_TASK_ID = "task_lifecycle_error", SLACK_CHANNEL_RESPONSE_TASK_ID = "task_channel_response", SLACK_TURN_ACTIVE_TASK_ID = "task_turn_active", DEFAULT_SLACK_PROGRESS_UPDATE_THROTTLE_MS = 1000, DEFAULT_SLACK_PROGRESS_STREAM_KEEPALIVE_MS = 60000, DEFAULT_SLACK_COMPLETION_FINALIZE_GRACE_MS = 500, SLACK_AGENT_THREAD_TTL_MS, SLACK_AGENT_THREAD_MAX = 2000, APP_MENTION_RETRY_TTL_MS = 60000;
|
|
156076
|
+
var INITIAL_SLACK_THREAD_HISTORY_LIMIT = 20, SLACK_ASSISTANT_STATUS_VERBS, IGNORED_SLACK_MESSAGE_SUBTYPES, WRAPPER_SLACK_MESSAGE_SUBTYPES, SLACK_INGRESS_DEDUPE_TTL_MS = 60000, SLACK_INGRESS_DEDUPE_MAX = 2000, SLACK_LIFECYCLE_ERROR_TEXT_MAX = 3000, SLACK_DEAD_STREAM_REWRITE_TEXT_MAX = 2900, SLACK_PROGRESS_CARD_TEXT_MAX = 300, SLACK_PROGRESS_CARD_STATE_TTL_MS, SLACK_PROGRESS_CARD_STATE_MAX = 2000, SLACK_ORPHANED_STREAMS_PER_THREAD_MAX = 4, SLACK_ORPHANED_STREAM_THREADS_MAX = 500, SLACK_STREAM_CHUNK_TEXT_MAX = 256, SLACK_LIFECYCLE_ERROR_TASK_ID = "task_lifecycle_error", SLACK_CHANNEL_RESPONSE_TASK_ID = "task_channel_response", SLACK_TURN_ACTIVE_TASK_ID = "task_turn_active", DEFAULT_SLACK_PROGRESS_UPDATE_THROTTLE_MS = 1000, DEFAULT_SLACK_PROGRESS_STREAM_KEEPALIVE_MS = 60000, DEFAULT_SLACK_COMPLETION_FINALIZE_GRACE_MS = 500, SLACK_AGENT_THREAD_TTL_MS, SLACK_AGENT_THREAD_MAX = 2000, APP_MENTION_RETRY_TTL_MS = 60000;
|
|
156289
156077
|
var init_adapter3 = __esm(async () => {
|
|
156290
156078
|
init_commands();
|
|
156291
156079
|
init_lifecycle_error();
|
|
@@ -159076,7 +158864,7 @@ function createWhatsAppAdapter(account) {
|
|
|
159076
158864
|
}
|
|
159077
158865
|
async function connect() {
|
|
159078
158866
|
connectionGeneration += 1;
|
|
159079
|
-
const
|
|
158867
|
+
const generation2 = connectionGeneration;
|
|
159080
158868
|
clearActiveSocket(true);
|
|
159081
158869
|
await ensureRuntimeHelpers();
|
|
159082
158870
|
connectedAtMs = Date.now();
|
|
@@ -159085,7 +158873,7 @@ function createWhatsAppAdapter(account) {
|
|
|
159085
158873
|
printQr: true,
|
|
159086
158874
|
messageStore,
|
|
159087
158875
|
onConnectionUpdate(update2) {
|
|
159088
|
-
if (
|
|
158876
|
+
if (generation2 !== connectionGeneration)
|
|
159089
158877
|
return;
|
|
159090
158878
|
if (update2.connection === "open") {
|
|
159091
158879
|
reconnectAttempts = 0;
|
|
@@ -159113,7 +158901,7 @@ function createWhatsAppAdapter(account) {
|
|
|
159113
158901
|
}
|
|
159114
158902
|
}
|
|
159115
158903
|
});
|
|
159116
|
-
if (
|
|
158904
|
+
if (generation2 !== connectionGeneration || stopping || !running) {
|
|
159117
158905
|
try {
|
|
159118
158906
|
result.sock.ws?.close?.();
|
|
159119
158907
|
} catch {}
|
|
@@ -162622,6 +162410,16 @@ var init_routing = __esm(() => {
|
|
|
162622
162410
|
routesByKey = new Map;
|
|
162623
162411
|
});
|
|
162624
162412
|
|
|
162413
|
+
// src/constants.ts
|
|
162414
|
+
var DEFAULT_SUMMARIZATION_MODEL = "letta/auto", DEFAULT_TITLE_SUMMARIZATION_MODEL = "letta/auto-fast", DEFAULT_AGENT_NAME = "Letta Code", INTERRUPTED_BY_USER = "Interrupted by user", TURN_DID_NOT_COMPLETE = "Turn did not complete", SYSTEM_REMINDER_TAG = "system-reminder", SYSTEM_REMINDER_OPEN, SYSTEM_REMINDER_CLOSE, SYSTEM_ALERT_TAG = "system-alert", SYSTEM_ALERT_OPEN, SYSTEM_ALERT_CLOSE, COMPACTION_SUMMARY_HEADER = "(Earlier messages in this conversation have been compacted to free up context, summarized below)", TOKEN_DISPLAY_THRESHOLD = 100, ELAPSED_DISPLAY_THRESHOLD_MS;
|
|
162415
|
+
var init_constants2 = __esm(() => {
|
|
162416
|
+
SYSTEM_REMINDER_OPEN = `<${SYSTEM_REMINDER_TAG}>`;
|
|
162417
|
+
SYSTEM_REMINDER_CLOSE = `</${SYSTEM_REMINDER_TAG}>`;
|
|
162418
|
+
SYSTEM_ALERT_OPEN = `<${SYSTEM_ALERT_TAG}>`;
|
|
162419
|
+
SYSTEM_ALERT_CLOSE = `</${SYSTEM_ALERT_TAG}>`;
|
|
162420
|
+
ELAPSED_DISPLAY_THRESHOLD_MS = 60 * 1000;
|
|
162421
|
+
});
|
|
162422
|
+
|
|
162625
162423
|
// src/cli/helpers/git-context.ts
|
|
162626
162424
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
162627
162425
|
function runGit(args, cwd) {
|
|
@@ -162850,7 +162648,7 @@ ${gitInfo.status}
|
|
|
162850
162648
|
}
|
|
162851
162649
|
}
|
|
162852
162650
|
var init_session_context = __esm(() => {
|
|
162853
|
-
|
|
162651
|
+
init_constants2();
|
|
162854
162652
|
init_version();
|
|
162855
162653
|
init_git_context();
|
|
162856
162654
|
});
|
|
@@ -163090,7 +162888,7 @@ function formatChannelNotification(msg) {
|
|
|
163090
162888
|
}
|
|
163091
162889
|
var init_xml = __esm(() => {
|
|
163092
162890
|
init_session_context();
|
|
163093
|
-
|
|
162891
|
+
init_constants2();
|
|
163094
162892
|
});
|
|
163095
162893
|
|
|
163096
162894
|
// src/channels/registry.ts
|
|
@@ -164752,6 +164550,278 @@ var init_registry = __esm(() => {
|
|
|
164752
164550
|
};
|
|
164753
164551
|
});
|
|
164754
164552
|
|
|
164553
|
+
// src/backend/api/conversations.ts
|
|
164554
|
+
var exports_conversations = {};
|
|
164555
|
+
__export(exports_conversations, {
|
|
164556
|
+
updateConversationDescription: () => updateConversationDescription,
|
|
164557
|
+
summarizeConversation: () => summarizeConversation,
|
|
164558
|
+
forkConversation: () => forkConversation
|
|
164559
|
+
});
|
|
164560
|
+
async function forkConversation(conversationId, options3 = {}) {
|
|
164561
|
+
const query2 = {
|
|
164562
|
+
...options3.agentId ? { agent_id: options3.agentId } : {},
|
|
164563
|
+
...options3.hidden !== undefined ? { hidden: options3.hidden } : {}
|
|
164564
|
+
};
|
|
164565
|
+
return apiRequest("POST", `/v1/conversations/${encodeURIComponent(conversationId)}/fork`, undefined, { query: query2, ...options3.headers ? { headers: options3.headers } : {} });
|
|
164566
|
+
}
|
|
164567
|
+
async function updateConversationDescription(conversationId, body) {
|
|
164568
|
+
return apiRequest("PATCH", `/v1/conversations/${encodeURIComponent(conversationId)}`, body);
|
|
164569
|
+
}
|
|
164570
|
+
async function summarizeConversation(conversationId, body, options3 = {}) {
|
|
164571
|
+
return apiRequest("POST", `/v1/conversations/${encodeURIComponent(conversationId)}/summarize`, body, options3);
|
|
164572
|
+
}
|
|
164573
|
+
var init_conversations4 = __esm(() => {
|
|
164574
|
+
init_request();
|
|
164575
|
+
});
|
|
164576
|
+
|
|
164577
|
+
// src/cli/helpers/conversation-title.ts
|
|
164578
|
+
function getConversationTitleSettings() {
|
|
164579
|
+
try {
|
|
164580
|
+
return {
|
|
164581
|
+
enabled: settingsManager.getSettings().autoConversationTitles === true
|
|
164582
|
+
};
|
|
164583
|
+
} catch {
|
|
164584
|
+
return { enabled: false };
|
|
164585
|
+
}
|
|
164586
|
+
}
|
|
164587
|
+
function setConversationTitleSettings(enabled) {
|
|
164588
|
+
settingsManager.updateSettings({ autoConversationTitles: enabled });
|
|
164589
|
+
return getConversationTitleSettings();
|
|
164590
|
+
}
|
|
164591
|
+
function normalizeConversationTitle(value) {
|
|
164592
|
+
let normalized = value.replace(/\s+/g, " ").trim();
|
|
164593
|
+
if (normalized.startsWith('"') && normalized.endsWith('"') || normalized.startsWith("'") && normalized.endsWith("'")) {
|
|
164594
|
+
normalized = normalized.slice(1, -1).trim();
|
|
164595
|
+
}
|
|
164596
|
+
if (!normalized || normalized.startsWith("/")) {
|
|
164597
|
+
return null;
|
|
164598
|
+
}
|
|
164599
|
+
return normalized.slice(0, CONVERSATION_TITLE_MAX_LENGTH);
|
|
164600
|
+
}
|
|
164601
|
+
function paginatedItems(value) {
|
|
164602
|
+
if (Array.isArray(value))
|
|
164603
|
+
return value;
|
|
164604
|
+
return value.getPaginatedItems?.() ?? [];
|
|
164605
|
+
}
|
|
164606
|
+
function extractAssistantText(content) {
|
|
164607
|
+
if (typeof content === "string") {
|
|
164608
|
+
return content;
|
|
164609
|
+
}
|
|
164610
|
+
if (Array.isArray(content)) {
|
|
164611
|
+
let collected = "";
|
|
164612
|
+
for (const part of content) {
|
|
164613
|
+
if (part && typeof part === "object" && "text" in part && typeof part.text === "string") {
|
|
164614
|
+
collected += part.text;
|
|
164615
|
+
}
|
|
164616
|
+
}
|
|
164617
|
+
return collected;
|
|
164618
|
+
}
|
|
164619
|
+
return "";
|
|
164620
|
+
}
|
|
164621
|
+
function stripSystemReminders(content) {
|
|
164622
|
+
return content.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g, "").trim();
|
|
164623
|
+
}
|
|
164624
|
+
function extractUserText(content) {
|
|
164625
|
+
if (typeof content === "string") {
|
|
164626
|
+
return stripSystemReminders(content);
|
|
164627
|
+
}
|
|
164628
|
+
if (Array.isArray(content)) {
|
|
164629
|
+
const parts = [];
|
|
164630
|
+
for (const part of content) {
|
|
164631
|
+
if (!part || typeof part !== "object")
|
|
164632
|
+
continue;
|
|
164633
|
+
const record5 = part;
|
|
164634
|
+
if (typeof record5.text === "string") {
|
|
164635
|
+
parts.push(record5.text);
|
|
164636
|
+
} else if (record5.type === "image") {
|
|
164637
|
+
parts.push("[image]");
|
|
164638
|
+
}
|
|
164639
|
+
}
|
|
164640
|
+
return stripSystemReminders(parts.join(`
|
|
164641
|
+
`));
|
|
164642
|
+
}
|
|
164643
|
+
return "";
|
|
164644
|
+
}
|
|
164645
|
+
function messageToTitleMessage(message) {
|
|
164646
|
+
if (message.message_type === "user_message") {
|
|
164647
|
+
const content = extractUserText(message.content).trim();
|
|
164648
|
+
return content ? { role: "user", content } : null;
|
|
164649
|
+
}
|
|
164650
|
+
if (message.message_type === "assistant_message") {
|
|
164651
|
+
const content = extractAssistantText(message.content).trim();
|
|
164652
|
+
return content ? { role: "assistant", content } : null;
|
|
164653
|
+
}
|
|
164654
|
+
return null;
|
|
164655
|
+
}
|
|
164656
|
+
function buildConversationTitleMessages(messages) {
|
|
164657
|
+
const titleMessages = [];
|
|
164658
|
+
for (const message of messages) {
|
|
164659
|
+
const titleMessage = messageToTitleMessage(message);
|
|
164660
|
+
if (titleMessage) {
|
|
164661
|
+
titleMessages.push(titleMessage);
|
|
164662
|
+
}
|
|
164663
|
+
}
|
|
164664
|
+
return titleMessages;
|
|
164665
|
+
}
|
|
164666
|
+
async function listConversationTitleMessages(backend, conversationId) {
|
|
164667
|
+
const page = await backend.listConversationMessages(conversationId, {
|
|
164668
|
+
limit: CONVERSATION_TITLE_MESSAGE_LIMIT,
|
|
164669
|
+
order: "desc",
|
|
164670
|
+
include_return_message_types: ["user_message", "assistant_message"]
|
|
164671
|
+
});
|
|
164672
|
+
return buildConversationTitleMessages(paginatedItems(page).reverse());
|
|
164673
|
+
}
|
|
164674
|
+
async function generateConversationTitleFromSummary(conversationId, messages, model = DEFAULT_TITLE_SUMMARIZATION_MODEL) {
|
|
164675
|
+
if (messages.length === 0) {
|
|
164676
|
+
return null;
|
|
164677
|
+
}
|
|
164678
|
+
const abortController = new AbortController;
|
|
164679
|
+
const timeoutId = setTimeout(() => abortController.abort(), CONVERSATION_TITLE_TIMEOUT_MS);
|
|
164680
|
+
try {
|
|
164681
|
+
const response = await summarizeConversation(conversationId, {
|
|
164682
|
+
prompt: CONVERSATION_TITLE_SYSTEM_PROMPT,
|
|
164683
|
+
messages,
|
|
164684
|
+
model
|
|
164685
|
+
}, {
|
|
164686
|
+
signal: abortController.signal
|
|
164687
|
+
});
|
|
164688
|
+
return normalizeConversationTitle(response.summary);
|
|
164689
|
+
} catch (err) {
|
|
164690
|
+
if (isDebugEnabled()) {
|
|
164691
|
+
console.error("[DEBUG] generateConversationTitleFromSummary failed:", err);
|
|
164692
|
+
}
|
|
164693
|
+
return null;
|
|
164694
|
+
} finally {
|
|
164695
|
+
clearTimeout(timeoutId);
|
|
164696
|
+
}
|
|
164697
|
+
}
|
|
164698
|
+
var CONVERSATION_TITLE_MAX_LENGTH = 100, CONVERSATION_TITLE_TIMEOUT_MS = 30000, CONVERSATION_TITLE_SYSTEM_PROMPT = `You are a conversation title generator.
|
|
164699
|
+
|
|
164700
|
+
Output ONLY a short, descriptive title for the conversation above.
|
|
164701
|
+
Rules:
|
|
164702
|
+
- 2 to 7 words
|
|
164703
|
+
- describe the actual topic, not the mood
|
|
164704
|
+
- no quotes, markdown, prefixes, or trailing punctuation
|
|
164705
|
+
- never call any tools — reply with plain text only
|
|
164706
|
+
- avoid generic titles like "New conversation" or "Help request"`, CONVERSATION_TITLE_MESSAGE_LIMIT = 1e4;
|
|
164707
|
+
var init_conversation_title = __esm(() => {
|
|
164708
|
+
init_conversations4();
|
|
164709
|
+
init_constants2();
|
|
164710
|
+
init_settings_manager();
|
|
164711
|
+
init_debug();
|
|
164712
|
+
});
|
|
164713
|
+
|
|
164714
|
+
// src/experiments/manager.ts
|
|
164715
|
+
function isEnabledToggle(value) {
|
|
164716
|
+
if (!value) {
|
|
164717
|
+
return false;
|
|
164718
|
+
}
|
|
164719
|
+
return ENABLED_TOGGLE_VALUES.has(value.trim().toLowerCase());
|
|
164720
|
+
}
|
|
164721
|
+
function getExperimentDefinition(id2) {
|
|
164722
|
+
const definition = EXPERIMENT_DEFINITIONS.find((entry) => entry.id === id2);
|
|
164723
|
+
if (!definition) {
|
|
164724
|
+
throw new Error(`Unknown experiment: ${id2}`);
|
|
164725
|
+
}
|
|
164726
|
+
return definition;
|
|
164727
|
+
}
|
|
164728
|
+
|
|
164729
|
+
class ExperimentManager {
|
|
164730
|
+
getStoredOverrides() {
|
|
164731
|
+
try {
|
|
164732
|
+
return settingsManager.getSettings().experiments ?? {};
|
|
164733
|
+
} catch {
|
|
164734
|
+
return {};
|
|
164735
|
+
}
|
|
164736
|
+
}
|
|
164737
|
+
list() {
|
|
164738
|
+
return EXPERIMENT_DEFINITIONS.map((definition) => this.getSnapshot(definition.id));
|
|
164739
|
+
}
|
|
164740
|
+
getSnapshot(id2) {
|
|
164741
|
+
const definition = getExperimentDefinition(id2);
|
|
164742
|
+
if (id2 === "conversation_titles") {
|
|
164743
|
+
return {
|
|
164744
|
+
...definition,
|
|
164745
|
+
enabled: getConversationTitleSettings().enabled,
|
|
164746
|
+
source: "default",
|
|
164747
|
+
override: null
|
|
164748
|
+
};
|
|
164749
|
+
}
|
|
164750
|
+
const override = this.getStoredOverrides()[id2];
|
|
164751
|
+
if (typeof override === "boolean") {
|
|
164752
|
+
return {
|
|
164753
|
+
...definition,
|
|
164754
|
+
enabled: override,
|
|
164755
|
+
source: "override",
|
|
164756
|
+
override
|
|
164757
|
+
};
|
|
164758
|
+
}
|
|
164759
|
+
const envEnabled = definition.envVar ? isEnabledToggle(process.env[definition.envVar]) : false;
|
|
164760
|
+
return {
|
|
164761
|
+
...definition,
|
|
164762
|
+
enabled: envEnabled,
|
|
164763
|
+
source: envEnabled ? "env" : "default",
|
|
164764
|
+
override: null
|
|
164765
|
+
};
|
|
164766
|
+
}
|
|
164767
|
+
isEnabled(id2) {
|
|
164768
|
+
return this.getSnapshot(id2).enabled;
|
|
164769
|
+
}
|
|
164770
|
+
set(id2, enabled) {
|
|
164771
|
+
if (id2 === "conversation_titles") {
|
|
164772
|
+
setConversationTitleSettings(enabled);
|
|
164773
|
+
return this.getSnapshot(id2);
|
|
164774
|
+
}
|
|
164775
|
+
const settings3 = settingsManager.getSettings();
|
|
164776
|
+
settingsManager.updateSettings({
|
|
164777
|
+
experiments: {
|
|
164778
|
+
...settings3.experiments ?? {},
|
|
164779
|
+
[id2]: enabled
|
|
164780
|
+
}
|
|
164781
|
+
});
|
|
164782
|
+
return this.getSnapshot(id2);
|
|
164783
|
+
}
|
|
164784
|
+
toggle(id2) {
|
|
164785
|
+
const snapshot = this.getSnapshot(id2);
|
|
164786
|
+
return this.set(id2, !snapshot.enabled);
|
|
164787
|
+
}
|
|
164788
|
+
}
|
|
164789
|
+
var ENABLED_TOGGLE_VALUES, EXPERIMENT_DEFINITIONS, experimentManager;
|
|
164790
|
+
var init_manager = __esm(() => {
|
|
164791
|
+
init_conversation_title();
|
|
164792
|
+
init_settings_manager();
|
|
164793
|
+
ENABLED_TOGGLE_VALUES = new Set(["1", "true", "yes"]);
|
|
164794
|
+
EXPERIMENT_DEFINITIONS = [
|
|
164795
|
+
{
|
|
164796
|
+
id: "artifacts",
|
|
164797
|
+
label: "artifacts",
|
|
164798
|
+
description: "Expose Letta Code Desktop artifact creation tools and artifact UI surfaces.",
|
|
164799
|
+
envVar: "LETTA_ARTIFACTS"
|
|
164800
|
+
},
|
|
164801
|
+
{
|
|
164802
|
+
id: "conversation_titles",
|
|
164803
|
+
label: "conversation titles",
|
|
164804
|
+
description: "Generate AI conversation titles automatically when possible."
|
|
164805
|
+
},
|
|
164806
|
+
{
|
|
164807
|
+
id: "desktop_conversation_bootstrap",
|
|
164808
|
+
label: "conversation bootstrap",
|
|
164809
|
+
description: "Inject lightweight prior-conversation context into the first turn of brand-new Letta Code conversations."
|
|
164810
|
+
},
|
|
164811
|
+
{
|
|
164812
|
+
id: "diffs",
|
|
164813
|
+
label: "diffs",
|
|
164814
|
+
description: "Open browser-based worktree diff previews powered by Diffs from Pierre."
|
|
164815
|
+
},
|
|
164816
|
+
{
|
|
164817
|
+
id: "tui_cron",
|
|
164818
|
+
label: "TUI cron scheduler",
|
|
164819
|
+
description: "Fire scheduled tasks from the CLI when the desktop app isn't running."
|
|
164820
|
+
}
|
|
164821
|
+
];
|
|
164822
|
+
experimentManager = new ExperimentManager;
|
|
164823
|
+
});
|
|
164824
|
+
|
|
164755
164825
|
// src/agent/subagent-state.ts
|
|
164756
164826
|
function updateSnapshot() {
|
|
164757
164827
|
const agents = Array.from(store2.agents.values());
|
|
@@ -165383,7 +165453,7 @@ async function executeAutoAllowedTools(autoAllowed, onChunk, options3) {
|
|
|
165383
165453
|
}
|
|
165384
165454
|
var PARALLEL_SAFE_TOOLS, FILE_PATH_TOOLS, GLOBAL_LOCK_TOOLS;
|
|
165385
165455
|
var init_approval_execution = __esm(async () => {
|
|
165386
|
-
|
|
165456
|
+
init_constants2();
|
|
165387
165457
|
init_runtime_context();
|
|
165388
165458
|
await init_manager4();
|
|
165389
165459
|
PARALLEL_SAFE_TOOLS = new Set([
|
|
@@ -172359,7 +172429,7 @@ ${errorMessage}`;
|
|
|
172359
172429
|
}
|
|
172360
172430
|
var cachedWorkingLauncher = null;
|
|
172361
172431
|
var init_bash = __esm(() => {
|
|
172362
|
-
|
|
172432
|
+
init_constants2();
|
|
172363
172433
|
init_runtime_context();
|
|
172364
172434
|
init_worktree_ownership();
|
|
172365
172435
|
init_process_manager();
|
|
@@ -180355,7 +180425,7 @@ function normalizeOutgoingApprovalMessages(messages, options3 = {}) {
|
|
|
180355
180425
|
}
|
|
180356
180426
|
var APPROVAL_COMMENT_PREFIX = "The user approved the tool execution with the following comment:";
|
|
180357
180427
|
var init_approval_result_normalization = __esm(() => {
|
|
180358
|
-
|
|
180428
|
+
init_constants2();
|
|
180359
180429
|
});
|
|
180360
180430
|
|
|
180361
180431
|
// src/agent/skills.ts
|
|
@@ -181249,7 +181319,7 @@ async function runModCommandWithTimeout(command, context2) {
|
|
|
181249
181319
|
}
|
|
181250
181320
|
var MOD_COMMAND_TIMEOUT_MS = 30000;
|
|
181251
181321
|
var init_command_runtime = __esm(() => {
|
|
181252
|
-
|
|
181322
|
+
init_constants2();
|
|
181253
181323
|
});
|
|
181254
181324
|
|
|
181255
181325
|
// src/mods/capabilities.ts
|
|
@@ -351268,14 +351338,14 @@ function resolveLocalModSources(options3 = {}) {
|
|
|
351268
351338
|
}
|
|
351269
351339
|
return sources;
|
|
351270
351340
|
}
|
|
351271
|
-
function createEmptyModRegistry(sources,
|
|
351341
|
+
function createEmptyModRegistry(sources, generation2, capabilities) {
|
|
351272
351342
|
return {
|
|
351273
351343
|
capabilities: cloneModCapabilities(capabilities),
|
|
351274
351344
|
commands: {},
|
|
351275
351345
|
diagnostics: [],
|
|
351276
351346
|
disposers: [],
|
|
351277
351347
|
events: {},
|
|
351278
|
-
generation,
|
|
351348
|
+
generation: generation2,
|
|
351279
351349
|
loadedPaths: [],
|
|
351280
351350
|
ownerAbortControllers: {},
|
|
351281
351351
|
owners: {},
|
|
@@ -351287,12 +351357,12 @@ function createEmptyModRegistry(sources, generation, capabilities) {
|
|
|
351287
351357
|
}
|
|
351288
351358
|
};
|
|
351289
351359
|
}
|
|
351290
|
-
function createModOwner(modPath, source2,
|
|
351360
|
+
function createModOwner(modPath, source2, generation2) {
|
|
351291
351361
|
return {
|
|
351292
351362
|
id: `${source2.scope}:${modPath}`,
|
|
351293
351363
|
path: modPath,
|
|
351294
351364
|
scope: source2.scope,
|
|
351295
|
-
generation
|
|
351365
|
+
generation: generation2
|
|
351296
351366
|
};
|
|
351297
351367
|
}
|
|
351298
351368
|
function isOwnerLive(registry2, owner) {
|
|
@@ -352066,13 +352136,13 @@ async function loadLocalMods(options3) {
|
|
|
352066
352136
|
const onChange = options3.onChange ?? (() => {});
|
|
352067
352137
|
const sources = resolveLocalModSources(options3);
|
|
352068
352138
|
const capabilities = resolveModCapabilities(options3.capabilities);
|
|
352069
|
-
const
|
|
352139
|
+
const generation2 = options3.generation ?? 1;
|
|
352070
352140
|
const builtinCommandIds = new Set([...options3.builtinCommandIds ?? []]);
|
|
352071
352141
|
const reservedToolNames = new Set([...options3.reservedToolNames ?? []]);
|
|
352072
|
-
const registry2 = createEmptyModRegistry(sources,
|
|
352142
|
+
const registry2 = createEmptyModRegistry(sources, generation2, capabilities);
|
|
352073
352143
|
for (const source2 of sources) {
|
|
352074
352144
|
for (const diagnostic of source2.diagnostics ?? []) {
|
|
352075
|
-
const owner = createModOwner(diagnostic.path, source2,
|
|
352145
|
+
const owner = createModOwner(diagnostic.path, source2, generation2);
|
|
352076
352146
|
recordModDiagnostic(registry2, {
|
|
352077
352147
|
error: diagnostic.error,
|
|
352078
352148
|
owner,
|
|
@@ -352080,7 +352150,7 @@ async function loadLocalMods(options3) {
|
|
|
352080
352150
|
}, options3.onDiagnostic);
|
|
352081
352151
|
}
|
|
352082
352152
|
for (const modPath of source2.files) {
|
|
352083
|
-
const owner = createModOwner(modPath, source2,
|
|
352153
|
+
const owner = createModOwner(modPath, source2, generation2);
|
|
352084
352154
|
const abortController = new AbortController;
|
|
352085
352155
|
let failurePhase = "import";
|
|
352086
352156
|
registry2.ownerAbortControllers[owner.id] = abortController;
|
|
@@ -352253,10 +352323,10 @@ function disposeLocalMods(registry2) {
|
|
|
352253
352323
|
}
|
|
352254
352324
|
function createModEngine(options3) {
|
|
352255
352325
|
const { getBackend: getBackend2, onDiagnostic, ...modOptions } = options3;
|
|
352256
|
-
let
|
|
352326
|
+
let generation2 = 0;
|
|
352257
352327
|
let disposed = false;
|
|
352258
352328
|
const capabilities = resolveModCapabilities(modOptions.capabilities);
|
|
352259
|
-
let activeRegistry = createEmptyModRegistry(resolveLocalModSources(modOptions),
|
|
352329
|
+
let activeRegistry = createEmptyModRegistry(resolveLocalModSources(modOptions), generation2, capabilities);
|
|
352260
352330
|
let snapshot = snapshotRegistryForReaders(activeRegistry);
|
|
352261
352331
|
const listeners2 = new Set;
|
|
352262
352332
|
const publish = () => {
|
|
@@ -352269,8 +352339,8 @@ function createModEngine(options3) {
|
|
|
352269
352339
|
if (disposed)
|
|
352270
352340
|
return;
|
|
352271
352341
|
disposeLocalMods(activeRegistry);
|
|
352272
|
-
|
|
352273
|
-
const loadGeneration =
|
|
352342
|
+
generation2 += 1;
|
|
352343
|
+
const loadGeneration = generation2;
|
|
352274
352344
|
activeRegistry = createEmptyModRegistry(resolveLocalModSources(modOptions), loadGeneration, capabilities);
|
|
352275
352345
|
publish();
|
|
352276
352346
|
let loadingRegistry = null;
|
|
@@ -352278,7 +352348,7 @@ function createModEngine(options3) {
|
|
|
352278
352348
|
...modOptions,
|
|
352279
352349
|
generation: loadGeneration,
|
|
352280
352350
|
onChange: () => {
|
|
352281
|
-
if (!disposed && loadingRegistry && loadGeneration ===
|
|
352351
|
+
if (!disposed && loadingRegistry && loadGeneration === generation2) {
|
|
352282
352352
|
activeRegistry = loadingRegistry;
|
|
352283
352353
|
publish();
|
|
352284
352354
|
}
|
|
@@ -352286,7 +352356,7 @@ function createModEngine(options3) {
|
|
|
352286
352356
|
onDiagnostic: (diagnostic) => {
|
|
352287
352357
|
if (disposed)
|
|
352288
352358
|
return;
|
|
352289
|
-
if (loadingRegistry && loadGeneration ===
|
|
352359
|
+
if (loadingRegistry && loadGeneration === generation2) {
|
|
352290
352360
|
activeRegistry = loadingRegistry;
|
|
352291
352361
|
publish();
|
|
352292
352362
|
onDiagnostic?.(diagnostic);
|
|
@@ -352298,7 +352368,7 @@ function createModEngine(options3) {
|
|
|
352298
352368
|
}
|
|
352299
352369
|
});
|
|
352300
352370
|
loadingRegistry = nextRegistry;
|
|
352301
|
-
if (disposed || loadGeneration !==
|
|
352371
|
+
if (disposed || loadGeneration !== generation2) {
|
|
352302
352372
|
disposeLocalMods(nextRegistry);
|
|
352303
352373
|
return;
|
|
352304
352374
|
}
|
|
@@ -352310,9 +352380,9 @@ function createModEngine(options3) {
|
|
|
352310
352380
|
if (disposed)
|
|
352311
352381
|
return;
|
|
352312
352382
|
disposed = true;
|
|
352313
|
-
|
|
352383
|
+
generation2 += 1;
|
|
352314
352384
|
disposeLocalMods(activeRegistry);
|
|
352315
|
-
activeRegistry = createEmptyModRegistry(resolveLocalModSources(modOptions),
|
|
352385
|
+
activeRegistry = createEmptyModRegistry(resolveLocalModSources(modOptions), generation2, capabilities);
|
|
352316
352386
|
publish();
|
|
352317
352387
|
listeners2.clear();
|
|
352318
352388
|
},
|
|
@@ -353481,7 +353551,7 @@ var init_protocol_outbound = __esm(async () => {
|
|
|
353481
353551
|
init_git_context();
|
|
353482
353552
|
init_memory_reminder();
|
|
353483
353553
|
init_system_prompt_warning();
|
|
353484
|
-
|
|
353554
|
+
init_constants2();
|
|
353485
353555
|
init_manager();
|
|
353486
353556
|
init_mode();
|
|
353487
353557
|
init_settings_manager();
|
|
@@ -359160,7 +359230,7 @@ ${SYSTEM_REMINDER_CLOSE}`
|
|
|
359160
359230
|
}
|
|
359161
359231
|
var IMAGE_EXTENSIONS2;
|
|
359162
359232
|
var init_read = __esm(async () => {
|
|
359163
|
-
|
|
359233
|
+
init_constants2();
|
|
359164
359234
|
init_runtime_context();
|
|
359165
359235
|
init_debug();
|
|
359166
359236
|
init_file_path();
|
|
@@ -368888,7 +368958,7 @@ var init_manager3 = __esm(() => {
|
|
|
368888
368958
|
init_metadata();
|
|
368889
368959
|
init_paths();
|
|
368890
368960
|
init_app_urls();
|
|
368891
|
-
|
|
368961
|
+
init_constants2();
|
|
368892
368962
|
init_cli_permissions_instance();
|
|
368893
368963
|
init_memory_paths();
|
|
368894
368964
|
init_session2();
|
|
@@ -369021,7 +369091,7 @@ function appendTaskNotificationEventsToBuffer(summaries, buffer, generateId, flu
|
|
|
369021
369091
|
return true;
|
|
369022
369092
|
}
|
|
369023
369093
|
var init_task_notifications = __esm(() => {
|
|
369024
|
-
|
|
369094
|
+
init_constants2();
|
|
369025
369095
|
});
|
|
369026
369096
|
|
|
369027
369097
|
// src/tools/impl/task.ts
|
|
@@ -376561,7 +376631,7 @@ var init_manager4 = __esm(async () => {
|
|
|
376561
376631
|
init_backend2();
|
|
376562
376632
|
init_message_tool();
|
|
376563
376633
|
init_registry();
|
|
376564
|
-
|
|
376634
|
+
init_constants2();
|
|
376565
376635
|
init_manager();
|
|
376566
376636
|
init_hooks2();
|
|
376567
376637
|
init_context2();
|
|
@@ -381629,7 +381699,7 @@ class LocalStore {
|
|
|
381629
381699
|
}
|
|
381630
381700
|
var DEFAULT_LOCAL_AGENT_NAME = "Letta Code", DEFAULT_LOCAL_MODEL = "local/default", LEGACY_LOCAL_CONTEXT_WINDOW_LIMIT = 128000, DEFAULT_LOCAL_CONVERSATION_ID_PREFIX = "local-conv-", DEFAULT_LOCAL_STORED_MESSAGE_ID_PREFIX = "letta-msg-", DEFAULT_LOCAL_UI_MESSAGE_ID_PREFIX = "ui-msg-", LocalBackendNotFoundError, LOCAL_TRANSCRIPT_LEGACY_SCHEMA_VERSION = 1, LOCAL_TRANSCRIPT_SCHEMA_VERSION = 2, LOCAL_TRANSCRIPT_LEGACY_MESSAGE_FORMAT = "pi-ai-message-jsonl", LOCAL_TRANSCRIPT_MESSAGE_FORMAT = "pi-session-entry-jsonl", LOCAL_TRANSCRIPT_PROVIDER_STACK = "pi-ai", LocalTranscriptMigrationRequiredError, LocalTranscriptRepairRequiredError;
|
|
381631
381701
|
var init_local_store = __esm(() => {
|
|
381632
|
-
|
|
381702
|
+
init_constants2();
|
|
381633
381703
|
init_local_stream_chunks();
|
|
381634
381704
|
LocalBackendNotFoundError = class LocalBackendNotFoundError extends Error {
|
|
381635
381705
|
status = 404;
|
|
@@ -383475,7 +383545,7 @@ var FAKE_HEADLESS_MODEL = "dev/fake-headless";
|
|
|
383475
383545
|
var init_fake_headless_backend = __esm(() => {
|
|
383476
383546
|
init_local_store();
|
|
383477
383547
|
init_local_stream_chunks();
|
|
383478
|
-
|
|
383548
|
+
init_constants2();
|
|
383479
383549
|
init_local_provider_errors();
|
|
383480
383550
|
});
|
|
383481
383551
|
|
|
@@ -386773,7 +386843,7 @@ class APIBackend {
|
|
|
386773
386843
|
if (this.forkConversationOverride) {
|
|
386774
386844
|
return this.forkConversationOverride(conversationId, options3);
|
|
386775
386845
|
}
|
|
386776
|
-
const { forkConversation: forkConversation2 } = await Promise.resolve().then(() => (
|
|
386846
|
+
const { forkConversation: forkConversation2 } = await Promise.resolve().then(() => (init_conversations4(), exports_conversations));
|
|
386777
386847
|
return forkConversation2(conversationId, options3);
|
|
386778
386848
|
}
|
|
386779
386849
|
}
|
|
@@ -425224,7 +425294,7 @@ var init_WelcomeScreen = __esm(async () => {
|
|
|
425224
425294
|
// src/agent/create-agent-request.ts
|
|
425225
425295
|
var LETTA_CODE_AGENT_TYPE = "letta_v1_agent", DEFAULT_CREATED_AGENT_BASE_TOOLS;
|
|
425226
425296
|
var init_create_agent_request = __esm(() => {
|
|
425227
|
-
|
|
425297
|
+
init_constants2();
|
|
425228
425298
|
init_memory5();
|
|
425229
425299
|
init_model_catalog();
|
|
425230
425300
|
init_personality_presets();
|
|
@@ -425421,7 +425491,7 @@ async function createAgent(nameOrOptions = DEFAULT_AGENT_NAME, model, embeddingM
|
|
|
425421
425491
|
var init_create6 = __esm(() => {
|
|
425422
425492
|
init_backend2();
|
|
425423
425493
|
init_request();
|
|
425424
|
-
|
|
425494
|
+
init_constants2();
|
|
425425
425495
|
init_settings_manager();
|
|
425426
425496
|
init_available_models();
|
|
425427
425497
|
init_create_agent_request();
|
|
@@ -427979,7 +428049,7 @@ var init_reflection_launcher = __esm(() => {
|
|
|
427979
428049
|
init_memory_reminder();
|
|
427980
428050
|
init_memory_subagent_completion();
|
|
427981
428051
|
init_reflection_transcript();
|
|
427982
|
-
|
|
428052
|
+
init_constants2();
|
|
427983
428053
|
init_telemetry();
|
|
427984
428054
|
init_reflection_threshold_feedback();
|
|
427985
428055
|
init_debug();
|
|
@@ -430502,8 +430572,8 @@ Rules:
|
|
|
430502
430572
|
- ignore setup noise like tool chatter, system reminders, approvals, and boilerplate unless the conversation is explicitly about them`;
|
|
430503
430573
|
var init_conversation_description = __esm(() => {
|
|
430504
430574
|
init_backend2();
|
|
430505
|
-
|
|
430506
|
-
|
|
430575
|
+
init_conversations4();
|
|
430576
|
+
init_constants2();
|
|
430507
430577
|
init_manager();
|
|
430508
430578
|
init_debug();
|
|
430509
430579
|
});
|
|
@@ -430932,7 +431002,7 @@ ${SYSTEM_REMINDER_CLOSE}`;
|
|
|
430932
431002
|
}
|
|
430933
431003
|
var init_init_command = __esm(() => {
|
|
430934
431004
|
init_subagent_state();
|
|
430935
|
-
|
|
431005
|
+
init_constants2();
|
|
430936
431006
|
init_git_context();
|
|
430937
431007
|
});
|
|
430938
431008
|
|
|
@@ -432033,7 +432103,7 @@ function isListModelsCommand(value) {
|
|
|
432033
432103
|
if (!value || typeof value !== "object")
|
|
432034
432104
|
return false;
|
|
432035
432105
|
const c = value;
|
|
432036
|
-
return c.type === "list_models" && typeof c.request_id === "string";
|
|
432106
|
+
return c.type === "list_models" && typeof c.request_id === "string" && (c.force === undefined || typeof c.force === "boolean");
|
|
432037
432107
|
}
|
|
432038
432108
|
function isListConnectProvidersCommand(value) {
|
|
432039
432109
|
if (!value || typeof value !== "object")
|
|
@@ -432500,7 +432570,6 @@ var init_protocol_inbound = __esm(async () => {
|
|
|
432500
432570
|
EXPERIMENT_IDS = new Set([
|
|
432501
432571
|
"conversation_titles",
|
|
432502
432572
|
"desktop_conversation_bootstrap",
|
|
432503
|
-
"node",
|
|
432504
432573
|
"tui_cron"
|
|
432505
432574
|
]);
|
|
432506
432575
|
CHANNEL_ACCOUNT_CREATE_FIELDS = new Set([
|
|
@@ -434016,7 +434085,7 @@ function setToolCallsRunning(b3, toolCallIds) {
|
|
|
434016
434085
|
}
|
|
434017
434086
|
var MAX_TAIL_LINES = 5, MAX_BUFFER_SIZE = 1e5, CANCEL_REASON_TEXT;
|
|
434018
434087
|
var init_accumulator = __esm(async () => {
|
|
434019
|
-
|
|
434088
|
+
init_constants2();
|
|
434020
434089
|
init_hooks2();
|
|
434021
434090
|
init_debug();
|
|
434022
434091
|
await init_tool_name_mapping();
|
|
@@ -434963,7 +435032,7 @@ ${SYSTEM_REMINDER_CLOSE}`;
|
|
|
434963
435032
|
var init_agent_info = __esm(() => {
|
|
434964
435033
|
init_memory_filesystem2();
|
|
434965
435034
|
init_paths();
|
|
434966
|
-
|
|
435035
|
+
init_constants2();
|
|
434967
435036
|
init_settings_manager();
|
|
434968
435037
|
});
|
|
434969
435038
|
|
|
@@ -435089,7 +435158,7 @@ var BOOTSTRAP_RECENT_LIMIT = 5, BOOTSTRAP_RELEVANT_LIMIT = 5, BOOTSTRAP_RECENT_F
|
|
|
435089
435158
|
var init_conversation_bootstrap = __esm(() => {
|
|
435090
435159
|
init_backend2();
|
|
435091
435160
|
init_conversation_search();
|
|
435092
|
-
|
|
435161
|
+
init_constants2();
|
|
435093
435162
|
BOOTSTRAP_RECENT_FETCH_LIMIT = BOOTSTRAP_RECENT_LIMIT + BOOTSTRAP_RELEVANT_LIMIT;
|
|
435094
435163
|
});
|
|
435095
435164
|
|
|
@@ -435420,7 +435489,7 @@ var init_engine3 = __esm(() => {
|
|
|
435420
435489
|
init_agent_info();
|
|
435421
435490
|
init_conversation_bootstrap();
|
|
435422
435491
|
init_session_context();
|
|
435423
|
-
|
|
435492
|
+
init_constants2();
|
|
435424
435493
|
init_manager();
|
|
435425
435494
|
init_mode();
|
|
435426
435495
|
init_settings_manager();
|
|
@@ -435524,7 +435593,7 @@ async function runPostTurnMemorySync(params) {
|
|
|
435524
435593
|
}
|
|
435525
435594
|
var init_memory_git_sync = __esm(() => {
|
|
435526
435595
|
init_memory_git();
|
|
435527
|
-
|
|
435596
|
+
init_constants2();
|
|
435528
435597
|
init_debug();
|
|
435529
435598
|
});
|
|
435530
435599
|
|
|
@@ -436541,7 +436610,7 @@ function stashRecoveredApprovalInterrupts(runtime, recovered) {
|
|
|
436541
436610
|
var INTERRUPT_TOOL_RETURN_MAX_CHARS, STREAMING_TOOL_OUTPUT_MAX_CHARS, STREAMING_TOOL_OUTPUT_EMIT_INTERVAL_MS = 100;
|
|
436542
436611
|
var init_interrupts = __esm(async () => {
|
|
436543
436612
|
init_approval_result_normalization();
|
|
436544
|
-
|
|
436613
|
+
init_constants2();
|
|
436545
436614
|
init_truncation();
|
|
436546
436615
|
init_debug();
|
|
436547
436616
|
init_runtime6();
|
|
@@ -443350,7 +443419,7 @@ var init_commands2 = __esm(async () => {
|
|
|
443350
443419
|
init_memory_reminder();
|
|
443351
443420
|
init_skill_name_frontmatter_repair();
|
|
443352
443421
|
init_command_runtime();
|
|
443353
|
-
|
|
443422
|
+
init_constants2();
|
|
443354
443423
|
init_hooks2();
|
|
443355
443424
|
init_settings_manager();
|
|
443356
443425
|
init_error_reporting();
|
|
@@ -444501,10 +444570,10 @@ function buildListModelsEntries() {
|
|
|
444501
444570
|
...model.updateArgs && typeof model.updateArgs === "object" ? { updateArgs: model.updateArgs } : {}
|
|
444502
444571
|
}));
|
|
444503
444572
|
}
|
|
444504
|
-
async function buildListModelsResponse(requestId) {
|
|
444573
|
+
async function buildListModelsResponse(requestId, options3 = {}) {
|
|
444505
444574
|
const entries = buildListModelsEntries();
|
|
444506
444575
|
const [handlesResult, providersResult] = await Promise.allSettled([
|
|
444507
|
-
getAvailableModelHandles(),
|
|
444576
|
+
getAvailableModelHandles(options3.forceRefresh === true ? { forceRefresh: true } : undefined),
|
|
444508
444577
|
listProviders2()
|
|
444509
444578
|
]);
|
|
444510
444579
|
const availableHandles = handlesResult.status === "fulfilled" ? [...handlesResult.value.handles] : null;
|
|
@@ -444530,7 +444599,9 @@ function handleModelToolsetCommand(parsed, context3) {
|
|
|
444530
444599
|
if (isListModelsCommand(parsed)) {
|
|
444531
444600
|
runDetachedListenerTask("list_models", async () => {
|
|
444532
444601
|
try {
|
|
444533
|
-
const response = await buildListModelsResponse(parsed.request_id
|
|
444602
|
+
const response = await buildListModelsResponse(parsed.request_id, {
|
|
444603
|
+
forceRefresh: parsed.force === true
|
|
444604
|
+
});
|
|
444534
444605
|
safeSocketSend(socket, response, "listener_list_models_send_failed", "listener_list_models");
|
|
444535
444606
|
} catch (error54) {
|
|
444536
444607
|
safeSocketSend(socket, {
|
|
@@ -444911,7 +444982,7 @@ async function handleCwdChange(msg, socket, runtime) {
|
|
|
444911
444982
|
}
|
|
444912
444983
|
var init_control_inputs = __esm(async () => {
|
|
444913
444984
|
init_backend2();
|
|
444914
|
-
|
|
444985
|
+
init_constants2();
|
|
444915
444986
|
init_mode();
|
|
444916
444987
|
init_error_reporting();
|
|
444917
444988
|
init_debug();
|
|
@@ -454874,7 +454945,7 @@ function PinDialog({ currentName, onSubmit, onCancel }) {
|
|
|
454874
454945
|
}
|
|
454875
454946
|
var import_react37, jsx_dev_runtime16;
|
|
454876
454947
|
var init_PinDialog = __esm(async () => {
|
|
454877
|
-
|
|
454948
|
+
init_constants2();
|
|
454878
454949
|
init_colors();
|
|
454879
454950
|
await __promiseAll([
|
|
454880
454951
|
init_build4(),
|
|
@@ -455920,7 +455991,7 @@ var init_AgentSelector = __esm(async () => {
|
|
|
455920
455991
|
init_backend();
|
|
455921
455992
|
init_local_agent_listing();
|
|
455922
455993
|
init_use_terminal_width();
|
|
455923
|
-
|
|
455994
|
+
init_constants2();
|
|
455924
455995
|
init_settings_manager();
|
|
455925
455996
|
init_colors();
|
|
455926
455997
|
await __promiseAll([
|
|
@@ -461854,7 +461925,7 @@ var init_headless = __esm(async () => {
|
|
|
461854
461925
|
init_reflection_launcher();
|
|
461855
461926
|
init_reflection_transcript();
|
|
461856
461927
|
init_local_backend_mod_events();
|
|
461857
|
-
|
|
461928
|
+
init_constants2();
|
|
461858
461929
|
init_diff_preview();
|
|
461859
461930
|
init_format_denial();
|
|
461860
461931
|
init_startup();
|
|
@@ -462101,7 +462172,7 @@ async function reconcileExistingAgentState(client, agent2) {
|
|
|
462101
462172
|
}
|
|
462102
462173
|
var DEFAULT_ATTACHED_BASE_TOOLS;
|
|
462103
462174
|
var init_reconcile_existing_agent_state = __esm(() => {
|
|
462104
|
-
|
|
462175
|
+
init_constants2();
|
|
462105
462176
|
DEFAULT_ATTACHED_BASE_TOOLS = [
|
|
462106
462177
|
"web_search",
|
|
462107
462178
|
"fetch_webpage"
|
|
@@ -463092,7 +463163,7 @@ function backfillBuffers(buffers, history) {
|
|
|
463092
463163
|
}
|
|
463093
463164
|
var CLIP_CHAR_LIMIT_TEXT = 500;
|
|
463094
463165
|
var init_backfill = __esm(() => {
|
|
463095
|
-
|
|
463166
|
+
init_constants2();
|
|
463096
463167
|
init_task_notifications();
|
|
463097
463168
|
});
|
|
463098
463169
|
|
|
@@ -468471,7 +468542,7 @@ var import_react60, jsx_dev_runtime33, BashCommandMessage;
|
|
|
468471
468542
|
var init_BashCommandMessage = __esm(async () => {
|
|
468472
468543
|
init_glyphs();
|
|
468473
468544
|
init_use_terminal_width();
|
|
468474
|
-
|
|
468545
|
+
init_constants2();
|
|
468475
468546
|
init_colors();
|
|
468476
468547
|
await __promiseAll([
|
|
468477
468548
|
init_build4(),
|
|
@@ -469753,7 +469824,7 @@ var init_ConversationSelector = __esm(async () => {
|
|
|
469753
469824
|
init_backend2();
|
|
469754
469825
|
init_glyphs();
|
|
469755
469826
|
init_use_terminal_width();
|
|
469756
|
-
|
|
469827
|
+
init_constants2();
|
|
469757
469828
|
init_colors();
|
|
469758
469829
|
await __promiseAll([
|
|
469759
469830
|
init_build4(),
|
|
@@ -469894,7 +469965,7 @@ var import_react69, jsx_dev_runtime42, EventMessage;
|
|
|
469894
469965
|
var init_EventMessage = __esm(async () => {
|
|
469895
469966
|
init_glyphs();
|
|
469896
469967
|
init_use_terminal_width();
|
|
469897
|
-
|
|
469968
|
+
init_constants2();
|
|
469898
469969
|
init_colors();
|
|
469899
469970
|
await __promiseAll([
|
|
469900
469971
|
init_build4(),
|
|
@@ -473410,7 +473481,7 @@ var init_AgentInfoBar = __esm(async () => {
|
|
|
473410
473481
|
init_string_width();
|
|
473411
473482
|
init_app_urls();
|
|
473412
473483
|
init_use_terminal_width();
|
|
473413
|
-
|
|
473484
|
+
init_constants2();
|
|
473414
473485
|
init_settings_manager();
|
|
473415
473486
|
init_version();
|
|
473416
473487
|
init_colors();
|
|
@@ -476390,7 +476461,7 @@ var init_InputRich = __esm(async () => {
|
|
|
476390
476461
|
init_thinking_messages();
|
|
476391
476462
|
init_use_shimmer_animation();
|
|
476392
476463
|
init_use_token_smoothing();
|
|
476393
|
-
|
|
476464
|
+
init_constants2();
|
|
476394
476465
|
init_mode();
|
|
476395
476466
|
init_openai_codex_provider();
|
|
476396
476467
|
init_settings_manager();
|
|
@@ -488088,7 +488159,7 @@ var import_react104, jsx_dev_runtime82, LIVE_SHELL_ARGS_MAX_LINES = 2, ToolCallM
|
|
|
488088
488159
|
var init_ToolCallMessageRich = __esm(async () => {
|
|
488089
488160
|
init_subagent_state();
|
|
488090
488161
|
init_glyphs();
|
|
488091
|
-
|
|
488162
|
+
init_constants2();
|
|
488092
488163
|
init_store();
|
|
488093
488164
|
init_use_terminal_width();
|
|
488094
488165
|
init_colors();
|
|
@@ -489274,7 +489345,7 @@ var import_react106, jsx_dev_runtime84, UserMessage;
|
|
|
489274
489345
|
var init_UserMessageRich = __esm(async () => {
|
|
489275
489346
|
init_glyphs();
|
|
489276
489347
|
init_use_terminal_width();
|
|
489277
|
-
|
|
489348
|
+
init_constants2();
|
|
489278
489349
|
init_task_notifications();
|
|
489279
489350
|
init_colors();
|
|
489280
489351
|
await __promiseAll([
|
|
@@ -507630,7 +507701,7 @@ ${expanded.command}` : expanded.command;
|
|
|
507630
507701
|
}
|
|
507631
507702
|
var import_react113;
|
|
507632
507703
|
var init_use_bash_handlers = __esm(async () => {
|
|
507633
|
-
|
|
507704
|
+
init_constants2();
|
|
507634
507705
|
init_ids();
|
|
507635
507706
|
await init_accumulator();
|
|
507636
507707
|
import_react113 = __toESM(require_react(), 1);
|
|
@@ -508448,7 +508519,7 @@ var init_use_configuration_handlers = __esm(async () => {
|
|
|
508448
508519
|
init_client2();
|
|
508449
508520
|
init_error_formatter();
|
|
508450
508521
|
init_memory_reminder();
|
|
508451
|
-
|
|
508522
|
+
init_constants2();
|
|
508452
508523
|
init_manager();
|
|
508453
508524
|
init_openai_codex_provider();
|
|
508454
508525
|
init_settings_manager();
|
|
@@ -508564,7 +508635,7 @@ function stripSystemReminders2(text2) {
|
|
|
508564
508635
|
return text2.replace(new RegExp(`${SYSTEM_REMINDER_OPEN}[\\s\\S]*?${SYSTEM_REMINDER_CLOSE}`, "g"), "").replace(new RegExp(`${SYSTEM_ALERT_OPEN}[\\s\\S]*?${SYSTEM_ALERT_CLOSE}`, "g"), "").trim();
|
|
508565
508636
|
}
|
|
508566
508637
|
var init_system_reminders = __esm(() => {
|
|
508567
|
-
|
|
508638
|
+
init_constants2();
|
|
508568
508639
|
});
|
|
508569
508640
|
|
|
508570
508641
|
// src/cli/app/use-conversation-loop.ts
|
|
@@ -510131,7 +510202,7 @@ var init_use_conversation_loop = __esm(async () => {
|
|
|
510131
510202
|
init_queued_message_parts();
|
|
510132
510203
|
init_reflection_transcript();
|
|
510133
510204
|
init_thinking_messages();
|
|
510134
|
-
|
|
510205
|
+
init_constants2();
|
|
510135
510206
|
init_hooks2();
|
|
510136
510207
|
init_format_denial();
|
|
510137
510208
|
init_mode();
|
|
@@ -511054,7 +511125,7 @@ var init_use_interrupt_handler = __esm(async () => {
|
|
|
511054
511125
|
init_backend2();
|
|
511055
511126
|
init_error_formatter();
|
|
511056
511127
|
init_reflection_launcher();
|
|
511057
|
-
|
|
511128
|
+
init_constants2();
|
|
511058
511129
|
init_constants7();
|
|
511059
511130
|
await init_accumulator();
|
|
511060
511131
|
import_react118 = __toESM(require_react(), 1);
|
|
@@ -515723,7 +515794,7 @@ function pushMessageHistory(parts, ctx) {
|
|
|
515723
515794
|
}
|
|
515724
515795
|
var MAX_HISTORY_MESSAGES = 8, MAX_MESSAGE_CHARS = 500;
|
|
515725
515796
|
var init_conversation_switch_alert = __esm(() => {
|
|
515726
|
-
|
|
515797
|
+
init_constants2();
|
|
515727
515798
|
});
|
|
515728
515799
|
|
|
515729
515800
|
// src/cli/app/use-submit-handler.ts
|
|
@@ -518011,7 +518082,7 @@ var init_use_submit_handler = __esm(async () => {
|
|
|
518011
518082
|
init_system_prompt_warning();
|
|
518012
518083
|
init_thinking_messages();
|
|
518013
518084
|
init_command_runtime();
|
|
518014
|
-
|
|
518085
|
+
init_constants2();
|
|
518015
518086
|
init_manager();
|
|
518016
518087
|
init_hooks2();
|
|
518017
518088
|
init_conversation_handle();
|
|
@@ -522287,7 +522358,7 @@ async function createAgent2(nameOrOptions = DEFAULT_AGENT_NAME, model, embedding
|
|
|
522287
522358
|
var init_create9 = __esm(() => {
|
|
522288
522359
|
init_backend2();
|
|
522289
522360
|
init_request();
|
|
522290
|
-
|
|
522361
|
+
init_constants2();
|
|
522291
522362
|
init_settings_manager();
|
|
522292
522363
|
init_available_models();
|
|
522293
522364
|
init_create_agent_request();
|
|
@@ -525087,7 +525158,7 @@ function extractBackendFlag(args) {
|
|
|
525087
525158
|
init_backend2();
|
|
525088
525159
|
init_glyphs();
|
|
525089
525160
|
init_use_terminal_width();
|
|
525090
|
-
|
|
525161
|
+
init_constants2();
|
|
525091
525162
|
init_colors();
|
|
525092
525163
|
await __promiseAll([
|
|
525093
525164
|
init_build4(),
|
|
@@ -529911,7 +529982,10 @@ var AGENTS_MD_GUIDANCE = [
|
|
|
529911
529982
|
"plain Markdown with any headings. Do NOT duplicate human-README content",
|
|
529912
529983
|
"(project pitch, quickstart, contribution guide). Prefer editing/merging",
|
|
529913
529984
|
"existing sections over appending; remove guidance that new evidence",
|
|
529914
|
-
"contradicts."
|
|
529985
|
+
"contradicts. Keep it concise and scannable — favor short bullets over prose",
|
|
529986
|
+
"so a coding agent can skim it quickly. Write timelessly: describe how the",
|
|
529987
|
+
"repo works, not how it recently changed, and avoid time-relative wording",
|
|
529988
|
+
"(currently, for now, no longer) that goes stale."
|
|
529915
529989
|
].join(`
|
|
529916
529990
|
`);
|
|
529917
529991
|
var GENERIC_GUIDANCE = [
|
|
@@ -529927,11 +530001,19 @@ function buildTargetInstruction(target2) {
|
|
|
529927
530001
|
`In addition to updating memory, maintain the file at $MEMORY_DIR/${relPath}.`,
|
|
529928
530002
|
guidance,
|
|
529929
530003
|
"",
|
|
529930
|
-
`
|
|
529931
|
-
"
|
|
529932
|
-
"
|
|
529933
|
-
"
|
|
529934
|
-
"
|
|
530004
|
+
`If $MEMORY_DIR/${relPath} already exists, revise it in place: apply only`,
|
|
530005
|
+
"the changes the new experience warrants, using your judgment. Often no",
|
|
530006
|
+
"change is needed — if so, leave it as-is. Keep the YAML frontmatter block",
|
|
530007
|
+
"(--- ... ---) at the top intact and edit only the body below it.",
|
|
530008
|
+
"",
|
|
530009
|
+
"If it does not exist, create it ONLY when the new experience yields",
|
|
530010
|
+
"durable, forward-looking guidance worth recording, and begin the file with",
|
|
530011
|
+
"a YAML frontmatter block (a --- ... --- header with a short `description:`).",
|
|
530012
|
+
"If there is nothing substantive to record yet, do NOT create the file —",
|
|
530013
|
+
"leave it absent rather than writing a placeholder that says nothing was",
|
|
530014
|
+
"learned. The file should first appear on a run that produces real guidance.",
|
|
530015
|
+
"",
|
|
530016
|
+
"Commit when done."
|
|
529935
530017
|
].join(`
|
|
529936
530018
|
`);
|
|
529937
530019
|
}
|
|
@@ -535886,7 +535968,7 @@ init_subagents();
|
|
|
535886
535968
|
init_backend2();
|
|
535887
535969
|
init_message_tool();
|
|
535888
535970
|
init_registry();
|
|
535889
|
-
|
|
535971
|
+
init_constants2();
|
|
535890
535972
|
init_manager();
|
|
535891
535973
|
init_hooks2();
|
|
535892
535974
|
init_context2();
|
|
@@ -538086,4 +538168,4 @@ Error during initialization: ${message}`);
|
|
|
538086
538168
|
}
|
|
538087
538169
|
main2();
|
|
538088
538170
|
|
|
538089
|
-
//# debugId=
|
|
538171
|
+
//# debugId=BDC82BB3FBA1F3D964756E2164756E21
|