@agenticmail/enterprise 0.5.108 → 0.5.110

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticmail/enterprise",
3
- "version": "0.5.108",
3
+ "version": "0.5.110",
4
4
  "description": "AgenticMail Enterprise — cloud-hosted AI agent identity, email, auth & compliance for organizations",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli-agent.ts CHANGED
@@ -73,8 +73,8 @@ export async function runAgent(_args: string[]) {
73
73
  console.log(` State: ${agent.state}`);
74
74
 
75
75
  // 4. Initialize lifecycle (manages agent state, config decryption)
76
- const { AgentLifecycle } = await import('./engine/lifecycle.js');
77
- const lifecycle = new AgentLifecycle(engineDb);
76
+ const { AgentLifecycleManager } = await import('./engine/lifecycle.js');
77
+ const lifecycle = new AgentLifecycleManager({ db: engineDb });
78
78
  await lifecycle.loadFromDb();
79
79
 
80
80
  const managed = lifecycle.getAgent(AGENT_ID);
@@ -198,4 +198,144 @@ export async function runAgent(_args: string[]) {
198
198
  );
199
199
  console.log(' State: running');
200
200
  } catch {}
201
+
202
+ // 10. Auto-onboarding + welcome email (runs after short delay to let runtime settle)
203
+ setTimeout(async () => {
204
+ try {
205
+ // Get org ID
206
+ const orgRows = await engineDb.query<any>(
207
+ `SELECT org_id FROM managed_agents WHERE id = $1`, [AGENT_ID]
208
+ );
209
+ const orgId = orgRows?.[0]?.org_id;
210
+ if (!orgId) { console.log('[onboarding] No org ID found, skipping'); return; }
211
+
212
+ // Check pending onboarding records
213
+ const pendingRows = await engineDb.query<any>(
214
+ `SELECT r.id, r.policy_id, p.name as policy_name, p.content as policy_content, p.priority
215
+ FROM onboarding_records r
216
+ JOIN org_policies p ON r.policy_id = p.id
217
+ WHERE r.agent_id = $1 AND r.status = 'pending'`,
218
+ [AGENT_ID]
219
+ );
220
+
221
+ if (!pendingRows || pendingRows.length === 0) {
222
+ console.log('[onboarding] Already complete or no records');
223
+ } else {
224
+ console.log(`[onboarding] ${pendingRows.length} pending policies — auto-acknowledging...`);
225
+ const ts = new Date().toISOString();
226
+ const policyNames: string[] = [];
227
+
228
+ for (const row of pendingRows) {
229
+ const policyName = row.policy_name || row.policy_id;
230
+ policyNames.push(policyName);
231
+ console.log(`[onboarding] Reading: ${policyName}`);
232
+
233
+ // Compute content hash
234
+ const { createHash } = await import('crypto');
235
+ const hash = createHash('sha256').update(row.policy_content || '').digest('hex').slice(0, 16);
236
+
237
+ // Update record to acknowledged
238
+ await engineDb.query(
239
+ `UPDATE onboarding_records SET status = 'acknowledged', acknowledged_at = $1, verification_hash = $2, updated_at = $1 WHERE id = $3`,
240
+ [ts, hash, row.id]
241
+ );
242
+ console.log(`[onboarding] ✅ Acknowledged: ${policyName}`);
243
+
244
+ // Store policy knowledge in memory
245
+ if (memoryManager) {
246
+ try {
247
+ await memoryManager.storeMemory(AGENT_ID, {
248
+ content: `Organization policy "${policyName}" (${row.priority}): ${(row.policy_content || '').slice(0, 500)}`,
249
+ category: 'org_knowledge',
250
+ importance: row.priority === 'mandatory' ? 'high' : 'medium',
251
+ confidence: 1.0,
252
+ });
253
+ } catch {}
254
+ }
255
+ }
256
+
257
+ // Record completion in memory
258
+ if (memoryManager) {
259
+ try {
260
+ await memoryManager.storeMemory(AGENT_ID, {
261
+ content: `Completed onboarding: read and acknowledged ${policyNames.length} organization policies: ${policyNames.join(', ')}.`,
262
+ category: 'org_knowledge',
263
+ importance: 'high',
264
+ confidence: 1.0,
265
+ });
266
+ } catch {}
267
+ }
268
+
269
+ console.log(`[onboarding] ✅ Onboarding complete — ${policyNames.length} policies acknowledged`);
270
+ }
271
+
272
+ // 11. Send welcome email to manager if configured
273
+ // Manager email can come from config.managerEmail or config.manager.email
274
+ const managerEmail = (config as any).managerEmail || ((config as any).manager?.type === 'external' ? (config as any).manager.email : null);
275
+ const emailConfig = (config as any).emailConfig;
276
+ if (managerEmail && emailConfig) {
277
+ console.log(`[welcome] Sending introduction email to ${managerEmail}...`);
278
+ try {
279
+ const { createEmailProvider } = await import('./agenticmail/index.js');
280
+ const emailProvider = await createEmailProvider(emailConfig);
281
+
282
+ const agentName = config.displayName || config.name;
283
+ const role = config.identity?.role || 'AI Agent';
284
+ const traits = config.identity?.traits || {};
285
+ const traitLines = Object.entries(traits)
286
+ .filter(([, v]) => v)
287
+ .map(([k, v]) => ` - ${k}: ${v}`)
288
+ .join('\n');
289
+
290
+ const policyCount = pendingRows?.length || 0;
291
+
292
+ const body = `Hello,
293
+
294
+ I'm ${agentName}, your new ${role}. I've just been deployed and have completed my onboarding — I've read and acknowledged all ${policyCount} organization policies.
295
+
296
+ About me:
297
+ - Role: ${role}
298
+ - Communication style: ${config.identity?.tone || 'professional'}
299
+ - Language: ${config.identity?.language || 'English'}
300
+ ${traitLines ? `- Personality traits:\n${traitLines}` : ''}
301
+
302
+ I'm ready to start working. Here's what I can help with:
303
+ - Responding to emails and communications
304
+ - Processing tasks and requests
305
+ - Following organization guidelines and escalation protocols
306
+
307
+ You can reach me by email at ${config.email?.address || emailConfig?.email || 'my configured email address'}, or through the enterprise dashboard.
308
+
309
+ Looking forward to working with you!
310
+
311
+ Best regards,
312
+ ${agentName}`;
313
+
314
+ await emailProvider.send({
315
+ to: managerEmail,
316
+ subject: `Hi! I'm ${agentName}, your new ${role}`,
317
+ text: body,
318
+ });
319
+ console.log(`[welcome] ✅ Welcome email sent to ${managerEmail}`);
320
+
321
+ if (memoryManager) {
322
+ try {
323
+ await memoryManager.storeMemory(AGENT_ID, {
324
+ content: `Sent welcome introduction email to manager at ${managerEmail}. Introduced myself as ${agentName}, ${role}.`,
325
+ category: 'interaction_pattern',
326
+ importance: 'medium',
327
+ confidence: 1.0,
328
+ });
329
+ } catch {}
330
+ }
331
+ } catch (err: any) {
332
+ console.error(`[welcome] Failed to send welcome email: ${err.message}`);
333
+ }
334
+ } else {
335
+ if (!managerEmail) console.log('[welcome] No manager email configured, skipping welcome email');
336
+ }
337
+ } catch (err: any) {
338
+ console.error(`[onboarding] Error: ${err.message}`);
339
+ }
340
+ }, 3000);
201
341
  }
@@ -106,6 +106,9 @@ export interface AgentConfig {
106
106
  };
107
107
  };
108
108
 
109
+ // Reporting
110
+ managerEmail?: string; // Manager/supervisor email — agent sends welcome email + reports here
111
+
109
112
  // Permission profile
110
113
  permissionProfileId: string;
111
114