@agenticmail/enterprise 0.5.167 → 0.5.168
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/agent-autonomy-VSPXV7QH.js +591 -0
- package/dist/cli-agent-7225VCWQ.js +987 -0
- package/dist/cli.js +1 -1
- package/package.json +1 -1
- package/src/cli-agent.ts +107 -1
- package/src/engine/agent-autonomy.ts +727 -0
package/dist/cli.js
CHANGED
|
@@ -50,7 +50,7 @@ Skill Development:
|
|
|
50
50
|
import("./cli-serve-ZNKBEF4M.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-7225VCWQ.js").then((m) => m.runAgent(args.slice(1))).catch(fatal);
|
|
54
54
|
break;
|
|
55
55
|
case "setup":
|
|
56
56
|
default:
|
package/package.json
CHANGED
package/src/cli-agent.ts
CHANGED
|
@@ -498,6 +498,67 @@ Available tools: gmail_send (to, subject, body) or agenticmail_send (to, subject
|
|
|
498
498
|
|
|
499
499
|
// 14. Start calendar polling loop (checks for upcoming meetings to auto-join)
|
|
500
500
|
startCalendarPolling(AGENT_ID, config, runtime, engineDb, memoryManager);
|
|
501
|
+
|
|
502
|
+
// 15. Start agent autonomy system (clock-in/out, catchup emails, goals, knowledge)
|
|
503
|
+
try {
|
|
504
|
+
const { AgentAutonomyManager } = await import('./engine/agent-autonomy.js');
|
|
505
|
+
const orgRows2 = await engineDb.query<any>(`SELECT org_id FROM managed_agents WHERE id = $1`, [AGENT_ID]);
|
|
506
|
+
const autoOrgId = orgRows2?.[0]?.org_id || orgId;
|
|
507
|
+
const managerEmail2 = (config as any).managerEmail || ((config as any).manager?.type === 'external' ? (config as any).manager.email : null);
|
|
508
|
+
|
|
509
|
+
// Parse schedule from work_schedules table
|
|
510
|
+
let schedule: { start: string; end: string; days: number[] } | undefined;
|
|
511
|
+
try {
|
|
512
|
+
const schedRows = await engineDb.query<any>(
|
|
513
|
+
`SELECT config FROM work_schedules WHERE agent_id = $1 ORDER BY created_at DESC LIMIT 1`,
|
|
514
|
+
[AGENT_ID]
|
|
515
|
+
);
|
|
516
|
+
if (schedRows && schedRows.length > 0) {
|
|
517
|
+
const schedConfig = typeof schedRows[0].config === 'string' ? JSON.parse(schedRows[0].config) : schedRows[0].config;
|
|
518
|
+
if (schedConfig?.standardHours) {
|
|
519
|
+
schedule = {
|
|
520
|
+
start: schedConfig.standardHours.start,
|
|
521
|
+
end: schedConfig.standardHours.end,
|
|
522
|
+
days: schedConfig.workDays || [0, 1, 2, 3, 4, 5, 6],
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
} catch {}
|
|
527
|
+
|
|
528
|
+
const autonomy = new AgentAutonomyManager({
|
|
529
|
+
agentId: AGENT_ID,
|
|
530
|
+
orgId: autoOrgId,
|
|
531
|
+
agentName: config.displayName || config.name,
|
|
532
|
+
role: config.identity?.role || 'AI Agent',
|
|
533
|
+
managerEmail: managerEmail2,
|
|
534
|
+
timezone: config.timezone || 'America/New_York',
|
|
535
|
+
schedule,
|
|
536
|
+
runtime,
|
|
537
|
+
engineDb,
|
|
538
|
+
memoryManager,
|
|
539
|
+
lifecycle,
|
|
540
|
+
});
|
|
541
|
+
await autonomy.start();
|
|
542
|
+
console.log('[autonomy] ✅ Agent autonomy system started');
|
|
543
|
+
|
|
544
|
+
// Store autonomy ref for shutdown
|
|
545
|
+
const origShutdown = process.listeners('SIGTERM');
|
|
546
|
+
process.on('SIGTERM', () => autonomy.stop());
|
|
547
|
+
process.on('SIGINT', () => autonomy.stop());
|
|
548
|
+
} catch (autoErr: any) {
|
|
549
|
+
console.warn(`[autonomy] Failed to start: ${autoErr.message}`);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// 16. Start guardrail enforcement
|
|
553
|
+
try {
|
|
554
|
+
const { GuardrailEnforcer } = await import('./engine/agent-autonomy.js');
|
|
555
|
+
const enforcer = new GuardrailEnforcer(engineDb);
|
|
556
|
+
// Store enforcer for use by email polling
|
|
557
|
+
(global as any).__guardrailEnforcer = enforcer;
|
|
558
|
+
console.log('[guardrails] ✅ Runtime guardrail enforcer active');
|
|
559
|
+
} catch (gErr: any) {
|
|
560
|
+
console.warn(`[guardrails] Failed to start enforcer: ${gErr.message}`);
|
|
561
|
+
}
|
|
501
562
|
}, 3000);
|
|
502
563
|
}
|
|
503
564
|
|
|
@@ -858,9 +919,54 @@ For meetings you organize or are invited to:
|
|
|
858
919
|
|
|
859
920
|
When you receive an email containing a meeting link (meet.google.com, zoom.us, teams.microsoft.com):
|
|
860
921
|
- Extract the link and attempt to join immediately if the meeting is now
|
|
861
|
-
- If the meeting is in the future, store it in memory and note the time
|
|
922
|
+
- If the meeting is in the future, store it in memory and note the time
|
|
862
923
|
|
|
924
|
+
== SMART ANSWER WORKFLOW (MANDATORY) ==
|
|
925
|
+
When you receive a question or request you're not 100% confident about, follow this escalation chain:
|
|
863
926
|
|
|
927
|
+
STEP 1: Search your own memory
|
|
928
|
+
- memory(action: "search", query: "relevant keywords")
|
|
929
|
+
- Check for similar past questions, corrections, and learned patterns
|
|
930
|
+
|
|
931
|
+
STEP 2: Search organization Drive (shared knowledge)
|
|
932
|
+
- google_drive_list with query parameter to search shared docs (e.g. "fullText contains 'search terms'")
|
|
933
|
+
- Read relevant documents with google_drive_get to find the answer
|
|
934
|
+
- Check Google Sheets for data tables, Google Docs for procedures
|
|
935
|
+
|
|
936
|
+
STEP 3: If still unsure — ESCALATE to manager
|
|
937
|
+
${managerEmail ? `- Send an email to ${managerEmail} with:` : '- Email your manager with:'}
|
|
938
|
+
Subject: "Need Guidance: [Brief topic]"
|
|
939
|
+
Body must include:
|
|
940
|
+
a) The original question/request (who asked, what they need)
|
|
941
|
+
b) What you found in your search (memory + Drive results)
|
|
942
|
+
c) Your proposed answer (what you THINK the answer should be)
|
|
943
|
+
d) What specifically you're unsure about
|
|
944
|
+
e) Ask for approval or correction before responding
|
|
945
|
+
|
|
946
|
+
NEVER guess or fabricate an answer when unsure. It's better to escalate than to be wrong.
|
|
947
|
+
After receiving manager feedback, store the correct answer in memory as a "correction" or "org_knowledge" entry.`;
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
|
|
951
|
+
// Guardrail check: scan inbound email for security rules
|
|
952
|
+
const enforcer = (global as any).__guardrailEnforcer;
|
|
953
|
+
if (enforcer) {
|
|
954
|
+
try {
|
|
955
|
+
const orgRows3 = await engineDb.query<any>(`SELECT org_id FROM managed_agents WHERE id = $1`, [agentId]);
|
|
956
|
+
const gOrgId = orgRows3?.[0]?.org_id || '';
|
|
957
|
+
const check = await enforcer.evaluate({
|
|
958
|
+
agentId, orgId: gOrgId, type: 'email_send' as const,
|
|
959
|
+
content: emailText, metadata: { from: senderEmail, subject: fullMsg.subject },
|
|
960
|
+
});
|
|
961
|
+
if (!check.allowed) {
|
|
962
|
+
console.warn(`[email-poll] ⚠️ Guardrail blocked email from ${senderEmail}: ${check.reason} (action: ${check.action})`);
|
|
963
|
+
continue; // Skip this email
|
|
964
|
+
}
|
|
965
|
+
} catch (gErr: any) {
|
|
966
|
+
console.warn(`[email-poll] Guardrail check error: ${gErr.message}`);
|
|
967
|
+
// Continue anyway — don't block on guardrail failures
|
|
968
|
+
}
|
|
969
|
+
}
|
|
864
970
|
|
|
865
971
|
const session = await runtime.spawnSession({
|
|
866
972
|
agentId,
|