@agenticmail/enterprise 0.5.113 → 0.5.115
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/chunk-DV7TLFRE.js +16106 -0
- package/dist/chunk-FUAX3VFP.js +1880 -0
- package/dist/chunk-KYOAISVB.js +898 -0
- package/dist/chunk-O32G2OYT.js +2194 -0
- package/dist/cli-agent-C7AENG3T.js +469 -0
- package/dist/cli-agent-GKRF7X2S.js +336 -0
- package/dist/cli-serve-QZA3G4VA.js +34 -0
- package/dist/cli.js +3 -3
- package/dist/index.js +4 -4
- package/dist/lifecycle-IFPWWGQ3.js +10 -0
- package/dist/routes-T4KALX5K.js +6958 -0
- package/dist/runtime-GB7V3PPC.js +49 -0
- package/dist/server-AA5AUIZJ.js +12 -0
- package/dist/setup-JI3PB5CE.js +20 -0
- package/package.json +1 -1
- package/src/cli-agent.ts +171 -0
- package/src/engine/deployer.ts +1 -1
|
@@ -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-DV7TLFRE.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-O32G2OYT.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-KYOAISVB.js";
|
|
10
|
+
import "./chunk-QDXUZP7Y.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
package/src/cli-agent.ts
CHANGED
|
@@ -390,5 +390,176 @@ ${agentName}`;
|
|
|
390
390
|
} catch (err: any) {
|
|
391
391
|
console.error(`[onboarding] Error: ${err.message}`);
|
|
392
392
|
}
|
|
393
|
+
|
|
394
|
+
// 12. Start email inbox polling loop
|
|
395
|
+
startEmailPolling(AGENT_ID, config, lifecycle, runtime, engineDb, memoryManager);
|
|
393
396
|
}, 3000);
|
|
394
397
|
}
|
|
398
|
+
|
|
399
|
+
// ─── Email Polling Loop ─────────────────────────────────────
|
|
400
|
+
|
|
401
|
+
async function startEmailPolling(
|
|
402
|
+
agentId: string, config: any, lifecycle: any, runtime: any,
|
|
403
|
+
engineDb: any, memoryManager: any
|
|
404
|
+
) {
|
|
405
|
+
const emailConfig = config.emailConfig;
|
|
406
|
+
if (!emailConfig) {
|
|
407
|
+
console.log('[email-poll] No email config, inbox polling disabled');
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
const providerType = emailConfig.provider || (emailConfig.oauthProvider === 'google' ? 'google' : emailConfig.oauthProvider === 'microsoft' ? 'microsoft' : 'imap');
|
|
412
|
+
|
|
413
|
+
// Build token refresh function
|
|
414
|
+
const refreshTokenFn = emailConfig.oauthRefreshToken ? async () => {
|
|
415
|
+
const tokenUrl = providerType === 'google'
|
|
416
|
+
? 'https://oauth2.googleapis.com/token'
|
|
417
|
+
: 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
|
|
418
|
+
const res = await fetch(tokenUrl, {
|
|
419
|
+
method: 'POST',
|
|
420
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
421
|
+
body: new URLSearchParams({
|
|
422
|
+
client_id: emailConfig.oauthClientId,
|
|
423
|
+
client_secret: emailConfig.oauthClientSecret,
|
|
424
|
+
refresh_token: emailConfig.oauthRefreshToken,
|
|
425
|
+
grant_type: 'refresh_token',
|
|
426
|
+
}),
|
|
427
|
+
});
|
|
428
|
+
const data = await res.json() as any;
|
|
429
|
+
if (data.access_token) {
|
|
430
|
+
emailConfig.oauthAccessToken = data.access_token;
|
|
431
|
+
if (data.expires_in) emailConfig.oauthTokenExpiry = new Date(Date.now() + data.expires_in * 1000).toISOString();
|
|
432
|
+
lifecycle.saveAgent(agentId).catch(() => {});
|
|
433
|
+
return data.access_token;
|
|
434
|
+
}
|
|
435
|
+
throw new Error(`Token refresh failed: ${JSON.stringify(data)}`);
|
|
436
|
+
} : undefined;
|
|
437
|
+
|
|
438
|
+
// Create and connect email provider
|
|
439
|
+
const { createEmailProvider } = await import('./agenticmail/index.js');
|
|
440
|
+
const emailProvider = createEmailProvider(providerType);
|
|
441
|
+
|
|
442
|
+
// Get fresh token
|
|
443
|
+
let accessToken = emailConfig.oauthAccessToken;
|
|
444
|
+
if (refreshTokenFn) {
|
|
445
|
+
try { accessToken = await refreshTokenFn(); } catch (e: any) { console.error(`[email-poll] Token refresh failed: ${e.message}`); }
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
const orgRows = await engineDb.query<any>(`SELECT org_id FROM managed_agents WHERE id = $1`, [agentId]);
|
|
449
|
+
const orgId = orgRows?.[0]?.org_id || '';
|
|
450
|
+
|
|
451
|
+
await emailProvider.connect({
|
|
452
|
+
agentId,
|
|
453
|
+
name: config.displayName || config.name,
|
|
454
|
+
email: emailConfig.email || config.email?.address || '',
|
|
455
|
+
orgId,
|
|
456
|
+
accessToken,
|
|
457
|
+
refreshToken: refreshTokenFn,
|
|
458
|
+
provider: providerType,
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
console.log('[email-poll] ✅ Email provider connected, starting inbox polling (every 30s)');
|
|
462
|
+
|
|
463
|
+
// Track processed message IDs to avoid duplicates
|
|
464
|
+
const processedIds = new Set<string>();
|
|
465
|
+
|
|
466
|
+
// Initial load — mark existing messages as processed so we don't reply to old emails
|
|
467
|
+
try {
|
|
468
|
+
const existing = await emailProvider.listMessages('INBOX', { limit: 50 });
|
|
469
|
+
for (const msg of existing) {
|
|
470
|
+
processedIds.add(msg.uid);
|
|
471
|
+
}
|
|
472
|
+
console.log(`[email-poll] Loaded ${processedIds.size} existing messages (will skip)`);
|
|
473
|
+
} catch (e: any) {
|
|
474
|
+
console.error(`[email-poll] Failed to load existing messages: ${e.message}`);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// Poll loop
|
|
478
|
+
const POLL_INTERVAL = 30_000; // 30 seconds
|
|
479
|
+
const agentEmail = (emailConfig.email || config.email?.address || '').toLowerCase();
|
|
480
|
+
|
|
481
|
+
async function pollOnce() {
|
|
482
|
+
try {
|
|
483
|
+
const messages = await emailProvider.listMessages('INBOX', { limit: 20 });
|
|
484
|
+
const unread = messages.filter(m => !m.flags?.includes('\\Seen') && !processedIds.has(m.uid));
|
|
485
|
+
|
|
486
|
+
for (const envelope of unread) {
|
|
487
|
+
processedIds.add(envelope.uid);
|
|
488
|
+
|
|
489
|
+
// Skip emails from ourselves
|
|
490
|
+
if (envelope.from?.email?.toLowerCase() === agentEmail) continue;
|
|
491
|
+
|
|
492
|
+
console.log(`[email-poll] New email from ${envelope.from?.email}: "${envelope.subject}"`);
|
|
493
|
+
|
|
494
|
+
// Read full message
|
|
495
|
+
const fullMsg = await emailProvider.readMessage(envelope.uid, 'INBOX');
|
|
496
|
+
|
|
497
|
+
// Mark as read
|
|
498
|
+
try { await emailProvider.markRead(envelope.uid, 'INBOX'); } catch {}
|
|
499
|
+
|
|
500
|
+
// Format as agent message and spawn a session
|
|
501
|
+
const emailText = [
|
|
502
|
+
`[Inbound Email]`,
|
|
503
|
+
`From: ${fullMsg.from?.name ? `${fullMsg.from.name} <${fullMsg.from.email}>` : fullMsg.from?.email}`,
|
|
504
|
+
`Subject: ${fullMsg.subject}`,
|
|
505
|
+
fullMsg.inReplyTo ? `In-Reply-To: ${fullMsg.inReplyTo}` : '',
|
|
506
|
+
'',
|
|
507
|
+
fullMsg.text || fullMsg.html || '(empty body)',
|
|
508
|
+
].filter(Boolean).join('\n');
|
|
509
|
+
|
|
510
|
+
// Create agent session to handle this email
|
|
511
|
+
try {
|
|
512
|
+
const agentName = config.displayName || config.name;
|
|
513
|
+
const role = config.identity?.role || 'AI Agent';
|
|
514
|
+
const senderName = fullMsg.from?.name || fullMsg.from?.email || 'someone';
|
|
515
|
+
const senderEmail = fullMsg.from?.email || '';
|
|
516
|
+
|
|
517
|
+
// System prompt tells the agent to reply via email
|
|
518
|
+
const emailSystemPrompt = `You are ${agentName}, a ${role}. You just received an email and need to respond to it.
|
|
519
|
+
|
|
520
|
+
Your email address: ${agentEmail}
|
|
521
|
+
Sender: ${senderName} <${senderEmail}>
|
|
522
|
+
Subject: ${fullMsg.subject}
|
|
523
|
+
|
|
524
|
+
IMPORTANT: After composing your response, you MUST reply using the email_reply tool or email_send tool. Do NOT just generate text — actually send the email reply.
|
|
525
|
+
If you have an email_reply tool, use it with the message UID. If not, use email_send to send to ${senderEmail} with subject "Re: ${fullMsg.subject}".
|
|
526
|
+
|
|
527
|
+
Be helpful, professional, and concise. Follow all organization policies you've been onboarded with.`;
|
|
528
|
+
|
|
529
|
+
const session = await runtime.spawnSession({
|
|
530
|
+
agentId,
|
|
531
|
+
message: emailText,
|
|
532
|
+
systemPrompt: emailSystemPrompt,
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
console.log(`[email-poll] Session ${session.id} created for email from ${senderEmail}`);
|
|
536
|
+
} catch (sessErr: any) {
|
|
537
|
+
console.error(`[email-poll] Failed to create session: ${sessErr.message}`);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
} catch (err: any) {
|
|
541
|
+
console.error(`[email-poll] Poll error: ${err.message}`);
|
|
542
|
+
// If token expired, try to refresh
|
|
543
|
+
if (err.message.includes('401') && refreshTokenFn) {
|
|
544
|
+
try {
|
|
545
|
+
const newToken = await refreshTokenFn();
|
|
546
|
+
await emailProvider.connect({
|
|
547
|
+
agentId,
|
|
548
|
+
name: config.displayName || config.name,
|
|
549
|
+
email: emailConfig.email || config.email?.address || '',
|
|
550
|
+
orgId,
|
|
551
|
+
accessToken: newToken,
|
|
552
|
+
refreshToken: refreshTokenFn,
|
|
553
|
+
provider: providerType,
|
|
554
|
+
});
|
|
555
|
+
console.log('[email-poll] Reconnected with fresh token');
|
|
556
|
+
} catch {}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// Start polling
|
|
562
|
+
setInterval(pollOnce, POLL_INTERVAL);
|
|
563
|
+
// First poll after 5s
|
|
564
|
+
setTimeout(pollOnce, 5000);
|
|
565
|
+
}
|
package/src/engine/deployer.ts
CHANGED
|
@@ -445,7 +445,7 @@ export class DeploymentEngine {
|
|
|
445
445
|
});
|
|
446
446
|
emit('provision', 'completed', `App "${appName}" created`);
|
|
447
447
|
} catch (e: any) {
|
|
448
|
-
if (e.message.includes('already exists')) {
|
|
448
|
+
if (e.message.includes('already exists') || e.message.includes('already been taken')) {
|
|
449
449
|
emit('provision', 'completed', `App "${appName}" already exists, reusing`);
|
|
450
450
|
} else {
|
|
451
451
|
throw e;
|