@agenticmail/api 0.5.61 → 0.5.62

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.
Files changed (2) hide show
  1. package/dist/index.js +49 -15
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1539,30 +1539,64 @@ async function closeCaches() {
1539
1539
  }
1540
1540
  receiverCache.clear();
1541
1541
  }
1542
- async function findUidByMessageId(receiver, messageId, maxAttempts = 5) {
1542
+ async function findUidByMessageId(receiver, messageId, maxAttempts = 8) {
1543
+ const target = normalizeMessageId(messageId);
1543
1544
  const client = receiver.getImapClient();
1544
- for (let i = 0; i < maxAttempts; i++) {
1545
+ const tryHeaderSearch = async () => {
1546
+ const lock = await client.getMailboxLock("INBOX");
1545
1547
  try {
1546
- const lock = await client.getMailboxLock("INBOX");
1547
- try {
1548
- const results = await client.search(
1549
- { header: ["Message-ID", messageId] },
1550
- { uid: true }
1551
- );
1552
- if (Array.isArray(results) && results.length > 0) {
1553
- return results[results.length - 1];
1548
+ const results = await client.search(
1549
+ { header: ["Message-ID", messageId] },
1550
+ { uid: true }
1551
+ );
1552
+ if (Array.isArray(results) && results.length > 0) {
1553
+ return results[results.length - 1];
1554
+ }
1555
+ } finally {
1556
+ lock.release();
1557
+ }
1558
+ return 0;
1559
+ };
1560
+ const tryEnvelopeScan = async () => {
1561
+ const lock = await client.getMailboxLock("INBOX");
1562
+ try {
1563
+ const status = await client.status("INBOX", { messages: true });
1564
+ const total = status?.messages ?? 0;
1565
+ if (total === 0) return 0;
1566
+ const start = Math.max(1, total - 9);
1567
+ const range = `${start}:${total}`;
1568
+ let bestUid = 0;
1569
+ for await (const msg of client.fetch(range, { uid: true, envelope: true })) {
1570
+ if (!msg.envelope?.messageId) continue;
1571
+ if (normalizeMessageId(msg.envelope.messageId) === target) {
1572
+ if (msg.uid > bestUid) bestUid = msg.uid;
1554
1573
  }
1555
- } finally {
1556
- lock.release();
1557
1574
  }
1558
- } catch {
1575
+ return bestUid;
1576
+ } finally {
1577
+ lock.release();
1559
1578
  }
1560
- if (i < maxAttempts - 1) {
1561
- await new Promise((r) => setTimeout(r, 200 * (i + 1)));
1579
+ };
1580
+ const delays = [0, 250, 500, 750, 1e3, 1250, 1500, 2e3];
1581
+ for (let i = 0; i < maxAttempts; i++) {
1582
+ if (delays[i]) await new Promise((r) => setTimeout(r, delays[i]));
1583
+ try {
1584
+ const headerHit = await tryHeaderSearch();
1585
+ if (headerHit > 0) return headerHit;
1586
+ const scanHit = await tryEnvelopeScan();
1587
+ if (scanHit > 0) return scanHit;
1588
+ } catch (err) {
1589
+ if (i === maxAttempts - 1) {
1590
+ console.warn(`[mail] findUidByMessageId attempt ${i + 1} failed for ${messageId}: ${err.message}`);
1591
+ }
1562
1592
  }
1563
1593
  }
1564
1594
  return 0;
1565
1595
  }
1596
+ function normalizeMessageId(id) {
1597
+ if (!id) return "";
1598
+ return id.trim().replace(/^<+|>+$/g, "").toLowerCase();
1599
+ }
1566
1600
  async function notifyLocalRecipientsOfNewMail(accountManager, toField, ccField, bccField, fromAgent, subject, messageId, config) {
1567
1601
  const collected = [];
1568
1602
  const push = (v) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticmail/api",
3
- "version": "0.5.61",
3
+ "version": "0.5.62",
4
4
  "description": "REST API server for AgenticMail — email and SMS endpoints for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",