@letta-ai/letta-code 0.28.5 → 0.28.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-presets.js +3 -1
- package/dist/agent-presets.js.map +3 -3
- package/dist/app-server-client.js +26 -4
- package/dist/app-server-client.js.map +3 -3
- package/dist/types/agent/agent-tags.d.ts +2 -0
- package/dist/types/agent/agent-tags.d.ts.map +1 -1
- package/dist/types/agent-presets.d.ts +1 -1
- package/dist/types/agent-presets.d.ts.map +1 -1
- package/dist/types/app-server-client.d.ts +11 -0
- package/dist/types/app-server-client.d.ts.map +1 -1
- package/dist/types/types/protocol_v2.d.ts +10 -1
- package/dist/types/types/protocol_v2.d.ts.map +1 -1
- package/letta.js +993 -595
- package/package.json +1 -1
- package/scripts/source-file-size-baseline.json +6 -6
package/letta.js
CHANGED
|
@@ -4837,7 +4837,7 @@ var package_default;
|
|
|
4837
4837
|
var init_package = __esm(() => {
|
|
4838
4838
|
package_default = {
|
|
4839
4839
|
name: "@letta-ai/letta-code",
|
|
4840
|
-
version: "0.28.
|
|
4840
|
+
version: "0.28.6",
|
|
4841
4841
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
4842
4842
|
type: "module",
|
|
4843
4843
|
packageManager: "bun@1.3.0",
|
|
@@ -6204,6 +6204,7 @@ var init_backend_mode = __esm(() => {
|
|
|
6204
6204
|
var exports_agent_tags = {};
|
|
6205
6205
|
__export(exports_agent_tags, {
|
|
6206
6206
|
buildCreatedAgentTags: () => buildCreatedAgentTags,
|
|
6207
|
+
ONBOARDING_ORIGIN_TAG: () => ONBOARDING_ORIGIN_TAG,
|
|
6207
6208
|
LETTA_CODE_SUBAGENT_TAG: () => LETTA_CODE_SUBAGENT_TAG,
|
|
6208
6209
|
LETTA_CODE_ORIGIN_TAG: () => LETTA_CODE_ORIGIN_TAG,
|
|
6209
6210
|
GIT_MEMORY_ENABLED_TAG: () => GIT_MEMORY_ENABLED_TAG
|
|
@@ -6221,7 +6222,7 @@ function buildCreatedAgentTags(options = {}) {
|
|
|
6221
6222
|
}
|
|
6222
6223
|
return Array.from(new Set(tags));
|
|
6223
6224
|
}
|
|
6224
|
-
var LETTA_CODE_ORIGIN_TAG = "origin:letta-code", LETTA_CODE_SUBAGENT_TAG = "role:subagent", GIT_MEMORY_ENABLED_TAG = "git-memory-enabled";
|
|
6225
|
+
var LETTA_CODE_ORIGIN_TAG = "origin:letta-code", ONBOARDING_ORIGIN_TAG = "origin:onboarding", LETTA_CODE_SUBAGENT_TAG = "role:subagent", GIT_MEMORY_ENABLED_TAG = "git-memory-enabled";
|
|
6225
6226
|
|
|
6226
6227
|
// src/utils/text-files.ts
|
|
6227
6228
|
import { readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
@@ -168409,238 +168410,91 @@ var init_approval_controller = __esm(async () => {
|
|
|
168409
168410
|
await init_presentation();
|
|
168410
168411
|
});
|
|
168411
168412
|
|
|
168412
|
-
// src/channels/slack/
|
|
168413
|
-
import {
|
|
168414
|
-
import {
|
|
168415
|
-
|
|
168416
|
-
|
|
168417
|
-
|
|
168418
|
-
|
|
168419
|
-
case ".jpg":
|
|
168420
|
-
case ".jpeg":
|
|
168421
|
-
return "image/jpeg";
|
|
168422
|
-
case ".gif":
|
|
168423
|
-
return "image/gif";
|
|
168424
|
-
case ".webp":
|
|
168425
|
-
return "image/webp";
|
|
168426
|
-
case ".pdf":
|
|
168427
|
-
return "application/pdf";
|
|
168428
|
-
case ".txt":
|
|
168429
|
-
return "text/plain";
|
|
168430
|
-
case ".md":
|
|
168431
|
-
return "text/markdown";
|
|
168432
|
-
default:
|
|
168433
|
-
return;
|
|
168434
|
-
}
|
|
168435
|
-
}
|
|
168436
|
-
async function uploadSlackFile(slackClient, msg) {
|
|
168437
|
-
if (!msg.mediaPath) {
|
|
168438
|
-
throw new Error("mediaPath is required for Slack file uploads.");
|
|
168439
|
-
}
|
|
168440
|
-
const buffer = await readFile4(msg.mediaPath);
|
|
168441
|
-
const uploadFileName = msg.fileName ?? basename7(msg.mediaPath);
|
|
168442
|
-
const uploadTitle = msg.title ?? uploadFileName;
|
|
168443
|
-
const uploadMimeType = resolveUploadMimeType(uploadFileName);
|
|
168444
|
-
const uploadUrlResp = await slackClient.files.getUploadURLExternal({
|
|
168445
|
-
filename: uploadFileName,
|
|
168446
|
-
length: buffer.length
|
|
168447
|
-
});
|
|
168448
|
-
if (!uploadUrlResp.ok || !uploadUrlResp.upload_url || !uploadUrlResp.file_id) {
|
|
168449
|
-
throw new Error(`Failed to get Slack upload URL: ${uploadUrlResp.error ?? "unknown error"}`);
|
|
168450
|
-
}
|
|
168451
|
-
const uploadResp = await fetch(uploadUrlResp.upload_url, {
|
|
168452
|
-
method: "POST",
|
|
168453
|
-
...uploadMimeType ? { headers: { "Content-Type": uploadMimeType } } : {},
|
|
168454
|
-
body: buffer
|
|
168455
|
-
});
|
|
168456
|
-
if (!uploadResp.ok) {
|
|
168457
|
-
throw new Error(`Failed to upload Slack file: HTTP ${uploadResp.status}`);
|
|
168458
|
-
}
|
|
168459
|
-
const threadTs = resolveSlackOutboundThreadTs({
|
|
168460
|
-
chatId: msg.chatId,
|
|
168461
|
-
threadId: msg.threadId,
|
|
168462
|
-
replyToMessageId: msg.replyToMessageId
|
|
168463
|
-
});
|
|
168464
|
-
const completeResp = await slackClient.files.completeUploadExternal({
|
|
168465
|
-
files: [{ id: uploadUrlResp.file_id, title: uploadTitle }],
|
|
168466
|
-
channel_id: msg.chatId,
|
|
168467
|
-
...msg.text.trim() ? { initial_comment: msg.text } : {},
|
|
168468
|
-
...threadTs ? { thread_ts: threadTs } : {}
|
|
168469
|
-
});
|
|
168470
|
-
if (!completeResp.ok) {
|
|
168471
|
-
throw new Error(`Failed to complete Slack upload: ${completeResp.error ?? "unknown error"}`);
|
|
168472
|
-
}
|
|
168473
|
-
return { messageId: uploadUrlResp.file_id };
|
|
168474
|
-
}
|
|
168475
|
-
var init_file_upload = __esm(() => {
|
|
168476
|
-
init_utils5();
|
|
168477
|
-
});
|
|
168478
|
-
|
|
168479
|
-
// src/channels/slack/inbound-debounce.ts
|
|
168480
|
-
function buildSlackDebounceKey(rawMessage, accountId) {
|
|
168481
|
-
const senderId = rawMessage.user ?? rawMessage.bot_id ?? null;
|
|
168482
|
-
if (!senderId)
|
|
168483
|
-
return null;
|
|
168484
|
-
const messageTs = rawMessage.ts ?? rawMessage.event_ts;
|
|
168485
|
-
const isDm = rawMessage.channel.startsWith("D");
|
|
168486
|
-
const scope = rawMessage.thread_ts ? `${rawMessage.channel}:${rawMessage.thread_ts}` : rawMessage.parent_user_id && messageTs ? `${rawMessage.channel}:maybe-thread:${messageTs}` : messageTs && !isDm ? `${rawMessage.channel}:${messageTs}` : rawMessage.channel;
|
|
168487
|
-
return `slack:${accountId}:${scope}:${senderId}`;
|
|
168488
|
-
}
|
|
168489
|
-
function buildTopLevelSlackConversationKey(rawMessage, accountId) {
|
|
168490
|
-
if (rawMessage.thread_ts || rawMessage.parent_user_id)
|
|
168491
|
-
return null;
|
|
168492
|
-
if (rawMessage.channel.startsWith("D"))
|
|
168493
|
-
return null;
|
|
168494
|
-
const senderId = rawMessage.user ?? rawMessage.bot_id;
|
|
168495
|
-
return senderId ? `slack:${accountId}:${rawMessage.channel}:${senderId}` : null;
|
|
168496
|
-
}
|
|
168497
|
-
function resolveSlackInboundDebounceMs(config3) {
|
|
168498
|
-
const raw = process.env.LETTA_SLACK_INBOUND_DEBOUNCE_MS;
|
|
168499
|
-
if (typeof raw === "string" && raw.trim() !== "") {
|
|
168500
|
-
const envOverride = Number(raw);
|
|
168501
|
-
if (Number.isFinite(envOverride) && envOverride >= 0) {
|
|
168502
|
-
return Math.trunc(envOverride);
|
|
168503
|
-
}
|
|
168504
|
-
}
|
|
168505
|
-
const fromConfig = config3.inboundDebounceMs;
|
|
168506
|
-
return typeof fromConfig === "number" && Number.isFinite(fromConfig) && fromConfig >= 0 ? Math.trunc(fromConfig) : 0;
|
|
168413
|
+
// src/channels/slack/attachment-stream.ts
|
|
168414
|
+
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
168415
|
+
import { mkdir as mkdir4, open as open2, rename, rm as rm2 } from "node:fs/promises";
|
|
168416
|
+
import { join as join12 } from "node:path";
|
|
168417
|
+
function sanitizeFileName(name) {
|
|
168418
|
+
const normalized = name.trim().replace(/[^\w.-]+/g, "_");
|
|
168419
|
+
return normalized.length > 0 ? normalized : "attachment";
|
|
168507
168420
|
}
|
|
168508
|
-
function
|
|
168509
|
-
const
|
|
168510
|
-
|
|
168511
|
-
const
|
|
168512
|
-
const
|
|
168513
|
-
const
|
|
168514
|
-
|
|
168515
|
-
|
|
168516
|
-
|
|
168517
|
-
|
|
168518
|
-
|
|
168519
|
-
|
|
168520
|
-
if (
|
|
168521
|
-
|
|
168522
|
-
}
|
|
168523
|
-
}
|
|
168524
|
-
function dedupeEntries(entries) {
|
|
168525
|
-
const indexByMessageKey = new Map;
|
|
168526
|
-
const deduped = [];
|
|
168527
|
-
for (const entry of entries) {
|
|
168528
|
-
const messageId = entry.inbound.messageId;
|
|
168529
|
-
const messageKey = isNonEmptyString2(messageId) ? `${entry.inbound.chatId}:${messageId}` : null;
|
|
168530
|
-
if (!messageKey) {
|
|
168531
|
-
deduped.push(entry);
|
|
168532
|
-
continue;
|
|
168421
|
+
async function saveSlackAttachmentStream(params) {
|
|
168422
|
+
const inboundDir = join12(getChannelDir("slack"), "inbound", sanitizeFileName(params.accountId));
|
|
168423
|
+
await mkdir4(inboundDir, { recursive: true });
|
|
168424
|
+
const filePath = join12(inboundDir, `${Date.now()}-${randomUUID8()}-${sanitizeFileName(params.fileName)}`);
|
|
168425
|
+
const temporaryPath = `${filePath}.partial`;
|
|
168426
|
+
const fileHandle = await open2(temporaryPath, "wx");
|
|
168427
|
+
const reader = params.body.getReader();
|
|
168428
|
+
let sizeBytes = 0;
|
|
168429
|
+
let completed = false;
|
|
168430
|
+
try {
|
|
168431
|
+
while (true) {
|
|
168432
|
+
const { done, value } = await reader.read();
|
|
168433
|
+
if (done) {
|
|
168434
|
+
break;
|
|
168533
168435
|
}
|
|
168534
|
-
|
|
168535
|
-
if (existingIndex === undefined) {
|
|
168536
|
-
indexByMessageKey.set(messageKey, deduped.length);
|
|
168537
|
-
deduped.push(entry);
|
|
168436
|
+
if (!value?.byteLength) {
|
|
168538
168437
|
continue;
|
|
168539
168438
|
}
|
|
168540
|
-
|
|
168541
|
-
if (
|
|
168542
|
-
|
|
168439
|
+
sizeBytes += value.byteLength;
|
|
168440
|
+
if (params.maxBytes !== undefined && sizeBytes > params.maxBytes) {
|
|
168441
|
+
throw new SlackAttachmentDownloadError("exceeds_auto_download_limit", `Slack attachment exceeds automatic download limit (${params.maxBytes} bytes).`);
|
|
168543
168442
|
}
|
|
168544
|
-
|
|
168545
|
-
|
|
168546
|
-
|
|
168547
|
-
|
|
168548
|
-
|
|
168549
|
-
buildKey: ({ raw }) => buildSlackDebounceKey(raw, config3.accountId),
|
|
168550
|
-
shouldDebounce: ({ inbound }) => !inbound.attachments?.length && !inbound.reaction,
|
|
168551
|
-
onFlush: async (entries) => {
|
|
168552
|
-
const dedupedEntries = dedupeEntries(entries);
|
|
168553
|
-
const last = dedupedEntries[dedupedEntries.length - 1];
|
|
168554
|
-
if (!last)
|
|
168555
|
-
return;
|
|
168556
|
-
const flushedKey = buildSlackDebounceKey(last.raw, config3.accountId);
|
|
168557
|
-
const conversationKey = buildTopLevelSlackConversationKey(last.raw, config3.accountId);
|
|
168558
|
-
if (flushedKey && conversationKey) {
|
|
168559
|
-
const pending = pendingTopLevelKeys.get(conversationKey);
|
|
168560
|
-
pending?.delete(flushedKey);
|
|
168561
|
-
if (pending?.size === 0)
|
|
168562
|
-
pendingTopLevelKeys.delete(conversationKey);
|
|
168563
|
-
}
|
|
168564
|
-
if (isNonEmptyString2(last.inbound.messageId)) {
|
|
168565
|
-
const seenKey = `${last.inbound.chatId}:${last.inbound.messageId}`;
|
|
168566
|
-
pruneAppMentionMaps(Date.now());
|
|
168567
|
-
if (last.opts.source === "app_mention") {
|
|
168568
|
-
appMentionDispatchedKeys.set(seenKey, Date.now() + APP_MENTION_RETRY_TTL_MS);
|
|
168569
|
-
} else if (appMentionDispatchedKeys.has(seenKey)) {
|
|
168570
|
-
appMentionDispatchedKeys.delete(seenKey);
|
|
168571
|
-
appMentionRetryKeys.delete(seenKey);
|
|
168572
|
-
return;
|
|
168443
|
+
let offset = 0;
|
|
168444
|
+
while (offset < value.byteLength) {
|
|
168445
|
+
const { bytesWritten } = await fileHandle.write(value, offset, value.byteLength - offset);
|
|
168446
|
+
if (bytesWritten <= 0) {
|
|
168447
|
+
throw new Error("Slack attachment write made no progress.");
|
|
168573
168448
|
}
|
|
168574
|
-
|
|
168449
|
+
offset += bytesWritten;
|
|
168575
168450
|
}
|
|
168576
|
-
|
|
168577
|
-
|
|
168451
|
+
}
|
|
168452
|
+
completed = true;
|
|
168453
|
+
} finally {
|
|
168454
|
+
if (!completed) {
|
|
168455
|
+
await reader.cancel().catch(() => {
|
|
168578
168456
|
return;
|
|
168579
|
-
|
|
168580
|
-
`);
|
|
168581
|
-
try {
|
|
168582
|
-
await onMessage({
|
|
168583
|
-
...last.inbound,
|
|
168584
|
-
text,
|
|
168585
|
-
isMention: dedupedEntries.some((entry) => entry.opts.wasMentioned || entry.inbound.isMention === true)
|
|
168586
|
-
});
|
|
168587
|
-
} catch (error54) {
|
|
168588
|
-
console.error("[Slack] Error handling debounced inbound message:", error54);
|
|
168589
|
-
}
|
|
168590
|
-
},
|
|
168591
|
-
onError: (error54) => {
|
|
168592
|
-
console.error("[Slack] Inbound debounce flush failed:", error54 instanceof Error ? error54.message : error54);
|
|
168457
|
+
});
|
|
168593
168458
|
}
|
|
168594
|
-
|
|
168595
|
-
|
|
168596
|
-
|
|
168597
|
-
|
|
168598
|
-
|
|
168599
|
-
|
|
168600
|
-
|
|
168601
|
-
|
|
168602
|
-
|
|
168603
|
-
|
|
168604
|
-
} catch {}
|
|
168605
|
-
}
|
|
168606
|
-
}
|
|
168607
|
-
if (canDebounce && debounceKey && conversationKey) {
|
|
168608
|
-
const pending = pendingTopLevelKeys.get(conversationKey) ?? new Set;
|
|
168609
|
-
pending.add(debounceKey);
|
|
168610
|
-
pendingTopLevelKeys.set(conversationKey, pending);
|
|
168611
|
-
}
|
|
168612
|
-
await debouncer.enqueue(entry);
|
|
168613
|
-
},
|
|
168614
|
-
rememberAppMentionRetry(seenKey) {
|
|
168615
|
-
const now = Date.now();
|
|
168616
|
-
pruneAppMentionMaps(now);
|
|
168617
|
-
appMentionRetryKeys.set(seenKey, now + APP_MENTION_RETRY_TTL_MS);
|
|
168618
|
-
},
|
|
168619
|
-
consumeAppMentionRetry(seenKey) {
|
|
168620
|
-
pruneAppMentionMaps(Date.now());
|
|
168621
|
-
if (!appMentionRetryKeys.has(seenKey))
|
|
168622
|
-
return false;
|
|
168623
|
-
appMentionRetryKeys.delete(seenKey);
|
|
168624
|
-
return true;
|
|
168625
|
-
},
|
|
168626
|
-
clear() {
|
|
168627
|
-
pendingTopLevelKeys.clear();
|
|
168628
|
-
appMentionRetryKeys.clear();
|
|
168629
|
-
appMentionDispatchedKeys.clear();
|
|
168459
|
+
try {
|
|
168460
|
+
reader.releaseLock();
|
|
168461
|
+
} catch {}
|
|
168462
|
+
await fileHandle.close().catch(() => {
|
|
168463
|
+
return;
|
|
168464
|
+
});
|
|
168465
|
+
if (!completed) {
|
|
168466
|
+
await rm2(temporaryPath, { force: true }).catch(() => {
|
|
168467
|
+
return;
|
|
168468
|
+
});
|
|
168630
168469
|
}
|
|
168631
|
-
}
|
|
168470
|
+
}
|
|
168471
|
+
try {
|
|
168472
|
+
await rename(temporaryPath, filePath);
|
|
168473
|
+
} catch (error54) {
|
|
168474
|
+
await rm2(temporaryPath, { force: true }).catch(() => {
|
|
168475
|
+
return;
|
|
168476
|
+
});
|
|
168477
|
+
throw error54;
|
|
168478
|
+
}
|
|
168479
|
+
return { localPath: filePath, sizeBytes };
|
|
168632
168480
|
}
|
|
168633
|
-
var
|
|
168634
|
-
var
|
|
168635
|
-
|
|
168481
|
+
var SlackAttachmentDownloadError;
|
|
168482
|
+
var init_attachment_stream = __esm(() => {
|
|
168483
|
+
init_config2();
|
|
168484
|
+
SlackAttachmentDownloadError = class SlackAttachmentDownloadError extends Error {
|
|
168485
|
+
reason;
|
|
168486
|
+
constructor(reason, message) {
|
|
168487
|
+
super(message);
|
|
168488
|
+
this.reason = reason;
|
|
168489
|
+
this.name = "SlackAttachmentDownloadError";
|
|
168490
|
+
}
|
|
168491
|
+
};
|
|
168636
168492
|
});
|
|
168637
168493
|
|
|
168638
168494
|
// src/channels/slack/media.ts
|
|
168639
|
-
import {
|
|
168640
|
-
|
|
168641
|
-
|
|
168642
|
-
async function mapSlackThreadMessage(message, attachmentOptions) {
|
|
168643
|
-
const attachments = await resolveSlackMessageAttachments(message, attachmentOptions);
|
|
168495
|
+
import { basename as basename7, extname as extname3 } from "node:path";
|
|
168496
|
+
async function mapSlackThreadMessage(message, attachmentOptions, sourceThreadId) {
|
|
168497
|
+
const attachments = await resolveSlackMessageAttachments(message, attachmentOptions, sourceThreadId);
|
|
168644
168498
|
return {
|
|
168645
168499
|
text: resolveSlackThreadMessageText(message),
|
|
168646
168500
|
userId: isNonEmptyString3(message.user) ? message.user : undefined,
|
|
@@ -168741,10 +168595,6 @@ function assertSlackFileUrl(rawUrl) {
|
|
|
168741
168595
|
}
|
|
168742
168596
|
return parsed;
|
|
168743
168597
|
}
|
|
168744
|
-
function sanitizeFileName(name) {
|
|
168745
|
-
const normalized = name.trim().replace(/[^\w.-]+/g, "_");
|
|
168746
|
-
return normalized.length > 0 ? normalized : "attachment";
|
|
168747
|
-
}
|
|
168748
168598
|
function extensionForMimeType2(mimeType) {
|
|
168749
168599
|
switch (mimeType?.toLowerCase()) {
|
|
168750
168600
|
case "image/png":
|
|
@@ -168782,7 +168632,7 @@ function resolveMimeType(name, fallback) {
|
|
|
168782
168632
|
if (fallback) {
|
|
168783
168633
|
return fallback;
|
|
168784
168634
|
}
|
|
168785
|
-
switch (
|
|
168635
|
+
switch (extname3(name).toLowerCase()) {
|
|
168786
168636
|
case ".png":
|
|
168787
168637
|
return "image/png";
|
|
168788
168638
|
case ".jpg":
|
|
@@ -168858,51 +168708,93 @@ async function fetchWithSlackAuth(url2, token) {
|
|
|
168858
168708
|
}
|
|
168859
168709
|
return fetch(resolved.href, { redirect: "follow" });
|
|
168860
168710
|
}
|
|
168861
|
-
|
|
168862
|
-
const
|
|
168863
|
-
|
|
168864
|
-
|
|
168865
|
-
|
|
168866
|
-
|
|
168711
|
+
function resolveSlackAttachmentFileName(params) {
|
|
168712
|
+
const hintedName = params.file.name ?? (params.url ? basename7(new URL(params.url).pathname) : undefined) ?? `${params.file.id ?? "attachment"}${extensionForMimeType2(params.file.mimetype)}`;
|
|
168713
|
+
return extname3(hintedName) || !params.mimeType ? hintedName : `${hintedName}${extensionForMimeType2(params.mimeType)}`;
|
|
168714
|
+
}
|
|
168715
|
+
function resolveSlackAttachmentMimeType(params) {
|
|
168716
|
+
const preferredMimeType = params.responseMimeType && !isGenericSlackMimeType(params.responseMimeType) ? params.responseMimeType : params.file.mimetype && !isGenericSlackMimeType(params.file.mimetype) ? params.file.mimetype : undefined;
|
|
168717
|
+
return resolveMimeType(params.fileName, preferredMimeType);
|
|
168718
|
+
}
|
|
168719
|
+
function createUndownloadedSlackAttachment(params) {
|
|
168720
|
+
const fileName = resolveSlackAttachmentFileName({ file: params.file });
|
|
168721
|
+
const mimeType = resolveSlackAttachmentMimeType({
|
|
168722
|
+
file: params.file,
|
|
168723
|
+
fileName
|
|
168724
|
+
});
|
|
168725
|
+
return {
|
|
168726
|
+
id: params.file.id,
|
|
168727
|
+
name: fileName,
|
|
168728
|
+
mimeType,
|
|
168729
|
+
sizeBytes: params.file.size,
|
|
168730
|
+
kind: resolveAttachmentKind(mimeType),
|
|
168731
|
+
sourceMessageId: params.sourceMessageId,
|
|
168732
|
+
...params.sourceThreadId ? { sourceThreadId: params.sourceThreadId } : {},
|
|
168733
|
+
downloadReason: params.reason,
|
|
168734
|
+
...params.reason === "exceeds_auto_download_limit" ? { autoDownloadLimitBytes: MAX_SLACK_ATTACHMENT_BYTES } : {}
|
|
168735
|
+
};
|
|
168867
168736
|
}
|
|
168868
|
-
async function
|
|
168737
|
+
async function materializeSlackAttachment(params) {
|
|
168738
|
+
if (params.maxBytes !== undefined && typeof params.file.size === "number" && params.file.size > params.maxBytes) {
|
|
168739
|
+
throw new SlackAttachmentDownloadError("exceeds_auto_download_limit", `Slack attachment is ${params.file.size} bytes; automatic download limit is ${params.maxBytes} bytes.`);
|
|
168740
|
+
}
|
|
168869
168741
|
const url2 = params.file.url_private_download ?? params.file.url_private;
|
|
168870
168742
|
if (!url2) {
|
|
168871
|
-
|
|
168743
|
+
throw new SlackAttachmentDownloadError("missing_download_url", "Slack attachment does not include a private download URL.");
|
|
168872
168744
|
}
|
|
168873
|
-
const response = await fetchWithSlackAuth(url2, params.token)
|
|
168745
|
+
const response = await fetchWithSlackAuth(url2, params.token).catch((error54) => {
|
|
168746
|
+
throw new SlackAttachmentDownloadError("download_failed", error54 instanceof Error ? error54.message : "Slack attachment fetch failed.");
|
|
168747
|
+
});
|
|
168874
168748
|
if (!response.ok) {
|
|
168875
|
-
|
|
168749
|
+
throw new SlackAttachmentDownloadError("download_failed", `Slack attachment fetch failed with HTTP ${response.status}.`);
|
|
168876
168750
|
}
|
|
168877
|
-
const
|
|
168878
|
-
|
|
168879
|
-
|
|
168751
|
+
const contentLengthHeader = response.headers.get("content-length");
|
|
168752
|
+
const contentLength = contentLengthHeader ? Number(contentLengthHeader) : undefined;
|
|
168753
|
+
if (params.maxBytes !== undefined && contentLength !== undefined && Number.isFinite(contentLength) && contentLength > params.maxBytes) {
|
|
168754
|
+
await response.body?.cancel().catch(() => {
|
|
168755
|
+
return;
|
|
168756
|
+
});
|
|
168757
|
+
throw new SlackAttachmentDownloadError("exceeds_auto_download_limit", `Slack attachment is ${contentLength} bytes; automatic download limit is ${params.maxBytes} bytes.`);
|
|
168880
168758
|
}
|
|
168881
|
-
const buffer = Buffer.from(arrayBuffer);
|
|
168882
|
-
const hintedName = params.file.name ?? basename8(new URL(url2).pathname) ?? `${params.file.id ?? "attachment"}${extensionForMimeType2(params.file.mimetype)}`;
|
|
168883
168759
|
const responseMimeType = response.headers.get("content-type")?.split(";")[0]?.trim() || undefined;
|
|
168884
|
-
const
|
|
168885
|
-
|
|
168886
|
-
|
|
168887
|
-
|
|
168888
|
-
const
|
|
168760
|
+
const hintedName = resolveSlackAttachmentFileName({
|
|
168761
|
+
file: params.file,
|
|
168762
|
+
url: url2
|
|
168763
|
+
});
|
|
168764
|
+
const mimeType = resolveSlackAttachmentMimeType({
|
|
168765
|
+
file: params.file,
|
|
168766
|
+
fileName: hintedName,
|
|
168767
|
+
responseMimeType
|
|
168768
|
+
});
|
|
168769
|
+
const fileName = resolveSlackAttachmentFileName({
|
|
168770
|
+
file: params.file,
|
|
168771
|
+
url: url2,
|
|
168772
|
+
mimeType
|
|
168773
|
+
});
|
|
168774
|
+
if (!response.body) {
|
|
168775
|
+
throw new SlackAttachmentDownloadError("download_failed", "Slack attachment response did not include a body.");
|
|
168776
|
+
}
|
|
168777
|
+
const saved = await saveSlackAttachmentStream({
|
|
168889
168778
|
accountId: params.accountId,
|
|
168890
168779
|
fileName,
|
|
168891
|
-
|
|
168780
|
+
body: response.body,
|
|
168781
|
+
maxBytes: params.maxBytes
|
|
168892
168782
|
});
|
|
168893
168783
|
const kind = resolveAttachmentKind(mimeType);
|
|
168894
168784
|
const attachment = {
|
|
168895
168785
|
id: params.file.id,
|
|
168896
168786
|
name: fileName,
|
|
168897
168787
|
mimeType,
|
|
168898
|
-
sizeBytes:
|
|
168788
|
+
sizeBytes: saved.sizeBytes,
|
|
168899
168789
|
kind,
|
|
168900
|
-
localPath
|
|
168790
|
+
localPath: saved.localPath,
|
|
168791
|
+
sourceMessageId: params.sourceMessageId,
|
|
168792
|
+
...params.sourceThreadId ? { sourceThreadId: params.sourceThreadId } : {}
|
|
168901
168793
|
};
|
|
168902
168794
|
if (kind === "audio" && params.transcribeVoice) {
|
|
168903
168795
|
const { isTranscriptionConfigured: isTranscriptionConfigured2, transcribeAudioFile: transcribeAudioFile2 } = await Promise.resolve().then(() => (init_transcription(), exports_transcription));
|
|
168904
168796
|
if (isTranscriptionConfigured2()) {
|
|
168905
|
-
const result = await transcribeAudioFile2(localPath);
|
|
168797
|
+
const result = await transcribeAudioFile2(saved.localPath);
|
|
168906
168798
|
if (result.success && result.text) {
|
|
168907
168799
|
attachment.transcription = result.text;
|
|
168908
168800
|
} else if (result.error) {
|
|
@@ -168953,13 +168845,28 @@ async function resolveSlackFilesAsAttachments(params) {
|
|
|
168953
168845
|
if (params.files.length === 0) {
|
|
168954
168846
|
return [];
|
|
168955
168847
|
}
|
|
168956
|
-
const resolved = await Promise.all(params.files.map((file3) =>
|
|
168957
|
-
|
|
168958
|
-
|
|
168959
|
-
|
|
168960
|
-
|
|
168961
|
-
|
|
168962
|
-
|
|
168848
|
+
const resolved = await Promise.all(params.files.map(async (file3) => {
|
|
168849
|
+
try {
|
|
168850
|
+
return await materializeSlackAttachment({
|
|
168851
|
+
accountId: params.accountId,
|
|
168852
|
+
token: params.token,
|
|
168853
|
+
file: file3,
|
|
168854
|
+
sourceMessageId: params.sourceMessageId,
|
|
168855
|
+
sourceThreadId: params.sourceThreadId,
|
|
168856
|
+
maxBytes: MAX_SLACK_ATTACHMENT_BYTES,
|
|
168857
|
+
transcribeVoice: params.transcribeVoice
|
|
168858
|
+
});
|
|
168859
|
+
} catch (error54) {
|
|
168860
|
+
const reason = error54 instanceof SlackAttachmentDownloadError ? error54.reason : "download_failed";
|
|
168861
|
+
return createUndownloadedSlackAttachment({
|
|
168862
|
+
file: file3,
|
|
168863
|
+
sourceMessageId: params.sourceMessageId,
|
|
168864
|
+
sourceThreadId: params.sourceThreadId,
|
|
168865
|
+
reason
|
|
168866
|
+
});
|
|
168867
|
+
}
|
|
168868
|
+
}));
|
|
168869
|
+
return resolved;
|
|
168963
168870
|
}
|
|
168964
168871
|
function resolveSlackThreadAttachmentOptions(params) {
|
|
168965
168872
|
if (!isNonEmptyString3(params.accountId) || !isNonEmptyString3(params.token)) {
|
|
@@ -168980,7 +168887,7 @@ function hasSlackThreadMessageContent(message, attachmentOptions) {
|
|
|
168980
168887
|
function hasHydratedSlackThreadMessageContent(message) {
|
|
168981
168888
|
return message.text.length > 0 || Boolean(message.attachments?.length);
|
|
168982
168889
|
}
|
|
168983
|
-
async function resolveSlackMessageAttachments(message, attachmentOptions) {
|
|
168890
|
+
async function resolveSlackMessageAttachments(message, attachmentOptions, sourceThreadId) {
|
|
168984
168891
|
if (!attachmentOptions) {
|
|
168985
168892
|
return [];
|
|
168986
168893
|
}
|
|
@@ -168988,14 +168895,19 @@ async function resolveSlackMessageAttachments(message, attachmentOptions) {
|
|
|
168988
168895
|
accountId: attachmentOptions.accountId,
|
|
168989
168896
|
token: attachmentOptions.token,
|
|
168990
168897
|
files: collectSlackFiles(message),
|
|
168898
|
+
sourceMessageId: message.ts,
|
|
168899
|
+
sourceThreadId: sourceThreadId ?? (isNonEmptyString3(message.thread_ts) ? message.thread_ts : null),
|
|
168991
168900
|
transcribeVoice: attachmentOptions.transcribeVoice
|
|
168992
168901
|
});
|
|
168993
168902
|
}
|
|
168994
168903
|
async function resolveSlackInboundAttachments(params) {
|
|
168904
|
+
const rawEvent = asRecord4(params.rawEvent);
|
|
168995
168905
|
return resolveSlackFilesAsAttachments({
|
|
168996
168906
|
accountId: params.accountId,
|
|
168997
168907
|
token: params.token,
|
|
168998
168908
|
files: collectSlackFiles(params.rawEvent),
|
|
168909
|
+
sourceMessageId: isNonEmptyString3(rawEvent?.ts) ? rawEvent.ts : undefined,
|
|
168910
|
+
sourceThreadId: isNonEmptyString3(rawEvent?.thread_ts) ? rawEvent.thread_ts : null,
|
|
168999
168911
|
transcribeVoice: params.transcribeVoice
|
|
169000
168912
|
});
|
|
169001
168913
|
}
|
|
@@ -169017,7 +168929,7 @@ async function resolveSlackCurrentMessageAttachments(params) {
|
|
|
169017
168929
|
});
|
|
169018
168930
|
const message = (response.messages ?? []).find((entry) => entry.ts === params.messageTs);
|
|
169019
168931
|
if (message) {
|
|
169020
|
-
return resolveSlackMessageAttachments(message, attachmentOptions);
|
|
168932
|
+
return resolveSlackMessageAttachments(message, attachmentOptions, params.threadTs);
|
|
169021
168933
|
}
|
|
169022
168934
|
const nextCursor = response.response_metadata?.next_cursor;
|
|
169023
168935
|
cursor = typeof nextCursor === "string" && nextCursor.trim().length > 0 ? nextCursor.trim() : undefined;
|
|
@@ -169043,7 +168955,7 @@ async function resolveSlackThreadStarter(params) {
|
|
|
169043
168955
|
if (!hasSlackThreadMessageContent(message, attachmentOptions)) {
|
|
169044
168956
|
return null;
|
|
169045
168957
|
}
|
|
169046
|
-
const mapped3 = await mapSlackThreadMessage(message, attachmentOptions);
|
|
168958
|
+
const mapped3 = await mapSlackThreadMessage(message, attachmentOptions, params.threadTs);
|
|
169047
168959
|
return hasHydratedSlackThreadMessageContent(mapped3) ? mapped3 : null;
|
|
169048
168960
|
} catch {
|
|
169049
168961
|
return null;
|
|
@@ -169088,7 +169000,7 @@ async function resolveSlackThreadHistory(params) {
|
|
|
169088
169000
|
const nextCursor = response.response_metadata?.next_cursor;
|
|
169089
169001
|
cursor = typeof nextCursor === "string" && nextCursor.trim().length > 0 ? nextCursor.trim() : undefined;
|
|
169090
169002
|
} while (cursor);
|
|
169091
|
-
const mapped3 = await Promise.all(retained.map((message) => mapSlackThreadMessage(message, attachmentOptions)));
|
|
169003
|
+
const mapped3 = await Promise.all(retained.map((message) => mapSlackThreadMessage(message, attachmentOptions, params.threadTs)));
|
|
169092
169004
|
return mapped3.filter(hasHydratedSlackThreadMessageContent);
|
|
169093
169005
|
} catch {
|
|
169094
169006
|
return [];
|
|
@@ -169122,7 +169034,7 @@ async function resolveSlackChannelHistory(params) {
|
|
|
169122
169034
|
}
|
|
169123
169035
|
var MAX_SLACK_ATTACHMENTS = 8, MAX_SLACK_ATTACHMENT_BYTES, ALLOWED_SLACK_HOST_SUFFIXES;
|
|
169124
169036
|
var init_media2 = __esm(() => {
|
|
169125
|
-
|
|
169037
|
+
init_attachment_stream();
|
|
169126
169038
|
MAX_SLACK_ATTACHMENT_BYTES = 20 * 1024 * 1024;
|
|
169127
169039
|
ALLOWED_SLACK_HOST_SUFFIXES = [
|
|
169128
169040
|
"slack.com",
|
|
@@ -169131,6 +169043,286 @@ var init_media2 = __esm(() => {
|
|
|
169131
169043
|
];
|
|
169132
169044
|
});
|
|
169133
169045
|
|
|
169046
|
+
// src/channels/slack/attachment-download.ts
|
|
169047
|
+
function isNonEmptyString4(value) {
|
|
169048
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
169049
|
+
}
|
|
169050
|
+
async function resolveCanonicalSlackMessage(params) {
|
|
169051
|
+
if (isNonEmptyString4(params.threadTs)) {
|
|
169052
|
+
let cursor;
|
|
169053
|
+
do {
|
|
169054
|
+
const response2 = await params.client.conversations.replies({
|
|
169055
|
+
channel: params.channelId,
|
|
169056
|
+
ts: params.threadTs,
|
|
169057
|
+
limit: 200,
|
|
169058
|
+
inclusive: true,
|
|
169059
|
+
...cursor ? { cursor } : {}
|
|
169060
|
+
});
|
|
169061
|
+
const message = (response2.messages ?? []).find((entry) => entry.ts === params.messageTs);
|
|
169062
|
+
if (message) {
|
|
169063
|
+
return message;
|
|
169064
|
+
}
|
|
169065
|
+
const nextCursor = response2.response_metadata?.next_cursor;
|
|
169066
|
+
cursor = isNonEmptyString4(nextCursor) ? nextCursor.trim() : undefined;
|
|
169067
|
+
} while (cursor);
|
|
169068
|
+
return null;
|
|
169069
|
+
}
|
|
169070
|
+
const response = await params.client.conversations.history({
|
|
169071
|
+
channel: params.channelId,
|
|
169072
|
+
oldest: params.messageTs,
|
|
169073
|
+
latest: params.messageTs,
|
|
169074
|
+
inclusive: true,
|
|
169075
|
+
limit: 1
|
|
169076
|
+
});
|
|
169077
|
+
return (response.messages ?? []).find((entry) => entry.ts === params.messageTs) ?? null;
|
|
169078
|
+
}
|
|
169079
|
+
async function downloadSlackAttachmentById(params) {
|
|
169080
|
+
const message = await resolveCanonicalSlackMessage(params);
|
|
169081
|
+
if (!message) {
|
|
169082
|
+
throw new Error(`Slack message ${params.messageTs} was not found in chat ${params.channelId}.`);
|
|
169083
|
+
}
|
|
169084
|
+
const file3 = collectSlackFiles(message).find((entry) => entry.id === params.attachmentId);
|
|
169085
|
+
if (!file3) {
|
|
169086
|
+
throw new Error(`Slack attachment ${params.attachmentId} is not attached to message ${params.messageTs}.`);
|
|
169087
|
+
}
|
|
169088
|
+
return await materializeSlackAttachment({
|
|
169089
|
+
accountId: params.accountId,
|
|
169090
|
+
token: params.token,
|
|
169091
|
+
file: file3,
|
|
169092
|
+
sourceMessageId: params.messageTs,
|
|
169093
|
+
sourceThreadId: params.threadTs ?? null
|
|
169094
|
+
});
|
|
169095
|
+
}
|
|
169096
|
+
var init_attachment_download = __esm(() => {
|
|
169097
|
+
init_media2();
|
|
169098
|
+
});
|
|
169099
|
+
|
|
169100
|
+
// src/channels/slack/file-upload.ts
|
|
169101
|
+
import { readFile as readFile4 } from "node:fs/promises";
|
|
169102
|
+
import { basename as basename8, extname as extname4 } from "node:path";
|
|
169103
|
+
function resolveUploadMimeType(filePath) {
|
|
169104
|
+
switch (extname4(filePath).toLowerCase()) {
|
|
169105
|
+
case ".png":
|
|
169106
|
+
return "image/png";
|
|
169107
|
+
case ".jpg":
|
|
169108
|
+
case ".jpeg":
|
|
169109
|
+
return "image/jpeg";
|
|
169110
|
+
case ".gif":
|
|
169111
|
+
return "image/gif";
|
|
169112
|
+
case ".webp":
|
|
169113
|
+
return "image/webp";
|
|
169114
|
+
case ".pdf":
|
|
169115
|
+
return "application/pdf";
|
|
169116
|
+
case ".txt":
|
|
169117
|
+
return "text/plain";
|
|
169118
|
+
case ".md":
|
|
169119
|
+
return "text/markdown";
|
|
169120
|
+
default:
|
|
169121
|
+
return;
|
|
169122
|
+
}
|
|
169123
|
+
}
|
|
169124
|
+
async function uploadSlackFile(slackClient, msg) {
|
|
169125
|
+
if (!msg.mediaPath) {
|
|
169126
|
+
throw new Error("mediaPath is required for Slack file uploads.");
|
|
169127
|
+
}
|
|
169128
|
+
const buffer = await readFile4(msg.mediaPath);
|
|
169129
|
+
const uploadFileName = msg.fileName ?? basename8(msg.mediaPath);
|
|
169130
|
+
const uploadTitle = msg.title ?? uploadFileName;
|
|
169131
|
+
const uploadMimeType = resolveUploadMimeType(uploadFileName);
|
|
169132
|
+
const uploadUrlResp = await slackClient.files.getUploadURLExternal({
|
|
169133
|
+
filename: uploadFileName,
|
|
169134
|
+
length: buffer.length
|
|
169135
|
+
});
|
|
169136
|
+
if (!uploadUrlResp.ok || !uploadUrlResp.upload_url || !uploadUrlResp.file_id) {
|
|
169137
|
+
throw new Error(`Failed to get Slack upload URL: ${uploadUrlResp.error ?? "unknown error"}`);
|
|
169138
|
+
}
|
|
169139
|
+
const uploadResp = await fetch(uploadUrlResp.upload_url, {
|
|
169140
|
+
method: "POST",
|
|
169141
|
+
...uploadMimeType ? { headers: { "Content-Type": uploadMimeType } } : {},
|
|
169142
|
+
body: buffer
|
|
169143
|
+
});
|
|
169144
|
+
if (!uploadResp.ok) {
|
|
169145
|
+
throw new Error(`Failed to upload Slack file: HTTP ${uploadResp.status}`);
|
|
169146
|
+
}
|
|
169147
|
+
const threadTs = resolveSlackOutboundThreadTs({
|
|
169148
|
+
chatId: msg.chatId,
|
|
169149
|
+
threadId: msg.threadId,
|
|
169150
|
+
replyToMessageId: msg.replyToMessageId
|
|
169151
|
+
});
|
|
169152
|
+
const completeResp = await slackClient.files.completeUploadExternal({
|
|
169153
|
+
files: [{ id: uploadUrlResp.file_id, title: uploadTitle }],
|
|
169154
|
+
channel_id: msg.chatId,
|
|
169155
|
+
...msg.text.trim() ? { initial_comment: msg.text } : {},
|
|
169156
|
+
...threadTs ? { thread_ts: threadTs } : {}
|
|
169157
|
+
});
|
|
169158
|
+
if (!completeResp.ok) {
|
|
169159
|
+
throw new Error(`Failed to complete Slack upload: ${completeResp.error ?? "unknown error"}`);
|
|
169160
|
+
}
|
|
169161
|
+
return { messageId: uploadUrlResp.file_id };
|
|
169162
|
+
}
|
|
169163
|
+
var init_file_upload = __esm(() => {
|
|
169164
|
+
init_utils5();
|
|
169165
|
+
});
|
|
169166
|
+
|
|
169167
|
+
// src/channels/slack/inbound-debounce.ts
|
|
169168
|
+
function buildSlackDebounceKey(rawMessage, accountId) {
|
|
169169
|
+
const senderId = rawMessage.user ?? rawMessage.bot_id ?? null;
|
|
169170
|
+
if (!senderId)
|
|
169171
|
+
return null;
|
|
169172
|
+
const messageTs = rawMessage.ts ?? rawMessage.event_ts;
|
|
169173
|
+
const isDm = rawMessage.channel.startsWith("D");
|
|
169174
|
+
const scope = rawMessage.thread_ts ? `${rawMessage.channel}:${rawMessage.thread_ts}` : rawMessage.parent_user_id && messageTs ? `${rawMessage.channel}:maybe-thread:${messageTs}` : messageTs && !isDm ? `${rawMessage.channel}:${messageTs}` : rawMessage.channel;
|
|
169175
|
+
return `slack:${accountId}:${scope}:${senderId}`;
|
|
169176
|
+
}
|
|
169177
|
+
function buildTopLevelSlackConversationKey(rawMessage, accountId) {
|
|
169178
|
+
if (rawMessage.thread_ts || rawMessage.parent_user_id)
|
|
169179
|
+
return null;
|
|
169180
|
+
if (rawMessage.channel.startsWith("D"))
|
|
169181
|
+
return null;
|
|
169182
|
+
const senderId = rawMessage.user ?? rawMessage.bot_id;
|
|
169183
|
+
return senderId ? `slack:${accountId}:${rawMessage.channel}:${senderId}` : null;
|
|
169184
|
+
}
|
|
169185
|
+
function resolveSlackInboundDebounceMs(config3) {
|
|
169186
|
+
const raw = process.env.LETTA_SLACK_INBOUND_DEBOUNCE_MS;
|
|
169187
|
+
if (typeof raw === "string" && raw.trim() !== "") {
|
|
169188
|
+
const envOverride = Number(raw);
|
|
169189
|
+
if (Number.isFinite(envOverride) && envOverride >= 0) {
|
|
169190
|
+
return Math.trunc(envOverride);
|
|
169191
|
+
}
|
|
169192
|
+
}
|
|
169193
|
+
const fromConfig = config3.inboundDebounceMs;
|
|
169194
|
+
return typeof fromConfig === "number" && Number.isFinite(fromConfig) && fromConfig >= 0 ? Math.trunc(fromConfig) : 0;
|
|
169195
|
+
}
|
|
169196
|
+
function createSlackInboundDebounceController(params) {
|
|
169197
|
+
const { config: config3 } = params;
|
|
169198
|
+
const debounceMs = resolveSlackInboundDebounceMs(config3);
|
|
169199
|
+
const pendingTopLevelKeys = new Map;
|
|
169200
|
+
const appMentionRetryKeys = new Map;
|
|
169201
|
+
const appMentionDispatchedKeys = new Map;
|
|
169202
|
+
function pruneAppMentionMaps(now) {
|
|
169203
|
+
for (const [key, expiresAt] of appMentionRetryKeys) {
|
|
169204
|
+
if (expiresAt <= now)
|
|
169205
|
+
appMentionRetryKeys.delete(key);
|
|
169206
|
+
}
|
|
169207
|
+
for (const [key, expiresAt] of appMentionDispatchedKeys) {
|
|
169208
|
+
if (expiresAt <= now)
|
|
169209
|
+
appMentionDispatchedKeys.delete(key);
|
|
169210
|
+
}
|
|
169211
|
+
}
|
|
169212
|
+
function dedupeEntries(entries) {
|
|
169213
|
+
const indexByMessageKey = new Map;
|
|
169214
|
+
const deduped = [];
|
|
169215
|
+
for (const entry of entries) {
|
|
169216
|
+
const messageId = entry.inbound.messageId;
|
|
169217
|
+
const messageKey = isNonEmptyString2(messageId) ? `${entry.inbound.chatId}:${messageId}` : null;
|
|
169218
|
+
if (!messageKey) {
|
|
169219
|
+
deduped.push(entry);
|
|
169220
|
+
continue;
|
|
169221
|
+
}
|
|
169222
|
+
const existingIndex = indexByMessageKey.get(messageKey);
|
|
169223
|
+
if (existingIndex === undefined) {
|
|
169224
|
+
indexByMessageKey.set(messageKey, deduped.length);
|
|
169225
|
+
deduped.push(entry);
|
|
169226
|
+
continue;
|
|
169227
|
+
}
|
|
169228
|
+
const current = deduped[existingIndex];
|
|
169229
|
+
if (current && current.opts.source !== "app_mention" && current.inbound.isMention !== true) {
|
|
169230
|
+
deduped[existingIndex] = entry;
|
|
169231
|
+
}
|
|
169232
|
+
}
|
|
169233
|
+
return deduped;
|
|
169234
|
+
}
|
|
169235
|
+
const debouncer = createInboundDebouncer({
|
|
169236
|
+
debounceMs,
|
|
169237
|
+
buildKey: ({ raw }) => buildSlackDebounceKey(raw, config3.accountId),
|
|
169238
|
+
shouldDebounce: ({ inbound }) => !inbound.attachments?.length && !inbound.reaction,
|
|
169239
|
+
onFlush: async (entries) => {
|
|
169240
|
+
const dedupedEntries = dedupeEntries(entries);
|
|
169241
|
+
const last = dedupedEntries[dedupedEntries.length - 1];
|
|
169242
|
+
if (!last)
|
|
169243
|
+
return;
|
|
169244
|
+
const flushedKey = buildSlackDebounceKey(last.raw, config3.accountId);
|
|
169245
|
+
const conversationKey = buildTopLevelSlackConversationKey(last.raw, config3.accountId);
|
|
169246
|
+
if (flushedKey && conversationKey) {
|
|
169247
|
+
const pending = pendingTopLevelKeys.get(conversationKey);
|
|
169248
|
+
pending?.delete(flushedKey);
|
|
169249
|
+
if (pending?.size === 0)
|
|
169250
|
+
pendingTopLevelKeys.delete(conversationKey);
|
|
169251
|
+
}
|
|
169252
|
+
if (isNonEmptyString2(last.inbound.messageId)) {
|
|
169253
|
+
const seenKey = `${last.inbound.chatId}:${last.inbound.messageId}`;
|
|
169254
|
+
pruneAppMentionMaps(Date.now());
|
|
169255
|
+
if (last.opts.source === "app_mention") {
|
|
169256
|
+
appMentionDispatchedKeys.set(seenKey, Date.now() + APP_MENTION_RETRY_TTL_MS);
|
|
169257
|
+
} else if (appMentionDispatchedKeys.has(seenKey)) {
|
|
169258
|
+
appMentionDispatchedKeys.delete(seenKey);
|
|
169259
|
+
appMentionRetryKeys.delete(seenKey);
|
|
169260
|
+
return;
|
|
169261
|
+
}
|
|
169262
|
+
appMentionRetryKeys.delete(seenKey);
|
|
169263
|
+
}
|
|
169264
|
+
const onMessage = params.getOnMessage();
|
|
169265
|
+
if (!onMessage)
|
|
169266
|
+
return;
|
|
169267
|
+
const text = dedupedEntries.length === 1 ? last.inbound.text : dedupedEntries.map((entry) => entry.inbound.text).filter(Boolean).join(`
|
|
169268
|
+
`);
|
|
169269
|
+
try {
|
|
169270
|
+
await onMessage({
|
|
169271
|
+
...last.inbound,
|
|
169272
|
+
text,
|
|
169273
|
+
isMention: dedupedEntries.some((entry) => entry.opts.wasMentioned || entry.inbound.isMention === true)
|
|
169274
|
+
});
|
|
169275
|
+
} catch (error54) {
|
|
169276
|
+
console.error("[Slack] Error handling debounced inbound message:", error54);
|
|
169277
|
+
}
|
|
169278
|
+
},
|
|
169279
|
+
onError: (error54) => {
|
|
169280
|
+
console.error("[Slack] Inbound debounce flush failed:", error54 instanceof Error ? error54.message : error54);
|
|
169281
|
+
}
|
|
169282
|
+
});
|
|
169283
|
+
return {
|
|
169284
|
+
async dispatch(entry) {
|
|
169285
|
+
const debounceKey = buildSlackDebounceKey(entry.raw, config3.accountId);
|
|
169286
|
+
const conversationKey = buildTopLevelSlackConversationKey(entry.raw, config3.accountId);
|
|
169287
|
+
const canDebounce = debounceMs > 0 && !entry.inbound.attachments?.length && !entry.inbound.reaction && Boolean(debounceKey);
|
|
169288
|
+
if (!canDebounce && conversationKey) {
|
|
169289
|
+
for (const pendingKey of Array.from(pendingTopLevelKeys.get(conversationKey) ?? [])) {
|
|
169290
|
+
try {
|
|
169291
|
+
await debouncer.flushKey(pendingKey);
|
|
169292
|
+
} catch {}
|
|
169293
|
+
}
|
|
169294
|
+
}
|
|
169295
|
+
if (canDebounce && debounceKey && conversationKey) {
|
|
169296
|
+
const pending = pendingTopLevelKeys.get(conversationKey) ?? new Set;
|
|
169297
|
+
pending.add(debounceKey);
|
|
169298
|
+
pendingTopLevelKeys.set(conversationKey, pending);
|
|
169299
|
+
}
|
|
169300
|
+
await debouncer.enqueue(entry);
|
|
169301
|
+
},
|
|
169302
|
+
rememberAppMentionRetry(seenKey) {
|
|
169303
|
+
const now = Date.now();
|
|
169304
|
+
pruneAppMentionMaps(now);
|
|
169305
|
+
appMentionRetryKeys.set(seenKey, now + APP_MENTION_RETRY_TTL_MS);
|
|
169306
|
+
},
|
|
169307
|
+
consumeAppMentionRetry(seenKey) {
|
|
169308
|
+
pruneAppMentionMaps(Date.now());
|
|
169309
|
+
if (!appMentionRetryKeys.has(seenKey))
|
|
169310
|
+
return false;
|
|
169311
|
+
appMentionRetryKeys.delete(seenKey);
|
|
169312
|
+
return true;
|
|
169313
|
+
},
|
|
169314
|
+
clear() {
|
|
169315
|
+
pendingTopLevelKeys.clear();
|
|
169316
|
+
appMentionRetryKeys.clear();
|
|
169317
|
+
appMentionDispatchedKeys.clear();
|
|
169318
|
+
}
|
|
169319
|
+
};
|
|
169320
|
+
}
|
|
169321
|
+
var APP_MENTION_RETRY_TTL_MS = 60000;
|
|
169322
|
+
var init_inbound_debounce = __esm(() => {
|
|
169323
|
+
init_utils5();
|
|
169324
|
+
});
|
|
169325
|
+
|
|
169134
169326
|
// src/channels/slack/ingress-controller.ts
|
|
169135
169327
|
function createSlackIngressController(params) {
|
|
169136
169328
|
const { config: config3 } = params;
|
|
@@ -169863,6 +170055,18 @@ function createSlackAdapter(config3) {
|
|
|
169863
170055
|
throw error54;
|
|
169864
170056
|
}
|
|
169865
170057
|
}
|
|
170058
|
+
async function downloadAttachment(params) {
|
|
170059
|
+
const slackApp = await ensureApp();
|
|
170060
|
+
return await downloadSlackAttachmentById({
|
|
170061
|
+
accountId: config3.accountId,
|
|
170062
|
+
token: config3.botToken,
|
|
170063
|
+
attachmentId: params.attachmentId,
|
|
170064
|
+
channelId: params.chatId,
|
|
170065
|
+
threadTs: params.threadId,
|
|
170066
|
+
messageTs: params.messageId,
|
|
170067
|
+
client: slackApp.client
|
|
170068
|
+
});
|
|
170069
|
+
}
|
|
169866
170070
|
async function sendLifecycleErrorReply(source2, errorText) {
|
|
169867
170071
|
const threadTs = resolveSlackSourceThreadTs(source2);
|
|
169868
170072
|
const text = formatSlackLifecycleErrorMessage(errorText);
|
|
@@ -170065,6 +170269,7 @@ function createSlackAdapter(config3) {
|
|
|
170065
170269
|
await Promise.all(status.getUniqueSources(event2.sources).map((source2) => status.activate(source2, SLACK_ASSISTANT_WORKING_STATUS, activity)));
|
|
170066
170270
|
},
|
|
170067
170271
|
sendMessage,
|
|
170272
|
+
downloadAttachment,
|
|
170068
170273
|
sendDirectReply,
|
|
170069
170274
|
handleControlRequestEvent,
|
|
170070
170275
|
prepareInboundMessage: (msg, options3) => prepareSlackInboundMessage({
|
|
@@ -170084,6 +170289,7 @@ var init_adapter3 = __esm(async () => {
|
|
|
170084
170289
|
init_model_picker_blocks();
|
|
170085
170290
|
init_error_reporting();
|
|
170086
170291
|
init_agent_thread_tracker();
|
|
170292
|
+
init_attachment_download();
|
|
170087
170293
|
init_file_upload();
|
|
170088
170294
|
init_inbound_debounce();
|
|
170089
170295
|
init_ingress_controller();
|
|
@@ -170474,13 +170680,47 @@ async function reactInSlack(ctx) {
|
|
|
170474
170680
|
});
|
|
170475
170681
|
return request.remove ? `Reaction removed on slack (message_id: ${result.messageId})` : `Reaction added on slack (message_id: ${result.messageId})`;
|
|
170476
170682
|
}
|
|
170683
|
+
async function downloadSlackFile(ctx) {
|
|
170684
|
+
const { request } = ctx;
|
|
170685
|
+
if (!request.attachmentId?.trim()) {
|
|
170686
|
+
return "Error: Slack download-file requires attachmentId.";
|
|
170687
|
+
}
|
|
170688
|
+
if (!request.messageId?.trim()) {
|
|
170689
|
+
return "Error: Slack download-file requires messageId from the attachment's Slack context.";
|
|
170690
|
+
}
|
|
170691
|
+
if (typeof ctx.adapter.downloadAttachment !== "function") {
|
|
170692
|
+
return "Error: Running Slack adapter does not support attachment downloads.";
|
|
170693
|
+
}
|
|
170694
|
+
const attachment = await ctx.adapter.downloadAttachment({
|
|
170695
|
+
attachmentId: request.attachmentId,
|
|
170696
|
+
chatId: request.chatId,
|
|
170697
|
+
threadId: request.threadId ?? null,
|
|
170698
|
+
messageId: request.messageId
|
|
170699
|
+
});
|
|
170700
|
+
if (!attachment.localPath) {
|
|
170701
|
+
return `Error: Slack attachment ${request.attachmentId} was not downloaded.`;
|
|
170702
|
+
}
|
|
170703
|
+
return `Slack attachment downloaded (local_path: ${attachment.localPath})`;
|
|
170704
|
+
}
|
|
170477
170705
|
var slackMessageActions;
|
|
170478
170706
|
var init_message_actions2 = __esm(() => {
|
|
170479
170707
|
init_target_resolution();
|
|
170480
170708
|
slackMessageActions = {
|
|
170481
170709
|
describeMessageTool() {
|
|
170482
170710
|
return {
|
|
170483
|
-
actions: ["send", "react", "upload-file"]
|
|
170711
|
+
actions: ["send", "react", "upload-file", "download-file"],
|
|
170712
|
+
schema: {
|
|
170713
|
+
properties: {
|
|
170714
|
+
attachmentId: {
|
|
170715
|
+
type: "string",
|
|
170716
|
+
description: "Slack attachment id for action='download-file'. Copy attachment_id from the channel notification."
|
|
170717
|
+
},
|
|
170718
|
+
messageId: {
|
|
170719
|
+
type: "string",
|
|
170720
|
+
description: "Target Slack message id for action='react', or the source message id containing attachmentId for action='download-file'."
|
|
170721
|
+
}
|
|
170722
|
+
}
|
|
170723
|
+
}
|
|
170484
170724
|
};
|
|
170485
170725
|
},
|
|
170486
170726
|
async resolveMessageTarget(params) {
|
|
@@ -170500,6 +170740,8 @@ var init_message_actions2 = __esm(() => {
|
|
|
170500
170740
|
return await sendSlackMessage(ctx);
|
|
170501
170741
|
case "react":
|
|
170502
170742
|
return await reactInSlack(ctx);
|
|
170743
|
+
case "download-file":
|
|
170744
|
+
return await downloadSlackFile(ctx);
|
|
170503
170745
|
default:
|
|
170504
170746
|
return `Error: Action "${ctx.request.action}" is not supported on slack.`;
|
|
170505
170747
|
}
|
|
@@ -170739,7 +170981,7 @@ function resolveDiscordChannelMode(channelId, parentChannelId, isThread, allowed
|
|
|
170739
170981
|
// src/channels/discord/media.ts
|
|
170740
170982
|
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
170741
170983
|
import { mkdirSync as mkdirSync6 } from "node:fs";
|
|
170742
|
-
import { writeFile as
|
|
170984
|
+
import { writeFile as writeFile6 } from "node:fs/promises";
|
|
170743
170985
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
170744
170986
|
import { join as join13 } from "node:path";
|
|
170745
170987
|
function ensureAttachmentsDir() {
|
|
@@ -170803,7 +171045,7 @@ async function resolveDiscordInboundAttachments(params) {
|
|
|
170803
171045
|
console.warn(`[Discord] Skipping oversized attachment ${name}: ${buffer.byteLength} bytes`);
|
|
170804
171046
|
continue;
|
|
170805
171047
|
}
|
|
170806
|
-
await
|
|
171048
|
+
await writeFile6(localPath, buffer);
|
|
170807
171049
|
const entry = {
|
|
170808
171050
|
id: attachment.id,
|
|
170809
171051
|
name,
|
|
@@ -170909,7 +171151,7 @@ function formatDiscordDeliveryError(error54) {
|
|
|
170909
171151
|
}
|
|
170910
171152
|
|
|
170911
171153
|
// src/channels/discord/utils.ts
|
|
170912
|
-
function
|
|
171154
|
+
function isNonEmptyString5(value) {
|
|
170913
171155
|
return typeof value === "string" && value.length > 0;
|
|
170914
171156
|
}
|
|
170915
171157
|
function isDiscordTextChannel(channel) {
|
|
@@ -170976,7 +171218,7 @@ function shouldAutoThreadOnDiscordMention(account, channelId) {
|
|
|
170976
171218
|
return account.autoThreadOnMention ?? false;
|
|
170977
171219
|
}
|
|
170978
171220
|
function buildDiscordIngressMessageKey(accountId, messageId) {
|
|
170979
|
-
if (!
|
|
171221
|
+
if (!isNonEmptyString5(accountId) || !isNonEmptyString5(messageId)) {
|
|
170980
171222
|
return null;
|
|
170981
171223
|
}
|
|
170982
171224
|
return `${accountId}:${messageId}`;
|
|
@@ -171060,13 +171302,13 @@ function createDiscordAdapter(config3) {
|
|
|
171060
171302
|
return false;
|
|
171061
171303
|
}
|
|
171062
171304
|
function getLifecycleMessageKey(source2) {
|
|
171063
|
-
if (source2.channel !== "discord" || !
|
|
171305
|
+
if (source2.channel !== "discord" || !isNonEmptyString5(source2.chatId) || !isNonEmptyString5(source2.messageId)) {
|
|
171064
171306
|
return null;
|
|
171065
171307
|
}
|
|
171066
171308
|
return `${source2.chatId}:${source2.messageId}`;
|
|
171067
171309
|
}
|
|
171068
171310
|
function getLifecycleReplyKey(source2) {
|
|
171069
|
-
if (source2.channel !== "discord" || !
|
|
171311
|
+
if (source2.channel !== "discord" || !isNonEmptyString5(source2.chatId)) {
|
|
171070
171312
|
return null;
|
|
171071
171313
|
}
|
|
171072
171314
|
return [
|
|
@@ -171079,7 +171321,7 @@ function createDiscordAdapter(config3) {
|
|
|
171079
171321
|
if (source2.channel !== "discord")
|
|
171080
171322
|
return null;
|
|
171081
171323
|
const channelId = source2.threadId ?? source2.chatId;
|
|
171082
|
-
return
|
|
171324
|
+
return isNonEmptyString5(channelId) ? channelId : null;
|
|
171083
171325
|
}
|
|
171084
171326
|
function getTypingSourceKey(source2) {
|
|
171085
171327
|
const channelId = getTypingChannelId(source2);
|
|
@@ -171131,7 +171373,7 @@ function createDiscordAdapter(config3) {
|
|
|
171131
171373
|
return true;
|
|
171132
171374
|
}
|
|
171133
171375
|
async function sendLifecycleReaction(source2, emoji3, remove = false) {
|
|
171134
|
-
if (!client || !
|
|
171376
|
+
if (!client || !isNonEmptyString5(source2.messageId))
|
|
171135
171377
|
return;
|
|
171136
171378
|
try {
|
|
171137
171379
|
const channel = await client.channels.fetch(source2.chatId);
|
|
@@ -171670,7 +171912,7 @@ function createDiscordAdapter(config3) {
|
|
|
171670
171912
|
clearTypingForChannel(chatId);
|
|
171671
171913
|
},
|
|
171672
171914
|
async prepareInboundMessage(msg, options3) {
|
|
171673
|
-
if (!options3?.isFirstRouteTurn || msg.channel !== "discord" || msg.chatType !== "channel" || !
|
|
171915
|
+
if (!options3?.isFirstRouteTurn || msg.channel !== "discord" || msg.chatType !== "channel" || !isNonEmptyString5(msg.threadId) || !client) {
|
|
171674
171916
|
return msg;
|
|
171675
171917
|
}
|
|
171676
171918
|
const starter = await resolveDiscordThreadStarter({
|
|
@@ -172091,7 +172333,7 @@ var WHATSAPP_PHONE_SUFFIX = "@s.whatsapp.net", WHATSAPP_LID_SUFFIX = "@lid", WHA
|
|
|
172091
172333
|
|
|
172092
172334
|
// src/channels/whatsapp/media.ts
|
|
172093
172335
|
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
172094
|
-
import { mkdir as mkdir5, writeFile as
|
|
172336
|
+
import { mkdir as mkdir5, writeFile as writeFile7 } from "node:fs/promises";
|
|
172095
172337
|
import { basename as basename10, extname as extname5, join as join14 } from "node:path";
|
|
172096
172338
|
function unwrapWhatsAppMessageContent(message) {
|
|
172097
172339
|
if (!message || typeof message !== "object")
|
|
@@ -172273,7 +172515,7 @@ async function collectWhatsAppAttachments(params) {
|
|
|
172273
172515
|
if (!buffer) {
|
|
172274
172516
|
return { attachments: [attachment] };
|
|
172275
172517
|
}
|
|
172276
|
-
await
|
|
172518
|
+
await writeFile7(localPath, buffer);
|
|
172277
172519
|
attachment.localPath = localPath;
|
|
172278
172520
|
if (isVoice && params.transcribeVoice) {
|
|
172279
172521
|
const result = await transcribeAudioFile(localPath);
|
|
@@ -177309,14 +177551,19 @@ function escapeXmlText(text) {
|
|
|
177309
177551
|
function escapeXmlAttribute(text) {
|
|
177310
177552
|
return escapeXmlText(text).replace(/"/g, """).replace(/'/g, "'");
|
|
177311
177553
|
}
|
|
177554
|
+
function formatMebibytes(bytes) {
|
|
177555
|
+
const mebibytes = bytes / (1024 * 1024);
|
|
177556
|
+
const rounded = mebibytes >= 100 ? Math.round(mebibytes).toString() : mebibytes.toFixed(1);
|
|
177557
|
+
return `${rounded.replace(/\.0$/, "")} MiB`;
|
|
177558
|
+
}
|
|
177312
177559
|
function hasNotificationAttachmentPaths(msg) {
|
|
177313
|
-
if (msg.attachments?.
|
|
177560
|
+
if (msg.attachments?.some((attachment) => attachment.localPath)) {
|
|
177314
177561
|
return true;
|
|
177315
177562
|
}
|
|
177316
|
-
if (msg.threadContext?.starter?.attachments?.
|
|
177563
|
+
if (msg.threadContext?.starter?.attachments?.some((attachment) => attachment.localPath)) {
|
|
177317
177564
|
return true;
|
|
177318
177565
|
}
|
|
177319
|
-
return Boolean(msg.threadContext?.history?.some((entry) => entry.attachments?.
|
|
177566
|
+
return Boolean(msg.threadContext?.history?.some((entry) => entry.attachments?.some((attachment) => attachment.localPath)));
|
|
177320
177567
|
}
|
|
177321
177568
|
function buildChannelReminderText(msg) {
|
|
177322
177569
|
const localTime = escapeXmlText(getLocalTime());
|
|
@@ -177339,7 +177586,7 @@ function buildChannelReminderText(msg) {
|
|
|
177339
177586
|
lines.splice(lines.length - 2, 0, threadLine);
|
|
177340
177587
|
}
|
|
177341
177588
|
if (msg.channel === "slack") {
|
|
177342
|
-
lines.splice(lines.length - 2, 0, 'On Slack, MessageChannel also supports action="react" with emoji + messageId, and action="
|
|
177589
|
+
lines.splice(lines.length - 2, 0, 'On Slack, MessageChannel also supports action="react" with emoji + messageId, action="upload-file" with media, and action="download-file" with attachmentId + messageId.', 'For Slack requests that require nontrivial work or several tool calls, send a short MessageChannel action="send" acknowledgement before starting other tools. This gives the Slack user verbal acknowledgement and a View in web link. Do not do this for no-ops, reaction-only responses, or simple no-tool answers.');
|
|
177343
177590
|
}
|
|
177344
177591
|
if (msg.channel === "telegram") {
|
|
177345
177592
|
lines.splice(lines.length - 2, 0, 'On Telegram, MessageChannel also supports action="react" with emoji + messageId, and action="upload-file" with media.');
|
|
@@ -177359,11 +177606,13 @@ function buildChannelReminderText(msg) {
|
|
|
177359
177606
|
return lines.join(`
|
|
177360
177607
|
`);
|
|
177361
177608
|
}
|
|
177362
|
-
function buildAttachmentXml(attachment) {
|
|
177363
|
-
const attrs = [
|
|
177364
|
-
|
|
177365
|
-
`local_path="${escapeXmlAttribute(attachment.localPath)}"`
|
|
177366
|
-
|
|
177609
|
+
function buildAttachmentXml(attachment, context3) {
|
|
177610
|
+
const attrs = [`kind="${escapeXmlAttribute(attachment.kind)}"`];
|
|
177611
|
+
if (attachment.localPath) {
|
|
177612
|
+
attrs.push(`local_path="${escapeXmlAttribute(attachment.localPath)}"`);
|
|
177613
|
+
} else {
|
|
177614
|
+
attrs.push('download_status="not_downloaded"');
|
|
177615
|
+
}
|
|
177367
177616
|
if (attachment.id) {
|
|
177368
177617
|
attrs.push(`attachment_id="${escapeXmlAttribute(attachment.id)}"`);
|
|
177369
177618
|
}
|
|
@@ -177376,6 +177625,19 @@ function buildAttachmentXml(attachment) {
|
|
|
177376
177625
|
if (typeof attachment.sizeBytes === "number") {
|
|
177377
177626
|
attrs.push(`size_bytes="${attachment.sizeBytes}"`);
|
|
177378
177627
|
}
|
|
177628
|
+
const sourceMessageId = attachment.sourceMessageId ?? context3.messageId;
|
|
177629
|
+
if (!attachment.localPath && sourceMessageId) {
|
|
177630
|
+
attrs.push(`source_message_id="${escapeXmlAttribute(sourceMessageId)}"`);
|
|
177631
|
+
}
|
|
177632
|
+
if (!attachment.localPath && attachment.sourceThreadId) {
|
|
177633
|
+
attrs.push(`source_thread_id="${escapeXmlAttribute(attachment.sourceThreadId)}"`);
|
|
177634
|
+
}
|
|
177635
|
+
if (attachment.downloadReason) {
|
|
177636
|
+
attrs.push(`download_reason="${escapeXmlAttribute(attachment.downloadReason)}"`);
|
|
177637
|
+
}
|
|
177638
|
+
if (typeof attachment.autoDownloadLimitBytes === "number") {
|
|
177639
|
+
attrs.push(`auto_download_limit_bytes="${attachment.autoDownloadLimitBytes}"`);
|
|
177640
|
+
}
|
|
177379
177641
|
const children = [];
|
|
177380
177642
|
if (attachment.transcription) {
|
|
177381
177643
|
children.push(`<attempted_transcription>${escapeXmlText(attachment.transcription)}</attempted_transcription>`);
|
|
@@ -177383,6 +177645,17 @@ function buildAttachmentXml(attachment) {
|
|
|
177383
177645
|
if (attachment.transcriptionError) {
|
|
177384
177646
|
children.push(`<attempted_transcription_error>${escapeXmlText(attachment.transcriptionError)}</attempted_transcription_error>`);
|
|
177385
177647
|
}
|
|
177648
|
+
if (!attachment.localPath && context3.channel === "slack" && attachment.id && sourceMessageId) {
|
|
177649
|
+
const accountArg = context3.accountId ? `, accountId="${escapeXmlAttribute(context3.accountId)}"` : "";
|
|
177650
|
+
const threadArg = attachment.sourceThreadId ? `, threadId="${escapeXmlAttribute(attachment.sourceThreadId)}"` : "";
|
|
177651
|
+
const action3 = `MessageChannel with action="download-file", channel="slack", chat_id="${escapeXmlAttribute(context3.chatId)}"${accountArg}${threadArg}, attachmentId="${escapeXmlAttribute(attachment.id)}", and messageId="${escapeXmlAttribute(sourceMessageId)}"`;
|
|
177652
|
+
if (attachment.downloadReason === "exceeds_auto_download_limit") {
|
|
177653
|
+
const sizeNote = typeof attachment.sizeBytes === "number" ? `This file is ${formatMebibytes(attachment.sizeBytes)}${typeof attachment.autoDownloadLimitBytes === "number" ? `, above the ${formatMebibytes(attachment.autoDownloadLimitBytes)} automatic download limit` : ""}. ` : "";
|
|
177654
|
+
children.push(`<download-instruction>${sizeNote}Call ${action3}. The tool downloads the file into the same Slack inbound attachment directory and returns its local_path. Do not ask the sender to reattach it.</download-instruction>`);
|
|
177655
|
+
} else {
|
|
177656
|
+
children.push(`<download-retry>Automatic download did not complete. Call ${action3} to retry. The action may return a precise error if Slack still cannot provide the file.</download-retry>`);
|
|
177657
|
+
}
|
|
177658
|
+
}
|
|
177386
177659
|
if (children.length > 0) {
|
|
177387
177660
|
return `<attachment ${attrs.join(" ")}>
|
|
177388
177661
|
${children.join(`
|
|
@@ -177432,7 +177705,7 @@ ${escapeXmlText(replyContext.text)}
|
|
|
177432
177705
|
}
|
|
177433
177706
|
return `<reply-context${attrString} />`;
|
|
177434
177707
|
}
|
|
177435
|
-
function buildThreadContextEntryXml(tagName, entry) {
|
|
177708
|
+
function buildThreadContextEntryXml(tagName, entry, context3) {
|
|
177436
177709
|
const attrs = [];
|
|
177437
177710
|
if (entry.senderId) {
|
|
177438
177711
|
attrs.push(`sender_id="${escapeXmlAttribute(entry.senderId)}"`);
|
|
@@ -177446,7 +177719,10 @@ function buildThreadContextEntryXml(tagName, entry) {
|
|
|
177446
177719
|
const attrString = attrs.length > 0 ? ` ${attrs.join(" ")}` : "";
|
|
177447
177720
|
const body = [
|
|
177448
177721
|
...entry.text ? [escapeXmlText(entry.text)] : [],
|
|
177449
|
-
...(entry.attachments ?? []).map(buildAttachmentXml
|
|
177722
|
+
...(entry.attachments ?? []).map((attachment) => buildAttachmentXml(attachment, {
|
|
177723
|
+
...context3,
|
|
177724
|
+
messageId: entry.messageId
|
|
177725
|
+
}))
|
|
177450
177726
|
].join(`
|
|
177451
177727
|
`);
|
|
177452
177728
|
return `<${tagName}${attrString}>
|
|
@@ -177460,13 +177736,21 @@ function buildThreadContextXml(msg) {
|
|
|
177460
177736
|
}
|
|
177461
177737
|
const parts = [];
|
|
177462
177738
|
if (threadContext.starter) {
|
|
177463
|
-
parts.push(buildThreadContextEntryXml("thread-starter", threadContext.starter
|
|
177739
|
+
parts.push(buildThreadContextEntryXml("thread-starter", threadContext.starter, {
|
|
177740
|
+
channel: msg.channel,
|
|
177741
|
+
accountId: msg.accountId,
|
|
177742
|
+
chatId: msg.chatId
|
|
177743
|
+
}));
|
|
177464
177744
|
}
|
|
177465
177745
|
const historyEntries = threadContext.history ?? [];
|
|
177466
177746
|
if (historyEntries.length > 0) {
|
|
177467
177747
|
parts.push([
|
|
177468
177748
|
"<thread-history>",
|
|
177469
|
-
...historyEntries.map((entry) => buildThreadContextEntryXml("thread-message", entry
|
|
177749
|
+
...historyEntries.map((entry) => buildThreadContextEntryXml("thread-message", entry, {
|
|
177750
|
+
channel: msg.channel,
|
|
177751
|
+
accountId: msg.accountId,
|
|
177752
|
+
chatId: msg.chatId
|
|
177753
|
+
})),
|
|
177470
177754
|
"</thread-history>"
|
|
177471
177755
|
].join(`
|
|
177472
177756
|
`));
|
|
@@ -177501,7 +177785,12 @@ function buildChannelNotificationXml(msg) {
|
|
|
177501
177785
|
const reactionXml = buildReactionXml(msg);
|
|
177502
177786
|
const replyContextXml = buildReplyContextXml(msg);
|
|
177503
177787
|
const threadContextXml = buildThreadContextXml(msg);
|
|
177504
|
-
const attachmentXml = (msg.attachments ?? []).map(buildAttachmentXml
|
|
177788
|
+
const attachmentXml = (msg.attachments ?? []).map((attachment) => buildAttachmentXml(attachment, {
|
|
177789
|
+
channel: msg.channel,
|
|
177790
|
+
accountId: msg.accountId,
|
|
177791
|
+
chatId: msg.chatId,
|
|
177792
|
+
messageId: msg.messageId
|
|
177793
|
+
}));
|
|
177505
177794
|
const body = [
|
|
177506
177795
|
threadContextXml,
|
|
177507
177796
|
replyContextXml,
|
|
@@ -179757,7 +180046,10 @@ This tool is currently scoped to a routed external channel turn. Plain assistant
|
|
|
179757
180046
|
const slackWorkAcknowledgement = discovery.activeChannels.includes("slack") ? `
|
|
179758
180047
|
|
|
179759
180048
|
For Slack requests that require nontrivial work or several tool calls, send one short MessageChannel call with action="send" before starting other tools. This gives the Slack user verbal acknowledgement and a View in web link. Do not do this for no-ops, reaction-only responses, or simple no-tool answers.` : "";
|
|
179760
|
-
|
|
180049
|
+
const slackAttachmentDownload = discovery.activeChannels.includes("slack") ? `
|
|
180050
|
+
|
|
180051
|
+
Slack attachments that exceed the automatic download limit include an exact recovery instruction. Use action="download-file" with channel, chat_id, attachmentId, and messageId from that instruction. The action saves the file in the normal Slack inbound attachment directory and returns its local_path.` : "";
|
|
180052
|
+
return `${description}${scopedReplyContract}${slackWorkAcknowledgement}${slackAttachmentDownload}
|
|
179761
180053
|
|
|
179762
180054
|
Currently active channels: ${channelList}. Available actions across the active channels: ${actionList}. The JSON schema reflects the currently active channel plugins.`;
|
|
179763
180055
|
}
|
|
@@ -183455,7 +183747,7 @@ var init_apply_patch = __esm(() => {
|
|
|
183455
183747
|
});
|
|
183456
183748
|
|
|
183457
183749
|
// src/tools/impl/artifact-files.ts
|
|
183458
|
-
import { mkdir as mkdir6, readFile as
|
|
183750
|
+
import { mkdir as mkdir6, readFile as readFile5, stat as stat3, writeFile as writeFile8 } from "node:fs/promises";
|
|
183459
183751
|
import { homedir as homedir9 } from "node:os";
|
|
183460
183752
|
import { dirname as dirname7, isAbsolute as isAbsolute5, join as join19, relative as relative2, resolve as resolve8 } from "node:path";
|
|
183461
183753
|
function assertArtifactsExperimentEnabled(toolName) {
|
|
@@ -183513,7 +183805,7 @@ async function read_artifact_file(args) {
|
|
|
183513
183805
|
if (stats.size > MAX_READ_FILE_BYTES) {
|
|
183514
183806
|
throw new Error(`read_artifact_file: file is too large to read (${stats.size} bytes)`);
|
|
183515
183807
|
}
|
|
183516
|
-
const buffer = await
|
|
183808
|
+
const buffer = await readFile5(absolutePath);
|
|
183517
183809
|
return {
|
|
183518
183810
|
path: relativePath,
|
|
183519
183811
|
content: buffer.toString(encoding),
|
|
@@ -183527,7 +183819,7 @@ async function write_artifact_file(args) {
|
|
|
183527
183819
|
const encoding = getEncoding(args.encoding);
|
|
183528
183820
|
const buffer = Buffer.from(args.content, encoding);
|
|
183529
183821
|
await mkdir6(dirname7(absolutePath), { recursive: true });
|
|
183530
|
-
await
|
|
183822
|
+
await writeFile8(absolutePath, buffer);
|
|
183531
183823
|
return {
|
|
183532
183824
|
path: relativePath,
|
|
183533
183825
|
bytes: buffer.byteLength,
|
|
@@ -184216,6 +184508,9 @@ class TurnLifecycle {
|
|
|
184216
184508
|
get activeRunId() {
|
|
184217
184509
|
return this.#state.kind === "active" ? this.#state.runId : null;
|
|
184218
184510
|
}
|
|
184511
|
+
get executingToolCallIds() {
|
|
184512
|
+
return this.#state.kind === "active" || this.#state.kind === "cancelling" ? this.#state.executingToolCallIds : [];
|
|
184513
|
+
}
|
|
184219
184514
|
get lastStopReason() {
|
|
184220
184515
|
return this.#lastStopReason;
|
|
184221
184516
|
}
|
|
@@ -187370,7 +187665,7 @@ var init_worktree_lock = __esm(() => {
|
|
|
187370
187665
|
|
|
187371
187666
|
// src/websocket/listener/remote-settings.ts
|
|
187372
187667
|
import { existsSync as existsSync20, readFileSync as readFileSync16 } from "node:fs";
|
|
187373
|
-
import { mkdir as mkdir7, writeFile as
|
|
187668
|
+
import { mkdir as mkdir7, writeFile as writeFile9 } from "node:fs/promises";
|
|
187374
187669
|
import { homedir as homedir16 } from "node:os";
|
|
187375
187670
|
import path12 from "node:path";
|
|
187376
187671
|
function getRemoteSettingsPath() {
|
|
@@ -187414,7 +187709,7 @@ function saveRemoteSettings(updates) {
|
|
|
187414
187709
|
};
|
|
187415
187710
|
const snapshot = _cache;
|
|
187416
187711
|
const settingsPath = getRemoteSettingsPath();
|
|
187417
|
-
mkdir7(path12.dirname(settingsPath), { recursive: true }).then(() =>
|
|
187712
|
+
mkdir7(path12.dirname(settingsPath), { recursive: true }).then(() => writeFile9(settingsPath, JSON.stringify(snapshot, null, 2))).catch(() => {});
|
|
187418
187713
|
}
|
|
187419
187714
|
function loadLegacyCwdCache() {
|
|
187420
187715
|
try {
|
|
@@ -188209,7 +188504,7 @@ var require_filesystem = __commonJS((exports, module3) => {
|
|
|
188209
188504
|
fs5.close(fd, () => {});
|
|
188210
188505
|
return buffer.subarray(0, bytesRead);
|
|
188211
188506
|
};
|
|
188212
|
-
var
|
|
188507
|
+
var readFile6 = (path13) => new Promise((resolve13, reject) => {
|
|
188213
188508
|
fs5.open(path13, "r", (err, fd) => {
|
|
188214
188509
|
if (err) {
|
|
188215
188510
|
reject(err);
|
|
@@ -188226,7 +188521,7 @@ var require_filesystem = __commonJS((exports, module3) => {
|
|
|
188226
188521
|
LDD_PATH,
|
|
188227
188522
|
SELF_PATH,
|
|
188228
188523
|
readFileSync: readFileSync19,
|
|
188229
|
-
readFile:
|
|
188524
|
+
readFile: readFile6
|
|
188230
188525
|
};
|
|
188231
188526
|
});
|
|
188232
188527
|
|
|
@@ -188268,7 +188563,7 @@ var require_elf = __commonJS((exports, module3) => {
|
|
|
188268
188563
|
var require_detect_libc = __commonJS((exports, module3) => {
|
|
188269
188564
|
var childProcess = __require("child_process");
|
|
188270
188565
|
var { isLinux, getReport } = require_process();
|
|
188271
|
-
var { LDD_PATH, SELF_PATH, readFile:
|
|
188566
|
+
var { LDD_PATH, SELF_PATH, readFile: readFile6, readFileSync: readFileSync19 } = require_filesystem();
|
|
188272
188567
|
var { interpreterPath } = require_elf();
|
|
188273
188568
|
var cachedFamilyInterpreter;
|
|
188274
188569
|
var cachedFamilyFilesystem;
|
|
@@ -188348,7 +188643,7 @@ var require_detect_libc = __commonJS((exports, module3) => {
|
|
|
188348
188643
|
}
|
|
188349
188644
|
cachedFamilyFilesystem = null;
|
|
188350
188645
|
try {
|
|
188351
|
-
const lddContent = await
|
|
188646
|
+
const lddContent = await readFile6(LDD_PATH);
|
|
188352
188647
|
cachedFamilyFilesystem = getFamilyFromLddContent(lddContent);
|
|
188353
188648
|
} catch (e2) {}
|
|
188354
188649
|
return cachedFamilyFilesystem;
|
|
@@ -188370,7 +188665,7 @@ var require_detect_libc = __commonJS((exports, module3) => {
|
|
|
188370
188665
|
}
|
|
188371
188666
|
cachedFamilyInterpreter = null;
|
|
188372
188667
|
try {
|
|
188373
|
-
const selfContent = await
|
|
188668
|
+
const selfContent = await readFile6(SELF_PATH);
|
|
188374
188669
|
const path13 = interpreterPath(selfContent);
|
|
188375
188670
|
cachedFamilyInterpreter = familyFromInterpreterPath(path13);
|
|
188376
188671
|
} catch (e2) {}
|
|
@@ -188430,7 +188725,7 @@ var require_detect_libc = __commonJS((exports, module3) => {
|
|
|
188430
188725
|
}
|
|
188431
188726
|
cachedVersionFilesystem = null;
|
|
188432
188727
|
try {
|
|
188433
|
-
const lddContent = await
|
|
188728
|
+
const lddContent = await readFile6(LDD_PATH);
|
|
188434
188729
|
const versionMatch = lddContent.match(RE_GLIBC_VERSION);
|
|
188435
188730
|
if (versionMatch) {
|
|
188436
188731
|
cachedVersionFilesystem = versionMatch[1];
|
|
@@ -194624,7 +194919,7 @@ __export(exports_image_resize_sips, {
|
|
|
194624
194919
|
convertHeicToJpegWithSips: () => convertHeicToJpegWithSips
|
|
194625
194920
|
});
|
|
194626
194921
|
import { execFile as execFile2 } from "node:child_process";
|
|
194627
|
-
import { mkdtemp, readFile as
|
|
194922
|
+
import { mkdtemp, readFile as readFile6, rm as rm3, writeFile as writeFile10 } from "node:fs/promises";
|
|
194628
194923
|
import { tmpdir as tmpdir6 } from "node:os";
|
|
194629
194924
|
import { join as join29 } from "node:path";
|
|
194630
194925
|
function execFileAsync2(file3, args) {
|
|
@@ -194643,7 +194938,7 @@ async function convertHeicToJpegWithSips(buffer) {
|
|
|
194643
194938
|
const inputPath = join29(workDir, "input.heic");
|
|
194644
194939
|
const outputPath = join29(workDir, "output.jpg");
|
|
194645
194940
|
try {
|
|
194646
|
-
await
|
|
194941
|
+
await writeFile10(inputPath, buffer);
|
|
194647
194942
|
await execFileAsync2("/usr/bin/sips", [
|
|
194648
194943
|
"-s",
|
|
194649
194944
|
"format",
|
|
@@ -194655,9 +194950,9 @@ async function convertHeicToJpegWithSips(buffer) {
|
|
|
194655
194950
|
"--out",
|
|
194656
194951
|
outputPath
|
|
194657
194952
|
]);
|
|
194658
|
-
return Buffer.from(await
|
|
194953
|
+
return Buffer.from(await readFile6(outputPath));
|
|
194659
194954
|
} finally {
|
|
194660
|
-
await
|
|
194955
|
+
await rm3(workDir, { recursive: true, force: true });
|
|
194661
194956
|
}
|
|
194662
194957
|
}
|
|
194663
194958
|
var init_image_resize_sips = () => {};
|
|
@@ -194737,13 +195032,40 @@ async function normalizeMessageContentImages(content, resize = resizeImageIfNeed
|
|
|
194737
195032
|
const filteredParts = normalizedParts.filter((part) => part !== null);
|
|
194738
195033
|
return didChange ? filteredParts : content;
|
|
194739
195034
|
}
|
|
194740
|
-
async function
|
|
195035
|
+
async function normalizeApprovalImages(message, resize, failureMode) {
|
|
195036
|
+
if (!Array.isArray(message.approvals)) {
|
|
195037
|
+
return message;
|
|
195038
|
+
}
|
|
195039
|
+
let didChange = false;
|
|
195040
|
+
const approvals = await Promise.all(message.approvals.map(async (approval) => {
|
|
195041
|
+
if (!("tool_return" in approval)) {
|
|
195042
|
+
return approval;
|
|
195043
|
+
}
|
|
195044
|
+
const toolReturn = await normalizeMessageContentImages(approval.tool_return, resize, failureMode);
|
|
195045
|
+
if (toolReturn === approval.tool_return) {
|
|
195046
|
+
return approval;
|
|
195047
|
+
}
|
|
195048
|
+
didChange = true;
|
|
195049
|
+
return {
|
|
195050
|
+
...approval,
|
|
195051
|
+
tool_return: toolReturn
|
|
195052
|
+
};
|
|
195053
|
+
}));
|
|
195054
|
+
return didChange ? { ...message, approvals } : message;
|
|
195055
|
+
}
|
|
195056
|
+
async function normalizeMessageImageParts(messages, options3 = {}) {
|
|
194741
195057
|
let didChange = false;
|
|
195058
|
+
const resize = options3.resize ?? resizeImageIfNeeded3;
|
|
194742
195059
|
const normalizedMessages = await Promise.all(messages.map(async (message) => {
|
|
195060
|
+
const failureMode = getImageFailureMode(message, options3.failureModesByMessageOtid);
|
|
194743
195061
|
if (!("content" in message)) {
|
|
194744
|
-
|
|
195062
|
+
const normalizedApproval = await normalizeApprovalImages(message, resize, failureMode);
|
|
195063
|
+
if (normalizedApproval !== message) {
|
|
195064
|
+
didChange = true;
|
|
195065
|
+
}
|
|
195066
|
+
return normalizedApproval;
|
|
194745
195067
|
}
|
|
194746
|
-
const normalizedContent = await normalizeMessageContentImages(message.content, resize);
|
|
195068
|
+
const normalizedContent = await normalizeMessageContentImages(message.content, resize, failureMode);
|
|
194747
195069
|
if (normalizedContent !== message.content) {
|
|
194748
195070
|
didChange = true;
|
|
194749
195071
|
return {
|
|
@@ -194755,18 +195077,51 @@ async function normalizeMessageImageParts(messages, resize = resizeImageIfNeeded
|
|
|
194755
195077
|
}));
|
|
194756
195078
|
return didChange ? normalizedMessages : messages;
|
|
194757
195079
|
}
|
|
195080
|
+
function getImageFailureMode(message, failureModesByMessageOtid) {
|
|
195081
|
+
if (!failureModesByMessageOtid) {
|
|
195082
|
+
return "strict";
|
|
195083
|
+
}
|
|
195084
|
+
const otid = message.otid;
|
|
195085
|
+
return typeof otid === "string" ? failureModesByMessageOtid[otid] ?? "strict" : "strict";
|
|
195086
|
+
}
|
|
195087
|
+
function buildImageFailureModesByMessageOtid(messages, failureMode) {
|
|
195088
|
+
const entries = [];
|
|
195089
|
+
for (const message of messages) {
|
|
195090
|
+
if (!("content" in message)) {
|
|
195091
|
+
continue;
|
|
195092
|
+
}
|
|
195093
|
+
const otid = message.otid;
|
|
195094
|
+
if (typeof otid === "string" && otid.length > 0) {
|
|
195095
|
+
entries.push([otid, failureMode]);
|
|
195096
|
+
}
|
|
195097
|
+
}
|
|
195098
|
+
return entries.length > 0 ? Object.fromEntries(entries) : undefined;
|
|
195099
|
+
}
|
|
195100
|
+
function mergeImageFailureModesByMessageOtid(...failureModes) {
|
|
195101
|
+
const presentModes = failureModes.filter((modes) => modes !== undefined);
|
|
195102
|
+
return presentModes.length > 0 ? Object.assign({}, ...presentModes) : undefined;
|
|
195103
|
+
}
|
|
194758
195104
|
function assertSupportedBase64ImageMediaTypes(messages) {
|
|
194759
195105
|
for (const message of messages) {
|
|
194760
|
-
if (
|
|
195106
|
+
if ("content" in message) {
|
|
195107
|
+
assertSupportedBase64ImageContent(message.content);
|
|
194761
195108
|
continue;
|
|
194762
195109
|
}
|
|
194763
|
-
for (const
|
|
194764
|
-
if (!
|
|
195110
|
+
for (const approval of message.approvals ?? []) {
|
|
195111
|
+
if (!("tool_return" in approval)) {
|
|
194765
195112
|
continue;
|
|
194766
195113
|
}
|
|
194767
|
-
|
|
194768
|
-
|
|
194769
|
-
|
|
195114
|
+
assertSupportedBase64ImageContent(approval.tool_return);
|
|
195115
|
+
}
|
|
195116
|
+
}
|
|
195117
|
+
}
|
|
195118
|
+
function assertSupportedBase64ImageContent(content) {
|
|
195119
|
+
if (typeof content === "string") {
|
|
195120
|
+
return;
|
|
195121
|
+
}
|
|
195122
|
+
for (const part of content) {
|
|
195123
|
+
if (isBase64ImageContentPart(part) && !isSupportedBase64ImageMediaType(part.source.media_type)) {
|
|
195124
|
+
throw new Error(`Unsupported base64 image media type after normalization: ${part.source.media_type}`);
|
|
194770
195125
|
}
|
|
194771
195126
|
}
|
|
194772
195127
|
}
|
|
@@ -194979,7 +195334,7 @@ __export(exports_skills2, {
|
|
|
194979
195334
|
GLOBAL_SKILLS_DIR: () => GLOBAL_SKILLS_DIR
|
|
194980
195335
|
});
|
|
194981
195336
|
import { existsSync as existsSync22 } from "node:fs";
|
|
194982
|
-
import { readdir as readdir3, readFile as
|
|
195337
|
+
import { readdir as readdir3, readFile as readFile7, realpath, stat as stat4 } from "node:fs/promises";
|
|
194983
195338
|
import { dirname as dirname12, join as join30 } from "node:path";
|
|
194984
195339
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
194985
195340
|
function getBundledSkillsPath() {
|
|
@@ -195151,7 +195506,7 @@ async function findSkillFiles(currentPath, rootPath, skills, errors7, source2, v
|
|
|
195151
195506
|
}
|
|
195152
195507
|
}
|
|
195153
195508
|
async function parseSkillFile(filePath, rootPath, source2) {
|
|
195154
|
-
const content = await
|
|
195509
|
+
const content = await readFile7(filePath, "utf-8");
|
|
195155
195510
|
const { frontmatter, body } = parseFrontmatter(content);
|
|
195156
195511
|
const normalizedRoot = rootPath.endsWith("/") ? rootPath.slice(0, -1) : rootPath;
|
|
195157
195512
|
const relativePath = filePath.slice(normalizedRoot.length + 1);
|
|
@@ -195585,12 +195940,15 @@ function getStreamRequestContext(stream11) {
|
|
|
195585
195940
|
return streamRequestContexts.get(stream11);
|
|
195586
195941
|
}
|
|
195587
195942
|
function buildConversationMessagesCreateRequestBody(conversationId, messages, opts = { streamTokens: true, background: true }, clientTools, clientSkills = []) {
|
|
195943
|
+
return buildRequestBodyFromPreparedMessages(conversationId, normalizeOutgoingApprovalMessages(messages, opts.approvalNormalization), opts, clientTools, clientSkills);
|
|
195944
|
+
}
|
|
195945
|
+
function buildRequestBodyFromPreparedMessages(conversationId, messages, opts, clientTools, clientSkills) {
|
|
195588
195946
|
const isDefaultConversation = conversationId === "default";
|
|
195589
195947
|
if (isDefaultConversation && !opts.agentId) {
|
|
195590
195948
|
throw new Error("agentId is required in opts when using default conversation");
|
|
195591
195949
|
}
|
|
195592
195950
|
return {
|
|
195593
|
-
messages
|
|
195951
|
+
messages,
|
|
195594
195952
|
streaming: true,
|
|
195595
195953
|
stream_tokens: opts.streamTokens ?? true,
|
|
195596
195954
|
include_pings: true,
|
|
@@ -195612,7 +195970,10 @@ async function sendMessageStreamWithBackend(backend, conversationId, messages, o
|
|
|
195612
195970
|
}) {
|
|
195613
195971
|
const requestStartTime = isTimingsEnabled() ? performance.now() : undefined;
|
|
195614
195972
|
const requestStartedAtMs = Date.now();
|
|
195615
|
-
const
|
|
195973
|
+
const canonicalMessages = normalizeOutgoingApprovalMessages(messages, opts.approvalNormalization);
|
|
195974
|
+
const normalizedMessages = await normalizeMessageImageParts(canonicalMessages, {
|
|
195975
|
+
failureModesByMessageOtid: opts.imageFailureModesByMessageOtid
|
|
195976
|
+
});
|
|
195616
195977
|
assertSupportedBase64ImageMediaTypes(normalizedMessages);
|
|
195617
195978
|
const preparedToolContext = opts.preparedToolContext ? opts.preparedToolContext : await (async () => {
|
|
195618
195979
|
await waitForToolsetReady();
|
|
@@ -195631,7 +195992,7 @@ async function sendMessageStreamWithBackend(backend, conversationId, messages, o
|
|
|
195631
195992
|
const isApprovalContinuation = isApprovalContinuationRequest(normalizedMessages);
|
|
195632
195993
|
const canUsePreviousResponseState = isApprovalContinuation && opts.allowResponseStateReuse === true;
|
|
195633
195994
|
const previousResponseId = canUsePreviousResponseState ? responseStateIdsByScope.get(responseStateScope) : undefined;
|
|
195634
|
-
const requestBody =
|
|
195995
|
+
const requestBody = buildRequestBodyFromPreparedMessages(conversationId, normalizedMessages, opts, clientTools, clientSkills);
|
|
195635
195996
|
if (isDebugEnabled()) {
|
|
195636
195997
|
debugLog("agent-message", "sendMessageStream: conversationId=%s, agentId=%s", conversationId, opts.agentId ?? "(none)");
|
|
195637
195998
|
const formattedSkills = clientSkills.map((skill) => `${skill.name} (${skill.location})`);
|
|
@@ -198443,7 +198804,7 @@ var require_typescript = __commonJS((exports, module3) => {
|
|
|
198443
198804
|
walkUpParenthesizedTypesAndGetParentAndChild: () => walkUpParenthesizedTypesAndGetParentAndChild,
|
|
198444
198805
|
whitespaceOrMapCommentRegExp: () => whitespaceOrMapCommentRegExp,
|
|
198445
198806
|
writeCommentRange: () => writeCommentRange,
|
|
198446
|
-
writeFile: () =>
|
|
198807
|
+
writeFile: () => writeFile11,
|
|
198447
198808
|
writeFileEnsuringDirectories: () => writeFileEnsuringDirectories,
|
|
198448
198809
|
zipWith: () => zipWith
|
|
198449
198810
|
});
|
|
@@ -204235,7 +204596,7 @@ ${lanes.join(`
|
|
|
204235
204596
|
writeOutputIsTTY() {
|
|
204236
204597
|
return process.stdout.isTTY;
|
|
204237
204598
|
},
|
|
204238
|
-
readFile:
|
|
204599
|
+
readFile: readFile8,
|
|
204239
204600
|
writeFile: writeFile22,
|
|
204240
204601
|
watchFile: watchFile2,
|
|
204241
204602
|
watchDirectory,
|
|
@@ -204428,7 +204789,7 @@ ${lanes.join(`
|
|
|
204428
204789
|
function fsWatchWorker(fileOrDirectory, recursive, callback) {
|
|
204429
204790
|
return _fs.watch(fileOrDirectory, fsSupportsRecursiveFsWatch ? { persistent: true, recursive: !!recursive } : { persistent: true }, callback);
|
|
204430
204791
|
}
|
|
204431
|
-
function
|
|
204792
|
+
function readFile8(fileName, _encoding) {
|
|
204432
204793
|
let buffer;
|
|
204433
204794
|
try {
|
|
204434
204795
|
buffer = _fs.readFileSync(fileName);
|
|
@@ -215752,7 +216113,7 @@ ${lanes.join(`
|
|
|
215752
216113
|
sourceFilePath = isSourceFileInCommonSourceDirectory ? sourceFilePath.substring(commonSourceDirectory.length) : sourceFilePath;
|
|
215753
216114
|
return combinePaths(newDirPath, sourceFilePath);
|
|
215754
216115
|
}
|
|
215755
|
-
function
|
|
216116
|
+
function writeFile11(host, diagnostics2, fileName, text, writeByteOrderMark, sourceFiles, data) {
|
|
215756
216117
|
host.writeFile(fileName, text, writeByteOrderMark, (hostErrorMessage) => {
|
|
215757
216118
|
diagnostics2.add(createCompilerDiagnostic(Diagnostics.Could_not_write_file_0_Colon_1, fileName, hostErrorMessage));
|
|
215758
216119
|
}, sourceFiles, data);
|
|
@@ -226205,8 +226566,8 @@ ${lanes.join(`
|
|
|
226205
226566
|
return;
|
|
226206
226567
|
}
|
|
226207
226568
|
function tryRenameExternalModule(factory2, moduleName, sourceFile) {
|
|
226208
|
-
const
|
|
226209
|
-
return
|
|
226569
|
+
const rename2 = sourceFile.renamedDependencies && sourceFile.renamedDependencies.get(moduleName.text);
|
|
226570
|
+
return rename2 ? factory2.createStringLiteral(rename2) : undefined;
|
|
226210
226571
|
}
|
|
226211
226572
|
function tryGetModuleNameFromFile(factory2, file3, host, options3) {
|
|
226212
226573
|
if (!file3) {
|
|
@@ -228735,8 +229096,8 @@ ${lanes.join(`
|
|
|
228735
229096
|
function isMissingList(arr) {
|
|
228736
229097
|
return !!arr.isMissingList;
|
|
228737
229098
|
}
|
|
228738
|
-
function parseBracketedList(kind, parseElement,
|
|
228739
|
-
if (parseExpected(
|
|
229099
|
+
function parseBracketedList(kind, parseElement, open3, close) {
|
|
229100
|
+
if (parseExpected(open3)) {
|
|
228740
229101
|
const result = parseDelimitedList(kind, parseElement);
|
|
228741
229102
|
parseExpected(close);
|
|
228742
229103
|
return result;
|
|
@@ -230441,12 +230802,12 @@ ${lanes.join(`
|
|
|
230441
230802
|
parseExpected(20);
|
|
230442
230803
|
return finishNode(factory2.createJsxSpreadAttribute(expression), pos);
|
|
230443
230804
|
}
|
|
230444
|
-
function parseJsxClosingElement(
|
|
230805
|
+
function parseJsxClosingElement(open3, inExpressionContext) {
|
|
230445
230806
|
const pos = getNodePos();
|
|
230446
230807
|
parseExpected(31);
|
|
230447
230808
|
const tagName = parseJsxElementName();
|
|
230448
230809
|
if (parseExpected(32, undefined, false)) {
|
|
230449
|
-
if (inExpressionContext || !tagNamesAreEquivalent(
|
|
230810
|
+
if (inExpressionContext || !tagNamesAreEquivalent(open3.tagName, tagName)) {
|
|
230450
230811
|
nextToken();
|
|
230451
230812
|
} else {
|
|
230452
230813
|
scanJsxText();
|
|
@@ -235375,7 +235736,7 @@ ${lanes.join(`
|
|
|
235375
235736
|
const possibleOption = getSpellingSuggestion(unknownOption, diagnostics2.optionDeclarations, getOptionName);
|
|
235376
235737
|
return possibleOption ? createDiagnosticForNodeInSourceFileOrCompilerDiagnostic(sourceFile, node, diagnostics2.unknownDidYouMeanDiagnostic, unknownOptionErrorText || unknownOption, possibleOption.name) : createDiagnosticForNodeInSourceFileOrCompilerDiagnostic(sourceFile, node, diagnostics2.unknownOptionDiagnostic, unknownOptionErrorText || unknownOption);
|
|
235377
235738
|
}
|
|
235378
|
-
function parseCommandLineWorker(diagnostics2, commandLine,
|
|
235739
|
+
function parseCommandLineWorker(diagnostics2, commandLine, readFile8) {
|
|
235379
235740
|
const options3 = {};
|
|
235380
235741
|
let watchOptions;
|
|
235381
235742
|
const fileNames = [];
|
|
@@ -235413,7 +235774,7 @@ ${lanes.join(`
|
|
|
235413
235774
|
}
|
|
235414
235775
|
}
|
|
235415
235776
|
function parseResponseFile(fileName) {
|
|
235416
|
-
const text = tryReadFile(fileName,
|
|
235777
|
+
const text = tryReadFile(fileName, readFile8 || ((fileName2) => sys.readFile(fileName2)));
|
|
235417
235778
|
if (!isString(text)) {
|
|
235418
235779
|
errors7.push(text);
|
|
235419
235780
|
return;
|
|
@@ -235516,8 +235877,8 @@ ${lanes.join(`
|
|
|
235516
235877
|
unknownDidYouMeanDiagnostic: Diagnostics.Unknown_compiler_option_0_Did_you_mean_1,
|
|
235517
235878
|
optionTypeMismatchDiagnostic: Diagnostics.Compiler_option_0_expects_an_argument
|
|
235518
235879
|
};
|
|
235519
|
-
function parseCommandLine(commandLine,
|
|
235520
|
-
return parseCommandLineWorker(compilerOptionsDidYouMeanDiagnostics, commandLine,
|
|
235880
|
+
function parseCommandLine(commandLine, readFile8) {
|
|
235881
|
+
return parseCommandLineWorker(compilerOptionsDidYouMeanDiagnostics, commandLine, readFile8);
|
|
235521
235882
|
}
|
|
235522
235883
|
function getOptionFromName(optionName, allowShort) {
|
|
235523
235884
|
return getOptionDeclarationFromName(getOptionsNameMap, optionName, allowShort);
|
|
@@ -235585,8 +235946,8 @@ ${lanes.join(`
|
|
|
235585
235946
|
result.originalFileName = result.fileName;
|
|
235586
235947
|
return parseJsonSourceFileConfigFileContent(result, host, getNormalizedAbsolutePath(getDirectoryPath(configFileName), cwd), optionsToExtend, getNormalizedAbsolutePath(configFileName, cwd), undefined, extraFileExtensions, extendedConfigCache, watchOptionsToExtend);
|
|
235587
235948
|
}
|
|
235588
|
-
function readConfigFile(fileName,
|
|
235589
|
-
const textOrDiagnostic = tryReadFile(fileName,
|
|
235949
|
+
function readConfigFile(fileName, readFile8) {
|
|
235950
|
+
const textOrDiagnostic = tryReadFile(fileName, readFile8);
|
|
235590
235951
|
return isString(textOrDiagnostic) ? parseConfigFileTextToJson(fileName, textOrDiagnostic) : { config: {}, error: textOrDiagnostic };
|
|
235591
235952
|
}
|
|
235592
235953
|
function parseConfigFileTextToJson(fileName, jsonText) {
|
|
@@ -235596,14 +235957,14 @@ ${lanes.join(`
|
|
|
235596
235957
|
error: jsonSourceFile.parseDiagnostics.length ? jsonSourceFile.parseDiagnostics[0] : undefined
|
|
235597
235958
|
};
|
|
235598
235959
|
}
|
|
235599
|
-
function readJsonConfigFile(fileName,
|
|
235600
|
-
const textOrDiagnostic = tryReadFile(fileName,
|
|
235960
|
+
function readJsonConfigFile(fileName, readFile8) {
|
|
235961
|
+
const textOrDiagnostic = tryReadFile(fileName, readFile8);
|
|
235601
235962
|
return isString(textOrDiagnostic) ? parseJsonText(fileName, textOrDiagnostic) : { fileName, parseDiagnostics: [textOrDiagnostic] };
|
|
235602
235963
|
}
|
|
235603
|
-
function tryReadFile(fileName,
|
|
235964
|
+
function tryReadFile(fileName, readFile8) {
|
|
235604
235965
|
let text;
|
|
235605
235966
|
try {
|
|
235606
|
-
text =
|
|
235967
|
+
text = readFile8(fileName);
|
|
235607
235968
|
} catch (e2) {
|
|
235608
235969
|
return createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, fileName, e2.message);
|
|
235609
235970
|
}
|
|
@@ -298345,7 +298706,7 @@ ${lanes.join(`
|
|
|
298345
298706
|
return;
|
|
298346
298707
|
}
|
|
298347
298708
|
const buildInfo = host.getBuildInfo() || { version: version2 };
|
|
298348
|
-
|
|
298709
|
+
writeFile11(host, emitterDiagnostics, buildInfoPath, getBuildInfoText(buildInfo), false, undefined, { buildInfo });
|
|
298349
298710
|
emittedFilesList == null || emittedFilesList.push(buildInfoPath);
|
|
298350
298711
|
}
|
|
298351
298712
|
function emitJsFileOrBundle(sourceFileOrBundle, jsFilePath, sourceMapFilePath) {
|
|
@@ -298504,14 +298865,14 @@ ${lanes.join(`
|
|
|
298504
298865
|
}
|
|
298505
298866
|
if (sourceMapFilePath) {
|
|
298506
298867
|
const sourceMap = sourceMapGenerator.toString();
|
|
298507
|
-
|
|
298868
|
+
writeFile11(host, emitterDiagnostics, sourceMapFilePath, sourceMap, false, sourceFiles);
|
|
298508
298869
|
}
|
|
298509
298870
|
} else {
|
|
298510
298871
|
writer.writeLine();
|
|
298511
298872
|
}
|
|
298512
298873
|
const text = writer.getText();
|
|
298513
298874
|
const data = { sourceMapUrlPos, diagnostics: transform22.diagnostics };
|
|
298514
|
-
|
|
298875
|
+
writeFile11(host, emitterDiagnostics, jsFilePath, text, !!compilerOptions.emitBOM, sourceFiles, data);
|
|
298515
298876
|
writer.clear();
|
|
298516
298877
|
return !data.skippedDtsWrite;
|
|
298517
298878
|
}
|
|
@@ -303033,12 +303394,12 @@ ${lanes.join(`
|
|
|
303033
303394
|
function createCompilerHost(options3, setParentNodes) {
|
|
303034
303395
|
return createCompilerHostWorker(options3, setParentNodes);
|
|
303035
303396
|
}
|
|
303036
|
-
function createGetSourceFile(
|
|
303397
|
+
function createGetSourceFile(readFile8, setParentNodes) {
|
|
303037
303398
|
return (fileName, languageVersionOrOptions, onError) => {
|
|
303038
303399
|
let text;
|
|
303039
303400
|
try {
|
|
303040
303401
|
mark("beforeIORead");
|
|
303041
|
-
text =
|
|
303402
|
+
text = readFile8(fileName);
|
|
303042
303403
|
mark("afterIORead");
|
|
303043
303404
|
measure("I/O Read", "beforeIORead", "afterIORead");
|
|
303044
303405
|
} catch (e2) {
|
|
@@ -303829,7 +304190,7 @@ ${lanes.join(`
|
|
|
303829
304190
|
getRedirectFromOutput,
|
|
303830
304191
|
forEachResolvedProjectReference: forEachResolvedProjectReference2
|
|
303831
304192
|
});
|
|
303832
|
-
const
|
|
304193
|
+
const readFile8 = host.readFile.bind(host);
|
|
303833
304194
|
(_e = tracing) == null || _e.push(tracing.Phase.Program, "shouldProgramCreateNewSourceFiles", { hasOldProgram: !!oldProgram });
|
|
303834
304195
|
const shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options3);
|
|
303835
304196
|
(_f = tracing) == null || _f.pop();
|
|
@@ -304005,7 +304366,7 @@ ${lanes.join(`
|
|
|
304005
304366
|
shouldTransformImportCall,
|
|
304006
304367
|
emitBuildInfo,
|
|
304007
304368
|
fileExists,
|
|
304008
|
-
readFile:
|
|
304369
|
+
readFile: readFile8,
|
|
304009
304370
|
directoryExists,
|
|
304010
304371
|
getSymlinkCache,
|
|
304011
304372
|
realpath: (_o = host.realpath) == null ? undefined : _o.bind(host),
|
|
@@ -330306,11 +330667,11 @@ ${newComment.split(`
|
|
|
330306
330667
|
}
|
|
330307
330668
|
function convertNamedExport(sourceFile, assignment, changes, exports2) {
|
|
330308
330669
|
const { text } = assignment.left.name;
|
|
330309
|
-
const
|
|
330310
|
-
if (
|
|
330670
|
+
const rename2 = exports2.get(text);
|
|
330671
|
+
if (rename2 !== undefined) {
|
|
330311
330672
|
const newNodes = [
|
|
330312
|
-
makeConst(undefined,
|
|
330313
|
-
makeExportDeclaration([factory.createExportSpecifier(false,
|
|
330673
|
+
makeConst(undefined, rename2, assignment.right),
|
|
330674
|
+
makeExportDeclaration([factory.createExportSpecifier(false, rename2, text)])
|
|
330314
330675
|
];
|
|
330315
330676
|
changes.replaceNodeWithNodes(sourceFile, assignment.parent, newNodes);
|
|
330316
330677
|
} else {
|
|
@@ -346930,11 +347291,11 @@ ${content}
|
|
|
346930
347291
|
}
|
|
346931
347292
|
return createOutliningSpanFromBounds(node.getStart(sourceFile), node.getEnd(), "code");
|
|
346932
347293
|
}
|
|
346933
|
-
function spanForObjectOrArrayLiteral(node,
|
|
346934
|
-
return spanForNode(node, false, !isArrayLiteralExpression(node.parent) && !isCallExpression(node.parent),
|
|
347294
|
+
function spanForObjectOrArrayLiteral(node, open3 = 19) {
|
|
347295
|
+
return spanForNode(node, false, !isArrayLiteralExpression(node.parent) && !isCallExpression(node.parent), open3);
|
|
346935
347296
|
}
|
|
346936
|
-
function spanForNode(hintSpanNode, autoCollapse = false, useFullStart = true,
|
|
346937
|
-
const openToken = findChildOfKind(n,
|
|
347297
|
+
function spanForNode(hintSpanNode, autoCollapse = false, useFullStart = true, open3 = 19, close = open3 === 19 ? 20 : 24) {
|
|
347298
|
+
const openToken = findChildOfKind(n, open3, sourceFile);
|
|
346938
347299
|
const closeToken = findChildOfKind(n, close, sourceFile);
|
|
346939
347300
|
return openToken && closeToken && spanBetweenTokens(openToken, closeToken, hintSpanNode, sourceFile, autoCollapse, useFullStart);
|
|
346940
347301
|
}
|
|
@@ -349202,9 +349563,9 @@ ${options3.prefix}` : `
|
|
|
349202
349563
|
return end;
|
|
349203
349564
|
}
|
|
349204
349565
|
function getClassOrObjectBraceEnds(cls, sourceFile) {
|
|
349205
|
-
const
|
|
349566
|
+
const open3 = findChildOfKind(cls, 19, sourceFile);
|
|
349206
349567
|
const close = findChildOfKind(cls, 20, sourceFile);
|
|
349207
|
-
return [
|
|
349568
|
+
return [open3 == null ? undefined : open3.end, close == null ? undefined : close.end];
|
|
349208
349569
|
}
|
|
349209
349570
|
function getMembersOrProperties(node) {
|
|
349210
349571
|
return isObjectLiteralExpression(node) ? node.properties : node.members;
|
|
@@ -354443,7 +354804,7 @@ ${options3.prefix}` : `
|
|
|
354443
354804
|
walkUpParenthesizedTypesAndGetParentAndChild: () => walkUpParenthesizedTypesAndGetParentAndChild,
|
|
354444
354805
|
whitespaceOrMapCommentRegExp: () => whitespaceOrMapCommentRegExp,
|
|
354445
354806
|
writeCommentRange: () => writeCommentRange,
|
|
354446
|
-
writeFile: () =>
|
|
354807
|
+
writeFile: () => writeFile11,
|
|
354447
354808
|
writeFileEnsuringDirectories: () => writeFileEnsuringDirectories,
|
|
354448
354809
|
zipWith: () => zipWith
|
|
354449
354810
|
});
|
|
@@ -367648,7 +368009,8 @@ function buildLoopStatus(runtime, params) {
|
|
|
367648
368009
|
if (!listener) {
|
|
367649
368010
|
return {
|
|
367650
368011
|
status: "WAITING_ON_INPUT",
|
|
367651
|
-
active_run_ids: []
|
|
368012
|
+
active_run_ids: [],
|
|
368013
|
+
executing_tool_call_ids: []
|
|
367652
368014
|
};
|
|
367653
368015
|
}
|
|
367654
368016
|
const scope = getScopeForRuntime(runtime, params);
|
|
@@ -367660,7 +368022,8 @@ function buildLoopStatus(runtime, params) {
|
|
|
367660
368022
|
const status = interruptedCacheActive ? !conversationRuntime?.isProcessing ? "WAITING_ON_INPUT" : conversationRuntime?.loopStatus === "WAITING_ON_APPROVAL" ? "WAITING_ON_INPUT" : conversationRuntime?.loopStatus ?? "WAITING_ON_INPUT" : recovered && recovered.pendingRequestIds.size > 0 && conversationRuntime?.loopStatus === "WAITING_ON_INPUT" ? "WAITING_ON_APPROVAL" : conversationRuntime?.loopStatus ?? "WAITING_ON_INPUT";
|
|
367661
368023
|
return {
|
|
367662
368024
|
status,
|
|
367663
|
-
active_run_ids: interruptedCacheActive && !conversationRuntime?.isProcessing ? [] : conversationRuntime?.activeRunId ? [conversationRuntime.activeRunId] : []
|
|
368025
|
+
active_run_ids: interruptedCacheActive && !conversationRuntime?.isProcessing ? [] : conversationRuntime?.activeRunId ? [conversationRuntime.activeRunId] : [],
|
|
368026
|
+
executing_tool_call_ids: status === "EXECUTING_CLIENT_SIDE_TOOL" && conversationRuntime ? [...conversationRuntime.turnLifecycle.executingToolCallIds] : []
|
|
367664
368027
|
};
|
|
367665
368028
|
}
|
|
367666
368029
|
function buildQueueSnapshot(runtime, params) {
|
|
@@ -368286,7 +368649,7 @@ import {
|
|
|
368286
368649
|
lstat,
|
|
368287
368650
|
mkdir as mkdir8,
|
|
368288
368651
|
readdir as readdir5,
|
|
368289
|
-
readFile as
|
|
368652
|
+
readFile as readFile8,
|
|
368290
368653
|
realpath as realpath2,
|
|
368291
368654
|
rmdir,
|
|
368292
368655
|
stat as stat6,
|
|
@@ -368523,7 +368886,7 @@ async function readProvisionConfig(primaryRoot) {
|
|
|
368523
368886
|
include: []
|
|
368524
368887
|
};
|
|
368525
368888
|
try {
|
|
368526
|
-
const raw = await
|
|
368889
|
+
const raw = await readFile8(path19.join(primaryRoot, ".letta", "settings.json"), "utf8");
|
|
368527
368890
|
const parsed = JSON.parse(raw);
|
|
368528
368891
|
const worktree = parsed.worktree;
|
|
368529
368892
|
if (!worktree) {
|
|
@@ -368615,7 +368978,7 @@ async function copyLocalSettingsFile(primaryRoot, worktreePath) {
|
|
|
368615
368978
|
}
|
|
368616
368979
|
async function readWorktreeIncludeEntries(primaryRoot) {
|
|
368617
368980
|
try {
|
|
368618
|
-
const raw = await
|
|
368981
|
+
const raw = await readFile8(path19.join(primaryRoot, ".worktreeinclude"), "utf8");
|
|
368619
368982
|
return raw.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
|
|
368620
368983
|
} catch {
|
|
368621
368984
|
return [];
|
|
@@ -371120,15 +371483,15 @@ var require_parse3 = __commonJS((exports, module3) => {
|
|
|
371120
371483
|
}
|
|
371121
371484
|
if (value === "{" && opts.nobrace !== true) {
|
|
371122
371485
|
increment("braces");
|
|
371123
|
-
const
|
|
371486
|
+
const open3 = {
|
|
371124
371487
|
type: "brace",
|
|
371125
371488
|
value,
|
|
371126
371489
|
output: "(",
|
|
371127
371490
|
outputIndex: state.output.length,
|
|
371128
371491
|
tokensIndex: state.tokens.length
|
|
371129
371492
|
};
|
|
371130
|
-
braces.push(
|
|
371131
|
-
push(
|
|
371493
|
+
braces.push(open3);
|
|
371494
|
+
push(open3);
|
|
371132
371495
|
continue;
|
|
371133
371496
|
}
|
|
371134
371497
|
if (value === "}") {
|
|
@@ -371779,12 +372142,12 @@ var init_list_directory_gemini = __esm(() => {
|
|
|
371779
372142
|
import { existsSync as existsSync27 } from "node:fs";
|
|
371780
372143
|
import {
|
|
371781
372144
|
mkdir as mkdir9,
|
|
371782
|
-
readFile as
|
|
371783
|
-
rename,
|
|
371784
|
-
rm as
|
|
372145
|
+
readFile as readFile9,
|
|
372146
|
+
rename as rename2,
|
|
372147
|
+
rm as rm4,
|
|
371785
372148
|
stat as stat8,
|
|
371786
372149
|
unlink as unlink2,
|
|
371787
|
-
writeFile as
|
|
372150
|
+
writeFile as writeFile11
|
|
371788
372151
|
} from "node:fs/promises";
|
|
371789
372152
|
import { dirname as dirname14, isAbsolute as isAbsolute15, relative as relative3, resolve as resolve18 } from "node:path";
|
|
371790
372153
|
async function getMemoryWriteSyncMode() {
|
|
@@ -371865,7 +372228,7 @@ async function applyMemoryCommand(memoryDir, args) {
|
|
|
371865
372228
|
throw new Error(`memory create: block already exists at ${pathArg}`);
|
|
371866
372229
|
}
|
|
371867
372230
|
await mkdir9(dirname14(filePath), { recursive: true });
|
|
371868
|
-
await
|
|
372231
|
+
await writeFile11(filePath, rendered, "utf8");
|
|
371869
372232
|
return [relPath];
|
|
371870
372233
|
}
|
|
371871
372234
|
if (command === "str_replace") {
|
|
@@ -371882,7 +372245,7 @@ async function applyMemoryCommand(memoryDir, args) {
|
|
|
371882
372245
|
}
|
|
371883
372246
|
const nextBody = `${file3.body.slice(0, idx)}${newString}${file3.body.slice(idx + oldString.length)}`;
|
|
371884
372247
|
const rendered = renderMemoryFile(file3.frontmatter, nextBody);
|
|
371885
|
-
await
|
|
372248
|
+
await writeFile11(filePath, rendered, "utf8");
|
|
371886
372249
|
return [relPath];
|
|
371887
372250
|
}
|
|
371888
372251
|
if (command === "insert") {
|
|
@@ -371905,7 +372268,7 @@ async function applyMemoryCommand(memoryDir, args) {
|
|
|
371905
372268
|
const nextBody = existingLines.join(`
|
|
371906
372269
|
`);
|
|
371907
372270
|
const rendered = renderMemoryFile(file3.frontmatter, nextBody);
|
|
371908
|
-
await
|
|
372271
|
+
await writeFile11(filePath, rendered, "utf8");
|
|
371909
372272
|
return [relPath];
|
|
371910
372273
|
}
|
|
371911
372274
|
if (command === "delete") {
|
|
@@ -371914,7 +372277,7 @@ async function applyMemoryCommand(memoryDir, args) {
|
|
|
371914
372277
|
const targetPath = resolveMemoryPath(memoryDir, label);
|
|
371915
372278
|
if (existsSync27(targetPath) && (await stat8(targetPath)).isDirectory()) {
|
|
371916
372279
|
const relPath2 = toRepoRelative(memoryDir, targetPath);
|
|
371917
|
-
await
|
|
372280
|
+
await rm4(targetPath, { recursive: true, force: false });
|
|
371918
372281
|
return [relPath2];
|
|
371919
372282
|
}
|
|
371920
372283
|
const filePath = resolveMemoryFilePath(memoryDir, label);
|
|
@@ -371937,7 +372300,7 @@ async function applyMemoryCommand(memoryDir, args) {
|
|
|
371937
372300
|
}
|
|
371938
372301
|
await loadEditableMemoryFile(oldFilePath, oldPathArg);
|
|
371939
372302
|
await mkdir9(dirname14(newFilePath), { recursive: true });
|
|
371940
|
-
await
|
|
372303
|
+
await rename2(oldFilePath, newFilePath);
|
|
371941
372304
|
return [oldRelPath, newRelPath];
|
|
371942
372305
|
}
|
|
371943
372306
|
if (command === "update_description") {
|
|
@@ -371951,7 +372314,7 @@ async function applyMemoryCommand(memoryDir, args) {
|
|
|
371951
372314
|
...file3.frontmatter,
|
|
371952
372315
|
description: newDescription
|
|
371953
372316
|
}, file3.body);
|
|
371954
|
-
await
|
|
372317
|
+
await writeFile11(filePath, rendered, "utf8");
|
|
371955
372318
|
return [relPath];
|
|
371956
372319
|
}
|
|
371957
372320
|
throw new Error(`Unsupported memory command: ${command}`);
|
|
@@ -372042,7 +372405,7 @@ function toRepoRelative(memoryDir, absolutePath) {
|
|
|
372042
372405
|
return rel.replace(/\\/g, "/");
|
|
372043
372406
|
}
|
|
372044
372407
|
async function loadEditableMemoryFile(filePath, sourcePath) {
|
|
372045
|
-
const content = await
|
|
372408
|
+
const content = await readFile9(filePath, "utf8").catch((error54) => {
|
|
372046
372409
|
const message = error54 instanceof Error ? error54.message : String(error54);
|
|
372047
372410
|
throw new Error(`memory: failed to read ${sourcePath}: ${message}`);
|
|
372048
372411
|
});
|
|
@@ -372138,7 +372501,7 @@ var init_memory4 = __esm(() => {
|
|
|
372138
372501
|
|
|
372139
372502
|
// src/tools/impl/memory-apply-patch.ts
|
|
372140
372503
|
import { existsSync as existsSync28 } from "node:fs";
|
|
372141
|
-
import { access, mkdir as mkdir10, rm as
|
|
372504
|
+
import { access, mkdir as mkdir10, rm as rm5, stat as stat9, unlink as unlink3 } from "node:fs/promises";
|
|
372142
372505
|
import { dirname as dirname15, isAbsolute as isAbsolute16, relative as relative4, resolve as resolve19 } from "node:path";
|
|
372143
372506
|
async function getMemoryWriteSyncMode2() {
|
|
372144
372507
|
const { getBackend: getBackend2 } = await Promise.resolve().then(() => (init_backend2(), exports_backend));
|
|
@@ -372291,7 +372654,7 @@ async function applyMemoryPatch(memoryDir, input) {
|
|
|
372291
372654
|
continue;
|
|
372292
372655
|
const stats = await stat9(absPath);
|
|
372293
372656
|
if (stats.isDirectory()) {
|
|
372294
|
-
await
|
|
372657
|
+
await rm5(absPath, { recursive: true, force: false });
|
|
372295
372658
|
} else {
|
|
372296
372659
|
await unlink3(absPath);
|
|
372297
372660
|
}
|
|
@@ -373302,6 +373665,7 @@ function normalizeMessageChannelInput(args) {
|
|
|
373302
373665
|
replyToMessageId: firstNonEmptyString3(args.replyTo),
|
|
373303
373666
|
threadId: firstNonEmptyString3(args.threadId) ?? null,
|
|
373304
373667
|
messageId: firstNonEmptyString3(args.messageId),
|
|
373668
|
+
attachmentId: firstNonEmptyString3(args.attachmentId),
|
|
373305
373669
|
emoji: firstNonEmptyString3(args.emoji),
|
|
373306
373670
|
remove: firstDefinedBoolean(args.remove),
|
|
373307
373671
|
mediaPath: firstNonEmptyString3(args.media),
|
|
@@ -373318,6 +373682,7 @@ function buildMessageChannelRequest(input, chatId, threadId) {
|
|
|
373318
373682
|
replyToMessageId: input.replyToMessageId,
|
|
373319
373683
|
threadId: threadId ?? input.threadId ?? null,
|
|
373320
373684
|
messageId: input.messageId,
|
|
373685
|
+
attachmentId: input.attachmentId,
|
|
373321
373686
|
emoji: input.emoji,
|
|
373322
373687
|
remove: input.remove,
|
|
373323
373688
|
mediaPath: input.mediaPath,
|
|
@@ -373423,6 +373788,9 @@ async function message_channel(args) {
|
|
|
373423
373788
|
if (typeof input === "string") {
|
|
373424
373789
|
return input;
|
|
373425
373790
|
}
|
|
373791
|
+
if (input.channel === "slack" && input.action === "download-file" && input.target) {
|
|
373792
|
+
return "Error: Slack download-file requires chat_id from a routed channel context; target is not supported.";
|
|
373793
|
+
}
|
|
373426
373794
|
try {
|
|
373427
373795
|
let executionContext;
|
|
373428
373796
|
if (input.chatId) {
|
|
@@ -373449,8 +373817,9 @@ async function message_channel(args) {
|
|
|
373449
373817
|
accountId: resolvedAccountId,
|
|
373450
373818
|
channelTurnSources: args.channelTurnSources
|
|
373451
373819
|
});
|
|
373820
|
+
const requestThreadId = input.action === "download-file" ? input.threadId : inferredThreadId ?? route2.threadId ?? input.threadId;
|
|
373452
373821
|
executionContext = {
|
|
373453
|
-
request: buildMessageChannelRequest(input, input.chatId,
|
|
373822
|
+
request: buildMessageChannelRequest(input, input.chatId, requestThreadId),
|
|
373454
373823
|
route: route2,
|
|
373455
373824
|
adapter: adapter2,
|
|
373456
373825
|
plugin: plugin2
|
|
@@ -375765,10 +376134,10 @@ globstar while`, file3, fr, pattern4, pr, swallowee);
|
|
|
375765
376134
|
}
|
|
375766
376135
|
return filtered.join("/");
|
|
375767
376136
|
}).join("|");
|
|
375768
|
-
const [
|
|
375769
|
-
re = "^" +
|
|
376137
|
+
const [open3, close] = set3.length > 1 ? ["(?:", ")"] : ["", ""];
|
|
376138
|
+
re = "^" + open3 + re + close + "$";
|
|
375770
376139
|
if (this.partial) {
|
|
375771
|
-
re = "^(?:\\/|" +
|
|
376140
|
+
re = "^(?:\\/|" + open3 + re.slice(1, -1) + close + ")$";
|
|
375772
376141
|
}
|
|
375773
376142
|
if (this.negate)
|
|
375774
376143
|
re = "^(?!" + re + ").+$";
|
|
@@ -381759,7 +382128,7 @@ __export(exports_skill, {
|
|
|
381759
382128
|
getResolvedSkillsDir: () => getResolvedSkillsDir
|
|
381760
382129
|
});
|
|
381761
382130
|
import { existsSync as existsSync29, readdirSync as readdirSync10 } from "node:fs";
|
|
381762
|
-
import { readFile as
|
|
382131
|
+
import { readFile as readFile10 } from "node:fs/promises";
|
|
381763
382132
|
import { dirname as dirname16, join as join34 } from "node:path";
|
|
381764
382133
|
function getMemorySkillsDirs2(agentId) {
|
|
381765
382134
|
const dirs = new Set;
|
|
@@ -381791,41 +382160,41 @@ async function readSkillContent(skillId, skillsDir, agentId) {
|
|
|
381791
382160
|
for (const projectSkillsDir of projectSkillsDirs) {
|
|
381792
382161
|
const projectSkillPath = join34(projectSkillsDir, skillId, "SKILL.md");
|
|
381793
382162
|
try {
|
|
381794
|
-
const content = await
|
|
382163
|
+
const content = await readFile10(projectSkillPath, "utf-8");
|
|
381795
382164
|
return { content, path: projectSkillPath };
|
|
381796
382165
|
} catch {}
|
|
381797
382166
|
}
|
|
381798
382167
|
if (agentId) {
|
|
381799
382168
|
const agentSkillPath = join34(getAgentSkillsDir(agentId), skillId, "SKILL.md");
|
|
381800
382169
|
try {
|
|
381801
|
-
const content = await
|
|
382170
|
+
const content = await readFile10(agentSkillPath, "utf-8");
|
|
381802
382171
|
return { content, path: agentSkillPath };
|
|
381803
382172
|
} catch {}
|
|
381804
382173
|
}
|
|
381805
382174
|
for (const memorySkillsDir of getMemorySkillsDirs2(agentId)) {
|
|
381806
382175
|
const memorySkillPath = join34(memorySkillsDir, skillId, "SKILL.md");
|
|
381807
382176
|
try {
|
|
381808
|
-
const content = await
|
|
382177
|
+
const content = await readFile10(memorySkillPath, "utf-8");
|
|
381809
382178
|
return { content, path: memorySkillPath };
|
|
381810
382179
|
} catch {}
|
|
381811
382180
|
}
|
|
381812
382181
|
const globalSkillPath = join34(GLOBAL_SKILLS_DIR, skillId, "SKILL.md");
|
|
381813
382182
|
try {
|
|
381814
|
-
const content = await
|
|
382183
|
+
const content = await readFile10(globalSkillPath, "utf-8");
|
|
381815
382184
|
return { content, path: globalSkillPath };
|
|
381816
382185
|
} catch {}
|
|
381817
382186
|
const bundledSkills = await getBundledSkills();
|
|
381818
382187
|
const bundledSkill = bundledSkills.find((s2) => s2.id === skillId);
|
|
381819
382188
|
if (bundledSkill?.path && isSkillAvailableForAgent(bundledSkill, agentId)) {
|
|
381820
382189
|
try {
|
|
381821
|
-
const content = await
|
|
382190
|
+
const content = await readFile10(bundledSkill.path, "utf-8");
|
|
381822
382191
|
return { content, path: bundledSkill.path };
|
|
381823
382192
|
} catch {}
|
|
381824
382193
|
}
|
|
381825
382194
|
try {
|
|
381826
382195
|
const bundledSkillsDir = join34(process.cwd(), "skills", "skills");
|
|
381827
382196
|
const bundledSkillPath = join34(bundledSkillsDir, skillId, "SKILL.md");
|
|
381828
|
-
const content = await
|
|
382197
|
+
const content = await readFile10(bundledSkillPath, "utf-8");
|
|
381829
382198
|
return { content, path: bundledSkillPath };
|
|
381830
382199
|
} catch {
|
|
381831
382200
|
throw new Error(`Skill "${skillId}" not found. Check that the skill name is correct and that it appears in the available skills list.`);
|
|
@@ -387720,8 +388089,8 @@ globstar while`, file3, fr, pattern4, pr, swallowee);
|
|
|
387720
388089
|
});
|
|
387721
388090
|
return pp.filter((p) => p !== GLOBSTAR2).join("/");
|
|
387722
388091
|
}).join("|");
|
|
387723
|
-
const [
|
|
387724
|
-
re = "^" +
|
|
388092
|
+
const [open3, close] = set3.length > 1 ? ["(?:", ")"] : ["", ""];
|
|
388093
|
+
re = "^" + open3 + re + close + "$";
|
|
387725
388094
|
if (this.negate)
|
|
387726
388095
|
re = "^(?!" + re + ").+$";
|
|
387727
388096
|
try {
|
|
@@ -395009,7 +395378,7 @@ class LocalStore {
|
|
|
395009
395378
|
}
|
|
395010
395379
|
this.ensureAgent(agentId);
|
|
395011
395380
|
const conversationId = this.nextConversationId();
|
|
395012
|
-
const conversation = createLocalConversationRecord(conversationId, agentId, this.conversationSeq, body);
|
|
395381
|
+
const conversation = this.withConversationModelDefaults(createLocalConversationRecord(conversationId, agentId, this.conversationSeq, body));
|
|
395013
395382
|
const key = this.conversationKey(conversation.id, agentId);
|
|
395014
395383
|
this.conversations.set(key, conversation);
|
|
395015
395384
|
this.localMessagesByConversationKey.set(key, []);
|
|
@@ -395028,32 +395397,31 @@ class LocalStore {
|
|
|
395028
395397
|
}
|
|
395029
395398
|
const created = this.ensureConversation(conversationId);
|
|
395030
395399
|
const updated2 = updateLocalConversationRecord(created, body, currentIsoTimestamp());
|
|
395031
|
-
const projected = this.
|
|
395400
|
+
const projected = this.withConversationModelDefaults(updated2);
|
|
395032
395401
|
this.conversations.set(this.conversationKey(conversationId, created.agent_id), projected);
|
|
395033
395402
|
this.persistConversationState(conversationId, created.agent_id);
|
|
395034
395403
|
return projected;
|
|
395035
395404
|
}
|
|
395036
|
-
const updated = this.
|
|
395405
|
+
const updated = this.withConversationModelDefaults(updateLocalConversationRecord(current, body, currentIsoTimestamp()));
|
|
395037
395406
|
this.conversations.set(this.conversationKey(conversationId, current.agent_id), updated);
|
|
395038
395407
|
this.persistConversationState(conversationId, current.agent_id);
|
|
395039
395408
|
return updated;
|
|
395040
395409
|
}
|
|
395041
|
-
|
|
395042
|
-
const requestedModel =
|
|
395410
|
+
withConversationModelDefaults(conversation) {
|
|
395411
|
+
const requestedModel = conversation.model;
|
|
395043
395412
|
if (typeof requestedModel !== "string")
|
|
395044
395413
|
return conversation;
|
|
395045
395414
|
const normalizedRequestedModel = normalizeLocalModelHandle(requestedModel, isRecord(conversation.model_settings) ? conversation.model_settings : {});
|
|
395046
|
-
if (previousConversation.model === normalizedRequestedModel)
|
|
395047
|
-
return conversation;
|
|
395048
395415
|
const defaults5 = this.modelSettingsDefaultsForModel(normalizedRequestedModel);
|
|
395049
395416
|
if (!defaults5 || Object.keys(defaults5).length === 0)
|
|
395050
395417
|
return conversation;
|
|
395051
395418
|
const existingSettings = isRecord(conversation.model_settings) ? conversation.model_settings : {};
|
|
395052
395419
|
return {
|
|
395053
395420
|
...conversation,
|
|
395421
|
+
model: normalizedRequestedModel,
|
|
395054
395422
|
model_settings: {
|
|
395055
|
-
...
|
|
395056
|
-
...
|
|
395423
|
+
...defaults5,
|
|
395424
|
+
...existingSettings
|
|
395057
395425
|
}
|
|
395058
395426
|
};
|
|
395059
395427
|
}
|
|
@@ -395949,7 +396317,7 @@ class LocalStore {
|
|
|
395949
396317
|
const existing = this.conversations.get(key);
|
|
395950
396318
|
if (existing && options3.forceRefresh !== true)
|
|
395951
396319
|
return existing;
|
|
395952
|
-
const normalizedInput = normalizeStoredLocalModelRecord(input);
|
|
396320
|
+
const normalizedInput = this.withConversationModelDefaults(normalizeStoredLocalModelRecord(input));
|
|
395953
396321
|
const timing = transcriptTimingForConversationDir(conversationDir);
|
|
395954
396322
|
const requiresFullTimestampRepair = isSyntheticLocalTimestamp(normalizedInput.created_at) || isSyntheticLocalTimestamp(normalizedInput.updated_at) || isSyntheticLocalTimestamp(normalizedInput.last_message_at);
|
|
395955
396323
|
const conversation = requiresFullTimestampRepair ? normalizedInput : repairSyntheticConversationTimestamps(normalizedInput, [], timing);
|
|
@@ -399092,24 +399460,6 @@ var init_local_model_config = __esm(() => {
|
|
|
399092
399460
|
UNSUPPORTED_LOCAL_CHATGPT_OAUTH_MODELS = new Set(["gpt-5.6-luna"]);
|
|
399093
399461
|
});
|
|
399094
399462
|
|
|
399095
|
-
// src/backend/dev/pi-output-budget.ts
|
|
399096
|
-
function assertViablePiOutputBudget(model, context3, requestedMaxTokens) {
|
|
399097
|
-
if (model.provider !== "llama-cpp")
|
|
399098
|
-
return;
|
|
399099
|
-
const requested = requestedMaxTokens ?? model.maxTokens;
|
|
399100
|
-
if (!Number.isFinite(requested) || requested <= 0)
|
|
399101
|
-
return;
|
|
399102
|
-
const clamped = clampMaxTokensToContext(model, context3, requested);
|
|
399103
|
-
const minimum3 = Math.min(requested, MIN_VIABLE_OUTPUT_TOKENS);
|
|
399104
|
-
if (clamped >= minimum3)
|
|
399105
|
-
return;
|
|
399106
|
-
throw new Error(`Context window of ${model.contextWindow} tokens leaves only ${clamped} output token${clamped === 1 ? "" : "s"}; at least ${minimum3} are required. Compact the conversation or increase the context window.`);
|
|
399107
|
-
}
|
|
399108
|
-
var MIN_VIABLE_OUTPUT_TOKENS = 1024;
|
|
399109
|
-
var init_pi_output_budget = __esm(() => {
|
|
399110
|
-
init_simple_options();
|
|
399111
|
-
});
|
|
399112
|
-
|
|
399113
399463
|
// src/backend/local/local-context-estimate.ts
|
|
399114
399464
|
function positiveUsageNumber(value) {
|
|
399115
399465
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : undefined;
|
|
@@ -399458,7 +399808,7 @@ function createProviderLettaStream(events, contextTokensEstimate) {
|
|
|
399458
399808
|
}
|
|
399459
399809
|
pendingStopReason = {
|
|
399460
399810
|
message_type: "stop_reason",
|
|
399461
|
-
stop_reason: sawToolCall || part.reason === "toolUse" ? "requires_approval" : "end_turn"
|
|
399811
|
+
stop_reason: sawToolCall || part.reason === "toolUse" ? "requires_approval" : part.reason === "length" ? "max_tokens_exceeded" : "end_turn"
|
|
399462
399812
|
};
|
|
399463
399813
|
continue;
|
|
399464
399814
|
}
|
|
@@ -399968,7 +400318,6 @@ class PiStreamAdapter {
|
|
|
399968
400318
|
messageCount: context3.messages.length,
|
|
399969
400319
|
contextWindow: resolved.model.contextWindow
|
|
399970
400320
|
});
|
|
399971
|
-
assertViablePiOutputBudget(resolved.model, context3, options3.maxTokens);
|
|
399972
400321
|
const result = this.runStream(resolved.model, context3, options3);
|
|
399973
400322
|
let streamError;
|
|
399974
400323
|
let finalMessage;
|
|
@@ -400109,7 +400458,6 @@ var init_pi_stream_adapter = __esm(() => {
|
|
|
400109
400458
|
init_context_window_overflow();
|
|
400110
400459
|
init_local_provider_errors();
|
|
400111
400460
|
init_pi_model_factory();
|
|
400112
|
-
init_pi_output_budget();
|
|
400113
400461
|
init_provider_turn_executor();
|
|
400114
400462
|
LOCAL_PROVIDER_ADAPTIVE_IMAGE_ELISION_AFTER_RETRIES = LOCAL_PROVIDER_MAX_RETRIES - 1;
|
|
400115
400463
|
PiProviderError = class PiProviderError extends Error {
|
|
@@ -423600,18 +423948,18 @@ var stdoutColor, stderrColor, GENERATOR, STYLER, IS_EMPTY, levelMapping, styles4
|
|
|
423600
423948
|
return getModelAnsi("rgb", level, type3, ...ansi_styles_default2.hexToRgb(...arguments_));
|
|
423601
423949
|
}
|
|
423602
423950
|
return ansi_styles_default2[type3][model](...arguments_);
|
|
423603
|
-
}, usedModels, proto, createStyler = (
|
|
423951
|
+
}, usedModels, proto, createStyler = (open3, close, parent) => {
|
|
423604
423952
|
let openAll;
|
|
423605
423953
|
let closeAll;
|
|
423606
423954
|
if (parent === undefined) {
|
|
423607
|
-
openAll =
|
|
423955
|
+
openAll = open3;
|
|
423608
423956
|
closeAll = close;
|
|
423609
423957
|
} else {
|
|
423610
|
-
openAll = parent.openAll +
|
|
423958
|
+
openAll = parent.openAll + open3;
|
|
423611
423959
|
closeAll = close + parent.closeAll;
|
|
423612
423960
|
}
|
|
423613
423961
|
return {
|
|
423614
|
-
open:
|
|
423962
|
+
open: open3,
|
|
423615
423963
|
close,
|
|
423616
423964
|
openAll,
|
|
423617
423965
|
closeAll,
|
|
@@ -441385,7 +441733,7 @@ var init_conversation_search = __esm(() => {
|
|
|
441385
441733
|
});
|
|
441386
441734
|
|
|
441387
441735
|
// src/utils/file-lock.ts
|
|
441388
|
-
import { open as
|
|
441736
|
+
import { open as open3, readFile as readFile13, stat as stat10, unlink as unlink4 } from "node:fs/promises";
|
|
441389
441737
|
async function withFileLock(lockPath, fn, options3) {
|
|
441390
441738
|
const opts = { ...DEFAULT_OPTIONS, ...options3 };
|
|
441391
441739
|
const release = await acquireFileLock(lockPath, opts);
|
|
@@ -441403,7 +441751,7 @@ async function acquireFileLock(lockPath, opts) {
|
|
|
441403
441751
|
});
|
|
441404
441752
|
while (true) {
|
|
441405
441753
|
try {
|
|
441406
|
-
const handle2 = await
|
|
441754
|
+
const handle2 = await open3(lockPath, "wx");
|
|
441407
441755
|
try {
|
|
441408
441756
|
await handle2.writeFile(payload, "utf-8");
|
|
441409
441757
|
await handle2.close();
|
|
@@ -441439,7 +441787,7 @@ async function acquireFileLock(lockPath, opts) {
|
|
|
441439
441787
|
async function tryReapStaleLock(lockPath, staleMs) {
|
|
441440
441788
|
let raw2;
|
|
441441
441789
|
try {
|
|
441442
|
-
raw2 = await
|
|
441790
|
+
raw2 = await readFile13(lockPath, "utf-8");
|
|
441443
441791
|
} catch {
|
|
441444
441792
|
return true;
|
|
441445
441793
|
}
|
|
@@ -441496,9 +441844,9 @@ import {
|
|
|
441496
441844
|
appendFile,
|
|
441497
441845
|
mkdir as mkdir12,
|
|
441498
441846
|
readdir as readdir8,
|
|
441499
|
-
readFile as
|
|
441847
|
+
readFile as readFile14,
|
|
441500
441848
|
stat as stat11,
|
|
441501
|
-
writeFile as
|
|
441849
|
+
writeFile as writeFile12
|
|
441502
441850
|
} from "node:fs/promises";
|
|
441503
441851
|
import { join as join46 } from "node:path";
|
|
441504
441852
|
function buildReflectionSubagentPrompt(input) {
|
|
@@ -441556,7 +441904,7 @@ async function collectParentMemoryFiles(memoryDir) {
|
|
|
441556
441904
|
continue;
|
|
441557
441905
|
}
|
|
441558
441906
|
try {
|
|
441559
|
-
const content = await
|
|
441907
|
+
const content = await readFile14(entryPath, "utf-8");
|
|
441560
441908
|
const { frontmatter } = parseFrontmatter(content);
|
|
441561
441909
|
const description = typeof frontmatter.description === "string" ? frontmatter.description : undefined;
|
|
441562
441910
|
files.push({
|
|
@@ -441885,11 +442233,11 @@ function lineToTranscriptEntry(line, capturedAt) {
|
|
|
441885
442233
|
}
|
|
441886
442234
|
async function ensurePaths(paths) {
|
|
441887
442235
|
await mkdir12(paths.rootDir, { recursive: true });
|
|
441888
|
-
await
|
|
442236
|
+
await writeFile12(paths.transcriptPath, "", { encoding: "utf-8", flag: "a" });
|
|
441889
442237
|
}
|
|
441890
442238
|
async function readTranscriptLines(paths) {
|
|
441891
442239
|
try {
|
|
441892
|
-
const raw2 = await
|
|
442240
|
+
const raw2 = await readFile14(paths.transcriptPath, "utf-8");
|
|
441893
442241
|
return raw2.split(`
|
|
441894
442242
|
`).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
441895
442243
|
} catch {
|
|
@@ -441962,7 +442310,7 @@ function buildUnreflectedStateFromTranscript(lines) {
|
|
|
441962
442310
|
async function readState(paths) {
|
|
441963
442311
|
let raw2 = null;
|
|
441964
442312
|
try {
|
|
441965
|
-
raw2 = await
|
|
442313
|
+
raw2 = await readFile14(paths.statePath, "utf-8");
|
|
441966
442314
|
} catch {
|
|
441967
442315
|
raw2 = null;
|
|
441968
442316
|
}
|
|
@@ -441987,7 +442335,7 @@ async function readState(paths) {
|
|
|
441987
442335
|
}
|
|
441988
442336
|
async function writeState(paths, state) {
|
|
441989
442337
|
state.steps_since_last_successful_reflection = Math.max(0, state.total_completed_steps - state.reflected_completed_steps);
|
|
441990
|
-
await
|
|
442338
|
+
await writeFile12(paths.statePath, `${JSON.stringify(state, null, 2)}
|
|
441991
442339
|
`, "utf-8");
|
|
441992
442340
|
}
|
|
441993
442341
|
function buildPayloadPath(rootDir, kind) {
|
|
@@ -442365,7 +442713,7 @@ async function buildReflectionAutoPayload(options3) {
|
|
|
442365
442713
|
candidates: sortedCandidates
|
|
442366
442714
|
};
|
|
442367
442715
|
const candidatesPath = buildPayloadPath(payloadRoot, "candidates");
|
|
442368
|
-
await
|
|
442716
|
+
await writeFile12(candidatesPath, `${JSON.stringify(candidateSet, null, 2)}
|
|
442369
442717
|
`, "utf-8");
|
|
442370
442718
|
return { candidatesPath, candidates: candidateSet };
|
|
442371
442719
|
}
|
|
@@ -442373,7 +442721,7 @@ function isReflectionAutoPriority(value) {
|
|
|
442373
442721
|
return value === "high" || value === "medium" || value === "low";
|
|
442374
442722
|
}
|
|
442375
442723
|
async function readReflectionAutoSelection(options3) {
|
|
442376
|
-
const raw2 = options3.selectionReport ?? (options3.selectionOutputPath ? await
|
|
442724
|
+
const raw2 = options3.selectionReport ?? (options3.selectionOutputPath ? await readFile14(options3.selectionOutputPath, "utf-8") : "");
|
|
442377
442725
|
const parsed = parseReflectionAutoSelectionJson(raw2);
|
|
442378
442726
|
if (!parsed || typeof parsed !== "object") {
|
|
442379
442727
|
throw new Error("Reflection selector did not return valid JSON.");
|
|
@@ -442493,7 +442841,7 @@ async function buildAutoReflectionPayload(agentId, conversationId, systemPrompt)
|
|
|
442493
442841
|
return null;
|
|
442494
442842
|
}
|
|
442495
442843
|
const payloadPath = buildPayloadPath(paths.rootDir, "auto");
|
|
442496
|
-
await
|
|
442844
|
+
await writeFile12(payloadPath, transcript, "utf-8");
|
|
442497
442845
|
state.last_reflection_started_at = new Date().toISOString();
|
|
442498
442846
|
await writeState(paths, state);
|
|
442499
442847
|
return {
|
|
@@ -442582,7 +442930,7 @@ async function buildMultiReflectionPayload(options3) {
|
|
|
442582
442930
|
return null;
|
|
442583
442931
|
}
|
|
442584
442932
|
const payloadPath2 = buildPayloadPath(payloadRoot, "slice");
|
|
442585
|
-
await
|
|
442933
|
+
await writeFile12(payloadPath2, transcript, "utf-8");
|
|
442586
442934
|
state.last_reflection_started_at = new Date().toISOString();
|
|
442587
442935
|
await writeState(paths, state);
|
|
442588
442936
|
return {
|
|
@@ -442624,7 +442972,7 @@ async function buildMultiReflectionPayload(options3) {
|
|
|
442624
442972
|
transcripts
|
|
442625
442973
|
};
|
|
442626
442974
|
const payloadPath = buildPayloadPath(payloadRoot, "multi");
|
|
442627
|
-
await
|
|
442975
|
+
await writeFile12(payloadPath, `${JSON.stringify(manifest, null, 2)}
|
|
442628
442976
|
`, "utf-8");
|
|
442629
442977
|
return {
|
|
442630
442978
|
payloadPath,
|
|
@@ -443433,19 +443781,18 @@ function getListenerBlockedReason(lifecycle, pendingApprovalsLen) {
|
|
|
443433
443781
|
return null;
|
|
443434
443782
|
}
|
|
443435
443783
|
|
|
443436
|
-
// src/websocket/listener/
|
|
443437
|
-
|
|
443438
|
-
|
|
443439
|
-
|
|
443440
|
-
|
|
443441
|
-
|
|
443442
|
-
|
|
443443
|
-
|
|
443444
|
-
|
|
443445
|
-
getQueueItemsScope: () => getQueueItemsScope,
|
|
443446
|
-
getQueueItemScope: () => getQueueItemScope,
|
|
443447
|
-
consumeQueuedTurn: () => consumeQueuedTurn
|
|
443784
|
+
// src/websocket/listener/image-policy.ts
|
|
443785
|
+
function getInboundImageFailureMode(incoming) {
|
|
443786
|
+
return (incoming?.channelTurnSources?.length ?? 0) > 0 ? "drop" : "strict";
|
|
443787
|
+
}
|
|
443788
|
+
function getInboundImageFailureModes(incoming) {
|
|
443789
|
+
return getInboundImageFailureMode(incoming) === "drop" ? buildImageFailureModesByMessageOtid(incoming.messages, "drop") : undefined;
|
|
443790
|
+
}
|
|
443791
|
+
var init_image_policy = __esm(async () => {
|
|
443792
|
+
await init_message_image_normalization();
|
|
443448
443793
|
});
|
|
443794
|
+
|
|
443795
|
+
// src/websocket/listener/queue.ts
|
|
443449
443796
|
function getQueueItemScope(item) {
|
|
443450
443797
|
if (!item) {
|
|
443451
443798
|
return {};
|
|
@@ -443549,27 +443896,6 @@ async function buildChannelTurnProgressBuilder(agentId) {
|
|
|
443549
443896
|
return createChannelTurnProgressBuilder();
|
|
443550
443897
|
}
|
|
443551
443898
|
}
|
|
443552
|
-
async function normalizeMessageContentImages2(content, resize = resizeImageIfNeeded3, failureMode = "strict") {
|
|
443553
|
-
return await normalizeMessageContentImages(content, resize, failureMode);
|
|
443554
|
-
}
|
|
443555
|
-
async function normalizeInboundMessages(messages, resize = resizeImageIfNeeded3, options3 = {}) {
|
|
443556
|
-
let didChange = false;
|
|
443557
|
-
const normalizedMessages = await Promise.all(messages.map(async (message) => {
|
|
443558
|
-
if (!("content" in message)) {
|
|
443559
|
-
return message;
|
|
443560
|
-
}
|
|
443561
|
-
const normalizedContent = await normalizeMessageContentImages2(message.content, resize, options3.imageFailureMode ?? "strict");
|
|
443562
|
-
if (normalizedContent !== message.content) {
|
|
443563
|
-
didChange = true;
|
|
443564
|
-
return {
|
|
443565
|
-
...message,
|
|
443566
|
-
content: normalizedContent
|
|
443567
|
-
};
|
|
443568
|
-
}
|
|
443569
|
-
return message;
|
|
443570
|
-
}));
|
|
443571
|
-
return didChange ? normalizedMessages : messages;
|
|
443572
|
-
}
|
|
443573
443899
|
function getPrimaryQueueMessageItem(items3) {
|
|
443574
443900
|
for (const item of items3) {
|
|
443575
443901
|
if (item.kind === "message") {
|
|
@@ -443670,10 +443996,18 @@ function consumeQueuedTurn(runtime) {
|
|
|
443670
443996
|
let hasTaskNotification = false;
|
|
443671
443997
|
let hasCronPrompt = false;
|
|
443672
443998
|
let hasModContinue = false;
|
|
443999
|
+
let batchImageFailureMode = null;
|
|
443673
444000
|
for (const item of queuedItems) {
|
|
443674
444001
|
if (!isCoalescable(item.kind) || !hasSameQueueScope(firstQueuedItem, item)) {
|
|
443675
444002
|
break;
|
|
443676
444003
|
}
|
|
444004
|
+
if (item.kind === "message") {
|
|
444005
|
+
const itemImageFailureMode = getInboundImageFailureMode(runtime.queuedMessagesByItemId.get(item.id));
|
|
444006
|
+
if (batchImageFailureMode !== null && itemImageFailureMode !== batchImageFailureMode) {
|
|
444007
|
+
break;
|
|
444008
|
+
}
|
|
444009
|
+
batchImageFailureMode = itemImageFailureMode;
|
|
444010
|
+
}
|
|
443677
444011
|
queueLen += 1;
|
|
443678
444012
|
if (item.kind === "message") {
|
|
443679
444013
|
hasMessage = true;
|
|
@@ -443806,8 +444140,7 @@ var init_queue = __esm(async () => {
|
|
|
443806
444140
|
init_runtime6();
|
|
443807
444141
|
await __promiseAll([
|
|
443808
444142
|
init_progress_builder(),
|
|
443809
|
-
|
|
443810
|
-
init_message_image_normalization(),
|
|
444143
|
+
init_image_policy(),
|
|
443811
444144
|
init_protocol_outbound()
|
|
443812
444145
|
]);
|
|
443813
444146
|
});
|
|
@@ -446200,7 +446533,7 @@ __export(exports_custom, {
|
|
|
446200
446533
|
COMMANDS_DIR: () => COMMANDS_DIR
|
|
446201
446534
|
});
|
|
446202
446535
|
import { existsSync as existsSync43 } from "node:fs";
|
|
446203
|
-
import { readdir as readdir9, readFile as
|
|
446536
|
+
import { readdir as readdir9, readFile as readFile15 } from "node:fs/promises";
|
|
446204
446537
|
import { basename as basename20, dirname as dirname24, join as join48 } from "node:path";
|
|
446205
446538
|
async function getCustomCommands() {
|
|
446206
446539
|
if (cachedCommands !== null) {
|
|
@@ -446259,7 +446592,7 @@ async function findCommandFiles(currentPath, rootPath, commands, source2) {
|
|
|
446259
446592
|
} catch (_error) {}
|
|
446260
446593
|
}
|
|
446261
446594
|
async function parseCommandFile(filePath, rootPath, source2) {
|
|
446262
|
-
const content = await
|
|
446595
|
+
const content = await readFile15(filePath, "utf-8");
|
|
446263
446596
|
const { frontmatter, body: body3 } = parseFrontmatter(content);
|
|
446264
446597
|
const id2 = basename20(filePath, ".md");
|
|
446265
446598
|
const relativePath = dirname24(filePath).slice(rootPath.length);
|
|
@@ -446418,7 +446751,7 @@ var init_init_command = __esm(() => {
|
|
|
446418
446751
|
});
|
|
446419
446752
|
|
|
446420
446753
|
// src/cli/helpers/skill-name-frontmatter-repair.ts
|
|
446421
|
-
import { readdir as readdir10, readFile as
|
|
446754
|
+
import { readdir as readdir10, readFile as readFile16, stat as stat12, writeFile as writeFile13 } from "node:fs/promises";
|
|
446422
446755
|
import { basename as basename21, dirname as dirname25, join as join49, relative as relative8 } from "node:path";
|
|
446423
446756
|
async function pathExists(path32) {
|
|
446424
446757
|
try {
|
|
@@ -446525,7 +446858,7 @@ async function repairMissingSkillNameFrontmatter(memoryDir) {
|
|
|
446525
446858
|
const displayPath = relative8(memoryDir, skillFile).replace(/\\/g, "/");
|
|
446526
446859
|
result.scanned++;
|
|
446527
446860
|
try {
|
|
446528
|
-
const content = await
|
|
446861
|
+
const content = await readFile16(skillFile, "utf8");
|
|
446529
446862
|
const repair3 = repairSkillNameFrontmatterContent(content, basename21(dirname25(skillFile)));
|
|
446530
446863
|
if (repair3.reason) {
|
|
446531
446864
|
result.skipped.push({ path: displayPath, reason: repair3.reason });
|
|
@@ -446534,7 +446867,7 @@ async function repairMissingSkillNameFrontmatter(memoryDir) {
|
|
|
446534
446867
|
if (!repair3.changed) {
|
|
446535
446868
|
continue;
|
|
446536
446869
|
}
|
|
446537
|
-
await
|
|
446870
|
+
await writeFile13(skillFile, repair3.content, "utf8");
|
|
446538
446871
|
result.repaired.push(displayPath);
|
|
446539
446872
|
} catch (error54) {
|
|
446540
446873
|
result.skipped.push({
|
|
@@ -447623,7 +447956,7 @@ function isCreateAgentCommand(value) {
|
|
|
447623
447956
|
if (!value || typeof value !== "object")
|
|
447624
447957
|
return false;
|
|
447625
447958
|
const c = value;
|
|
447626
|
-
return c.type === "create_agent" && typeof c.request_id === "string" && (c.personality === "memo" || c.personality === "blank" || c.personality === "tutorial" || c.personality === "linus" || c.personality === "kawaii") && (c.model === undefined || typeof c.model === "string") && (c.pin_global === undefined || typeof c.pin_global === "boolean");
|
|
447959
|
+
return c.type === "create_agent" && typeof c.request_id === "string" && (c.personality === "memo" || c.personality === "blank" || c.personality === "tutorial" || c.personality === "linus" || c.personality === "kawaii") && (c.model === undefined || typeof c.model === "string") && (c.tags === undefined || isStringArray6(c.tags)) && (c.pin_global === undefined || typeof c.pin_global === "boolean");
|
|
447627
447960
|
}
|
|
447628
447961
|
function isAgentListCommand(value) {
|
|
447629
447962
|
if (!value || typeof value !== "object")
|
|
@@ -451105,6 +451438,19 @@ function emitToolExecutionFinishedEvents(socket, runtime, params) {
|
|
|
451105
451438
|
});
|
|
451106
451439
|
}
|
|
451107
451440
|
}
|
|
451441
|
+
function emitToolExecutionAbortedEvents(socket, runtime, params) {
|
|
451442
|
+
for (const toolCallId of params.toolCallIds) {
|
|
451443
|
+
const delta2 = {
|
|
451444
|
+
...createLifecycleMessageBase("client_tool_end", params.runId),
|
|
451445
|
+
tool_call_id: toolCallId,
|
|
451446
|
+
status: "error"
|
|
451447
|
+
};
|
|
451448
|
+
emitCanonicalMessageDelta(socket, runtime, delta2, {
|
|
451449
|
+
agent_id: params.agentId,
|
|
451450
|
+
conversation_id: params.conversationId
|
|
451451
|
+
});
|
|
451452
|
+
}
|
|
451453
|
+
}
|
|
451108
451454
|
function createToolExecutionOutputEmitter(socket, runtime, params) {
|
|
451109
451455
|
const outputByToolCallId = new Map;
|
|
451110
451456
|
const emitToolOutput = (toolCallId, outputState) => {
|
|
@@ -451695,6 +452041,17 @@ var init_approval_suggestions = __esm(async () => {
|
|
|
451695
452041
|
]);
|
|
451696
452042
|
});
|
|
451697
452043
|
|
|
452044
|
+
// src/websocket/listener/continuation-input.ts
|
|
452045
|
+
function appendQueuedTurnToInput(input, queuedTurn) {
|
|
452046
|
+
return {
|
|
452047
|
+
input: [...input, ...queuedTurn.messages],
|
|
452048
|
+
imageFailureModesByMessageOtid: getInboundImageFailureModes(queuedTurn)
|
|
452049
|
+
};
|
|
452050
|
+
}
|
|
452051
|
+
var init_continuation_input = __esm(async () => {
|
|
452052
|
+
await init_image_policy();
|
|
452053
|
+
});
|
|
452054
|
+
|
|
451698
452055
|
// src/websocket/listener/turn-terminal.ts
|
|
451699
452056
|
function finishListenerTurn(runtime, lease, options3) {
|
|
451700
452057
|
const transition = runtime.turnLifecycle.finish(lease, options3.stopReason);
|
|
@@ -452119,25 +452476,25 @@ async function resolveRecoveredApprovalResponse(runtime, socket, response, proce
|
|
|
452119
452476
|
conversationId: recovered.conversationId,
|
|
452120
452477
|
shouldEmit: () => runtime.turnLifecycle.isCurrent(recoveryLease)
|
|
452121
452478
|
});
|
|
452122
|
-
await ensureSecretsHydrated(runtime.listener, recovered.agentId);
|
|
452123
|
-
if (!runtime.turnLifecycle.isCurrent(recoveryLease)) {
|
|
452124
|
-
return true;
|
|
452125
|
-
}
|
|
452126
|
-
const preparedToolContext = await prepareToolExecutionContext({
|
|
452127
|
-
agentId: recovered.agentId,
|
|
452128
|
-
conversationId: recovered.conversationId,
|
|
452129
|
-
workingDirectory,
|
|
452130
|
-
permissionModeState: getOrCreateConversationPermissionModeStateRef(runtime.listener, recovered.agentId, recovered.conversationId),
|
|
452131
|
-
modEvents: ensureListenerModAdapter(runtime.listener).events
|
|
452132
|
-
});
|
|
452133
|
-
if (!runtime.turnLifecycle.isCurrent(recoveryLease)) {
|
|
452134
|
-
return true;
|
|
452135
|
-
}
|
|
452136
|
-
runtime.currentToolset = preparedToolContext.toolset;
|
|
452137
|
-
runtime.currentToolsetPreference = preparedToolContext.toolsetPreference;
|
|
452138
|
-
runtime.currentLoadedTools = preparedToolContext.preparedToolContext.loadedToolNames;
|
|
452139
452479
|
let approvalResults;
|
|
452140
452480
|
try {
|
|
452481
|
+
await ensureSecretsHydrated(runtime.listener, recovered.agentId);
|
|
452482
|
+
if (!runtime.turnLifecycle.isCurrent(recoveryLease)) {
|
|
452483
|
+
return true;
|
|
452484
|
+
}
|
|
452485
|
+
const preparedToolContext = await prepareToolExecutionContext({
|
|
452486
|
+
agentId: recovered.agentId,
|
|
452487
|
+
conversationId: recovered.conversationId,
|
|
452488
|
+
workingDirectory,
|
|
452489
|
+
permissionModeState: getOrCreateConversationPermissionModeStateRef(runtime.listener, recovered.agentId, recovered.conversationId),
|
|
452490
|
+
modEvents: ensureListenerModAdapter(runtime.listener).events
|
|
452491
|
+
});
|
|
452492
|
+
if (!runtime.turnLifecycle.isCurrent(recoveryLease)) {
|
|
452493
|
+
return true;
|
|
452494
|
+
}
|
|
452495
|
+
runtime.currentToolset = preparedToolContext.toolset;
|
|
452496
|
+
runtime.currentToolsetPreference = preparedToolContext.toolsetPreference;
|
|
452497
|
+
runtime.currentLoadedTools = preparedToolContext.preparedToolContext.loadedToolNames;
|
|
452141
452498
|
approvalResults = await executeApprovals(decisions, undefined, {
|
|
452142
452499
|
abortSignal: recoveryLease.signal,
|
|
452143
452500
|
onStreamingOutput: emitToolExecutionOutput,
|
|
@@ -452149,6 +452506,17 @@ async function resolveRecoveredApprovalResponse(runtime, socket, response, proce
|
|
|
452149
452506
|
} : undefined,
|
|
452150
452507
|
channelTurnSources: executionChannelTurnSources
|
|
452151
452508
|
});
|
|
452509
|
+
} catch (error54) {
|
|
452510
|
+
emitToolExecutionOutput.flush();
|
|
452511
|
+
if (runtime.turnLifecycle.isCurrent(recoveryLease)) {
|
|
452512
|
+
emitToolExecutionAbortedEvents(socket, runtime, {
|
|
452513
|
+
toolCallIds: approvedToolCallIds,
|
|
452514
|
+
runId: executionRunId,
|
|
452515
|
+
agentId: recovered.agentId,
|
|
452516
|
+
conversationId: recovered.conversationId
|
|
452517
|
+
});
|
|
452518
|
+
}
|
|
452519
|
+
throw error54;
|
|
452152
452520
|
} finally {
|
|
452153
452521
|
emitToolExecutionOutput.flush();
|
|
452154
452522
|
}
|
|
@@ -452168,7 +452536,7 @@ async function resolveRecoveredApprovalResponse(runtime, socket, response, proce
|
|
|
452168
452536
|
return true;
|
|
452169
452537
|
}
|
|
452170
452538
|
emitRuntimeStateUpdates(runtime, scope);
|
|
452171
|
-
|
|
452539
|
+
let continuationMessages = [
|
|
452172
452540
|
{
|
|
452173
452541
|
type: "approval",
|
|
452174
452542
|
approvals: approvalResults,
|
|
@@ -452176,11 +452544,13 @@ async function resolveRecoveredApprovalResponse(runtime, socket, response, proce
|
|
|
452176
452544
|
}
|
|
452177
452545
|
];
|
|
452178
452546
|
let continuationBatchId = `batch-recovered-${crypto.randomUUID()}`;
|
|
452547
|
+
let queuedChannelTurnSources;
|
|
452179
452548
|
const consumedQueuedTurn = consumeQueuedTurn(runtime);
|
|
452180
452549
|
if (consumedQueuedTurn) {
|
|
452181
452550
|
const { dequeuedBatch, queuedTurn } = consumedQueuedTurn;
|
|
452182
452551
|
continuationBatchId = dequeuedBatch.batchId;
|
|
452183
|
-
continuationMessages
|
|
452552
|
+
continuationMessages = appendQueuedTurnToInput(continuationMessages, queuedTurn).input;
|
|
452553
|
+
queuedChannelTurnSources = queuedTurn.channelTurnSources;
|
|
452184
452554
|
emitDequeuedUserMessage(socket, runtime, queuedTurn, dequeuedBatch);
|
|
452185
452555
|
}
|
|
452186
452556
|
if (!runtime.turnLifecycle.isCurrent(recoveryLease)) {
|
|
@@ -452190,7 +452560,8 @@ async function resolveRecoveredApprovalResponse(runtime, socket, response, proce
|
|
|
452190
452560
|
type: "message",
|
|
452191
452561
|
agentId: recovered.agentId,
|
|
452192
452562
|
conversationId: recovered.conversationId,
|
|
452193
|
-
messages: continuationMessages
|
|
452563
|
+
messages: continuationMessages,
|
|
452564
|
+
...queuedChannelTurnSources?.length ? { channelTurnSources: queuedChannelTurnSources } : {}
|
|
452194
452565
|
}, socket, runtime, opts?.onStatusChange, opts?.connectionId, continuationBatchId, recoveryLease);
|
|
452195
452566
|
if (runtime.turnLifecycle.isCurrent(recoveryLease)) {
|
|
452196
452567
|
throw new Error("Recovered continuation returned without finalizing");
|
|
@@ -452261,6 +452632,7 @@ var init_recovery = __esm(async () => {
|
|
|
452261
452632
|
init_stream(),
|
|
452262
452633
|
init_toolset(),
|
|
452263
452634
|
init_approval_suggestions(),
|
|
452635
|
+
init_continuation_input(),
|
|
452264
452636
|
init_interrupts(),
|
|
452265
452637
|
init_mod_adapter2(),
|
|
452266
452638
|
init_protocol_outbound(),
|
|
@@ -452490,17 +452862,20 @@ async function resolveStaleApprovals(runtime, socket, turnLease, deps = {}) {
|
|
|
452490
452862
|
return null;
|
|
452491
452863
|
}
|
|
452492
452864
|
try {
|
|
452493
|
-
|
|
452865
|
+
let continuationMessages = [
|
|
452494
452866
|
{
|
|
452495
452867
|
type: "approval",
|
|
452496
452868
|
approvals: approvalResults,
|
|
452497
452869
|
otid: crypto.randomUUID()
|
|
452498
452870
|
}
|
|
452499
452871
|
];
|
|
452872
|
+
let queuedImageFailureModes;
|
|
452500
452873
|
const consumedQueuedTurn = consumeQueuedTurn(runtime);
|
|
452501
452874
|
if (consumedQueuedTurn) {
|
|
452502
452875
|
const { dequeuedBatch, queuedTurn } = consumedQueuedTurn;
|
|
452503
|
-
continuationMessages
|
|
452876
|
+
const appended = appendQueuedTurnToInput(continuationMessages, queuedTurn);
|
|
452877
|
+
continuationMessages = appended.input;
|
|
452878
|
+
queuedImageFailureModes = appended.imageFailureModesByMessageOtid;
|
|
452504
452879
|
emitDequeuedUserMessage(socket, runtime, queuedTurn, dequeuedBatch);
|
|
452505
452880
|
}
|
|
452506
452881
|
const continuationMessagesWithSkillContent = injectQueuedSkillContent(continuationMessages);
|
|
@@ -452509,7 +452884,8 @@ async function resolveStaleApprovals(runtime, socket, turnLease, deps = {}) {
|
|
|
452509
452884
|
streamTokens: true,
|
|
452510
452885
|
background: true,
|
|
452511
452886
|
workingDirectory: recoveryWorkingDirectory,
|
|
452512
|
-
preparedToolContext: preparedToolContext.preparedToolContext
|
|
452887
|
+
preparedToolContext: preparedToolContext.preparedToolContext,
|
|
452888
|
+
...queuedImageFailureModes ? { imageFailureModesByMessageOtid: queuedImageFailureModes } : {}
|
|
452513
452889
|
}, socket, runtime, turnLease, { allowApprovalRecovery: false });
|
|
452514
452890
|
assertCurrentTurnLease();
|
|
452515
452891
|
if (recoverySendResult.kind !== "stream") {
|
|
@@ -452850,6 +453226,7 @@ var init_send = __esm(async () => {
|
|
|
452850
453226
|
init_message(),
|
|
452851
453227
|
init_toolset(),
|
|
452852
453228
|
init_approval(),
|
|
453229
|
+
init_continuation_input(),
|
|
452853
453230
|
init_mod_adapter2(),
|
|
452854
453231
|
init_protocol_outbound(),
|
|
452855
453232
|
init_queue(),
|
|
@@ -455231,6 +455608,17 @@ async function handleApprovalStop(params) {
|
|
|
455231
455608
|
channelTurnSources: runtime.activeChannelTurn?.sources,
|
|
455232
455609
|
onFileWrite
|
|
455233
455610
|
});
|
|
455611
|
+
} catch (error54) {
|
|
455612
|
+
emitToolExecutionOutput.flush();
|
|
455613
|
+
if (!shouldInterrupt()) {
|
|
455614
|
+
emitToolExecutionAbortedEvents(socket, runtime, {
|
|
455615
|
+
toolCallIds: lastExecutingToolCallIds,
|
|
455616
|
+
runId: executionRunId,
|
|
455617
|
+
agentId,
|
|
455618
|
+
conversationId
|
|
455619
|
+
});
|
|
455620
|
+
}
|
|
455621
|
+
throw error54;
|
|
455234
455622
|
} finally {
|
|
455235
455623
|
emitToolExecutionOutput.flush();
|
|
455236
455624
|
}
|
|
@@ -455254,7 +455642,7 @@ async function handleApprovalStop(params) {
|
|
|
455254
455642
|
if (shouldInterrupt()) {
|
|
455255
455643
|
return interruptTermination();
|
|
455256
455644
|
}
|
|
455257
|
-
|
|
455645
|
+
let nextInput = [
|
|
455258
455646
|
{
|
|
455259
455647
|
type: "approval",
|
|
455260
455648
|
approvals: persistedExecutionResults,
|
|
@@ -455262,11 +455650,14 @@ async function handleApprovalStop(params) {
|
|
|
455262
455650
|
}
|
|
455263
455651
|
];
|
|
455264
455652
|
let continuationBatchId = dequeuedBatchId;
|
|
455653
|
+
let queuedImageFailureModes;
|
|
455265
455654
|
const consumedQueuedTurn = consumeQueuedTurn(runtime);
|
|
455266
455655
|
if (consumedQueuedTurn) {
|
|
455267
455656
|
const { dequeuedBatch, queuedTurn } = consumedQueuedTurn;
|
|
455268
455657
|
continuationBatchId = dequeuedBatch.batchId;
|
|
455269
|
-
nextInput
|
|
455658
|
+
const appended = appendQueuedTurnToInput(nextInput, queuedTurn);
|
|
455659
|
+
nextInput = appended.input;
|
|
455660
|
+
queuedImageFailureModes = appended.imageFailureModesByMessageOtid;
|
|
455270
455661
|
emitDequeuedUserMessage(socket, runtime, queuedTurn, dequeuedBatch);
|
|
455271
455662
|
}
|
|
455272
455663
|
const nextInputWithSkillContent = injectQueuedSkillContent(nextInput);
|
|
@@ -455279,8 +455670,11 @@ async function handleApprovalStop(params) {
|
|
|
455279
455670
|
});
|
|
455280
455671
|
let sendResult;
|
|
455281
455672
|
try {
|
|
455673
|
+
const sendOptions = buildSendOptions() ?? {};
|
|
455674
|
+
const imageFailureModesByMessageOtid = mergeImageFailureModesByMessageOtid(sendOptions.imageFailureModesByMessageOtid, queuedImageFailureModes);
|
|
455282
455675
|
sendResult = await sendApprovalContinuationWithRetry(conversationId, nextInputWithSkillContent, {
|
|
455283
|
-
...
|
|
455676
|
+
...sendOptions,
|
|
455677
|
+
...imageFailureModesByMessageOtid ? { imageFailureModesByMessageOtid } : {},
|
|
455284
455678
|
...continuationWasFullyAutoHandled ? { allowResponseStateReuse: true } : {}
|
|
455285
455679
|
}, socket, runtime, turnLease, { providerFallback });
|
|
455286
455680
|
} catch (error54) {
|
|
@@ -455348,8 +455742,10 @@ var init_turn_approval = __esm(async () => {
|
|
|
455348
455742
|
init_transport();
|
|
455349
455743
|
await __promiseAll([
|
|
455350
455744
|
init_approval_execution(),
|
|
455745
|
+
init_message_image_normalization(),
|
|
455351
455746
|
init_approval(),
|
|
455352
455747
|
init_approval_suggestions(),
|
|
455748
|
+
init_continuation_input(),
|
|
455353
455749
|
init_interrupts(),
|
|
455354
455750
|
init_protocol_outbound(),
|
|
455355
455751
|
init_queue(),
|
|
@@ -456518,14 +456914,7 @@ async function prepareListenerTurn(params) {
|
|
|
456518
456914
|
if (connectionId) {
|
|
456519
456915
|
onStatusChange?.("processing", connectionId);
|
|
456520
456916
|
}
|
|
456521
|
-
|
|
456522
|
-
const normalizedMessages = await normalizeInboundMessages2(msg.messages, undefined, {
|
|
456523
|
-
imageFailureMode: (msg.channelTurnSources?.length ?? 0) > 0 ? "drop" : "strict"
|
|
456524
|
-
});
|
|
456525
|
-
if (isInterrupted()) {
|
|
456526
|
-
return { kind: "interrupted" };
|
|
456527
|
-
}
|
|
456528
|
-
trackListenerUserInput(normalizedMessages, "unknown");
|
|
456917
|
+
trackListenerUserInput(msg.messages, "unknown");
|
|
456529
456918
|
const messagesToSend = [];
|
|
456530
456919
|
let queuedInterruptedToolCallIds = [];
|
|
456531
456920
|
const consumed = consumeInterruptQueue(runtime, agentId, conversationId);
|
|
@@ -456533,12 +456922,16 @@ async function prepareListenerTurn(params) {
|
|
|
456533
456922
|
messagesToSend.push(consumed.approvalMessage);
|
|
456534
456923
|
queuedInterruptedToolCallIds = consumed.interruptedToolCallIds;
|
|
456535
456924
|
}
|
|
456536
|
-
messagesToSend.push(...
|
|
456925
|
+
messagesToSend.push(...msg.messages.map((message) => ("content" in message) && !message.otid ? {
|
|
456537
456926
|
...message,
|
|
456538
456927
|
otid: "client_message_id" in message && typeof message.client_message_id === "string" ? message.client_message_id : crypto.randomUUID()
|
|
456539
456928
|
} : message));
|
|
456929
|
+
const imageFailureModesByMessageOtid = getInboundImageFailureModes({
|
|
456930
|
+
channelTurnSources: msg.channelTurnSources,
|
|
456931
|
+
messages: messagesToSend
|
|
456932
|
+
});
|
|
456540
456933
|
let inboundUserTranscriptLines = buildInboundUserTranscriptLines(messagesToSend);
|
|
456541
|
-
const firstMessage =
|
|
456934
|
+
const firstMessage = msg.messages[0];
|
|
456542
456935
|
const isApprovalMessage = firstMessage && "type" in firstMessage && firstMessage.type === "approval" && "approvals" in firstMessage;
|
|
456543
456936
|
let cachedAgent = null;
|
|
456544
456937
|
if (!isApprovalMessage) {
|
|
@@ -456650,6 +457043,7 @@ async function prepareListenerTurn(params) {
|
|
|
456650
457043
|
kind: "ready",
|
|
456651
457044
|
getCachedAgent: () => cachedAgent,
|
|
456652
457045
|
currentInput,
|
|
457046
|
+
imageFailureModesByMessageOtid,
|
|
456653
457047
|
inboundUserTranscriptLines,
|
|
456654
457048
|
pendingNormalizationInterruptedToolCallIds: [
|
|
456655
457049
|
...queuedInterruptedToolCallIds
|
|
@@ -456668,6 +457062,7 @@ var init_turn_setup = __esm(async () => {
|
|
|
456668
457062
|
init_warmup();
|
|
456669
457063
|
await __promiseAll([
|
|
456670
457064
|
init_toolset(),
|
|
457065
|
+
init_image_policy(),
|
|
456671
457066
|
init_interrupts(),
|
|
456672
457067
|
init_mod_adapter2(),
|
|
456673
457068
|
init_turn_events()
|
|
@@ -456802,7 +457197,9 @@ async function handleIncomingMessage(msg, socket, runtime, onStatusChange, conne
|
|
|
456802
457197
|
workingDirectory: turnWorkingDirectory,
|
|
456803
457198
|
permissionModeState: turnPermissionModeState,
|
|
456804
457199
|
preparedToolContext: preparedToolContext.preparedToolContext,
|
|
456805
|
-
|
|
457200
|
+
...setup.imageFailureModesByMessageOtid ? {
|
|
457201
|
+
imageFailureModesByMessageOtid: setup.imageFailureModesByMessageOtid
|
|
457202
|
+
} : {},
|
|
456806
457203
|
...providerFallback.overrideModel ? { overrideModel: providerFallback.overrideModel } : {},
|
|
456807
457204
|
...msg.actingUserId ? { actingUserId: msg.actingUserId } : {},
|
|
456808
457205
|
...pendingNormalizationInterruptedToolCallIds.length > 0 ? {
|
|
@@ -461156,7 +461553,7 @@ var init_grep_in_files = __esm(() => {
|
|
|
461156
461553
|
});
|
|
461157
461554
|
|
|
461158
461555
|
// src/websocket/listener/file-commands.ts
|
|
461159
|
-
import { readdir as readdir11, readFile as
|
|
461556
|
+
import { readdir as readdir11, readFile as readFile17 } from "node:fs/promises";
|
|
461160
461557
|
import { homedir as homedir30 } from "node:os";
|
|
461161
461558
|
import path35 from "node:path";
|
|
461162
461559
|
function trackListenerError2(errorType, error54, context4) {
|
|
@@ -461211,7 +461608,7 @@ async function getIgnoreConfig(root2) {
|
|
|
461211
461608
|
return cached3;
|
|
461212
461609
|
let patterns2 = [];
|
|
461213
461610
|
try {
|
|
461214
|
-
const content = await
|
|
461611
|
+
const content = await readFile17(path35.join(absRoot, ".letta", ".lettaignore"), "utf-8");
|
|
461215
461612
|
patterns2 = parseLettaIgnore(content);
|
|
461216
461613
|
} catch {
|
|
461217
461614
|
patterns2 = [];
|
|
@@ -463954,7 +464351,7 @@ function handleMemoryProtocolCommand(parsed, context4) {
|
|
|
463954
464351
|
ensureLocalMemfsCheckout: ensureLocalMemfsCheckout2,
|
|
463955
464352
|
isMemfsEnabledOnServer: isMemfsEnabledOnServer2
|
|
463956
464353
|
} = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
463957
|
-
const { readFile:
|
|
464354
|
+
const { readFile: readFile18 } = await import("node:fs/promises");
|
|
463958
464355
|
const { existsSync: existsSync46 } = await import("node:fs");
|
|
463959
464356
|
const { isAbsolute: isAbsolute24, join: join52, normalize: normalize5, relative: relative13, sep: sep6 } = await import("node:path");
|
|
463960
464357
|
if (isAbsolute24(parsed.path) || parsed.path.length === 0) {
|
|
@@ -463980,7 +464377,7 @@ function handleMemoryProtocolCommand(parsed, context4) {
|
|
|
463980
464377
|
return;
|
|
463981
464378
|
}
|
|
463982
464379
|
}
|
|
463983
|
-
const buffer = await
|
|
464380
|
+
const buffer = await readFile18(absolutePath);
|
|
463984
464381
|
const content = encoding === "base64" ? buffer.toString("base64") : buffer.toString("utf-8");
|
|
463985
464382
|
const pathspec = rel.split(sep6).join("/");
|
|
463986
464383
|
safeSocketSend(socket, {
|
|
@@ -464020,7 +464417,7 @@ function handleMemoryProtocolCommand(parsed, context4) {
|
|
|
464020
464417
|
isMemfsEnabledOnServer: isMemfsEnabledOnServer2
|
|
464021
464418
|
} = await Promise.resolve().then(() => (init_memory_filesystem2(), exports_memory_filesystem));
|
|
464022
464419
|
const { commitMemoryWrite: commitMemoryWrite2 } = await Promise.resolve().then(() => (init_memory_git(), exports_memory_git));
|
|
464023
|
-
const { writeFile:
|
|
464420
|
+
const { writeFile: writeFile14, mkdir: mkdir13 } = await import("node:fs/promises");
|
|
464024
464421
|
const { existsSync: existsSync46 } = await import("node:fs");
|
|
464025
464422
|
const { dirname: dirname27, isAbsolute: isAbsolute24, join: join52, normalize: normalize5, relative: relative13, sep: sep6 } = await import("node:path");
|
|
464026
464423
|
if (isAbsolute24(parsed.path) || parsed.path.length === 0) {
|
|
@@ -464048,7 +464445,7 @@ function handleMemoryProtocolCommand(parsed, context4) {
|
|
|
464048
464445
|
}
|
|
464049
464446
|
const buffer = encoding === "base64" ? Buffer.from(parsed.content, "base64") : Buffer.from(parsed.content, "utf-8");
|
|
464050
464447
|
await mkdir13(dirname27(absolutePath), { recursive: true });
|
|
464051
|
-
await
|
|
464448
|
+
await writeFile14(absolutePath, buffer);
|
|
464052
464449
|
const { getBackend: getBackend2 } = await Promise.resolve().then(() => (init_backend2(), exports_backend));
|
|
464053
464450
|
const backend4 = getBackend2();
|
|
464054
464451
|
const memorySyncMode = backend4.capabilities.localMemfs && !backend4.capabilities.remoteMemfs ? "local" : undefined;
|
|
@@ -464688,7 +465085,8 @@ async function handleCreateAgentCommand(parsed, socket, safeSocketSend) {
|
|
|
464688
465085
|
const { createAgentForPersonality: createAgentForPersonality2 } = await Promise.resolve().then(() => (init_personality(), exports_personality));
|
|
464689
465086
|
const result = await createAgentForPersonality2({
|
|
464690
465087
|
personalityId: parsed.personality,
|
|
464691
|
-
model: parsed.model
|
|
465088
|
+
model: parsed.model,
|
|
465089
|
+
...parsed.tags && { tags: parsed.tags }
|
|
464692
465090
|
});
|
|
464693
465091
|
if (parsed.pin_global !== false) {
|
|
464694
465092
|
settingsManager.pinAgent(result.agent.id);
|
|
@@ -467177,7 +467575,7 @@ var execFile15, __dirname2, localXdgOpenPath, platform8, arch3, pTryEach = async
|
|
|
467177
467575
|
}
|
|
467178
467576
|
subprocess.unref();
|
|
467179
467577
|
return subprocess;
|
|
467180
|
-
},
|
|
467578
|
+
}, open4 = (target2, options3) => {
|
|
467181
467579
|
if (typeof target2 !== "string") {
|
|
467182
467580
|
throw new TypeError("Expected a `target`");
|
|
467183
467581
|
}
|
|
@@ -467246,14 +467644,14 @@ var init_open = __esm(() => {
|
|
|
467246
467644
|
}));
|
|
467247
467645
|
defineLazyProperty(apps, "browser", () => "browser");
|
|
467248
467646
|
defineLazyProperty(apps, "browserPrivate", () => "browserPrivate");
|
|
467249
|
-
open_default =
|
|
467647
|
+
open_default = open4;
|
|
467250
467648
|
});
|
|
467251
467649
|
|
|
467252
467650
|
// src/cli/commands/connect-oauth-core.ts
|
|
467253
467651
|
async function openOAuthBrowser(authorizationUrl) {
|
|
467254
467652
|
try {
|
|
467255
|
-
const { default:
|
|
467256
|
-
const subprocess = await
|
|
467653
|
+
const { default: open5 } = await Promise.resolve().then(() => (init_open(), exports_open));
|
|
467654
|
+
const subprocess = await open5(authorizationUrl, { wait: false });
|
|
467257
467655
|
subprocess.on("error", () => {});
|
|
467258
467656
|
} catch {}
|
|
467259
467657
|
}
|
|
@@ -469560,8 +469958,6 @@ var init_client7 = __esm(async () => {
|
|
|
469560
469958
|
shouldAttemptPostStopApprovalRecovery,
|
|
469561
469959
|
markAwaitingAcceptedApprovalContinuationRunId,
|
|
469562
469960
|
resolveStaleApprovals,
|
|
469563
|
-
normalizeMessageContentImages: normalizeMessageContentImages2,
|
|
469564
|
-
normalizeInboundMessages,
|
|
469565
469961
|
consumeQueuedTurn,
|
|
469566
469962
|
handleIncomingMessage,
|
|
469567
469963
|
handleApprovalResponseInput,
|
|
@@ -470005,7 +470401,7 @@ function ConstellationLoginView({
|
|
|
470005
470401
|
const deviceData = await requestDeviceCode();
|
|
470006
470402
|
setUserCode(deviceData.user_code);
|
|
470007
470403
|
setVerificationUri(deviceData.verification_uri_complete);
|
|
470008
|
-
Promise.resolve().then(() => (init_open(), exports_open)).then(({ default:
|
|
470404
|
+
Promise.resolve().then(() => (init_open(), exports_open)).then(({ default: open5 }) => open5(deviceData.verification_uri_complete, { wait: false })).then((subprocess) => {
|
|
470009
470405
|
subprocess.on("error", () => {});
|
|
470010
470406
|
}).catch(() => {});
|
|
470011
470407
|
const deviceId = settingsManager.getOrCreateDeviceId();
|
|
@@ -471930,7 +472326,7 @@ __export(exports_skills3, {
|
|
|
471930
472326
|
GLOBAL_SKILLS_DIR: () => GLOBAL_SKILLS_DIR2
|
|
471931
472327
|
});
|
|
471932
472328
|
import { existsSync as existsSync54 } from "node:fs";
|
|
471933
|
-
import { readdir as readdir15, readFile as
|
|
472329
|
+
import { readdir as readdir15, readFile as readFile21, realpath as realpath6, stat as stat15 } from "node:fs/promises";
|
|
471934
472330
|
import { dirname as dirname31, join as join62 } from "node:path";
|
|
471935
472331
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
471936
472332
|
function getBundledSkillsPath2() {
|
|
@@ -472102,7 +472498,7 @@ async function findSkillFiles2(currentPath, rootPath, skills, errors7, source2,
|
|
|
472102
472498
|
}
|
|
472103
472499
|
}
|
|
472104
472500
|
async function parseSkillFile2(filePath, rootPath, source2) {
|
|
472105
|
-
const content = await
|
|
472501
|
+
const content = await readFile21(filePath, "utf-8");
|
|
472106
472502
|
const { frontmatter, body: body3 } = parseFrontmatter(content);
|
|
472107
472503
|
const normalizedRoot = rootPath.endsWith("/") ? rootPath.slice(0, -1) : rootPath;
|
|
472108
472504
|
const relativePath = filePath.slice(normalizedRoot.length + 1);
|
|
@@ -472162,9 +472558,9 @@ var init_skills4 = __esm(() => {
|
|
|
472162
472558
|
var exports_fs = {};
|
|
472163
472559
|
__export(exports_fs, {
|
|
472164
472560
|
writeJsonFile: () => writeJsonFile2,
|
|
472165
|
-
writeFile: () =>
|
|
472561
|
+
writeFile: () => writeFile16,
|
|
472166
472562
|
readJsonFile: () => readJsonFile4,
|
|
472167
|
-
readFile: () =>
|
|
472563
|
+
readFile: () => readFile22,
|
|
472168
472564
|
mkdir: () => mkdir15,
|
|
472169
472565
|
exists: () => exists2
|
|
472170
472566
|
});
|
|
@@ -472175,10 +472571,10 @@ import {
|
|
|
472175
472571
|
mkdirSync as mkdirSync38
|
|
472176
472572
|
} from "node:fs";
|
|
472177
472573
|
import { dirname as dirname32 } from "node:path";
|
|
472178
|
-
async function
|
|
472574
|
+
async function readFile22(path39) {
|
|
472179
472575
|
return fsReadFileSync2(path39, { encoding: "utf-8" });
|
|
472180
472576
|
}
|
|
472181
|
-
async function
|
|
472577
|
+
async function writeFile16(path39, content) {
|
|
472182
472578
|
const dir = dirname32(path39);
|
|
472183
472579
|
if (!existsSync55(dir)) {
|
|
472184
472580
|
mkdirSync38(dir, { recursive: true });
|
|
@@ -472192,14 +472588,14 @@ async function mkdir15(path39, options3) {
|
|
|
472192
472588
|
mkdirSync38(path39, options3);
|
|
472193
472589
|
}
|
|
472194
472590
|
async function readJsonFile4(path39) {
|
|
472195
|
-
const text2 = await
|
|
472591
|
+
const text2 = await readFile22(path39);
|
|
472196
472592
|
return JSON.parse(text2);
|
|
472197
472593
|
}
|
|
472198
472594
|
async function writeJsonFile2(path39, data, options3) {
|
|
472199
472595
|
const indent = options3?.indent ?? 2;
|
|
472200
472596
|
const content = `${JSON.stringify(data, null, indent)}
|
|
472201
472597
|
`;
|
|
472202
|
-
await
|
|
472598
|
+
await writeFile16(path39, content);
|
|
472203
472599
|
}
|
|
472204
472600
|
var init_fs2 = () => {};
|
|
472205
472601
|
|
|
@@ -472398,7 +472794,7 @@ import {
|
|
|
472398
472794
|
execFile as execFile17
|
|
472399
472795
|
} from "node:child_process";
|
|
472400
472796
|
import { accessSync as accessSync2, constants as constants4, realpathSync as realpathSync6 } from "node:fs";
|
|
472401
|
-
import { readdir as readdir16, rm as
|
|
472797
|
+
import { readdir as readdir16, rm as rm7 } from "node:fs/promises";
|
|
472402
472798
|
import { dirname as dirname33, join as join63 } from "node:path";
|
|
472403
472799
|
import { promisify as promisify15 } from "node:util";
|
|
472404
472800
|
function debugLog4(...args) {
|
|
@@ -472630,7 +473026,7 @@ async function cleanupOrphanedDirs2(globalPath) {
|
|
|
472630
473026
|
if (entry.startsWith(".letta-code-")) {
|
|
472631
473027
|
const orphanPath = join63(lettaAiDir, entry);
|
|
472632
473028
|
debugLog4("Cleaning orphaned temp directory:", orphanPath);
|
|
472633
|
-
await
|
|
473029
|
+
await rm7(orphanPath, { recursive: true, force: true });
|
|
472634
473030
|
}
|
|
472635
473031
|
}
|
|
472636
473032
|
} catch {}
|
|
@@ -474098,7 +474494,7 @@ __export(exports_import, {
|
|
|
474098
474494
|
extractSkillsFromAf: () => extractSkillsFromAf
|
|
474099
474495
|
});
|
|
474100
474496
|
import { createReadStream as createReadStream2 } from "node:fs";
|
|
474101
|
-
import { access as access2, chmod, mkdir as mkdir16, readFile as
|
|
474497
|
+
import { access as access2, chmod, mkdir as mkdir16, readFile as readFile23, writeFile as writeFile17 } from "node:fs/promises";
|
|
474102
474498
|
import { dirname as dirname34, isAbsolute as isAbsolute25, relative as relative13, resolve as resolve36, sep as sep7, win32 as win325 } from "node:path";
|
|
474103
474499
|
function validateImportedSkillName(name) {
|
|
474104
474500
|
const trimmedName = name.trim();
|
|
@@ -474199,7 +474595,7 @@ async function importAgentFromFile(options3) {
|
|
|
474199
474595
|
}
|
|
474200
474596
|
async function extractSkillsFromAf(afPath, destDir) {
|
|
474201
474597
|
const extracted = [];
|
|
474202
|
-
const content = await
|
|
474598
|
+
const content = await readFile23(afPath, "utf-8");
|
|
474203
474599
|
const afData = JSON.parse(content);
|
|
474204
474600
|
if (!afData.skills || !Array.isArray(afData.skills)) {
|
|
474205
474601
|
return [];
|
|
@@ -474228,7 +474624,7 @@ async function writeSkillFiles(skillDir, files) {
|
|
|
474228
474624
|
async function writeSkillFile(skillDir, filePath, content) {
|
|
474229
474625
|
const fullPath = resolveImportedSkillFilePath(skillDir, filePath);
|
|
474230
474626
|
await mkdir16(dirname34(fullPath), { recursive: true });
|
|
474231
|
-
await
|
|
474627
|
+
await writeFile17(fullPath, content, "utf-8");
|
|
474232
474628
|
const isScript = filePath.startsWith("scripts/") || content.trimStart().startsWith("#!");
|
|
474233
474629
|
if (isScript) {
|
|
474234
474630
|
try {
|
|
@@ -474281,7 +474677,7 @@ function parseRegistryHandle(handle2) {
|
|
|
474281
474677
|
async function importAgentFromRegistry(options3) {
|
|
474282
474678
|
const { tmpdir: tmpdir10 } = await import("node:os");
|
|
474283
474679
|
const { join: join68 } = await import("node:path");
|
|
474284
|
-
const { writeFile:
|
|
474680
|
+
const { writeFile: writeFile18, unlink: unlink5 } = await import("node:fs/promises");
|
|
474285
474681
|
const { author, name } = parseRegistryHandle(options3.handle);
|
|
474286
474682
|
const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER}/${AGENT_REGISTRY_REPO}/refs/heads/${AGENT_REGISTRY_BRANCH}/agents/@${author}/${name}/${name}.af`;
|
|
474287
474683
|
const response = await fetch(rawUrl);
|
|
@@ -474293,7 +474689,7 @@ async function importAgentFromRegistry(options3) {
|
|
|
474293
474689
|
}
|
|
474294
474690
|
const afContent = await response.text();
|
|
474295
474691
|
const tempPath = join68(tmpdir10(), `letta-import-${author}-${name}-${Date.now()}.af`);
|
|
474296
|
-
await
|
|
474692
|
+
await writeFile18(tempPath, afContent, "utf-8");
|
|
474297
474693
|
try {
|
|
474298
474694
|
const result = await importAgentFromFile({
|
|
474299
474695
|
filePath: tempPath,
|
|
@@ -474401,7 +474797,8 @@ async function ensureDefaultAgents(backend4, options3) {
|
|
|
474401
474797
|
const createOptions = personality === "tutorial" ? {
|
|
474402
474798
|
...await buildCreateAgentOptionsForPersonality2({
|
|
474403
474799
|
personalityId: "tutorial",
|
|
474404
|
-
model
|
|
474800
|
+
model,
|
|
474801
|
+
tags: [ONBOARDING_ORIGIN_TAG]
|
|
474405
474802
|
}),
|
|
474406
474803
|
memoryPromptMode
|
|
474407
474804
|
} : {
|
|
@@ -479108,7 +479505,7 @@ var init_queued_message_parts = __esm(() => {
|
|
|
479108
479505
|
// src/cli/helpers/reflection-arena-hf-upload.ts
|
|
479109
479506
|
import { execFile as execFileCb5 } from "node:child_process";
|
|
479110
479507
|
import { existsSync as existsSync60 } from "node:fs";
|
|
479111
|
-
import { appendFile as appendFile2, chmod as chmod2, mkdir as mkdir17, writeFile as
|
|
479508
|
+
import { appendFile as appendFile2, chmod as chmod2, mkdir as mkdir17, writeFile as writeFile18 } from "node:fs/promises";
|
|
479112
479509
|
import { homedir as homedir38 } from "node:os";
|
|
479113
479510
|
import { join as join69 } from "node:path";
|
|
479114
479511
|
import { promisify as promisify16 } from "node:util";
|
|
@@ -479147,7 +479544,7 @@ async function runGit6(cwd2, args, env5) {
|
|
|
479147
479544
|
}
|
|
479148
479545
|
async function writeGitAskpass(repoRoot) {
|
|
479149
479546
|
const askpassPath = join69(repoRoot, "hf-askpass.sh");
|
|
479150
|
-
await
|
|
479547
|
+
await writeFile18(askpassPath, [
|
|
479151
479548
|
"#!/bin/sh",
|
|
479152
479549
|
'case "$1" in',
|
|
479153
479550
|
" *Username*) printf '%s\\n' 'hf_user' ;;",
|
|
@@ -479232,7 +479629,7 @@ var init_reflection_arena_hf_upload = __esm(() => {
|
|
|
479232
479629
|
// src/cli/helpers/reflection-arena.ts
|
|
479233
479630
|
import { execFile as execFileCb6 } from "node:child_process";
|
|
479234
479631
|
import { randomInt, randomUUID as randomUUID30 } from "node:crypto";
|
|
479235
|
-
import { appendFile as appendFile3, mkdir as mkdir18, readFile as
|
|
479632
|
+
import { appendFile as appendFile3, mkdir as mkdir18, readFile as readFile24, writeFile as writeFile19 } from "node:fs/promises";
|
|
479236
479633
|
import { homedir as homedir39 } from "node:os";
|
|
479237
479634
|
import { join as join70 } from "node:path";
|
|
479238
479635
|
import { promisify as promisify17 } from "node:util";
|
|
@@ -479277,11 +479674,11 @@ function getReflectionArenaRunPath(runId) {
|
|
|
479277
479674
|
}
|
|
479278
479675
|
async function saveReflectionArenaRun(run) {
|
|
479279
479676
|
await mkdir18(getReflectionArenaRunsDir(), { recursive: true });
|
|
479280
|
-
await
|
|
479677
|
+
await writeFile19(getReflectionArenaRunPath(run.runId), `${JSON.stringify(run, null, 2)}
|
|
479281
479678
|
`, "utf-8");
|
|
479282
479679
|
}
|
|
479283
479680
|
async function loadReflectionArenaRun(runId) {
|
|
479284
|
-
const raw2 = await
|
|
479681
|
+
const raw2 = await readFile24(getReflectionArenaRunPath(runId), "utf-8");
|
|
479285
479682
|
return JSON.parse(raw2);
|
|
479286
479683
|
}
|
|
479287
479684
|
async function updateReflectionArenaRun(runId, update2) {
|
|
@@ -479473,7 +479870,7 @@ async function appendChoiceRecord(run) {
|
|
|
479473
479870
|
}
|
|
479474
479871
|
async function readTranscriptPayloadForTelemetry(payloadPath) {
|
|
479475
479872
|
try {
|
|
479476
|
-
const transcript = await
|
|
479873
|
+
const transcript = await readFile24(payloadPath, "utf-8");
|
|
479477
479874
|
return {
|
|
479478
479875
|
transcriptPayload: transcript.slice(0, REFLECTION_ARENA_TELEMETRY_TRANSCRIPT_MAX_CHARS),
|
|
479479
479876
|
transcriptPayloadChars: transcript.length,
|
|
@@ -494711,7 +495108,7 @@ var init_McpConnectFlow = __esm(async () => {
|
|
|
494711
495108
|
const authorizationUrl = event2.url;
|
|
494712
495109
|
setAuthUrl(authorizationUrl);
|
|
494713
495110
|
setConnectionStatus("Opening browser for authorization...");
|
|
494714
|
-
Promise.resolve().then(() => (init_open(), exports_open)).then(({ default:
|
|
495111
|
+
Promise.resolve().then(() => (init_open(), exports_open)).then(({ default: open5 }) => open5(authorizationUrl)).catch(() => {});
|
|
494715
495112
|
}
|
|
494716
495113
|
break;
|
|
494717
495114
|
case "waiting_for_auth" /* WAITING_FOR_AUTH */:
|
|
@@ -500905,7 +501302,7 @@ var init_PersonalitySelector = __esm(async () => {
|
|
|
500905
501302
|
});
|
|
500906
501303
|
|
|
500907
501304
|
// src/utils/aws-credentials.ts
|
|
500908
|
-
import { readFile as
|
|
501305
|
+
import { readFile as readFile25 } from "node:fs/promises";
|
|
500909
501306
|
import { homedir as homedir45 } from "node:os";
|
|
500910
501307
|
import { join as join77 } from "node:path";
|
|
500911
501308
|
async function parseAwsCredentials() {
|
|
@@ -500913,11 +501310,11 @@ async function parseAwsCredentials() {
|
|
|
500913
501310
|
const configPath = join77(homedir45(), ".aws", "config");
|
|
500914
501311
|
const profiles = new Map;
|
|
500915
501312
|
try {
|
|
500916
|
-
const content = await
|
|
501313
|
+
const content = await readFile25(credentialsPath, "utf-8");
|
|
500917
501314
|
parseIniFile(content, profiles, false);
|
|
500918
501315
|
} catch {}
|
|
500919
501316
|
try {
|
|
500920
|
-
const content = await
|
|
501317
|
+
const content = await readFile25(configPath, "utf-8");
|
|
500921
501318
|
parseIniFile(content, profiles, true);
|
|
500922
501319
|
} catch {}
|
|
500923
501320
|
return Array.from(profiles.values());
|
|
@@ -528291,7 +528688,7 @@ The deployment target for this project is CITATION-DOGFOOD-OK.
|
|
|
528291
528688
|
|
|
528292
528689
|
// src/mods/learning-harness.ts
|
|
528293
528690
|
import { spawn as spawn13 } from "node:child_process";
|
|
528294
|
-
import { access as access3, copyFile as copyFile2, mkdir as mkdir19, readFile as
|
|
528691
|
+
import { access as access3, copyFile as copyFile2, mkdir as mkdir19, readFile as readFile26, writeFile as writeFile20 } from "node:fs/promises";
|
|
528295
528692
|
import path42 from "node:path";
|
|
528296
528693
|
function slugify2(value) {
|
|
528297
528694
|
const slug = value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
@@ -528539,14 +528936,14 @@ async function existingPath(filePath) {
|
|
|
528539
528936
|
return await fileExists(filePath) ? filePath : undefined;
|
|
528540
528937
|
}
|
|
528541
528938
|
async function writeJsonArtifact(filePath, value) {
|
|
528542
|
-
await
|
|
528939
|
+
await writeFile20(filePath, `${JSON.stringify(value, null, 2)}
|
|
528543
528940
|
`, "utf8");
|
|
528544
528941
|
}
|
|
528545
528942
|
async function writeCommandArtifacts(prefix, command, args, result) {
|
|
528546
|
-
await
|
|
528943
|
+
await writeFile20(`${prefix}.command.txt`, `${renderCommand(command, args)}
|
|
528547
528944
|
`, "utf8");
|
|
528548
|
-
await
|
|
528549
|
-
await
|
|
528945
|
+
await writeFile20(`${prefix}.stdout`, result.stdout, "utf8");
|
|
528946
|
+
await writeFile20(`${prefix}.stderr`, result.stderr, "utf8");
|
|
528550
528947
|
await writeJsonArtifact(`${prefix}.result.json`, result);
|
|
528551
528948
|
}
|
|
528552
528949
|
async function prepareMemoryFiles(memoryDir, memoryFiles) {
|
|
@@ -528554,7 +528951,7 @@ async function prepareMemoryFiles(memoryDir, memoryFiles) {
|
|
|
528554
528951
|
for (const [relativePath, content] of Object.entries(memoryFiles ?? {})) {
|
|
528555
528952
|
const filePath = safeJoin(memoryDir, relativePath);
|
|
528556
528953
|
await mkdir19(path42.dirname(filePath), { recursive: true });
|
|
528557
|
-
await
|
|
528954
|
+
await writeFile20(filePath, content, "utf8");
|
|
528558
528955
|
}
|
|
528559
528956
|
}
|
|
528560
528957
|
function renderEvaluationPrompt(prompt, memoryDir) {
|
|
@@ -529217,7 +529614,7 @@ function renderProposerGuide(params) {
|
|
|
529217
529614
|
`;
|
|
529218
529615
|
}
|
|
529219
529616
|
async function writeHistoryArtifacts(params) {
|
|
529220
|
-
await
|
|
529617
|
+
await writeFile20(params.historyPath, renderHistoryIndex({
|
|
529221
529618
|
attempts: params.attempts,
|
|
529222
529619
|
historyManifestPath: params.historyManifestPath,
|
|
529223
529620
|
proposerGuidePath: params.proposerGuidePath,
|
|
@@ -529225,7 +529622,7 @@ async function writeHistoryArtifacts(params) {
|
|
|
529225
529622
|
spec: params.spec
|
|
529226
529623
|
}), "utf8");
|
|
529227
529624
|
await writeJsonArtifact(params.historyManifestPath, buildHistoryManifest(params));
|
|
529228
|
-
await
|
|
529625
|
+
await writeFile20(params.proposerGuidePath, renderProposerGuide(params), "utf8");
|
|
529229
529626
|
}
|
|
529230
529627
|
async function defaultCommandRunner(command, args, options3) {
|
|
529231
529628
|
const startedAt = Date.now();
|
|
@@ -529316,7 +529713,7 @@ function createScenarioSuiteEvaluator(params) {
|
|
|
529316
529713
|
outputFormat
|
|
529317
529714
|
})
|
|
529318
529715
|
];
|
|
529319
|
-
await
|
|
529716
|
+
await writeFile20(hasConfiguredScenarios ? path42.join(scenarioDir, "prompt.md") : path42.join(context4.runDir, "eval-prompt.md"), evalPrompt, "utf8");
|
|
529320
529717
|
const scenarioEvalResult = await context4.runner(context4.cliCommand, evalArgs, {
|
|
529321
529718
|
cwd: context4.repoRoot,
|
|
529322
529719
|
env: {
|
|
@@ -529508,7 +529905,7 @@ async function runModLearningCandidate(params) {
|
|
|
529508
529905
|
outputFormat: "json"
|
|
529509
529906
|
})
|
|
529510
529907
|
];
|
|
529511
|
-
await
|
|
529908
|
+
await writeFile20(path42.join(runDir, "generation-prompt.md"), generationPrompt, "utf8");
|
|
529512
529909
|
generationResult = await params.runner(params.cliCommand, generationArgs, {
|
|
529513
529910
|
cwd: repoRoot,
|
|
529514
529911
|
env: {
|
|
@@ -529587,7 +529984,7 @@ async function runModLearningCandidate(params) {
|
|
|
529587
529984
|
spec: options3.spec
|
|
529588
529985
|
};
|
|
529589
529986
|
await writeJsonArtifact(path42.join(runDir, "report.json"), report);
|
|
529590
|
-
await
|
|
529987
|
+
await writeFile20(reportPath, renderMarkdownReport(report), "utf8");
|
|
529591
529988
|
await writeCandidateManifest(report);
|
|
529592
529989
|
emitProgress("done", params.candidateCount > 1 ? `Optimization iteration ${params.candidateIndex}/${params.candidateCount} complete` : "mod optimization complete", {
|
|
529593
529990
|
attempts: [...params.previousAttempts, summarizeAttempt(report)],
|
|
@@ -529765,7 +530162,7 @@ async function runModLearning(options3) {
|
|
|
529765
530162
|
spec: normalizedOptions.spec
|
|
529766
530163
|
});
|
|
529767
530164
|
await writeJsonArtifact(path42.join(runDir, "report.json"), report);
|
|
529768
|
-
await
|
|
530165
|
+
await writeFile20(reportPath, renderMarkdownReport(report), "utf8");
|
|
529769
530166
|
normalizedOptions.onProgress?.({
|
|
529770
530167
|
candidateCount,
|
|
529771
530168
|
candidateIndex: selectedCandidateIndex,
|
|
@@ -529783,7 +530180,7 @@ async function runModLearning(options3) {
|
|
|
529783
530180
|
return report;
|
|
529784
530181
|
}
|
|
529785
530182
|
async function readModLearningEnv(envPath) {
|
|
529786
|
-
return JSON.parse(await
|
|
530183
|
+
return JSON.parse(await readFile26(envPath, "utf8"));
|
|
529787
530184
|
}
|
|
529788
530185
|
var init_learning_harness = __esm(async () => {
|
|
529789
530186
|
await init_mod_engine();
|
|
@@ -532163,7 +532560,7 @@ var exports_export = {};
|
|
|
532163
532560
|
__export(exports_export, {
|
|
532164
532561
|
packageSkills: () => packageSkills
|
|
532165
532562
|
});
|
|
532166
|
-
import { readdir as readdir17, readFile as
|
|
532563
|
+
import { readdir as readdir17, readFile as readFile27 } from "node:fs/promises";
|
|
532167
532564
|
import { relative as relative16, resolve as resolve40 } from "node:path";
|
|
532168
532565
|
async function packageSkills(agentId, skillsDir) {
|
|
532169
532566
|
const skills = [];
|
|
@@ -532184,7 +532581,7 @@ async function packageSkills(agentId, skillsDir) {
|
|
|
532184
532581
|
const skillDir = resolve40(baseDir, entry.name);
|
|
532185
532582
|
const skillMdPath = resolve40(skillDir, "SKILL.md");
|
|
532186
532583
|
try {
|
|
532187
|
-
await
|
|
532584
|
+
await readFile27(skillMdPath, "utf-8");
|
|
532188
532585
|
} catch {
|
|
532189
532586
|
console.warn(`Skipping invalid skill ${entry.name}: missing SKILL.md`);
|
|
532190
532587
|
continue;
|
|
@@ -532216,7 +532613,7 @@ async function readSkillFiles(skillDir) {
|
|
|
532216
532613
|
if (entry.isDirectory()) {
|
|
532217
532614
|
await walk(fullPath);
|
|
532218
532615
|
} else {
|
|
532219
|
-
const content = await
|
|
532616
|
+
const content = await readFile27(fullPath, "utf-8");
|
|
532220
532617
|
const relativePath = relative16(skillDir, fullPath).replace(/\\/g, "/");
|
|
532221
532618
|
files[relativePath] = content;
|
|
532222
532619
|
}
|
|
@@ -533035,7 +533432,7 @@ ${SYSTEM_REMINDER_CLOSE}`),
|
|
|
533035
533432
|
const adeUrl = buildChatUrl(agentId, {
|
|
533036
533433
|
conversationId: conversationIdRef.current
|
|
533037
533434
|
});
|
|
533038
|
-
Promise.resolve().then(() => (init_open(), exports_open)).then(({ default:
|
|
533435
|
+
Promise.resolve().then(() => (init_open(), exports_open)).then(({ default: open5 }) => open5(adeUrl, { wait: false })).catch(() => {});
|
|
533039
533436
|
cmd.finish(`Opening ADE...
|
|
533040
533437
|
→ ${adeUrl}`, true);
|
|
533041
533438
|
return { submitted: true };
|
|
@@ -538994,7 +539391,8 @@ async function ensureDefaultAgents2(backend4, options3) {
|
|
|
538994
539391
|
const createOptions = personality === "tutorial" ? {
|
|
538995
539392
|
...await buildCreateAgentOptionsForPersonality2({
|
|
538996
539393
|
personalityId: "tutorial",
|
|
538997
|
-
model
|
|
539394
|
+
model,
|
|
539395
|
+
tags: [ONBOARDING_ORIGIN_TAG]
|
|
538998
539396
|
}),
|
|
538999
539397
|
memoryPromptMode
|
|
539000
539398
|
} : {
|
|
@@ -539242,7 +539640,7 @@ __export(exports_import2, {
|
|
|
539242
539640
|
extractSkillsFromAf: () => extractSkillsFromAf2
|
|
539243
539641
|
});
|
|
539244
539642
|
import { createReadStream as createReadStream3 } from "node:fs";
|
|
539245
|
-
import { access as access4, chmod as chmod3, mkdir as mkdir20, readFile as
|
|
539643
|
+
import { access as access4, chmod as chmod3, mkdir as mkdir20, readFile as readFile28, writeFile as writeFile21 } from "node:fs/promises";
|
|
539246
539644
|
import { dirname as dirname38, isAbsolute as isAbsolute27, relative as relative17, resolve as resolve41, sep as sep8, win32 as win326 } from "node:path";
|
|
539247
539645
|
function validateImportedSkillName2(name) {
|
|
539248
539646
|
const trimmedName = name.trim();
|
|
@@ -539343,7 +539741,7 @@ async function importAgentFromFile2(options3) {
|
|
|
539343
539741
|
}
|
|
539344
539742
|
async function extractSkillsFromAf2(afPath, destDir) {
|
|
539345
539743
|
const extracted = [];
|
|
539346
|
-
const content = await
|
|
539744
|
+
const content = await readFile28(afPath, "utf-8");
|
|
539347
539745
|
const afData = JSON.parse(content);
|
|
539348
539746
|
if (!afData.skills || !Array.isArray(afData.skills)) {
|
|
539349
539747
|
return [];
|
|
@@ -539372,7 +539770,7 @@ async function writeSkillFiles2(skillDir, files) {
|
|
|
539372
539770
|
async function writeSkillFile2(skillDir, filePath, content) {
|
|
539373
539771
|
const fullPath = resolveImportedSkillFilePath2(skillDir, filePath);
|
|
539374
539772
|
await mkdir20(dirname38(fullPath), { recursive: true });
|
|
539375
|
-
await
|
|
539773
|
+
await writeFile21(fullPath, content, "utf-8");
|
|
539376
539774
|
const isScript = filePath.startsWith("scripts/") || content.trimStart().startsWith("#!");
|
|
539377
539775
|
if (isScript) {
|
|
539378
539776
|
try {
|
|
@@ -539425,7 +539823,7 @@ function parseRegistryHandle2(handle2) {
|
|
|
539425
539823
|
async function importAgentFromRegistry2(options3) {
|
|
539426
539824
|
const { tmpdir: tmpdir12 } = await import("node:os");
|
|
539427
539825
|
const { join: join84 } = await import("node:path");
|
|
539428
|
-
const { writeFile:
|
|
539826
|
+
const { writeFile: writeFile22, unlink: unlink5 } = await import("node:fs/promises");
|
|
539429
539827
|
const { author, name } = parseRegistryHandle2(options3.handle);
|
|
539430
539828
|
const rawUrl = `https://raw.githubusercontent.com/${AGENT_REGISTRY_OWNER2}/${AGENT_REGISTRY_REPO2}/refs/heads/${AGENT_REGISTRY_BRANCH2}/agents/@${author}/${name}/${name}.af`;
|
|
539431
539829
|
const response = await fetch(rawUrl);
|
|
@@ -539437,7 +539835,7 @@ async function importAgentFromRegistry2(options3) {
|
|
|
539437
539835
|
}
|
|
539438
539836
|
const afContent = await response.text();
|
|
539439
539837
|
const tempPath = join84(tmpdir12(), `letta-import-${author}-${name}-${Date.now()}.af`);
|
|
539440
|
-
await
|
|
539838
|
+
await writeFile22(tempPath, afContent, "utf-8");
|
|
539441
539839
|
try {
|
|
539442
539840
|
const result = await importAgentFromFile2({
|
|
539443
539841
|
filePath: tempPath,
|
|
@@ -544527,7 +544925,7 @@ import WebSocket7, { WebSocketServer } from "ws";
|
|
|
544527
544925
|
|
|
544528
544926
|
// src/websocket/app-server-auth.ts
|
|
544529
544927
|
import { createHash as createHash5, createHmac, timingSafeEqual } from "node:crypto";
|
|
544530
|
-
import { readFile as
|
|
544928
|
+
import { readFile as readFile12 } from "node:fs/promises";
|
|
544531
544929
|
import { isIP as isIP2 } from "node:net";
|
|
544532
544930
|
import { isAbsolute as isAbsolute22 } from "node:path";
|
|
544533
544931
|
var INVALID_AUTHORIZATION_HEADER_MESSAGE = "invalid authorization header";
|
|
@@ -544771,7 +545169,7 @@ function bearerTokenFromHeaders(headers) {
|
|
|
544771
545169
|
async function readTrimmedSecret(path31) {
|
|
544772
545170
|
let raw2;
|
|
544773
545171
|
try {
|
|
544774
|
-
raw2 = await
|
|
545172
|
+
raw2 = await readFile12(path31, "utf8");
|
|
544775
545173
|
} catch (error54) {
|
|
544776
545174
|
const message = error54 instanceof Error ? error54.message : String(error54);
|
|
544777
545175
|
throw new Error(`failed to read websocket auth secret ${path31}: ${message}`);
|
|
@@ -546624,7 +547022,7 @@ init_reflection_transcript();
|
|
|
546624
547022
|
import { createHash as createHash7 } from "node:crypto";
|
|
546625
547023
|
|
|
546626
547024
|
// src/cli/subcommands/dream-sources/openhands.ts
|
|
546627
|
-
import { readdir as readdir12, readFile as
|
|
547025
|
+
import { readdir as readdir12, readFile as readFile18, stat as stat14 } from "node:fs/promises";
|
|
546628
547026
|
import { join as join52 } from "node:path";
|
|
546629
547027
|
var RESULT_TEXT_TRUNCATE_LIMIT = 4000;
|
|
546630
547028
|
function joinTextContent(content) {
|
|
@@ -546751,7 +547149,7 @@ async function readOpenHandsEventDir(dir) {
|
|
|
546751
547149
|
}
|
|
546752
547150
|
const events = [];
|
|
546753
547151
|
for (const name of fileNames) {
|
|
546754
|
-
const raw2 = await
|
|
547152
|
+
const raw2 = await readFile18(join52(eventsDir, name), "utf-8");
|
|
546755
547153
|
const event2 = safeJsonParseOr(raw2, null);
|
|
546756
547154
|
if (event2 && typeof event2 === "object") {
|
|
546757
547155
|
events.push(event2);
|
|
@@ -546766,17 +547164,17 @@ var openHandsAdapter = {
|
|
|
546766
547164
|
if (info?.isDirectory()) {
|
|
546767
547165
|
return convertOpenHandsEvents(await readOpenHandsEventDir(locator));
|
|
546768
547166
|
}
|
|
546769
|
-
const raw2 = await
|
|
547167
|
+
const raw2 = await readFile18(locator, "utf-8");
|
|
546770
547168
|
return convertOpenHandsEvents(parseOpenHandsEventsFile(raw2, locator));
|
|
546771
547169
|
}
|
|
546772
547170
|
};
|
|
546773
547171
|
|
|
546774
547172
|
// src/cli/subcommands/dream-sources/transcript.ts
|
|
546775
|
-
import { readFile as
|
|
547173
|
+
import { readFile as readFile19 } from "node:fs/promises";
|
|
546776
547174
|
var transcriptAdapter = {
|
|
546777
547175
|
type: "transcript",
|
|
546778
547176
|
async convert(locator) {
|
|
546779
|
-
const raw2 = await
|
|
547177
|
+
const raw2 = await readFile19(locator, "utf-8");
|
|
546780
547178
|
const entries = [];
|
|
546781
547179
|
for (const line of raw2.split(`
|
|
546782
547180
|
`)) {
|
|
@@ -546828,7 +547226,7 @@ async function stageFromSource(agentId, parsed) {
|
|
|
546828
547226
|
init_memory_filesystem2();
|
|
546829
547227
|
init_memory_git();
|
|
546830
547228
|
import { execFileSync as execFileSync7 } from "node:child_process";
|
|
546831
|
-
import { mkdir as mkdir13, readFile as
|
|
547229
|
+
import { mkdir as mkdir13, readFile as readFile20, rm as rm6, writeFile as writeFile14 } from "node:fs/promises";
|
|
546832
547230
|
import { basename as basename25, dirname as dirname27, join as join53 } from "node:path";
|
|
546833
547231
|
function resolveDreamTarget(spec) {
|
|
546834
547232
|
const fileName = basename25(spec);
|
|
@@ -546904,7 +547302,7 @@ function buildTargetInstruction(target2) {
|
|
|
546904
547302
|
}
|
|
546905
547303
|
async function readExistingTarget(target2) {
|
|
546906
547304
|
try {
|
|
546907
|
-
return await
|
|
547305
|
+
return await readFile20(target2.path, "utf-8");
|
|
546908
547306
|
} catch {
|
|
546909
547307
|
return null;
|
|
546910
547308
|
}
|
|
@@ -546932,7 +547330,7 @@ async function syncTargetIntoMemory(agentId, target2, content) {
|
|
|
546932
547330
|
}
|
|
546933
547331
|
const absPath = join53(memoryDir, relPath);
|
|
546934
547332
|
await mkdir13(dirname27(absPath), { recursive: true });
|
|
546935
|
-
await
|
|
547333
|
+
await writeFile14(absPath, addManagedFrontmatter(content, target2.kind), "utf-8");
|
|
546936
547334
|
try {
|
|
546937
547335
|
const { getBackend: getBackend2 } = await Promise.resolve().then(() => (init_backend2(), exports_backend));
|
|
546938
547336
|
const syncMode = getBackend2().capabilities.localMemfs ? "local" : "remote";
|
|
@@ -546949,7 +547347,7 @@ async function syncTargetIntoMemory(agentId, target2, content) {
|
|
|
546949
547347
|
});
|
|
546950
547348
|
return { synced: result.committed };
|
|
546951
547349
|
} catch (error54) {
|
|
546952
|
-
await
|
|
547350
|
+
await rm6(absPath, { force: true });
|
|
546953
547351
|
throw error54;
|
|
546954
547352
|
}
|
|
546955
547353
|
}
|
|
@@ -546965,7 +547363,7 @@ function readTargetFromMemory(agentId, target2) {
|
|
|
546965
547363
|
}
|
|
546966
547364
|
async function writeTarget(target2, content) {
|
|
546967
547365
|
await mkdir13(dirname27(target2.path), { recursive: true });
|
|
546968
|
-
await
|
|
547366
|
+
await writeFile14(target2.path, content, "utf-8");
|
|
546969
547367
|
}
|
|
546970
547368
|
|
|
546971
547369
|
// src/cli/subcommands/dream.ts
|
|
@@ -548860,7 +549258,7 @@ async function runMemorySubcommand(argv) {
|
|
|
548860
549258
|
init_backend2();
|
|
548861
549259
|
init_message_search();
|
|
548862
549260
|
init_settings_manager();
|
|
548863
|
-
import { writeFile as
|
|
549261
|
+
import { writeFile as writeFile15 } from "node:fs/promises";
|
|
548864
549262
|
import { resolve as resolve31 } from "node:path";
|
|
548865
549263
|
import { parseArgs as parseArgs12 } from "node:util";
|
|
548866
549264
|
function printUsage9() {
|
|
@@ -549205,7 +549603,7 @@ async function runMessagesSubcommand(argv, deps = {}) {
|
|
|
549205
549603
|
`).trim();
|
|
549206
549604
|
if (outputPathRaw && typeof outputPathRaw === "string") {
|
|
549207
549605
|
const outputPath = resolve31(process.cwd(), outputPathRaw);
|
|
549208
|
-
await
|
|
549606
|
+
await writeFile15(outputPath, `${transcript}
|
|
549209
549607
|
`, "utf-8");
|
|
549210
549608
|
console.log(JSON.stringify({
|
|
549211
549609
|
conversation_id: conversationId,
|
|
@@ -554966,4 +555364,4 @@ Error during initialization: ${message}`);
|
|
|
554966
555364
|
}
|
|
554967
555365
|
main2();
|
|
554968
555366
|
|
|
554969
|
-
//# debugId=
|
|
555367
|
+
//# debugId=8DBFF6903CD7B1D064756E2164756E21
|