@agenticmail/enterprise 0.5.131 → 0.5.133

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.
@@ -0,0 +1,49 @@
1
+ import {
2
+ AgentRuntime,
3
+ EmailChannel,
4
+ FollowUpScheduler,
5
+ SessionManager,
6
+ SubAgentManager,
7
+ ToolRegistry,
8
+ callLLM,
9
+ createAgentRuntime,
10
+ createNoopHooks,
11
+ createRuntimeHooks,
12
+ estimateMessageTokens,
13
+ estimateTokens,
14
+ executeTool,
15
+ runAgentLoop,
16
+ toolsToDefinitions
17
+ } from "./chunk-NPR7DZZ6.js";
18
+ import "./chunk-TYW5XTOW.js";
19
+ import "./chunk-AQH4DFYV.js";
20
+ import {
21
+ PROVIDER_REGISTRY,
22
+ listAllProviders,
23
+ resolveApiKeyForProvider,
24
+ resolveProvider
25
+ } from "./chunk-67KZYSLU.js";
26
+ import "./chunk-JLSQOQ5L.js";
27
+ import "./chunk-NRF3YRF7.js";
28
+ import "./chunk-KFQGP6VL.js";
29
+ export {
30
+ AgentRuntime,
31
+ EmailChannel,
32
+ FollowUpScheduler,
33
+ PROVIDER_REGISTRY,
34
+ SessionManager,
35
+ SubAgentManager,
36
+ ToolRegistry,
37
+ callLLM,
38
+ createAgentRuntime,
39
+ createNoopHooks,
40
+ createRuntimeHooks,
41
+ estimateMessageTokens,
42
+ estimateTokens,
43
+ executeTool,
44
+ listAllProviders,
45
+ resolveApiKeyForProvider,
46
+ resolveProvider,
47
+ runAgentLoop,
48
+ toolsToDefinitions
49
+ };
@@ -0,0 +1,49 @@
1
+ import {
2
+ AgentRuntime,
3
+ EmailChannel,
4
+ FollowUpScheduler,
5
+ SessionManager,
6
+ SubAgentManager,
7
+ ToolRegistry,
8
+ callLLM,
9
+ createAgentRuntime,
10
+ createNoopHooks,
11
+ createRuntimeHooks,
12
+ estimateMessageTokens,
13
+ estimateTokens,
14
+ executeTool,
15
+ runAgentLoop,
16
+ toolsToDefinitions
17
+ } from "./chunk-5ZWCRPH2.js";
18
+ import "./chunk-TYW5XTOW.js";
19
+ import "./chunk-AQH4DFYV.js";
20
+ import {
21
+ PROVIDER_REGISTRY,
22
+ listAllProviders,
23
+ resolveApiKeyForProvider,
24
+ resolveProvider
25
+ } from "./chunk-67KZYSLU.js";
26
+ import "./chunk-JLSQOQ5L.js";
27
+ import "./chunk-NRF3YRF7.js";
28
+ import "./chunk-KFQGP6VL.js";
29
+ export {
30
+ AgentRuntime,
31
+ EmailChannel,
32
+ FollowUpScheduler,
33
+ PROVIDER_REGISTRY,
34
+ SessionManager,
35
+ SubAgentManager,
36
+ ToolRegistry,
37
+ callLLM,
38
+ createAgentRuntime,
39
+ createNoopHooks,
40
+ createRuntimeHooks,
41
+ estimateMessageTokens,
42
+ estimateTokens,
43
+ executeTool,
44
+ listAllProviders,
45
+ resolveApiKeyForProvider,
46
+ resolveProvider,
47
+ runAgentLoop,
48
+ toolsToDefinitions
49
+ };
@@ -0,0 +1,12 @@
1
+ import {
2
+ createServer
3
+ } from "./chunk-G2Q7KYR5.js";
4
+ import "./chunk-3SMTCIR4.js";
5
+ import "./chunk-RO537U6H.js";
6
+ import "./chunk-DRXMYYKN.js";
7
+ import "./chunk-67KZYSLU.js";
8
+ import "./chunk-JLSQOQ5L.js";
9
+ import "./chunk-KFQGP6VL.js";
10
+ export {
11
+ createServer
12
+ };
@@ -0,0 +1,12 @@
1
+ import {
2
+ createServer
3
+ } from "./chunk-USHML5Q2.js";
4
+ import "./chunk-3SMTCIR4.js";
5
+ import "./chunk-RO537U6H.js";
6
+ import "./chunk-DRXMYYKN.js";
7
+ import "./chunk-67KZYSLU.js";
8
+ import "./chunk-JLSQOQ5L.js";
9
+ import "./chunk-KFQGP6VL.js";
10
+ export {
11
+ createServer
12
+ };
@@ -0,0 +1,20 @@
1
+ import {
2
+ promptCompanyInfo,
3
+ promptDatabase,
4
+ promptDeployment,
5
+ promptDomain,
6
+ promptRegistration,
7
+ provision,
8
+ runSetupWizard
9
+ } from "./chunk-AOIFD23N.js";
10
+ import "./chunk-MHIFVS5L.js";
11
+ import "./chunk-KFQGP6VL.js";
12
+ export {
13
+ promptCompanyInfo,
14
+ promptDatabase,
15
+ promptDeployment,
16
+ promptDomain,
17
+ promptRegistration,
18
+ provision,
19
+ runSetupWizard
20
+ };
@@ -0,0 +1,20 @@
1
+ import {
2
+ promptCompanyInfo,
3
+ promptDatabase,
4
+ promptDeployment,
5
+ promptDomain,
6
+ promptRegistration,
7
+ provision,
8
+ runSetupWizard
9
+ } from "./chunk-KQ6XQFEO.js";
10
+ import "./chunk-MHIFVS5L.js";
11
+ import "./chunk-KFQGP6VL.js";
12
+ export {
13
+ promptCompanyInfo,
14
+ promptDatabase,
15
+ promptDeployment,
16
+ promptDomain,
17
+ promptRegistration,
18
+ provision,
19
+ runSetupWizard
20
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticmail/enterprise",
3
- "version": "0.5.131",
3
+ "version": "0.5.133",
4
4
  "description": "AgenticMail Enterprise — cloud-hosted AI agent identity, email, auth & compliance for organizations",
5
5
  "type": "module",
6
6
  "bin": {
@@ -351,12 +351,13 @@ export function createGmailTools(config: GoogleToolsConfig, _options?: ToolCreat
351
351
  const token = await tp.getAccessToken();
352
352
  const email = tp.getEmail();
353
353
 
354
- // Fetch original message for threading
355
- const original = await gmail(token, `/messages/${params.messageId}`, { query: { format: 'metadata', metadataHeaders: 'From,To,Cc,Subject,Message-ID,References' } });
354
+ // Fetch original message for threading (use full format to ensure headers are present)
355
+ const original = await gmail(token, `/messages/${params.messageId}`, { query: { format: 'full' } });
356
356
  const oh = extractHeaders(original.payload?.headers || [], ['From', 'To', 'Cc', 'Subject', 'Message-ID', 'References']);
357
357
 
358
358
  // Extract clean email from From header (handles "Name <email>" format)
359
- const extractEmail = (h: string) => {
359
+ const extractEmail = (h: string | undefined) => {
360
+ if (!h) return '';
360
361
  const m = h.match(/<([^>]+)>/);
361
362
  return m ? m[1] : h.trim();
362
363
  };
package/src/cli-agent.ts CHANGED
@@ -95,9 +95,10 @@ export async function runAgent(_args: string[]) {
95
95
  let memoryManager: any;
96
96
  try {
97
97
  const { AgentMemoryManager } = await import('./engine/agent-memory.js');
98
- memoryManager = new AgentMemoryManager(engineDb);
98
+ memoryManager = new AgentMemoryManager();
99
+ await memoryManager.setDb(engineDb);
99
100
  console.log(' Memory: DB-backed');
100
- } catch { console.log(' Memory: file-based fallback'); }
101
+ } catch (memErr: any) { console.log(` Memory: failed (${memErr.message})`); }
101
102
 
102
103
  // 6. Load provider API keys from DB settings
103
104
  try {
@@ -351,24 +352,21 @@ export async function runAgent(_args: string[]) {
351
352
  const identity = config.identity || {};
352
353
  const agentEmailAddr = config.email?.address || emailConfig?.email || '';
353
354
 
354
- // Check if welcome email was already sent (only send once)
355
+ // Check if welcome email was already sent (only send once) — use DB directly for reliability
355
356
  let alreadySent = false;
356
- if (memoryManager) {
357
+ try {
358
+ const sentCheck = await engineDb.query(
359
+ `SELECT id FROM agent_memory WHERE agent_id = $1 AND content LIKE '%welcome_email_sent%' LIMIT 1`,
360
+ [AGENT_ID]
361
+ );
362
+ alreadySent = (sentCheck && sentCheck.length > 0);
363
+ } catch {}
364
+ if (!alreadySent && memoryManager) {
357
365
  try {
358
- const memories = await memoryManager.recall(AGENT_ID, 'welcome email sent to manager', 5);
366
+ const memories = await memoryManager.recall(AGENT_ID, 'welcome_email_sent', 3);
359
367
  alreadySent = memories.some((m: any) => m.content?.includes('welcome_email_sent'));
360
368
  } catch {}
361
369
  }
362
- if (!alreadySent) {
363
- try {
364
- // Also check DB directly as fallback
365
- const sentCheck = await engineDb.query(
366
- `SELECT id FROM agent_memory WHERE agent_id = $1 AND content LIKE '%welcome_email_sent%' LIMIT 1`,
367
- [AGENT_ID]
368
- );
369
- alreadySent = sentCheck.rows.length > 0;
370
- } catch {}
371
- }
372
370
 
373
371
  if (alreadySent) {
374
372
  console.log('[welcome] Welcome email already sent, skipping');
@@ -547,9 +545,19 @@ async function startEmailPolling(
547
545
 
548
546
  console.log('[email-poll] ✅ Email provider connected, starting inbox polling (every 30s)');
549
547
 
550
- // Track processed message IDs to avoid duplicates
548
+ // Track processed message IDs to avoid duplicates — persist to DB so they survive restarts
551
549
  const processedIds = new Set<string>();
552
550
 
551
+ // Load previously processed IDs from DB
552
+ try {
553
+ const prev = await engineDb.query(
554
+ `SELECT content FROM agent_memory WHERE agent_id = $1 AND category = 'processed_email'`,
555
+ [agentId]
556
+ );
557
+ if (prev) for (const row of prev) processedIds.add((row as any).content);
558
+ if (processedIds.size > 0) console.log(`[email-poll] Restored ${processedIds.size} processed email IDs from DB`);
559
+ } catch {}
560
+
553
561
  // Initial load — mark existing messages as processed so we don't reply to old emails
554
562
  try {
555
563
  const existing = await emailProvider.listMessages('INBOX', { limit: 50 });
@@ -581,6 +589,14 @@ async function startEmailPolling(
581
589
 
582
590
  console.log(`[email-poll] New email from ${envelope.from?.email}: "${envelope.subject}"`);
583
591
 
592
+ // Persist processed ID to DB so it survives restarts
593
+ try {
594
+ await engineDb.execute(
595
+ `INSERT INTO agent_memory (id, agent_id, org_id, category, content, importance, confidence, access_count, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)`,
596
+ [crypto.randomUUID(), agentId, orgId, 'processed_email', envelope.uid, 'low', 1.0, 0, new Date().toISOString(), new Date().toISOString()]
597
+ );
598
+ } catch {}
599
+
584
600
  // Read full message
585
601
  const fullMsg = await emailProvider.readMessage(envelope.uid, 'INBOX');
586
602
 
@@ -665,13 +681,15 @@ IMPORTANT: Use gmail_reply, NOT gmail_send. gmail_send creates a new email threa
665
681
  Be helpful, professional, and match the tone of the sender.
666
682
  Keep responses concise but thorough. Sign off with your name: ${agentName}
667
683
 
668
- FORMATTING RULES:
669
- - NEVER use "--" or "---" or em dashes (—) in your emails
670
- - NEVER use markdown formatting (no **, no ##, no bullet points with -)
671
- - Write natural, flowing prose like a real human email
684
+ FORMATTING RULES (STRICTLY ENFORCED):
685
+ - ABSOLUTELY NEVER use "--", "---", "—", or any dash separator lines in emails
686
+ - NEVER use markdown: no **, no ##, no bullet points starting with - or *
687
+ - NEVER use horizontal rules or separators of any kind
688
+ - Write natural, flowing prose paragraphs like a real human email
689
+ - Use line breaks between paragraphs, nothing else for formatting
672
690
  - Keep it warm and conversational, not robotic or formatted
673
691
 
674
- DO NOT just generate text you MUST call gmail_reply to actually send the reply.`;
692
+ CRITICAL: You MUST call gmail_reply EXACTLY ONCE to send your reply. Do NOT call it multiple times. Do NOT just generate text without calling the tool.`;
675
693
 
676
694
  const session = await runtime.spawnSession({
677
695
  agentId,
@@ -191,6 +191,42 @@ export class AgentMemoryManager {
191
191
  return result;
192
192
  }
193
193
 
194
+ // ─── Convenience Methods ─────────────────────────────
195
+
196
+ /**
197
+ * Convenience method for storing a memory with minimal input.
198
+ * Handles the common case where you just want to store a piece of text.
199
+ */
200
+ async storeMemory(agentId: string, opts: {
201
+ content: string;
202
+ category?: string;
203
+ importance?: string;
204
+ confidence?: number;
205
+ title?: string;
206
+ orgId?: string;
207
+ }): Promise<AgentMemoryEntry> {
208
+ return this.createMemory({
209
+ agentId,
210
+ orgId: opts.orgId || 'default',
211
+ content: opts.content,
212
+ category: (opts.category || 'general') as any,
213
+ importance: (opts.importance || 'normal') as any,
214
+ confidence: opts.confidence ?? 1.0,
215
+ title: opts.title || '',
216
+ source: 'system',
217
+ tags: [],
218
+ metadata: {},
219
+ });
220
+ }
221
+
222
+ /**
223
+ * Convenience method for searching memories by text query.
224
+ * Returns matching entries sorted by relevance.
225
+ */
226
+ async recall(agentId: string, query: string, limit: number = 5): Promise<AgentMemoryEntry[]> {
227
+ return this.queryMemories({ agentId, query, limit });
228
+ }
229
+
194
230
  // ─── CRUD Operations ────────────────────────────────
195
231
 
196
232
  /**