@agenticmail/enterprise 0.5.319 → 0.5.321
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/CHANGELOG.md +68 -0
- package/CODE_OF_CONDUCT.md +31 -0
- package/README.md +118 -38
- package/SECURITY.md +42 -0
- package/dist/agent-heartbeat-3FWNHZFX.js +510 -0
- package/dist/agent-heartbeat-4RWHZR7H.js +510 -0
- package/dist/agent-heartbeat-6ZGB5ILY.js +510 -0
- package/dist/agent-heartbeat-BIVHLKFM.js +510 -0
- package/dist/agent-heartbeat-HRKVFK2T.js +510 -0
- package/dist/agent-heartbeat-JC5GWVXD.js +510 -0
- package/dist/agent-heartbeat-K6A4HMHB.js +510 -0
- package/dist/agent-heartbeat-LCDXWFVB.js +510 -0
- package/dist/agent-heartbeat-P7HZCZAQ.js +510 -0
- package/dist/agent-heartbeat-PUIRSNIO.js +510 -0
- package/dist/agent-heartbeat-SN5ILQ6Y.js +510 -0
- package/dist/agent-heartbeat-TW5YTDYC.js +510 -0
- package/dist/agent-heartbeat-Z2QQXROL.js +510 -0
- package/dist/agent-notify-OEQBCZLN.js +43 -0
- package/dist/{agent-tools-263HM5QU.js → agent-tools-3W7XLUYA.js} +1 -1
- package/dist/agent-tools-4QK7LLNP.js +9 -0
- package/dist/agent-tools-54VZGT6L.js +9 -0
- package/dist/{agent-tools-AT4D276V.js → agent-tools-AYYDPO27.js} +7 -7
- package/dist/{agent-tools-MSTAPX2I.js → agent-tools-F2X47FKF.js} +7 -7
- package/dist/{agent-tools-FA26SY5O.js → agent-tools-O6W3QAZL.js} +11 -6
- package/dist/agent-tools-OAWVZBMW.js +9 -0
- package/dist/agent-tools-QCCU74PN.js +13949 -0
- package/dist/chunk-2LHUARN6.js +4929 -0
- package/dist/chunk-2WVCNCYC.js +5087 -0
- package/dist/{chunk-6PWDS7KY.js → chunk-3FM6YQUK.js} +20 -20
- package/dist/chunk-3UAFHUEC.js +212 -0
- package/dist/{chunk-WJO57PMO.js → chunk-46GOWZT4.js} +20 -20
- package/dist/{chunk-BNRE7TSX.js → chunk-5KYJAUZV.js} +3 -3
- package/dist/chunk-6C5PKREN.js +467 -0
- package/dist/{chunk-447MTPZF.js → chunk-6ZMLNEHB.js} +3 -3
- package/dist/chunk-BPZQT5N5.js +25652 -0
- package/dist/chunk-BQM7MBPS.js +1380 -0
- package/dist/{chunk-ZRFKGPIU.js → chunk-C52OQNNY.js} +20 -20
- package/dist/chunk-C7HGQF4Y.js +25652 -0
- package/dist/chunk-CAHNZGGK.js +25656 -0
- package/dist/{chunk-FL3CH3ET.js → chunk-CK7R6UHE.js} +51 -27
- package/dist/chunk-D36RPWB7.js +25652 -0
- package/dist/{chunk-36NM2B4C.js → chunk-DJK2UPFH.js} +63 -93
- package/dist/chunk-DM7FTF7W.js +4929 -0
- package/dist/chunk-DMD24UFZ.js +5101 -0
- package/dist/{chunk-36XNMIHA.js → chunk-DXZGPUAF.js} +20 -20
- package/dist/chunk-F46WB5IL.js +5087 -0
- package/dist/chunk-F5QG5SQH.js +5087 -0
- package/dist/{chunk-JGEVQZDR.js → chunk-FLQ5FLHW.js} +13 -16
- package/dist/chunk-H7GP733U.js +5087 -0
- package/dist/{chunk-OZSQLOV6.js → chunk-HHBXWB5U.js} +415 -19
- package/dist/{chunk-D24JY75H.js → chunk-IMXS4N6W.js} +3 -3
- package/dist/{chunk-6PVBV6ZP.js → chunk-JNMDD7JY.js} +3 -3
- package/dist/chunk-JTV5LA47.js +1519 -0
- package/dist/chunk-KV6G7NZX.js +1519 -0
- package/dist/chunk-MU5MEBIK.js +1519 -0
- package/dist/chunk-NLT5MC7X.js +465 -0
- package/dist/{chunk-GTFZZUXX.js → chunk-NVLYIM4J.js} +51 -27
- package/dist/{chunk-6G5SXLXC.js → chunk-NZY2BIZH.js} +63 -93
- package/dist/chunk-O42L6G67.js +1519 -0
- package/dist/chunk-OCNERGGM.js +4891 -0
- package/dist/chunk-OJSNHONE.js +1519 -0
- package/dist/{chunk-2TAZJWJN.js → chunk-OWL3QVH7.js} +18 -0
- package/dist/{chunk-P3HVY2HS.js → chunk-OWTLNV4Q.js} +382 -7
- package/dist/chunk-PCNYEP6T.js +4891 -0
- package/dist/{chunk-YL3Z5KPR.js → chunk-PI4AQ4Z6.js} +438 -15
- package/dist/chunk-PN3EGTCA.js +194 -0
- package/dist/chunk-Q37UKNRC.js +1519 -0
- package/dist/chunk-QXTC6J7H.js +5087 -0
- package/dist/{chunk-SPBQVNDI.js → chunk-RKERL5LZ.js} +25 -21
- package/dist/chunk-RVBK2IOX.js +25652 -0
- package/dist/chunk-SAKODCZ5.js +4891 -0
- package/dist/{chunk-XV4TU65E.js → chunk-SALGFC5L.js} +51 -27
- package/dist/chunk-STGWZ2MS.js +1519 -0
- package/dist/chunk-UY3ZVQDP.js +25652 -0
- package/dist/chunk-V6OSD62M.js +5087 -0
- package/dist/chunk-VP6YAHX4.js +1519 -0
- package/dist/chunk-WDYJOEAI.js +5087 -0
- package/dist/chunk-WEAFQNOS.js +195 -0
- package/dist/chunk-XKUSAZGP.js +5087 -0
- package/dist/chunk-Z6K5FKAB.js +548 -0
- package/dist/chunk-ZGE3XAXY.js +1519 -0
- package/dist/chunk-ZGYVXYQQ.js +3296 -0
- package/dist/cli-agent-7TB2BWS6.js +2370 -0
- package/dist/cli-agent-AKXFFST2.js +2370 -0
- package/dist/cli-agent-DZTKLITB.js +2357 -0
- package/dist/cli-agent-FOF7PFEP.js +2357 -0
- package/dist/cli-agent-H74M2ZYN.js +2357 -0
- package/dist/cli-agent-HORWVPHB.js +2370 -0
- package/dist/cli-agent-HSZT6SKF.js +2423 -0
- package/dist/cli-agent-JLUQ4ZU6.js +2424 -0
- package/dist/cli-agent-MVCDH4HV.js +2370 -0
- package/dist/cli-agent-NZXOEPJ2.js +2357 -0
- package/dist/cli-agent-PADN3QRC.js +2357 -0
- package/dist/cli-agent-QAYEX3BE.js +2441 -0
- package/dist/cli-agent-QT64DT5J.js +2370 -0
- package/dist/cli-agent-TFL2M6UK.js +2424 -0
- package/dist/cli-agent-UIKXATTD.js +2357 -0
- package/dist/cli-agent-UJN6FYTO.js +2370 -0
- package/dist/cli-agent-VIQAYVY4.js +2357 -0
- package/dist/cli-agent-WNWFVOFM.js +2370 -0
- package/dist/cli-agent-XBQX67VJ.js +2423 -0
- package/dist/cli-agent-ZLSC6FF4.js +2357 -0
- package/dist/cli-serve-2IL5DTEY.js +153 -0
- package/dist/cli-serve-47N5UKKW.js +153 -0
- package/dist/cli-serve-4XGZFUV2.js +140 -0
- package/dist/cli-serve-6OT3UEAN.js +140 -0
- package/dist/cli-serve-7L6EY5UH.js +153 -0
- package/dist/cli-serve-BDGOOOKQ.js +260 -0
- package/dist/cli-serve-BFNIW2LF.js +153 -0
- package/dist/cli-serve-C7MN6U5Q.js +153 -0
- package/dist/cli-serve-CR3OY3IM.js +153 -0
- package/dist/cli-serve-DAJFRWQ7.js +153 -0
- package/dist/cli-serve-FW6FHFW4.js +153 -0
- package/dist/cli-serve-GEEOQS77.js +153 -0
- package/dist/cli-serve-H562I3ZK.js +153 -0
- package/dist/cli-serve-HDQZF4C4.js +153 -0
- package/dist/cli-serve-LICAOMEB.js +140 -0
- package/dist/cli-serve-LLGYLWFS.js +153 -0
- package/dist/cli-serve-N3OISDNB.js +153 -0
- package/dist/cli-serve-TIZ27EVR.js +153 -0
- package/dist/cli-serve-TUNI2RCN.js +153 -0
- package/dist/cli-serve-WNOZMAWD.js +153 -0
- package/dist/cli-validate-Z726VJCN.js +150 -0
- package/dist/cli.js +4 -4
- package/dist/connection-manager-KAWEUWUR.js +9 -0
- package/dist/dashboard/app.js +9 -3
- package/dist/dashboard/components/knowledge-link.js +15 -0
- package/dist/dashboard/components/settings-help.js +4 -2
- package/dist/dashboard/docs/agent-deployment.html +33 -1
- package/dist/dashboard/docs/settings-network.html +321 -0
- package/dist/dashboard/docs/settings-security.html +347 -0
- package/dist/dashboard/docs/settings-tool-security.html +176 -0
- package/dist/dashboard/docs/settings.html +36 -16
- package/dist/dashboard/pages/agent-detail/deployment.js +39 -6
- package/dist/dashboard/pages/agent-detail/tools.js +10 -0
- package/dist/dashboard/pages/database-access.js +4 -3
- package/dist/dashboard/pages/settings.js +174 -37
- package/dist/dashboard/pages/task-pipeline.js +400 -843
- package/dist/db-adapter-2T56ORSD.js +7 -0
- package/dist/db-adapter-IRHOUMVC.js +7 -0
- package/dist/index.js +41 -41
- package/dist/microsoft-VREAZ7M2.js +3955 -0
- package/dist/routes-3MMLQTB6.js +90 -0
- package/dist/routes-4ZUIJ4HE.js +90 -0
- package/dist/routes-5MXHKKH4.js +90 -0
- package/dist/routes-64NJFK3B.js +90 -0
- package/dist/routes-6AKQ2LBV.js +90 -0
- package/dist/routes-CRRBUDO4.js +90 -0
- package/dist/routes-DIAF3MC3.js +90 -0
- package/dist/routes-KMUNU6CY.js +90 -0
- package/dist/routes-LRRLXIZR.js +90 -0
- package/dist/routes-N647AJYG.js +90 -0
- package/dist/routes-SSSELAAR.js +90 -0
- package/dist/routes-STERVGKJ.js +90 -0
- package/dist/routes-ZEZZACZP.js +90 -0
- package/dist/runtime-5EQN4GFM.js +45 -0
- package/dist/runtime-5LP7PUD4.js +45 -0
- package/dist/runtime-6BULDBR3.js +45 -0
- package/dist/runtime-6YEENDN3.js +45 -0
- package/dist/runtime-7LQFRG3B.js +45 -0
- package/dist/runtime-AMXJU2MB.js +45 -0
- package/dist/runtime-D6WSE7FG.js +45 -0
- package/dist/runtime-EYVN7NFJ.js +45 -0
- package/dist/runtime-F6RPWQVW.js +45 -0
- package/dist/runtime-FYMJURFC.js +45 -0
- package/dist/runtime-JRNBL4O4.js +45 -0
- package/dist/runtime-OM2NIBMI.js +45 -0
- package/dist/runtime-QWPVD7CY.js +45 -0
- package/dist/runtime-YLIIPTE4.js +45 -0
- package/dist/runtime-YU6P22CG.js +45 -0
- package/dist/screen-unlock-4RPZBHOI.js +118 -0
- package/dist/server-AMCSXINC.js +28 -0
- package/dist/server-CU6LVQS4.js +28 -0
- package/dist/server-DFYGH2CV.js +28 -0
- package/dist/server-EELWOC3X.js +28 -0
- package/dist/server-EN5E2OWQ.js +28 -0
- package/dist/server-GW2HYJYI.js +28 -0
- package/dist/server-J25NCRWJ.js +28 -0
- package/dist/server-JDGNOTFV.js +28 -0
- package/dist/server-NE5HD5DJ.js +28 -0
- package/dist/server-NQOT7W77.js +28 -0
- package/dist/server-PWE5PQTR.js +28 -0
- package/dist/server-Q2Q32H2B.js +28 -0
- package/dist/server-Q77ME7TL.js +28 -0
- package/dist/server-WLLH4WST.js +28 -0
- package/dist/server-WTUJ2O3F.js +28 -0
- package/dist/server-X4CJTHHF.js +28 -0
- package/dist/server-XK3ILCJC.js +28 -0
- package/dist/server-ZRD3NDJE.js +28 -0
- package/dist/setup-44VBAO4J.js +20 -0
- package/dist/setup-4ONNQBWB.js +20 -0
- package/dist/setup-4OSBXSCL.js +20 -0
- package/dist/setup-4QFGRBLZ.js +20 -0
- package/dist/setup-6766SGAR.js +20 -0
- package/dist/setup-AYY24DKM.js +20 -0
- package/dist/setup-B34N4HPU.js +20 -0
- package/dist/setup-E2YLC2EY.js +20 -0
- package/dist/setup-ER6NXTY5.js +20 -0
- package/dist/setup-H2AGCBW5.js +20 -0
- package/dist/setup-ICOZRKCX.js +20 -0
- package/dist/setup-JFTJH7UF.js +20 -0
- package/dist/setup-PRFNI6YW.js +20 -0
- package/dist/setup-RAHBMYHE.js +20 -0
- package/dist/setup-TXPR5UQX.js +20 -0
- package/dist/setup-XCJMELVU.js +20 -0
- package/dist/setup-XIYEIFVK.js +20 -0
- package/dist/setup-Z4PZSHBI.js +20 -0
- package/dist/skills-FR7I5V7H.js +16 -0
- package/dist/skills-HCVBA6PK.js +16 -0
- package/dist/system-prompts-TM7OA32C.js +913 -0
- package/dist/task-queue-O7IVZYUO.js +9 -0
- package/dist/transport-encryption-2T7PIXKG.js +25 -0
- package/logs/cloudflared-error.log +61 -0
- package/logs/cloudflared-out.log +0 -0
- package/logs/enterprise-error.log +0 -0
- package/logs/enterprise-out.log +3 -0
- package/logs/fola-error.log +0 -0
- package/logs/fola-out.log +0 -0
- package/logs/john-error.log +8 -0
- package/logs/john-out.log +0 -0
- package/package.json +31 -3
- package/src/agent-tools/tool-resolver.ts +50 -61
- package/src/agent-tools/tools/enterprise-database.ts +5 -5
- package/src/agent-tools/tools/local/dependency-manager.ts +2 -2
- package/src/agent-tools/tools/microsoft/graph-api.ts +137 -26
- package/src/agent-tools/tools/microsoft/outlook-mail.ts +392 -100
- package/src/agent-tools/tools/microsoft/teams.ts +267 -48
- package/src/auth/routes.ts +4 -4
- package/src/cli-agent.ts +108 -8
- package/src/cli-serve.ts +140 -0
- package/src/dashboard/app.js +9 -3
- package/src/dashboard/components/knowledge-link.js +15 -0
- package/src/dashboard/components/settings-help.js +4 -2
- package/src/dashboard/docs/agent-deployment.html +33 -1
- package/src/dashboard/docs/settings-network.html +321 -0
- package/src/dashboard/docs/settings-security.html +347 -0
- package/src/dashboard/docs/settings-tool-security.html +176 -0
- package/src/dashboard/docs/settings.html +36 -16
- package/src/dashboard/pages/agent-detail/deployment.js +39 -6
- package/src/dashboard/pages/agent-detail/tools.js +10 -0
- package/src/dashboard/pages/database-access.js +4 -3
- package/src/dashboard/pages/settings.js +174 -37
- package/src/dashboard/pages/task-pipeline.js +400 -843
- package/src/database-access/agent-tools.ts +78 -63
- package/src/database-access/connection-manager.ts +13 -2
- package/src/database-access/routes.ts +13 -1
- package/src/db/adapter.ts +1 -0
- package/src/engine/agent-memory.ts +2 -1
- package/src/engine/agent-notify.ts +50 -0
- package/src/engine/agent-routes.ts +257 -4
- package/src/engine/db-adapter.ts +16 -0
- package/src/engine/lifecycle.ts +4 -0
- package/src/engine/routes.ts +4 -3
- package/src/engine/screen-unlock.ts +136 -0
- package/src/engine/skills/database-access.ts +78 -0
- package/src/engine/skills/index.ts +3 -2
- package/src/engine/skills.ts +2 -0
- package/src/engine/task-queue-routes.ts +18 -0
- package/src/engine/task-queue.ts +15 -2
- package/src/middleware/transport-encryption.ts +1 -4
- package/src/runtime/agent-loop.ts +4 -0
- package/src/runtime/index.ts +15 -6
- package/src/server.ts +14 -1
- package/src/system-prompts/google/index.ts +1 -2
- package/src/system-prompts/index.ts +1 -1
- package/src/system-prompts/microsoft/contacts.ts +34 -0
- package/src/system-prompts/microsoft/excel.ts +52 -0
- package/src/system-prompts/microsoft/index.ts +31 -0
- package/src/system-prompts/microsoft/onedrive.ts +41 -0
- package/src/system-prompts/microsoft/onenote.ts +36 -0
- package/src/system-prompts/microsoft/outlook-calendar.ts +37 -0
- package/src/system-prompts/microsoft/outlook-mail.ts +46 -0
- package/src/system-prompts/microsoft/planner.ts +37 -0
- package/src/system-prompts/microsoft/powerbi.ts +38 -0
- package/src/system-prompts/microsoft/powerpoint.ts +35 -0
- package/src/system-prompts/microsoft/sharepoint.ts +44 -0
- package/src/system-prompts/microsoft/teams.ts +49 -0
- package/src/system-prompts/microsoft/todo.ts +37 -0
- package/src/types/hono-env.ts +4 -0
- package/.github/CODEOWNERS +0 -23
- package/.github/workflows/publish-community-skills.yml +0 -121
- package/.github/workflows/validate-community-skills.yml +0 -172
- package/agriculture_southwest_nigeria_research.txt +0 -10
- package/boa_credit_cards_research.txt +0 -10
- package/customer_support_research_feb2026.txt +0 -10
- package/dist/agent-tools-LRA7PPXG.js +0 -13922
- package/dist/agent-tools-VAU5DOQB.js +0 -13910
- package/dist/agent-tools-VWV7OWXU.js +0 -13922
- package/dist/chunk-2Z7MWTCX.js +0 -4977
- package/dist/chunk-3T4XU3VV.js +0 -5010
- package/dist/chunk-445QM4NX.js +0 -5061
- package/dist/chunk-5TW3Y7DJ.js +0 -1519
- package/dist/chunk-6I7VY3LT.js +0 -5060
- package/dist/chunk-6W5EK3UP.js +0 -4977
- package/dist/chunk-AQMSHJQT.js +0 -5069
- package/dist/chunk-ASSQW7HX.js +0 -5051
- package/dist/chunk-CIN27FGC.js +0 -5037
- package/dist/chunk-CMXY3NUB.js +0 -4977
- package/dist/chunk-DRLMRUDP.js +0 -5052
- package/dist/chunk-EHI7Z446.js +0 -1519
- package/dist/chunk-FEAILFAQ.js +0 -1519
- package/dist/chunk-GA3PYBZL.js +0 -1519
- package/dist/chunk-GWX63G5J.js +0 -1519
- package/dist/chunk-HHMZ4UY6.js +0 -1519
- package/dist/chunk-HVQMNF7E.js +0 -4921
- package/dist/chunk-HXM7F3YN.js +0 -1519
- package/dist/chunk-K6NGOUXG.js +0 -5060
- package/dist/chunk-KPG5WINJ.js +0 -4977
- package/dist/chunk-LBCUBYDL.js +0 -1519
- package/dist/chunk-LIRQSWLR.js +0 -5014
- package/dist/chunk-LRCKO5KE.js +0 -1519
- package/dist/chunk-M7XL3DJD.js +0 -5069
- package/dist/chunk-MHJULEIQ.js +0 -1519
- package/dist/chunk-MJGGW6MC.js +0 -106
- package/dist/chunk-MMYBDHDB.js +0 -4921
- package/dist/chunk-MQT5FXKD.js +0 -1519
- package/dist/chunk-OIMPEQF5.js +0 -4977
- package/dist/chunk-OOU7JUYE.js +0 -542
- package/dist/chunk-OW4GLBHP.js +0 -1519
- package/dist/chunk-Q4K4MMLU.js +0 -4977
- package/dist/chunk-RUK4CRPF.js +0 -1519
- package/dist/chunk-T7H65XQY.js +0 -1519
- package/dist/chunk-TQVFWG57.js +0 -5064
- package/dist/chunk-UEPK3IMC.js +0 -1519
- package/dist/chunk-VUWTXJH6.js +0 -1519
- package/dist/chunk-WCPGGSAD.js +0 -1519
- package/dist/chunk-WO63NZOJ.js +0 -1519
- package/dist/chunk-YPJDRVUM.js +0 -5064
- package/dist/chunk-ZROMH5DL.js +0 -4921
- package/src/dashboard/docs/_template.txt +0 -92
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
import "./chunk-KFQGP6VL.js";
|
|
2
|
+
|
|
3
|
+
// src/engine/agent-heartbeat.ts
|
|
4
|
+
var DEFAULT_SETTINGS = {
|
|
5
|
+
enabled: true,
|
|
6
|
+
baseIntervalMs: 5 * 6e4,
|
|
7
|
+
// 5 minutes
|
|
8
|
+
maxIntervalMs: 30 * 6e4,
|
|
9
|
+
// 30 minutes
|
|
10
|
+
dampingFactor: 0.5,
|
|
11
|
+
maxBatchSize: 5,
|
|
12
|
+
quietHoursStart: 23,
|
|
13
|
+
quietHoursEnd: 8
|
|
14
|
+
};
|
|
15
|
+
function createUnreadEmailCheck() {
|
|
16
|
+
return {
|
|
17
|
+
id: "unread_emails",
|
|
18
|
+
name: "Unread Emails",
|
|
19
|
+
intervalMs: 10 * 6e4,
|
|
20
|
+
// 10 minutes
|
|
21
|
+
priority: "high",
|
|
22
|
+
requiresClockIn: false,
|
|
23
|
+
// emails can be urgent outside hours
|
|
24
|
+
consecutiveNoOps: 0,
|
|
25
|
+
enabled: true,
|
|
26
|
+
check: async (ctx) => {
|
|
27
|
+
try {
|
|
28
|
+
const rows = await ctx.db.query(
|
|
29
|
+
`SELECT COUNT(*) as cnt FROM agent_memory
|
|
30
|
+
WHERE agent_id = $1
|
|
31
|
+
AND category = 'processed_email'
|
|
32
|
+
AND created_at > NOW() - INTERVAL '4 hours'`,
|
|
33
|
+
[ctx.agentId]
|
|
34
|
+
);
|
|
35
|
+
const processedRecently = parseInt(rows?.[0]?.cnt || "0");
|
|
36
|
+
const lastProcessed = await ctx.db.query(
|
|
37
|
+
`SELECT MAX(created_at) as last_at FROM agent_memory
|
|
38
|
+
WHERE agent_id = $1 AND category = 'processed_email'`,
|
|
39
|
+
[ctx.agentId]
|
|
40
|
+
);
|
|
41
|
+
const lastAt = lastProcessed?.[0]?.last_at;
|
|
42
|
+
if (ctx.isWorkHours && processedRecently === 0 && ctx.hour >= 10) {
|
|
43
|
+
return {
|
|
44
|
+
needsAction: true,
|
|
45
|
+
summary: "No emails processed in the last 4 hours during work hours. Check inbox.",
|
|
46
|
+
priority: "medium",
|
|
47
|
+
data: { lastProcessedAt: lastAt }
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
return { needsAction: false, priority: "low" };
|
|
51
|
+
} catch {
|
|
52
|
+
return { needsAction: false, priority: "low" };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function createUpcomingEventsCheck() {
|
|
58
|
+
return {
|
|
59
|
+
id: "upcoming_events",
|
|
60
|
+
name: "Upcoming Calendar Events",
|
|
61
|
+
intervalMs: 15 * 6e4,
|
|
62
|
+
// 15 minutes
|
|
63
|
+
priority: "high",
|
|
64
|
+
requiresClockIn: false,
|
|
65
|
+
consecutiveNoOps: 0,
|
|
66
|
+
enabled: true,
|
|
67
|
+
check: async (ctx) => {
|
|
68
|
+
try {
|
|
69
|
+
const twoHoursFromNow = new Date(ctx.now.getTime() + 2 * 60 * 60 * 1e3).toISOString();
|
|
70
|
+
const rows = await ctx.db.query(
|
|
71
|
+
`SELECT content FROM agent_memory
|
|
72
|
+
WHERE agent_id = $1
|
|
73
|
+
AND category = 'context'
|
|
74
|
+
AND content LIKE '%meeting%'
|
|
75
|
+
AND created_at > NOW() - INTERVAL '24 hours'
|
|
76
|
+
ORDER BY created_at DESC LIMIT 5`,
|
|
77
|
+
[ctx.agentId]
|
|
78
|
+
);
|
|
79
|
+
const upcomingMeetings = (rows || []).filter((r) => {
|
|
80
|
+
const content = r.content || "";
|
|
81
|
+
return content.includes("meeting") || content.includes("event");
|
|
82
|
+
});
|
|
83
|
+
if (upcomingMeetings.length > 0) {
|
|
84
|
+
return {
|
|
85
|
+
needsAction: true,
|
|
86
|
+
summary: `${upcomingMeetings.length} potential upcoming event(s). Agent should check Google Calendar.`,
|
|
87
|
+
priority: "high",
|
|
88
|
+
data: { count: upcomingMeetings.length }
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
return { needsAction: false, priority: "low" };
|
|
92
|
+
} catch {
|
|
93
|
+
return { needsAction: false, priority: "low" };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function createStaleSessionsCheck() {
|
|
99
|
+
return {
|
|
100
|
+
id: "stale_sessions",
|
|
101
|
+
name: "Stale Sessions",
|
|
102
|
+
intervalMs: 30 * 6e4,
|
|
103
|
+
// 30 minutes
|
|
104
|
+
priority: "medium",
|
|
105
|
+
requiresClockIn: true,
|
|
106
|
+
consecutiveNoOps: 0,
|
|
107
|
+
enabled: true,
|
|
108
|
+
check: async (ctx) => {
|
|
109
|
+
try {
|
|
110
|
+
const rows = await ctx.db.query(
|
|
111
|
+
`SELECT COUNT(*) as cnt FROM agent_sessions
|
|
112
|
+
WHERE agent_id = $1
|
|
113
|
+
AND status = 'active'
|
|
114
|
+
AND updated_at < NOW() - INTERVAL '2 hours'`,
|
|
115
|
+
[ctx.agentId]
|
|
116
|
+
);
|
|
117
|
+
const staleCount = parseInt(rows?.[0]?.cnt || "0");
|
|
118
|
+
if (staleCount > 0) {
|
|
119
|
+
return {
|
|
120
|
+
needsAction: true,
|
|
121
|
+
summary: `${staleCount} stale session(s) detected (active > 2 hours with no updates). May need cleanup.`,
|
|
122
|
+
priority: "medium",
|
|
123
|
+
data: { staleCount }
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
return { needsAction: false, priority: "low" };
|
|
127
|
+
} catch {
|
|
128
|
+
return { needsAction: false, priority: "low" };
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function createMemoryHealthCheck() {
|
|
134
|
+
return {
|
|
135
|
+
id: "memory_health",
|
|
136
|
+
name: "Memory Health",
|
|
137
|
+
intervalMs: 60 * 6e4,
|
|
138
|
+
// 1 hour
|
|
139
|
+
priority: "low",
|
|
140
|
+
requiresClockIn: true,
|
|
141
|
+
consecutiveNoOps: 0,
|
|
142
|
+
enabled: true,
|
|
143
|
+
check: async (ctx) => {
|
|
144
|
+
try {
|
|
145
|
+
const rows = await ctx.db.query(
|
|
146
|
+
`SELECT COUNT(*) as cnt FROM agent_memory
|
|
147
|
+
WHERE agent_id = $1 AND created_at > NOW() - INTERVAL '24 hours'`,
|
|
148
|
+
[ctx.agentId]
|
|
149
|
+
);
|
|
150
|
+
const recentCount = parseInt(rows?.[0]?.cnt || "0");
|
|
151
|
+
if (recentCount > 200) {
|
|
152
|
+
return {
|
|
153
|
+
needsAction: true,
|
|
154
|
+
summary: `Memory flood detected: ${recentCount} memories in 24h (threshold: 200). Consider pruning.`,
|
|
155
|
+
priority: "medium",
|
|
156
|
+
data: { recentCount }
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
return { needsAction: false, priority: "low" };
|
|
160
|
+
} catch {
|
|
161
|
+
return { needsAction: false, priority: "low" };
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
function createUnansweredChatCheck() {
|
|
167
|
+
return {
|
|
168
|
+
id: "unanswered_chat",
|
|
169
|
+
name: "Unanswered Chat Messages",
|
|
170
|
+
intervalMs: 5 * 6e4,
|
|
171
|
+
// 5 minutes
|
|
172
|
+
priority: "high",
|
|
173
|
+
requiresClockIn: false,
|
|
174
|
+
consecutiveNoOps: 0,
|
|
175
|
+
enabled: true,
|
|
176
|
+
check: async (ctx) => {
|
|
177
|
+
try {
|
|
178
|
+
const rows = await ctx.db.query(
|
|
179
|
+
`SELECT COUNT(*) as cnt FROM agent_sessions
|
|
180
|
+
WHERE agent_id = $1
|
|
181
|
+
AND status = 'failed'
|
|
182
|
+
AND metadata::text LIKE '%chat%'
|
|
183
|
+
AND created_at > NOW() - INTERVAL '1 hour'`,
|
|
184
|
+
[ctx.agentId]
|
|
185
|
+
);
|
|
186
|
+
const failedChats = parseInt(rows?.[0]?.cnt || "0");
|
|
187
|
+
if (failedChats > 0) {
|
|
188
|
+
return {
|
|
189
|
+
needsAction: true,
|
|
190
|
+
summary: `${failedChats} failed chat session(s) in the last hour. Messages may be unanswered.`,
|
|
191
|
+
priority: "urgent",
|
|
192
|
+
data: { failedChats }
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
return { needsAction: false, priority: "low" };
|
|
196
|
+
} catch {
|
|
197
|
+
return { needsAction: false, priority: "low" };
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function createTaskDeadlineCheck() {
|
|
203
|
+
return {
|
|
204
|
+
id: "task_deadlines",
|
|
205
|
+
name: "Task Deadlines",
|
|
206
|
+
intervalMs: 60 * 6e4,
|
|
207
|
+
// 1 hour
|
|
208
|
+
priority: "medium",
|
|
209
|
+
requiresClockIn: true,
|
|
210
|
+
consecutiveNoOps: 0,
|
|
211
|
+
enabled: true,
|
|
212
|
+
check: async (ctx) => {
|
|
213
|
+
try {
|
|
214
|
+
const rows = await ctx.db.query(
|
|
215
|
+
`SELECT COUNT(*) as cnt FROM agent_memory
|
|
216
|
+
WHERE agent_id = $1
|
|
217
|
+
AND category = 'context'
|
|
218
|
+
AND importance = 'high'
|
|
219
|
+
AND content LIKE '%deadline%'
|
|
220
|
+
AND created_at > NOW() - INTERVAL '48 hours'`,
|
|
221
|
+
[ctx.agentId]
|
|
222
|
+
);
|
|
223
|
+
const urgentTasks = parseInt(rows?.[0]?.cnt || "0");
|
|
224
|
+
if (urgentTasks > 0) {
|
|
225
|
+
return {
|
|
226
|
+
needsAction: true,
|
|
227
|
+
summary: `${urgentTasks} task(s) with approaching deadlines. Agent should review and prioritize.`,
|
|
228
|
+
priority: "high",
|
|
229
|
+
data: { urgentTasks }
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
return { needsAction: false, priority: "low" };
|
|
233
|
+
} catch {
|
|
234
|
+
return { needsAction: false, priority: "low" };
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
function createErrorRateCheck() {
|
|
240
|
+
return {
|
|
241
|
+
id: "error_rate",
|
|
242
|
+
name: "Error Rate Monitor",
|
|
243
|
+
intervalMs: 15 * 6e4,
|
|
244
|
+
// 15 minutes
|
|
245
|
+
priority: "high",
|
|
246
|
+
requiresClockIn: false,
|
|
247
|
+
// errors can happen anytime
|
|
248
|
+
consecutiveNoOps: 0,
|
|
249
|
+
enabled: true,
|
|
250
|
+
check: async (ctx) => {
|
|
251
|
+
try {
|
|
252
|
+
const totalRows = await ctx.db.query(
|
|
253
|
+
`SELECT COUNT(*) as cnt FROM agent_sessions
|
|
254
|
+
WHERE agent_id = $1 AND created_at > NOW() - INTERVAL '1 hour'`,
|
|
255
|
+
[ctx.agentId]
|
|
256
|
+
);
|
|
257
|
+
const failedRows = await ctx.db.query(
|
|
258
|
+
`SELECT COUNT(*) as cnt FROM agent_sessions
|
|
259
|
+
WHERE agent_id = $1 AND status = 'failed' AND created_at > NOW() - INTERVAL '1 hour'`,
|
|
260
|
+
[ctx.agentId]
|
|
261
|
+
);
|
|
262
|
+
const total = parseInt(totalRows?.[0]?.cnt || "0");
|
|
263
|
+
const failed = parseInt(failedRows?.[0]?.cnt || "0");
|
|
264
|
+
if (total >= 3 && failed / total > 0.5) {
|
|
265
|
+
return {
|
|
266
|
+
needsAction: true,
|
|
267
|
+
summary: `High error rate: ${failed}/${total} sessions failed in the last hour (${Math.round(failed / total * 100)}%). Possible infrastructure issue.`,
|
|
268
|
+
priority: "urgent",
|
|
269
|
+
data: { total, failed, rate: failed / total }
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
return { needsAction: false, priority: "low" };
|
|
273
|
+
} catch {
|
|
274
|
+
return { needsAction: false, priority: "low" };
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
var AgentHeartbeatManager = class {
|
|
280
|
+
config;
|
|
281
|
+
settings;
|
|
282
|
+
checks = /* @__PURE__ */ new Map();
|
|
283
|
+
tickTimer = null;
|
|
284
|
+
globalConsecutiveNoOps = 0;
|
|
285
|
+
lastActionTimestamp = 0;
|
|
286
|
+
stats = {
|
|
287
|
+
totalTicks: 0,
|
|
288
|
+
totalChecksRun: 0,
|
|
289
|
+
totalActionsTriggered: 0,
|
|
290
|
+
totalTokensSaved: 0,
|
|
291
|
+
// estimated tokens NOT spent due to no-op ticks
|
|
292
|
+
startedAt: Date.now()
|
|
293
|
+
};
|
|
294
|
+
constructor(config, settings) {
|
|
295
|
+
this.config = config;
|
|
296
|
+
this.settings = { ...DEFAULT_SETTINGS, ...settings };
|
|
297
|
+
this.registerCheck(createUnreadEmailCheck());
|
|
298
|
+
this.registerCheck(createUpcomingEventsCheck());
|
|
299
|
+
this.registerCheck(createStaleSessionsCheck());
|
|
300
|
+
this.registerCheck(createMemoryHealthCheck());
|
|
301
|
+
this.registerCheck(createUnansweredChatCheck());
|
|
302
|
+
this.registerCheck(createTaskDeadlineCheck());
|
|
303
|
+
this.registerCheck(createErrorRateCheck());
|
|
304
|
+
if (config.enabledChecks) {
|
|
305
|
+
for (const [id, enabled] of Object.entries(config.enabledChecks)) {
|
|
306
|
+
const check = this.checks.get(id);
|
|
307
|
+
if (check) check.enabled = enabled;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
registerCheck(check) {
|
|
312
|
+
this.checks.set(check.id, check);
|
|
313
|
+
}
|
|
314
|
+
async start() {
|
|
315
|
+
if (!this.settings.enabled) {
|
|
316
|
+
console.log("[heartbeat] Disabled, skipping");
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
console.log(`[heartbeat] Starting with ${this.checks.size} checks, base interval ${this.settings.baseIntervalMs / 1e3}s`);
|
|
320
|
+
setTimeout(() => this.tick(), 6e4);
|
|
321
|
+
this.scheduleNextTick();
|
|
322
|
+
}
|
|
323
|
+
stop() {
|
|
324
|
+
if (this.tickTimer) {
|
|
325
|
+
clearTimeout(this.tickTimer);
|
|
326
|
+
this.tickTimer = null;
|
|
327
|
+
}
|
|
328
|
+
console.log(`[heartbeat] Stopped. Stats: ${this.stats.totalTicks} ticks, ${this.stats.totalChecksRun} checks, ${this.stats.totalActionsTriggered} actions, ~${this.stats.totalTokensSaved} tokens saved`);
|
|
329
|
+
}
|
|
330
|
+
getStats() {
|
|
331
|
+
return {
|
|
332
|
+
...this.stats,
|
|
333
|
+
uptimeMs: Date.now() - this.stats.startedAt,
|
|
334
|
+
currentIntervalMs: this.calculateInterval(),
|
|
335
|
+
globalConsecutiveNoOps: this.globalConsecutiveNoOps,
|
|
336
|
+
checks: Array.from(this.checks.values()).map((c) => ({
|
|
337
|
+
id: c.id,
|
|
338
|
+
name: c.name,
|
|
339
|
+
enabled: c.enabled,
|
|
340
|
+
lastRunAt: c.lastRunAt,
|
|
341
|
+
lastActionAt: c.lastActionAt,
|
|
342
|
+
consecutiveNoOps: c.consecutiveNoOps
|
|
343
|
+
}))
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
// ─── Core Tick Logic ────────────────────────────────
|
|
347
|
+
async tick() {
|
|
348
|
+
this.stats.totalTicks++;
|
|
349
|
+
const now = /* @__PURE__ */ new Date();
|
|
350
|
+
const tz = this.config.timezone || "UTC";
|
|
351
|
+
const localTime = new Date(now.toLocaleString("en-US", { timeZone: tz }));
|
|
352
|
+
const hour = localTime.getHours();
|
|
353
|
+
const minute = localTime.getMinutes();
|
|
354
|
+
const dayOfWeek = localTime.getDay();
|
|
355
|
+
const isWorkHours = this.isWithinWorkHours(hour, minute, dayOfWeek);
|
|
356
|
+
const isQuietHours = this.isQuietHours(hour);
|
|
357
|
+
const isClockedIn = this.config.isClockedIn();
|
|
358
|
+
const ctx = {
|
|
359
|
+
agentId: this.config.agentId,
|
|
360
|
+
orgId: this.config.orgId,
|
|
361
|
+
agentName: this.config.agentName,
|
|
362
|
+
role: this.config.role,
|
|
363
|
+
managerEmail: this.config.managerEmail,
|
|
364
|
+
timezone: tz,
|
|
365
|
+
db: this.config.db,
|
|
366
|
+
now,
|
|
367
|
+
localTime,
|
|
368
|
+
hour,
|
|
369
|
+
minute,
|
|
370
|
+
dayOfWeek,
|
|
371
|
+
isWorkHours,
|
|
372
|
+
isClockedIn
|
|
373
|
+
};
|
|
374
|
+
const actionableItems = [];
|
|
375
|
+
for (const check of this.checks.values()) {
|
|
376
|
+
if (!check.enabled) continue;
|
|
377
|
+
if (check.requiresClockIn && !isClockedIn) continue;
|
|
378
|
+
if (isQuietHours && check.priority !== "high") continue;
|
|
379
|
+
const adaptiveInterval = Math.min(
|
|
380
|
+
check.intervalMs * (1 + this.settings.dampingFactor * check.consecutiveNoOps),
|
|
381
|
+
this.settings.maxIntervalMs
|
|
382
|
+
);
|
|
383
|
+
const timeSinceLastRun = now.getTime() - (check.lastRunAt || 0);
|
|
384
|
+
if (timeSinceLastRun < adaptiveInterval) continue;
|
|
385
|
+
this.stats.totalChecksRun++;
|
|
386
|
+
check.lastRunAt = now.getTime();
|
|
387
|
+
try {
|
|
388
|
+
const result = await check.check(ctx);
|
|
389
|
+
if (result.needsAction) {
|
|
390
|
+
actionableItems.push({ check, result });
|
|
391
|
+
check.consecutiveNoOps = 0;
|
|
392
|
+
check.lastActionAt = now.getTime();
|
|
393
|
+
} else {
|
|
394
|
+
check.consecutiveNoOps++;
|
|
395
|
+
this.stats.totalTokensSaved += 500;
|
|
396
|
+
}
|
|
397
|
+
} catch (err) {
|
|
398
|
+
console.warn(`[heartbeat] Check ${check.id} error: ${err.message}`);
|
|
399
|
+
check.consecutiveNoOps++;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
if (actionableItems.length > 0) {
|
|
403
|
+
this.globalConsecutiveNoOps = 0;
|
|
404
|
+
this.lastActionTimestamp = now.getTime();
|
|
405
|
+
this.stats.totalActionsTriggered++;
|
|
406
|
+
const priorityOrder = { urgent: 0, high: 1, medium: 2, low: 3 };
|
|
407
|
+
actionableItems.sort((a, b) => priorityOrder[a.result.priority] - priorityOrder[b.result.priority]);
|
|
408
|
+
const batch = actionableItems.slice(0, this.settings.maxBatchSize);
|
|
409
|
+
await this.dispatchBatch(batch, ctx);
|
|
410
|
+
} else {
|
|
411
|
+
this.globalConsecutiveNoOps++;
|
|
412
|
+
}
|
|
413
|
+
this.scheduleNextTick();
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Calculate next tick interval using damped oscillator model:
|
|
417
|
+
* interval = base * (1 + damping * consecutiveNoOps)
|
|
418
|
+
*
|
|
419
|
+
* With fibonacci-like acceleration:
|
|
420
|
+
* After 0 no-ops: 5min (base)
|
|
421
|
+
* After 1 no-op: 7.5min
|
|
422
|
+
* After 2 no-ops: 10min
|
|
423
|
+
* After 4 no-ops: 15min
|
|
424
|
+
* After 8 no-ops: 25min
|
|
425
|
+
* After 10 no-ops: 30min (max)
|
|
426
|
+
*
|
|
427
|
+
* Resets to base immediately when action is detected.
|
|
428
|
+
*/
|
|
429
|
+
calculateInterval() {
|
|
430
|
+
const base = this.settings.baseIntervalMs;
|
|
431
|
+
const max = this.settings.maxIntervalMs;
|
|
432
|
+
const damping = this.settings.dampingFactor;
|
|
433
|
+
const noOps = this.globalConsecutiveNoOps;
|
|
434
|
+
return Math.min(base * (1 + damping * noOps), max);
|
|
435
|
+
}
|
|
436
|
+
scheduleNextTick() {
|
|
437
|
+
if (this.tickTimer) clearTimeout(this.tickTimer);
|
|
438
|
+
const interval = this.calculateInterval();
|
|
439
|
+
this.tickTimer = setTimeout(() => this.tick(), interval);
|
|
440
|
+
this.tickTimer.unref();
|
|
441
|
+
}
|
|
442
|
+
isWithinWorkHours(hour, minute, dayOfWeek) {
|
|
443
|
+
const schedule = this.config.schedule;
|
|
444
|
+
if (!schedule) return true;
|
|
445
|
+
const isWorkday = schedule.days.includes(dayOfWeek);
|
|
446
|
+
const timeStr = `${String(hour).padStart(2, "0")}:${String(minute).padStart(2, "0")}`;
|
|
447
|
+
const isWithinHours = timeStr >= schedule.start && timeStr < schedule.end;
|
|
448
|
+
return isWorkday && isWithinHours;
|
|
449
|
+
}
|
|
450
|
+
isQuietHours(hour) {
|
|
451
|
+
const start = this.settings.quietHoursStart;
|
|
452
|
+
const end = this.settings.quietHoursEnd;
|
|
453
|
+
if (start === void 0 || end === void 0) return false;
|
|
454
|
+
if (start > end) {
|
|
455
|
+
return hour >= start || hour < end;
|
|
456
|
+
}
|
|
457
|
+
return hour >= start && hour < end;
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Dispatch a batch of actionable items to the agent via one LLM session.
|
|
461
|
+
* This is the ONLY place tokens are spent.
|
|
462
|
+
*/
|
|
463
|
+
async dispatchBatch(items, ctx) {
|
|
464
|
+
if (!this.config.runtime) {
|
|
465
|
+
console.warn("[heartbeat] No runtime \u2014 cannot dispatch actions");
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
try {
|
|
469
|
+
const { guardrails } = await import("./routes-4ZUIJ4HE.js");
|
|
470
|
+
const status = await guardrails.getStatus(ctx.agentId);
|
|
471
|
+
if (status.paused || status.offDuty) {
|
|
472
|
+
console.log(`[heartbeat] Skipping action dispatch \u2014 agent is ${status.offDuty ? "off duty" : "paused"}`);
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
} catch {
|
|
476
|
+
}
|
|
477
|
+
const summaries = items.map(
|
|
478
|
+
(item, i) => `${i + 1}. [${item.result.priority.toUpperCase()}] ${item.check.name}: ${item.result.summary}`
|
|
479
|
+
).join("\n");
|
|
480
|
+
const prompt = `HEARTBEAT ALERT \u2014 The following ${items.length} item(s) need your attention:
|
|
481
|
+
|
|
482
|
+
${summaries}
|
|
483
|
+
|
|
484
|
+
For each item, take the appropriate action:
|
|
485
|
+
- For unread emails: Check your inbox with gmail_search and respond to any urgent ones.
|
|
486
|
+
- For upcoming events: Check google_calendar_list for the next 2 hours and prepare.
|
|
487
|
+
- For stale sessions: Review and close any stuck sessions.
|
|
488
|
+
- For unanswered chats: Check Google Chat and respond.
|
|
489
|
+
- For error rate issues: Investigate recent failures and notify your manager if critical.
|
|
490
|
+
- For task deadlines: Review google_tasks_list and prioritize.
|
|
491
|
+
- For memory health: Consider pruning old or low-importance memories.
|
|
492
|
+
|
|
493
|
+
Be efficient \u2014 handle what you can and note what needs human intervention.
|
|
494
|
+
If something needs your manager's attention, email ${ctx.managerEmail || "your manager"}.`;
|
|
495
|
+
const systemPrompt = `You are ${ctx.agentName}, a ${ctx.role}. This is an automated heartbeat check \u2014 items flagged as needing attention. Handle them efficiently. Don't create unnecessary work \u2014 only act on what's genuinely important.`;
|
|
496
|
+
try {
|
|
497
|
+
const session = await this.config.runtime.spawnSession({
|
|
498
|
+
agentId: ctx.agentId,
|
|
499
|
+
message: prompt,
|
|
500
|
+
systemPrompt
|
|
501
|
+
});
|
|
502
|
+
console.log(`[heartbeat] \u2705 Action session ${session.id} dispatched (${items.length} items: ${items.map((i) => i.check.id).join(", ")})`);
|
|
503
|
+
} catch (err) {
|
|
504
|
+
console.error(`[heartbeat] Failed to dispatch action: ${err.message}`);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
};
|
|
508
|
+
export {
|
|
509
|
+
AgentHeartbeatManager
|
|
510
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__esm
|
|
3
|
+
} from "./chunk-KFQGP6VL.js";
|
|
4
|
+
|
|
5
|
+
// src/engine/agent-notify.ts
|
|
6
|
+
async function notifyAgent(agentId, scope, lifecycle) {
|
|
7
|
+
const port = resolveAgentPort(agentId, lifecycle);
|
|
8
|
+
if (!port) return false;
|
|
9
|
+
try {
|
|
10
|
+
const resp = await fetch(`http://127.0.0.1:${port}/reload?scope=${scope}`, {
|
|
11
|
+
method: "POST",
|
|
12
|
+
signal: AbortSignal.timeout(3e3)
|
|
13
|
+
});
|
|
14
|
+
if (resp.ok) {
|
|
15
|
+
const data = await resp.json();
|
|
16
|
+
console.log(`[notify] Agent ${agentId} reloaded: ${data.reloaded?.join(", ") || scope}`);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
} catch {
|
|
20
|
+
}
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
async function notifyAllAgents(scope, lifecycle) {
|
|
24
|
+
if (!lifecycle) return;
|
|
25
|
+
const agents = lifecycle.getAllAgents().filter((a) => a.state === "running");
|
|
26
|
+
await Promise.allSettled(agents.map((a) => notifyAgent(a.id, scope, lifecycle)));
|
|
27
|
+
}
|
|
28
|
+
function resolveAgentPort(agentId, lifecycle) {
|
|
29
|
+
if (!lifecycle) return null;
|
|
30
|
+
const agent = lifecycle.getAgent(agentId);
|
|
31
|
+
if (!agent) return null;
|
|
32
|
+
const dep = agent.config?.deployment;
|
|
33
|
+
return dep?.port || dep?.config?.local?.port || null;
|
|
34
|
+
}
|
|
35
|
+
var init_agent_notify = __esm({
|
|
36
|
+
"src/engine/agent-notify.ts"() {
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
init_agent_notify();
|
|
40
|
+
export {
|
|
41
|
+
notifyAgent,
|
|
42
|
+
notifyAllAgents
|
|
43
|
+
};
|
|
@@ -13735,7 +13735,7 @@ async function createAllTools(options) {
|
|
|
13735
13735
|
workspaceTools = workspaceTools.concat(createMeetingLifecycleTools({ tokenProvider: tp }, options));
|
|
13736
13736
|
}
|
|
13737
13737
|
if (provider === "microsoft") {
|
|
13738
|
-
const { createAllMicrosoftTools } = await import("./microsoft-
|
|
13738
|
+
const { createAllMicrosoftTools } = await import("./microsoft-VREAZ7M2.js");
|
|
13739
13739
|
const msOpts = options?.enabledMicrosoftServices ? { ...options, enabledMicrosoftServices: options.enabledMicrosoftServices } : options;
|
|
13740
13740
|
workspaceTools = createAllMicrosoftTools({ tokenProvider: tp }, msOpts);
|
|
13741
13741
|
}
|
|
@@ -8535,7 +8535,7 @@ function createDatabaseTools(options) {
|
|
|
8535
8535
|
var entDbQuery = {
|
|
8536
8536
|
name: "ent_db_query",
|
|
8537
8537
|
label: "Database Query",
|
|
8538
|
-
description: "Execute a read-only SQL query against a database
|
|
8538
|
+
description: "Execute a read-only SQL query against a LOCAL SQLite database file. For external/cloud databases, use db_query instead.",
|
|
8539
8539
|
category: "utility",
|
|
8540
8540
|
risk: "medium",
|
|
8541
8541
|
parameters: {
|
|
@@ -8688,8 +8688,8 @@ function createDatabaseTools(options) {
|
|
|
8688
8688
|
};
|
|
8689
8689
|
var entDbConnections = {
|
|
8690
8690
|
name: "ent_db_connections",
|
|
8691
|
-
label: "List Database
|
|
8692
|
-
description: "List
|
|
8691
|
+
label: "List Local Database Files",
|
|
8692
|
+
description: "List LOCAL SQLite database files found in the workspace directory. ONLY for local .db/.sqlite files on this machine. For external/cloud databases (Postgres, MySQL, Supabase, etc.) granted by your admin, use db_list_connections instead.",
|
|
8693
8693
|
category: "utility",
|
|
8694
8694
|
risk: "low",
|
|
8695
8695
|
parameters: {
|
|
@@ -8728,8 +8728,8 @@ function createDatabaseTools(options) {
|
|
|
8728
8728
|
};
|
|
8729
8729
|
var entDbTables = {
|
|
8730
8730
|
name: "ent_db_tables",
|
|
8731
|
-
label: "List Tables",
|
|
8732
|
-
description: "List all tables in a database
|
|
8731
|
+
label: "List Local DB Tables",
|
|
8732
|
+
description: "List all tables in a LOCAL SQLite database file. For external/cloud databases, use db_list_tables instead.",
|
|
8733
8733
|
category: "utility",
|
|
8734
8734
|
risk: "low",
|
|
8735
8735
|
parameters: {
|
|
@@ -13677,7 +13677,7 @@ async function createAllTools(options) {
|
|
|
13677
13677
|
rawTools = rawTools.concat(visualMemoryTools);
|
|
13678
13678
|
if (options?.databaseManager && options?.agentId) {
|
|
13679
13679
|
try {
|
|
13680
|
-
const { createDatabaseTools: createDbAccessTools } = await import("./agent-tools-
|
|
13680
|
+
const { createDatabaseTools: createDbAccessTools } = await import("./agent-tools-4QK7LLNP.js");
|
|
13681
13681
|
const dbAccessTools = createDbAccessTools(options.databaseManager, options.agentId);
|
|
13682
13682
|
rawTools = rawTools.concat(dbAccessTools);
|
|
13683
13683
|
} catch (e) {
|
|
@@ -13735,7 +13735,7 @@ async function createAllTools(options) {
|
|
|
13735
13735
|
workspaceTools = workspaceTools.concat(createMeetingLifecycleTools({ tokenProvider: tp }, options));
|
|
13736
13736
|
}
|
|
13737
13737
|
if (provider === "microsoft") {
|
|
13738
|
-
const { createAllMicrosoftTools } = await import("./microsoft-
|
|
13738
|
+
const { createAllMicrosoftTools } = await import("./microsoft-VREAZ7M2.js");
|
|
13739
13739
|
const msOpts = options?.enabledMicrosoftServices ? { ...options, enabledMicrosoftServices: options.enabledMicrosoftServices } : options;
|
|
13740
13740
|
workspaceTools = createAllMicrosoftTools({ tokenProvider: tp }, msOpts);
|
|
13741
13741
|
}
|
|
@@ -8535,7 +8535,7 @@ function createDatabaseTools(options) {
|
|
|
8535
8535
|
var entDbQuery = {
|
|
8536
8536
|
name: "ent_db_query",
|
|
8537
8537
|
label: "Database Query",
|
|
8538
|
-
description: "Execute a read-only SQL query against a database
|
|
8538
|
+
description: "Execute a read-only SQL query against a LOCAL SQLite database file. For external/cloud databases, use db_query instead.",
|
|
8539
8539
|
category: "utility",
|
|
8540
8540
|
risk: "medium",
|
|
8541
8541
|
parameters: {
|
|
@@ -8688,8 +8688,8 @@ function createDatabaseTools(options) {
|
|
|
8688
8688
|
};
|
|
8689
8689
|
var entDbConnections = {
|
|
8690
8690
|
name: "ent_db_connections",
|
|
8691
|
-
label: "List Database
|
|
8692
|
-
description: "List
|
|
8691
|
+
label: "List Local Database Files",
|
|
8692
|
+
description: "List LOCAL SQLite database files found in the workspace directory. ONLY for local .db/.sqlite files on this machine. For external/cloud databases (Postgres, MySQL, Supabase, etc.) granted by your admin, use db_list_connections instead.",
|
|
8693
8693
|
category: "utility",
|
|
8694
8694
|
risk: "low",
|
|
8695
8695
|
parameters: {
|
|
@@ -8728,8 +8728,8 @@ function createDatabaseTools(options) {
|
|
|
8728
8728
|
};
|
|
8729
8729
|
var entDbTables = {
|
|
8730
8730
|
name: "ent_db_tables",
|
|
8731
|
-
label: "List Tables",
|
|
8732
|
-
description: "List all tables in a database
|
|
8731
|
+
label: "List Local DB Tables",
|
|
8732
|
+
description: "List all tables in a LOCAL SQLite database file. For external/cloud databases, use db_list_tables instead.",
|
|
8733
8733
|
category: "utility",
|
|
8734
8734
|
risk: "low",
|
|
8735
8735
|
parameters: {
|
|
@@ -13677,7 +13677,7 @@ async function createAllTools(options) {
|
|
|
13677
13677
|
rawTools = rawTools.concat(visualMemoryTools);
|
|
13678
13678
|
if (options?.databaseManager && options?.agentId) {
|
|
13679
13679
|
try {
|
|
13680
|
-
const { createDatabaseTools: createDbAccessTools } = await import("./agent-tools-
|
|
13680
|
+
const { createDatabaseTools: createDbAccessTools } = await import("./agent-tools-OAWVZBMW.js");
|
|
13681
13681
|
const dbAccessTools = createDbAccessTools(options.databaseManager, options.agentId);
|
|
13682
13682
|
rawTools = rawTools.concat(dbAccessTools);
|
|
13683
13683
|
} catch (e) {
|
|
@@ -13735,7 +13735,7 @@ async function createAllTools(options) {
|
|
|
13735
13735
|
workspaceTools = workspaceTools.concat(createMeetingLifecycleTools({ tokenProvider: tp }, options));
|
|
13736
13736
|
}
|
|
13737
13737
|
if (provider === "microsoft") {
|
|
13738
|
-
const { createAllMicrosoftTools } = await import("./microsoft-
|
|
13738
|
+
const { createAllMicrosoftTools } = await import("./microsoft-VREAZ7M2.js");
|
|
13739
13739
|
const msOpts = options?.enabledMicrosoftServices ? { ...options, enabledMicrosoftServices: options.enabledMicrosoftServices } : options;
|
|
13740
13740
|
workspaceTools = createAllMicrosoftTools({ tokenProvider: tp }, msOpts);
|
|
13741
13741
|
}
|