@agenticmail/enterprise 0.5.153 → 0.5.155
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/agenticmail-EDO5XOTP.js +19 -0
- package/dist/chunk-HKCKMCPY.js +1134 -0
- package/dist/cli-agent-6DJML73P.js +840 -0
- package/dist/cli-agent-VNXOYV4K.js +867 -0
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/agenticmail/providers/google.ts +6 -2
- package/src/cli-agent.ts +62 -23
package/dist/cli.js
CHANGED
|
@@ -50,7 +50,7 @@ Skill Development:
|
|
|
50
50
|
import("./cli-serve-DHVSPFW5.js").then((m) => m.runServe(args.slice(1))).catch(fatal);
|
|
51
51
|
break;
|
|
52
52
|
case "agent":
|
|
53
|
-
import("./cli-agent-
|
|
53
|
+
import("./cli-agent-VNXOYV4K.js").then((m) => m.runAgent(args.slice(1))).catch(fatal);
|
|
54
54
|
break;
|
|
55
55
|
case "setup":
|
|
56
56
|
default:
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -50,10 +50,14 @@ export class GoogleEmailProvider implements IEmailProvider {
|
|
|
50
50
|
|
|
51
51
|
// ─── Connection ─────────────────────────────────────
|
|
52
52
|
|
|
53
|
+
/** Last known historyId — used for efficient polling via history.list */
|
|
54
|
+
public lastHistoryId: string = '';
|
|
55
|
+
|
|
53
56
|
async connect(identity: AgentEmailIdentity): Promise<void> {
|
|
54
57
|
this.identity = identity;
|
|
55
|
-
// Validate token
|
|
56
|
-
await this.gmailFetch('/profile');
|
|
58
|
+
// Validate token and capture historyId
|
|
59
|
+
const profile = await this.gmailFetch('/profile');
|
|
60
|
+
this.lastHistoryId = profile.historyId || '';
|
|
57
61
|
}
|
|
58
62
|
|
|
59
63
|
async disconnect(): Promise<void> {
|
package/src/cli-agent.ts
CHANGED
|
@@ -577,13 +577,19 @@ async function startEmailPolling(
|
|
|
577
577
|
} catch {}
|
|
578
578
|
|
|
579
579
|
// Initial load — mark existing messages as processed so we don't reply to old emails
|
|
580
|
+
// Also capture historyId for Gmail History API polling
|
|
581
|
+
let lastHistoryId = '';
|
|
580
582
|
try {
|
|
581
583
|
console.log('[email-poll] Loading existing messages...');
|
|
582
584
|
const existing = await emailProvider.listMessages('INBOX', { limit: 50 });
|
|
583
585
|
for (const msg of existing) {
|
|
584
586
|
processedIds.add(msg.uid);
|
|
585
587
|
}
|
|
586
|
-
|
|
588
|
+
// Get historyId from Google provider if available
|
|
589
|
+
if ('lastHistoryId' in emailProvider) {
|
|
590
|
+
lastHistoryId = (emailProvider as any).lastHistoryId || '';
|
|
591
|
+
}
|
|
592
|
+
console.log(`[email-poll] Loaded ${processedIds.size} existing messages (will skip)${lastHistoryId ? `, historyId: ${lastHistoryId}` : ''}`);
|
|
587
593
|
} catch (e: any) {
|
|
588
594
|
console.error(`[email-poll] Failed to load existing messages: ${e.message}`);
|
|
589
595
|
}
|
|
@@ -593,31 +599,67 @@ async function startEmailPolling(
|
|
|
593
599
|
// Poll loop
|
|
594
600
|
const POLL_INTERVAL = 30_000; // 30 seconds
|
|
595
601
|
const agentEmail = (emailConfig.email || config.email?.address || '').toLowerCase();
|
|
602
|
+
const useHistoryApi = 'getHistory' in emailProvider && !!lastHistoryId;
|
|
603
|
+
if (useHistoryApi) console.log('[email-poll] Using Gmail History API for reliable change detection');
|
|
596
604
|
|
|
597
605
|
async function pollOnce() {
|
|
598
606
|
try {
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
607
|
+
let newMessageIds: string[] = [];
|
|
608
|
+
|
|
609
|
+
if (useHistoryApi && lastHistoryId) {
|
|
610
|
+
// Use Gmail History API — most reliable for detecting new messages
|
|
611
|
+
try {
|
|
612
|
+
const history = await (emailProvider as any).getHistory(lastHistoryId);
|
|
613
|
+
if (history.historyId) lastHistoryId = history.historyId;
|
|
614
|
+
// Filter to only messages we haven't processed
|
|
615
|
+
newMessageIds = history.messages
|
|
616
|
+
.map((m: any) => m.id)
|
|
617
|
+
.filter((id: string) => !processedIds.has(id));
|
|
618
|
+
if (newMessageIds.length > 0) {
|
|
619
|
+
console.log(`[email-poll] History API: ${newMessageIds.length} new messages since historyId ${lastHistoryId}`);
|
|
620
|
+
}
|
|
621
|
+
} catch (histErr: any) {
|
|
622
|
+
// historyId might be too old (404), fall back to list
|
|
623
|
+
console.warn(`[email-poll] History API failed (${histErr.message?.slice(0, 60)}), falling back to list`);
|
|
624
|
+
const msgs = await emailProvider.listMessages('INBOX', { limit: 50 });
|
|
625
|
+
newMessageIds = msgs.filter(m => !processedIds.has(m.uid)).map(m => m.uid);
|
|
626
|
+
// Update historyId from provider
|
|
627
|
+
if ('lastHistoryId' in emailProvider) lastHistoryId = (emailProvider as any).lastHistoryId || lastHistoryId;
|
|
628
|
+
}
|
|
629
|
+
} else {
|
|
630
|
+
// Fallback: list + search combo
|
|
631
|
+
const today = new Date().toISOString().split('T')[0];
|
|
632
|
+
const recentSearch = await emailProvider.searchMessages({ since: today }).catch(() => [] as any[]);
|
|
633
|
+
const inboxList = await emailProvider.listMessages('INBOX', { limit: 50 });
|
|
634
|
+
const seenUids = new Set<string>();
|
|
635
|
+
const combined: string[] = [];
|
|
636
|
+
for (const m of [...(recentSearch || []), ...inboxList]) {
|
|
637
|
+
if (!seenUids.has(m.uid) && !processedIds.has(m.uid)) { seenUids.add(m.uid); combined.push(m.uid); }
|
|
638
|
+
}
|
|
639
|
+
newMessageIds = combined;
|
|
608
640
|
}
|
|
609
|
-
|
|
610
|
-
if (
|
|
611
|
-
console.log(`[email-poll]
|
|
612
|
-
} else if (msgs.length < processedIds.size) {
|
|
613
|
-
console.log(`[email-poll] No new (${msgs.length} fetched < ${processedIds.size} known — possible API gap)`);
|
|
641
|
+
|
|
642
|
+
if (newMessageIds.length > 0) {
|
|
643
|
+
console.log(`[email-poll] Processing ${newMessageIds.length} new messages`);
|
|
614
644
|
}
|
|
615
645
|
|
|
616
|
-
for (const
|
|
617
|
-
processedIds.add(
|
|
646
|
+
for (const msgId of newMessageIds) {
|
|
647
|
+
processedIds.add(msgId);
|
|
648
|
+
|
|
649
|
+
// Read full message
|
|
650
|
+
let fullMsg: any;
|
|
651
|
+
try {
|
|
652
|
+
fullMsg = await emailProvider.readMessage(msgId, 'INBOX');
|
|
653
|
+
} catch (readErr: any) {
|
|
654
|
+
console.warn(`[email-poll] Failed to read message ${msgId}: ${readErr.message?.slice(0, 80)}`);
|
|
655
|
+
continue;
|
|
656
|
+
}
|
|
657
|
+
const envelope = { uid: msgId, from: fullMsg.from, to: fullMsg.to, subject: fullMsg.subject, date: fullMsg.date };
|
|
618
658
|
|
|
619
659
|
// Skip emails from ourselves
|
|
620
|
-
if (envelope.from?.email?.toLowerCase() === agentEmail)
|
|
660
|
+
if (envelope.from?.email?.toLowerCase() === agentEmail) {
|
|
661
|
+
continue;
|
|
662
|
+
}
|
|
621
663
|
|
|
622
664
|
console.log(`[email-poll] New email from ${envelope.from?.email}: "${envelope.subject}"`);
|
|
623
665
|
|
|
@@ -632,14 +674,11 @@ async function startEmailPolling(
|
|
|
632
674
|
console.warn(`[email-poll] Failed to persist processed ID: ${peErr.message}`);
|
|
633
675
|
}
|
|
634
676
|
|
|
635
|
-
// Read full message
|
|
636
|
-
const fullMsg = await emailProvider.readMessage(envelope.uid, 'INBOX');
|
|
637
|
-
|
|
638
677
|
// Mark as read
|
|
639
|
-
try { await emailProvider.markRead(
|
|
678
|
+
try { await emailProvider.markRead(msgId, 'INBOX'); } catch {}
|
|
640
679
|
|
|
641
680
|
// Format as agent message and spawn a session
|
|
642
|
-
const emailUid =
|
|
681
|
+
const emailUid = msgId;
|
|
643
682
|
const emailText = [
|
|
644
683
|
`[Inbound Email]`,
|
|
645
684
|
`Message-ID: ${emailUid}`,
|