@letta-ai/letta-code 0.30.10 → 0.30.11
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/channels-public.js +411 -2
- package/dist/channels-public.js.map +6 -3
- package/dist/channels-slack.js +209 -11
- package/dist/channels-slack.js.map +6 -5
- package/dist/gateway-core.js +110 -13
- package/dist/gateway-core.js.map +6 -5
- package/dist/mcp-client.js +2 -2
- package/dist/mcp-client.js.map +1 -1
- package/dist/schedules.js +4 -2
- package/dist/schedules.js.map +3 -3
- package/dist/types/agent/client-skills.d.ts +2 -0
- package/dist/types/agent/client-skills.d.ts.map +1 -1
- package/dist/types/agent/message.d.ts.map +1 -1
- package/dist/types/backend/local/local-store.d.ts.map +1 -1
- package/dist/types/channels/command-surface.d.ts +54 -0
- package/dist/types/channels/command-surface.d.ts.map +1 -0
- package/dist/types/channels/gateway-core.d.ts +2 -1
- package/dist/types/channels/gateway-core.d.ts.map +1 -1
- package/dist/types/channels/message-channel-executor.d.ts +2 -0
- package/dist/types/channels/message-channel-executor.d.ts.map +1 -1
- package/dist/types/channels/message-channel-idempotency.d.ts +13 -0
- package/dist/types/channels/message-channel-idempotency.d.ts.map +1 -0
- package/dist/types/channels-public.d.ts +4 -0
- package/dist/types/channels-public.d.ts.map +1 -1
- package/dist/types/channels-slack.d.ts +1 -0
- package/dist/types/channels-slack.d.ts.map +1 -1
- package/dist/types/cron/scheduled-task-prompt.d.ts +7 -0
- package/dist/types/cron/scheduled-task-prompt.d.ts.map +1 -1
- package/dist/types/schedules.d.ts +1 -1
- package/dist/types/schedules.d.ts.map +1 -1
- package/dist/types/websocket/listener/runtime.d.ts.map +1 -1
- package/dist/types/websocket/listener/types.d.ts +2 -1
- package/dist/types/websocket/listener/types.d.ts.map +1 -1
- package/letta.js +388 -226
- package/package.json +1 -1
- package/scripts/source-file-size-baseline.json +1 -1
package/dist/channels-public.js
CHANGED
|
@@ -1,3 +1,207 @@
|
|
|
1
|
+
// src/channels/command-surface.ts
|
|
2
|
+
var DEFAULT_CHANNEL_DISPLAY_NAMES = {
|
|
3
|
+
custom: "Custom",
|
|
4
|
+
discord: "Discord",
|
|
5
|
+
signal: "Signal",
|
|
6
|
+
slack: "Slack",
|
|
7
|
+
telegram: "Telegram",
|
|
8
|
+
whatsapp: "WhatsApp"
|
|
9
|
+
};
|
|
10
|
+
function defaultChannelDisplayName(channelId) {
|
|
11
|
+
return DEFAULT_CHANNEL_DISPLAY_NAMES[channelId] ?? channelId;
|
|
12
|
+
}
|
|
13
|
+
var CHANNEL_SLASH_COMMANDS = [
|
|
14
|
+
{
|
|
15
|
+
name: "help",
|
|
16
|
+
kind: "direct",
|
|
17
|
+
summary: "Show channel usage guidance."
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: "status",
|
|
21
|
+
kind: "direct",
|
|
22
|
+
summary: "Show this chat's channel connection status."
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: "whoami",
|
|
26
|
+
kind: "direct",
|
|
27
|
+
summary: "Show your access tier and runnable commands here."
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: "pause",
|
|
31
|
+
kind: "direct",
|
|
32
|
+
summary: "Pause agent routing for this chat."
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: "resume",
|
|
36
|
+
kind: "direct",
|
|
37
|
+
summary: "Resume agent routing for this chat."
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: "cancel",
|
|
41
|
+
kind: "agent-scoped",
|
|
42
|
+
summary: "Cancel the in-progress agent turn for this chat."
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: "chat",
|
|
46
|
+
kind: "direct",
|
|
47
|
+
summary: "Show the Letta web chat link for this channel route."
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: "feedback",
|
|
51
|
+
kind: "direct",
|
|
52
|
+
summary: "Send feedback about Letta Code from this routed chat."
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: "model",
|
|
56
|
+
kind: "agent-scoped",
|
|
57
|
+
summary: "Show, list, or switch the model for this chat's routed conversation."
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: "reflection",
|
|
61
|
+
aliases: ["reflect"],
|
|
62
|
+
kind: "agent-scoped",
|
|
63
|
+
summary: "Start a memory reflection pass for this conversation."
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: "reload",
|
|
67
|
+
kind: "agent-scoped",
|
|
68
|
+
summary: "Reload settings, local mods, and agent secrets."
|
|
69
|
+
}
|
|
70
|
+
];
|
|
71
|
+
var SLACK_MENTION_COMMAND_NAMES = [
|
|
72
|
+
"help",
|
|
73
|
+
"detach",
|
|
74
|
+
"model",
|
|
75
|
+
"new",
|
|
76
|
+
"reload"
|
|
77
|
+
];
|
|
78
|
+
function listChannelSlashCommands() {
|
|
79
|
+
return CHANNEL_SLASH_COMMANDS.map((definition) => ({
|
|
80
|
+
...definition,
|
|
81
|
+
aliases: definition.aliases ? [...definition.aliases] : undefined
|
|
82
|
+
}));
|
|
83
|
+
}
|
|
84
|
+
function parseSingleLineChannelCommand(text, prefix) {
|
|
85
|
+
const trimmed = text.trim();
|
|
86
|
+
const escapedPrefix = prefix === "/" ? "\\/" : "!";
|
|
87
|
+
const match = trimmed.match(new RegExp(`^${escapedPrefix}([A-Za-z][\\w-]*)(?:@[A-Za-z0-9_]+)?(?:[^\\S\\r\\n]+(.*))?$`));
|
|
88
|
+
if (!match) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
const [, name, args] = match;
|
|
92
|
+
if (!name) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
name: name.toLowerCase(),
|
|
97
|
+
args: args?.trim() ?? "",
|
|
98
|
+
raw: trimmed
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function parseAnySingleLineChannelCommand(text) {
|
|
102
|
+
return parseSingleLineChannelCommand(text, "/") ?? parseSingleLineChannelCommand(text, "!");
|
|
103
|
+
}
|
|
104
|
+
function parseChannelCommand(text, prefix) {
|
|
105
|
+
const lines = text.trim().split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
106
|
+
const [firstLine, ...remainingLines] = lines;
|
|
107
|
+
if (!firstLine) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
const firstCommand = parseSingleLineChannelCommand(firstLine, prefix);
|
|
111
|
+
if (!firstCommand) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
const laterCommand = remainingLines.find((line) => Boolean(parseAnySingleLineChannelCommand(line)));
|
|
115
|
+
if (laterCommand) {
|
|
116
|
+
return firstCommand;
|
|
117
|
+
}
|
|
118
|
+
const continuationArgs = remainingLines.join(`
|
|
119
|
+
`).trim();
|
|
120
|
+
if (!continuationArgs) {
|
|
121
|
+
return firstCommand;
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
...firstCommand,
|
|
125
|
+
args: [firstCommand.args, continuationArgs].filter((part) => part.length > 0).join(`
|
|
126
|
+
`)
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function parseChannelSlashCommand(text) {
|
|
130
|
+
return parseChannelCommand(text, "/");
|
|
131
|
+
}
|
|
132
|
+
function parseChannelBangCommand(text) {
|
|
133
|
+
return parseChannelCommand(text, "!");
|
|
134
|
+
}
|
|
135
|
+
function supportedCommandsText(prefix = "/") {
|
|
136
|
+
return listChannelSlashCommands().map((definition) => `${prefix}${definition.name}`).join(", ");
|
|
137
|
+
}
|
|
138
|
+
var SLACK_MENTION_SLASH_COMMAND_EXAMPLES = [
|
|
139
|
+
"@agent /help",
|
|
140
|
+
"@agent /status",
|
|
141
|
+
"@agent /whoami",
|
|
142
|
+
"@agent /model",
|
|
143
|
+
"@agent /model list",
|
|
144
|
+
"@agent /model <handle-or-id>",
|
|
145
|
+
"@agent /cancel",
|
|
146
|
+
"@agent /chat",
|
|
147
|
+
"@agent /feedback <message>",
|
|
148
|
+
"@agent /reflection",
|
|
149
|
+
"@agent /detach",
|
|
150
|
+
"@agent /new",
|
|
151
|
+
"@agent /reload"
|
|
152
|
+
];
|
|
153
|
+
function supportedSlackMentionSlashCommandsText() {
|
|
154
|
+
return SLACK_MENTION_SLASH_COMMAND_EXAMPLES.join(", ");
|
|
155
|
+
}
|
|
156
|
+
function supportedBangCommandsText() {
|
|
157
|
+
return SLACK_MENTION_COMMAND_NAMES.map((name) => `!${name}`).join(", ");
|
|
158
|
+
}
|
|
159
|
+
function buildChannelHelpMessage(channelId, resolveDisplayName = defaultChannelDisplayName) {
|
|
160
|
+
const displayName = resolveDisplayName(channelId);
|
|
161
|
+
if (channelId === "slack") {
|
|
162
|
+
return [
|
|
163
|
+
`${displayName} is connected to Letta Code.`,
|
|
164
|
+
"Talk by mentioning the app in a channel thread. Once a thread is routed, normal replies continue the same agent conversation until detached.",
|
|
165
|
+
"Control commands start immediately after the mention:",
|
|
166
|
+
"@agent /model - show this thread's current model",
|
|
167
|
+
"@agent /model list - show available models",
|
|
168
|
+
"@agent /model <handle-or-id> - switch this thread's model",
|
|
169
|
+
"@agent /status - show route and listener status",
|
|
170
|
+
"@agent /cancel - cancel the current turn",
|
|
171
|
+
"@agent /chat - show the web chat link",
|
|
172
|
+
"@agent /feedback <message> - send feedback to the Letta team from this routed thread",
|
|
173
|
+
"@agent /reflection - start a memory reflection pass",
|
|
174
|
+
"@agent /detach - stop replying in this thread until mentioned again",
|
|
175
|
+
"@agent /new - start a fresh conversation for this thread",
|
|
176
|
+
"@agent /reload - reload settings, local mods, and agent secrets",
|
|
177
|
+
`Legacy bang aliases still work after a mention: ${supportedBangCommandsText()}.`,
|
|
178
|
+
"If this chat is not connected yet, send a normal message and follow the pairing instructions."
|
|
179
|
+
].join(`
|
|
180
|
+
`);
|
|
181
|
+
}
|
|
182
|
+
return [
|
|
183
|
+
`${displayName} is connected to Letta Code.`,
|
|
184
|
+
"Send a normal message here and the connected agent will reply in this chat.",
|
|
185
|
+
`Supported slash commands here: ${supportedCommandsText()}.`,
|
|
186
|
+
"If this chat is not connected yet, send any non-command message and follow the pairing instructions."
|
|
187
|
+
].join(`
|
|
188
|
+
|
|
189
|
+
`);
|
|
190
|
+
}
|
|
191
|
+
function buildUnsupportedChannelCommandMessage(channelId, command, resolveDisplayName = defaultChannelDisplayName) {
|
|
192
|
+
const displayName = resolveDisplayName(channelId);
|
|
193
|
+
const isBang = command.raw.startsWith("!");
|
|
194
|
+
const commandKind = isBang ? "bang" : "slash";
|
|
195
|
+
const supportedCommands = isBang ? supportedBangCommandsText() : channelId === "slack" ? supportedSlackMentionSlashCommandsText() : supportedCommandsText();
|
|
196
|
+
const supportedLabel = channelId === "slack" && !isBang ? "Slack mention commands" : `${commandKind} commands`;
|
|
197
|
+
return [
|
|
198
|
+
`${displayName} received ${command.raw}, but that ${commandKind} command is not supported in channels yet.`,
|
|
199
|
+
`Supported ${supportedLabel}: ${supportedCommands}.`,
|
|
200
|
+
`Send normal messages without a leading ${isBang ? "bang" : "slash"} command to talk to the connected agent.`
|
|
201
|
+
].join(`
|
|
202
|
+
|
|
203
|
+
`);
|
|
204
|
+
}
|
|
1
205
|
// src/channels/core-stream.ts
|
|
2
206
|
var LETTA_STREAM_NO_ASSISTANT_MESSAGE_ERROR = "No assistant message received in stream";
|
|
3
207
|
|
|
@@ -148,6 +352,199 @@ async function collectLettaSseAssistantText(body, options = {}) {
|
|
|
148
352
|
stopReason
|
|
149
353
|
};
|
|
150
354
|
}
|
|
355
|
+
// src/utils/conversation-busy-error.ts
|
|
356
|
+
var CONVERSATION_BUSY_ERROR_PATTERNS = [
|
|
357
|
+
/another request is (?:currently )?(?:being )?processed/i,
|
|
358
|
+
/currently being processed for this conversation/i,
|
|
359
|
+
/busy with another active run/i,
|
|
360
|
+
/already processing for this conversation/i,
|
|
361
|
+
/turn still running/i
|
|
362
|
+
];
|
|
363
|
+
var CONVERSATION_BUSY_TITLE = "Turn still running";
|
|
364
|
+
function isConversationBusyErrorText(errorText) {
|
|
365
|
+
if (!errorText)
|
|
366
|
+
return false;
|
|
367
|
+
return CONVERSATION_BUSY_ERROR_PATTERNS.some((pattern) => pattern.test(errorText));
|
|
368
|
+
}
|
|
369
|
+
function buildConversationBusyErrorBody(automaticRetry) {
|
|
370
|
+
return automaticRetry ? "Another request is already processing for this conversation. I’ll wait for it to finish and retry automatically." : "Another request is already processing for this conversation. Please wait for it to finish, then try again.";
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// src/channels/lifecycle-error.ts
|
|
374
|
+
var RAW_LOOP_ERROR_PATTERN = /^Unexpected stop reason:\s*error$/i;
|
|
375
|
+
var APP_CHAT_URL_PATTERN = /https:\/\/app\.letta\.com\/chat\/\S+/i;
|
|
376
|
+
var ESCAPE_CHARACTER = String.fromCharCode(27);
|
|
377
|
+
var OSC8_PREFIX = `${ESCAPE_CHARACTER}]8;;`;
|
|
378
|
+
var OSC8_TERMINATOR = `${ESCAPE_CHARACTER}\\`;
|
|
379
|
+
var APPROVAL_PENDING_ERROR_PATTERNS = [
|
|
380
|
+
/waiting for approval/i,
|
|
381
|
+
/pending request before continuing/i,
|
|
382
|
+
/approve or deny the pending request/i
|
|
383
|
+
];
|
|
384
|
+
var DATABASE_LOCK_TIMEOUT_PATTERN = /\bcancel(?:l)?ing statement due to lock timeout\b/i;
|
|
385
|
+
var POSTGRES_LOCK_NOT_AVAILABLE_CODE_PATTERN = /\b55P03\b/i;
|
|
386
|
+
var POSTGRES_LOCK_NOT_AVAILABLE_SQLSTATE_PATTERN = /\b(?:sqlstate|pgcode)\s*[:=]?\s*["']?55P03\b/i;
|
|
387
|
+
var POSTGRES_LOCK_NOT_AVAILABLE_CONTEXT_PATTERN = /\b(?:postgres(?:ql)?|psycopg|sqlalchemy|lock[_ -]?not[_ -]?available|lock timeout)\b/i;
|
|
388
|
+
var RUN_ID_PATTERNS = [
|
|
389
|
+
/"run_id"\s*:\s*"([^"\\]+)"/i,
|
|
390
|
+
/\brun[_\s-]?id\b["']?\s*[:=]\s*["']?([A-Za-z0-9_-]+)/i,
|
|
391
|
+
/\(run:\s*([A-Za-z0-9_-]+)\)/i
|
|
392
|
+
];
|
|
393
|
+
var CHANNEL_LIFECYCLE_FALLBACK_ERROR_MESSAGE = "Something went wrong while processing that message. Please try again.";
|
|
394
|
+
var CHANNEL_LIFECYCLE_APPROVAL_PENDING_MESSAGE = "The agent is still waiting on a tool approval from an earlier turn. Please approve or deny that pending request, then send your message again.";
|
|
395
|
+
var CHANNEL_LIFECYCLE_TRANSIENT_ERROR_MESSAGE = "A temporary error interrupted this turn. Please try again.";
|
|
396
|
+
var CHANNEL_LIFECYCLE_CONVERSATION_BUSY_TITLE = CONVERSATION_BUSY_TITLE;
|
|
397
|
+
function stripTrailingRunIdPunctuation(runId) {
|
|
398
|
+
return runId.replace(/[)"'.,;]+$/g, "");
|
|
399
|
+
}
|
|
400
|
+
function extractChannelLifecycleRunId(errorText) {
|
|
401
|
+
if (!errorText)
|
|
402
|
+
return;
|
|
403
|
+
for (const pattern of RUN_ID_PATTERNS) {
|
|
404
|
+
const match = errorText.match(pattern);
|
|
405
|
+
const runId = match?.[1]?.trim();
|
|
406
|
+
if (runId) {
|
|
407
|
+
return stripTrailingRunIdPunctuation(runId);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
function stripOsc8TerminalLinks(errorText) {
|
|
413
|
+
let output = "";
|
|
414
|
+
let cursor = 0;
|
|
415
|
+
while (cursor < errorText.length) {
|
|
416
|
+
const linkStart = errorText.indexOf(OSC8_PREFIX, cursor);
|
|
417
|
+
if (linkStart === -1) {
|
|
418
|
+
output += errorText.slice(cursor);
|
|
419
|
+
break;
|
|
420
|
+
}
|
|
421
|
+
const labelStart = errorText.indexOf(OSC8_TERMINATOR, linkStart + OSC8_PREFIX.length);
|
|
422
|
+
if (labelStart === -1) {
|
|
423
|
+
output += errorText.slice(cursor);
|
|
424
|
+
break;
|
|
425
|
+
}
|
|
426
|
+
const closeStart = errorText.indexOf(OSC8_PREFIX, labelStart + OSC8_TERMINATOR.length);
|
|
427
|
+
if (closeStart === -1) {
|
|
428
|
+
output += errorText.slice(cursor);
|
|
429
|
+
break;
|
|
430
|
+
}
|
|
431
|
+
const closeEnd = errorText.indexOf(OSC8_TERMINATOR, closeStart + OSC8_PREFIX.length);
|
|
432
|
+
if (closeEnd === -1) {
|
|
433
|
+
output += errorText.slice(cursor);
|
|
434
|
+
break;
|
|
435
|
+
}
|
|
436
|
+
output += errorText.slice(cursor, linkStart);
|
|
437
|
+
output += errorText.slice(labelStart + OSC8_TERMINATOR.length, closeStart);
|
|
438
|
+
cursor = closeEnd + OSC8_TERMINATOR.length;
|
|
439
|
+
}
|
|
440
|
+
return output;
|
|
441
|
+
}
|
|
442
|
+
function sanitizeChannelLifecycleErrorText(errorText) {
|
|
443
|
+
if (!errorText)
|
|
444
|
+
return "";
|
|
445
|
+
const withoutTerminalLinks = stripOsc8TerminalLinks(errorText);
|
|
446
|
+
return withoutTerminalLinks.split(`
|
|
447
|
+
`).filter((line) => {
|
|
448
|
+
const trimmed = line.trim();
|
|
449
|
+
if (/^View agent:/i.test(trimmed))
|
|
450
|
+
return false;
|
|
451
|
+
if (APP_CHAT_URL_PATTERN.test(trimmed))
|
|
452
|
+
return false;
|
|
453
|
+
return true;
|
|
454
|
+
}).join(`
|
|
455
|
+
`).replace(/[ \t]+\n/g, `
|
|
456
|
+
`).trim();
|
|
457
|
+
}
|
|
458
|
+
function truncateLifecycleMessage(text, maxLength) {
|
|
459
|
+
if (text.length <= maxLength)
|
|
460
|
+
return text;
|
|
461
|
+
return `${text.slice(0, Math.max(0, maxLength - 1)).trimEnd()}…`;
|
|
462
|
+
}
|
|
463
|
+
function isDatabaseLockErrorText(errorText) {
|
|
464
|
+
return DATABASE_LOCK_TIMEOUT_PATTERN.test(errorText) || POSTGRES_LOCK_NOT_AVAILABLE_SQLSTATE_PATTERN.test(errorText) || POSTGRES_LOCK_NOT_AVAILABLE_CODE_PATTERN.test(errorText) && POSTGRES_LOCK_NOT_AVAILABLE_CONTEXT_PATTERN.test(errorText);
|
|
465
|
+
}
|
|
466
|
+
function getChannelLifecycleErrorDisplay(errorText, options = {}) {
|
|
467
|
+
const normalized = sanitizeChannelLifecycleErrorText(errorText);
|
|
468
|
+
const optionsRunId = options.runId?.trim();
|
|
469
|
+
const runId = optionsRunId || extractChannelLifecycleRunId(errorText);
|
|
470
|
+
if (!normalized || RAW_LOOP_ERROR_PATTERN.test(normalized)) {
|
|
471
|
+
return {
|
|
472
|
+
kind: "generic",
|
|
473
|
+
title: "Turn failed",
|
|
474
|
+
body: CHANNEL_LIFECYCLE_FALLBACK_ERROR_MESSAGE,
|
|
475
|
+
runId
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
if (isDatabaseLockErrorText(normalized)) {
|
|
479
|
+
return {
|
|
480
|
+
kind: "database_lock_timeout",
|
|
481
|
+
title: "Turn failed",
|
|
482
|
+
body: CHANNEL_LIFECYCLE_TRANSIENT_ERROR_MESSAGE,
|
|
483
|
+
runId
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
if (isConversationBusyErrorText(normalized)) {
|
|
487
|
+
return {
|
|
488
|
+
kind: "conversation_busy",
|
|
489
|
+
title: CHANNEL_LIFECYCLE_CONVERSATION_BUSY_TITLE,
|
|
490
|
+
body: buildConversationBusyErrorBody(options.automaticRetry ?? false),
|
|
491
|
+
runId
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
if (APPROVAL_PENDING_ERROR_PATTERNS.some((pattern) => pattern.test(normalized))) {
|
|
495
|
+
return {
|
|
496
|
+
kind: "approval_pending",
|
|
497
|
+
title: "Turn failed",
|
|
498
|
+
body: CHANNEL_LIFECYCLE_APPROVAL_PENDING_MESSAGE,
|
|
499
|
+
runId
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
return {
|
|
503
|
+
kind: "generic",
|
|
504
|
+
title: "Turn failed",
|
|
505
|
+
body: normalized,
|
|
506
|
+
runId
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
function normalizeChannelLifecycleErrorMessage(errorText, options = {}) {
|
|
510
|
+
return getChannelLifecycleErrorDisplay(errorText, options).body;
|
|
511
|
+
}
|
|
512
|
+
function formatChannelLifecycleErrorMessage(errorText, options = {}) {
|
|
513
|
+
const display = getChannelLifecycleErrorDisplay(errorText, options);
|
|
514
|
+
const maxLength = options.maxLength ?? Number.POSITIVE_INFINITY;
|
|
515
|
+
const body = truncateLifecycleMessage(display.body, maxLength);
|
|
516
|
+
if (display.kind === "conversation_busy") {
|
|
517
|
+
const lines2 = [display.title, body];
|
|
518
|
+
if (display.runId) {
|
|
519
|
+
lines2.push("", `Run ID: ${display.runId}`);
|
|
520
|
+
}
|
|
521
|
+
return lines2.join(`
|
|
522
|
+
`);
|
|
523
|
+
}
|
|
524
|
+
if (display.kind === "database_lock_timeout") {
|
|
525
|
+
const lines2 = [`${display.title}:`, body];
|
|
526
|
+
if (display.runId) {
|
|
527
|
+
lines2.push("", `Run ID: ${display.runId}`);
|
|
528
|
+
}
|
|
529
|
+
return lines2.join(`
|
|
530
|
+
`);
|
|
531
|
+
}
|
|
532
|
+
if (options.codeBlock) {
|
|
533
|
+
const escaped = body.replace(/```/g, "```");
|
|
534
|
+
const lines2 = [`${display.title}:`, "```", escaped, "```"];
|
|
535
|
+
if (display.runId) {
|
|
536
|
+
lines2.push("", `Run ID: ${display.runId}`);
|
|
537
|
+
}
|
|
538
|
+
return lines2.join(`
|
|
539
|
+
`);
|
|
540
|
+
}
|
|
541
|
+
const lines = [`${display.title}:`, body];
|
|
542
|
+
if (display.runId) {
|
|
543
|
+
lines.push("", `Run ID: ${display.runId}`);
|
|
544
|
+
}
|
|
545
|
+
return lines.join(`
|
|
546
|
+
`);
|
|
547
|
+
}
|
|
151
548
|
// src/constants.ts
|
|
152
549
|
var SYSTEM_REMINDER_TAG = "system-reminder";
|
|
153
550
|
var SYSTEM_REMINDER_OPEN = `<${SYSTEM_REMINDER_TAG}>`;
|
|
@@ -1209,16 +1606,28 @@ function createChannelTurnProgressBuilder(options = {}) {
|
|
|
1209
1606
|
return { buildUpdates };
|
|
1210
1607
|
}
|
|
1211
1608
|
export {
|
|
1609
|
+
sanitizeChannelLifecycleErrorText,
|
|
1610
|
+
parseChannelSlashCommand,
|
|
1611
|
+
parseChannelBangCommand,
|
|
1612
|
+
normalizeChannelLifecycleErrorMessage,
|
|
1613
|
+
listChannelSlashCommands,
|
|
1614
|
+
getChannelLifecycleErrorDisplay,
|
|
1212
1615
|
formatLettaStreamCoreErrorForChannel,
|
|
1213
1616
|
formatInboundChannelMessageForAgent,
|
|
1617
|
+
formatChannelLifecycleErrorMessage,
|
|
1214
1618
|
formatBatchedChannelMessagesForAgent,
|
|
1619
|
+
extractChannelLifecycleRunId,
|
|
1620
|
+
defaultChannelDisplayName,
|
|
1215
1621
|
createChannelTurnProgressBuilder,
|
|
1216
1622
|
collectLettaSseAssistantText,
|
|
1623
|
+
buildUnsupportedChannelCommandMessage,
|
|
1217
1624
|
buildOutboundChannelMessageFromTurnSource,
|
|
1218
1625
|
buildChannelTurnSource,
|
|
1626
|
+
buildChannelHelpMessage,
|
|
1219
1627
|
LettaStreamNoAssistantMessageError,
|
|
1220
1628
|
LettaStreamCoreError,
|
|
1221
|
-
LETTA_STREAM_NO_ASSISTANT_MESSAGE_ERROR
|
|
1629
|
+
LETTA_STREAM_NO_ASSISTANT_MESSAGE_ERROR,
|
|
1630
|
+
CHANNEL_LIFECYCLE_FALLBACK_ERROR_MESSAGE
|
|
1222
1631
|
};
|
|
1223
1632
|
|
|
1224
|
-
//# debugId=
|
|
1633
|
+
//# debugId=A70285B59041328B64756E2164756E21
|