@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.
Files changed (330) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/CODE_OF_CONDUCT.md +31 -0
  3. package/README.md +118 -38
  4. package/SECURITY.md +42 -0
  5. package/dist/agent-heartbeat-3FWNHZFX.js +510 -0
  6. package/dist/agent-heartbeat-4RWHZR7H.js +510 -0
  7. package/dist/agent-heartbeat-6ZGB5ILY.js +510 -0
  8. package/dist/agent-heartbeat-BIVHLKFM.js +510 -0
  9. package/dist/agent-heartbeat-HRKVFK2T.js +510 -0
  10. package/dist/agent-heartbeat-JC5GWVXD.js +510 -0
  11. package/dist/agent-heartbeat-K6A4HMHB.js +510 -0
  12. package/dist/agent-heartbeat-LCDXWFVB.js +510 -0
  13. package/dist/agent-heartbeat-P7HZCZAQ.js +510 -0
  14. package/dist/agent-heartbeat-PUIRSNIO.js +510 -0
  15. package/dist/agent-heartbeat-SN5ILQ6Y.js +510 -0
  16. package/dist/agent-heartbeat-TW5YTDYC.js +510 -0
  17. package/dist/agent-heartbeat-Z2QQXROL.js +510 -0
  18. package/dist/agent-notify-OEQBCZLN.js +43 -0
  19. package/dist/{agent-tools-263HM5QU.js → agent-tools-3W7XLUYA.js} +1 -1
  20. package/dist/agent-tools-4QK7LLNP.js +9 -0
  21. package/dist/agent-tools-54VZGT6L.js +9 -0
  22. package/dist/{agent-tools-AT4D276V.js → agent-tools-AYYDPO27.js} +7 -7
  23. package/dist/{agent-tools-MSTAPX2I.js → agent-tools-F2X47FKF.js} +7 -7
  24. package/dist/{agent-tools-FA26SY5O.js → agent-tools-O6W3QAZL.js} +11 -6
  25. package/dist/agent-tools-OAWVZBMW.js +9 -0
  26. package/dist/agent-tools-QCCU74PN.js +13949 -0
  27. package/dist/chunk-2LHUARN6.js +4929 -0
  28. package/dist/chunk-2WVCNCYC.js +5087 -0
  29. package/dist/{chunk-6PWDS7KY.js → chunk-3FM6YQUK.js} +20 -20
  30. package/dist/chunk-3UAFHUEC.js +212 -0
  31. package/dist/{chunk-WJO57PMO.js → chunk-46GOWZT4.js} +20 -20
  32. package/dist/{chunk-BNRE7TSX.js → chunk-5KYJAUZV.js} +3 -3
  33. package/dist/chunk-6C5PKREN.js +467 -0
  34. package/dist/{chunk-447MTPZF.js → chunk-6ZMLNEHB.js} +3 -3
  35. package/dist/chunk-BPZQT5N5.js +25652 -0
  36. package/dist/chunk-BQM7MBPS.js +1380 -0
  37. package/dist/{chunk-ZRFKGPIU.js → chunk-C52OQNNY.js} +20 -20
  38. package/dist/chunk-C7HGQF4Y.js +25652 -0
  39. package/dist/chunk-CAHNZGGK.js +25656 -0
  40. package/dist/{chunk-FL3CH3ET.js → chunk-CK7R6UHE.js} +51 -27
  41. package/dist/chunk-D36RPWB7.js +25652 -0
  42. package/dist/{chunk-36NM2B4C.js → chunk-DJK2UPFH.js} +63 -93
  43. package/dist/chunk-DM7FTF7W.js +4929 -0
  44. package/dist/chunk-DMD24UFZ.js +5101 -0
  45. package/dist/{chunk-36XNMIHA.js → chunk-DXZGPUAF.js} +20 -20
  46. package/dist/chunk-F46WB5IL.js +5087 -0
  47. package/dist/chunk-F5QG5SQH.js +5087 -0
  48. package/dist/{chunk-JGEVQZDR.js → chunk-FLQ5FLHW.js} +13 -16
  49. package/dist/chunk-H7GP733U.js +5087 -0
  50. package/dist/{chunk-OZSQLOV6.js → chunk-HHBXWB5U.js} +415 -19
  51. package/dist/{chunk-D24JY75H.js → chunk-IMXS4N6W.js} +3 -3
  52. package/dist/{chunk-6PVBV6ZP.js → chunk-JNMDD7JY.js} +3 -3
  53. package/dist/chunk-JTV5LA47.js +1519 -0
  54. package/dist/chunk-KV6G7NZX.js +1519 -0
  55. package/dist/chunk-MU5MEBIK.js +1519 -0
  56. package/dist/chunk-NLT5MC7X.js +465 -0
  57. package/dist/{chunk-GTFZZUXX.js → chunk-NVLYIM4J.js} +51 -27
  58. package/dist/{chunk-6G5SXLXC.js → chunk-NZY2BIZH.js} +63 -93
  59. package/dist/chunk-O42L6G67.js +1519 -0
  60. package/dist/chunk-OCNERGGM.js +4891 -0
  61. package/dist/chunk-OJSNHONE.js +1519 -0
  62. package/dist/{chunk-2TAZJWJN.js → chunk-OWL3QVH7.js} +18 -0
  63. package/dist/{chunk-P3HVY2HS.js → chunk-OWTLNV4Q.js} +382 -7
  64. package/dist/chunk-PCNYEP6T.js +4891 -0
  65. package/dist/{chunk-YL3Z5KPR.js → chunk-PI4AQ4Z6.js} +438 -15
  66. package/dist/chunk-PN3EGTCA.js +194 -0
  67. package/dist/chunk-Q37UKNRC.js +1519 -0
  68. package/dist/chunk-QXTC6J7H.js +5087 -0
  69. package/dist/{chunk-SPBQVNDI.js → chunk-RKERL5LZ.js} +25 -21
  70. package/dist/chunk-RVBK2IOX.js +25652 -0
  71. package/dist/chunk-SAKODCZ5.js +4891 -0
  72. package/dist/{chunk-XV4TU65E.js → chunk-SALGFC5L.js} +51 -27
  73. package/dist/chunk-STGWZ2MS.js +1519 -0
  74. package/dist/chunk-UY3ZVQDP.js +25652 -0
  75. package/dist/chunk-V6OSD62M.js +5087 -0
  76. package/dist/chunk-VP6YAHX4.js +1519 -0
  77. package/dist/chunk-WDYJOEAI.js +5087 -0
  78. package/dist/chunk-WEAFQNOS.js +195 -0
  79. package/dist/chunk-XKUSAZGP.js +5087 -0
  80. package/dist/chunk-Z6K5FKAB.js +548 -0
  81. package/dist/chunk-ZGE3XAXY.js +1519 -0
  82. package/dist/chunk-ZGYVXYQQ.js +3296 -0
  83. package/dist/cli-agent-7TB2BWS6.js +2370 -0
  84. package/dist/cli-agent-AKXFFST2.js +2370 -0
  85. package/dist/cli-agent-DZTKLITB.js +2357 -0
  86. package/dist/cli-agent-FOF7PFEP.js +2357 -0
  87. package/dist/cli-agent-H74M2ZYN.js +2357 -0
  88. package/dist/cli-agent-HORWVPHB.js +2370 -0
  89. package/dist/cli-agent-HSZT6SKF.js +2423 -0
  90. package/dist/cli-agent-JLUQ4ZU6.js +2424 -0
  91. package/dist/cli-agent-MVCDH4HV.js +2370 -0
  92. package/dist/cli-agent-NZXOEPJ2.js +2357 -0
  93. package/dist/cli-agent-PADN3QRC.js +2357 -0
  94. package/dist/cli-agent-QAYEX3BE.js +2441 -0
  95. package/dist/cli-agent-QT64DT5J.js +2370 -0
  96. package/dist/cli-agent-TFL2M6UK.js +2424 -0
  97. package/dist/cli-agent-UIKXATTD.js +2357 -0
  98. package/dist/cli-agent-UJN6FYTO.js +2370 -0
  99. package/dist/cli-agent-VIQAYVY4.js +2357 -0
  100. package/dist/cli-agent-WNWFVOFM.js +2370 -0
  101. package/dist/cli-agent-XBQX67VJ.js +2423 -0
  102. package/dist/cli-agent-ZLSC6FF4.js +2357 -0
  103. package/dist/cli-serve-2IL5DTEY.js +153 -0
  104. package/dist/cli-serve-47N5UKKW.js +153 -0
  105. package/dist/cli-serve-4XGZFUV2.js +140 -0
  106. package/dist/cli-serve-6OT3UEAN.js +140 -0
  107. package/dist/cli-serve-7L6EY5UH.js +153 -0
  108. package/dist/cli-serve-BDGOOOKQ.js +260 -0
  109. package/dist/cli-serve-BFNIW2LF.js +153 -0
  110. package/dist/cli-serve-C7MN6U5Q.js +153 -0
  111. package/dist/cli-serve-CR3OY3IM.js +153 -0
  112. package/dist/cli-serve-DAJFRWQ7.js +153 -0
  113. package/dist/cli-serve-FW6FHFW4.js +153 -0
  114. package/dist/cli-serve-GEEOQS77.js +153 -0
  115. package/dist/cli-serve-H562I3ZK.js +153 -0
  116. package/dist/cli-serve-HDQZF4C4.js +153 -0
  117. package/dist/cli-serve-LICAOMEB.js +140 -0
  118. package/dist/cli-serve-LLGYLWFS.js +153 -0
  119. package/dist/cli-serve-N3OISDNB.js +153 -0
  120. package/dist/cli-serve-TIZ27EVR.js +153 -0
  121. package/dist/cli-serve-TUNI2RCN.js +153 -0
  122. package/dist/cli-serve-WNOZMAWD.js +153 -0
  123. package/dist/cli-validate-Z726VJCN.js +150 -0
  124. package/dist/cli.js +4 -4
  125. package/dist/connection-manager-KAWEUWUR.js +9 -0
  126. package/dist/dashboard/app.js +9 -3
  127. package/dist/dashboard/components/knowledge-link.js +15 -0
  128. package/dist/dashboard/components/settings-help.js +4 -2
  129. package/dist/dashboard/docs/agent-deployment.html +33 -1
  130. package/dist/dashboard/docs/settings-network.html +321 -0
  131. package/dist/dashboard/docs/settings-security.html +347 -0
  132. package/dist/dashboard/docs/settings-tool-security.html +176 -0
  133. package/dist/dashboard/docs/settings.html +36 -16
  134. package/dist/dashboard/pages/agent-detail/deployment.js +39 -6
  135. package/dist/dashboard/pages/agent-detail/tools.js +10 -0
  136. package/dist/dashboard/pages/database-access.js +4 -3
  137. package/dist/dashboard/pages/settings.js +174 -37
  138. package/dist/dashboard/pages/task-pipeline.js +400 -843
  139. package/dist/db-adapter-2T56ORSD.js +7 -0
  140. package/dist/db-adapter-IRHOUMVC.js +7 -0
  141. package/dist/index.js +41 -41
  142. package/dist/microsoft-VREAZ7M2.js +3955 -0
  143. package/dist/routes-3MMLQTB6.js +90 -0
  144. package/dist/routes-4ZUIJ4HE.js +90 -0
  145. package/dist/routes-5MXHKKH4.js +90 -0
  146. package/dist/routes-64NJFK3B.js +90 -0
  147. package/dist/routes-6AKQ2LBV.js +90 -0
  148. package/dist/routes-CRRBUDO4.js +90 -0
  149. package/dist/routes-DIAF3MC3.js +90 -0
  150. package/dist/routes-KMUNU6CY.js +90 -0
  151. package/dist/routes-LRRLXIZR.js +90 -0
  152. package/dist/routes-N647AJYG.js +90 -0
  153. package/dist/routes-SSSELAAR.js +90 -0
  154. package/dist/routes-STERVGKJ.js +90 -0
  155. package/dist/routes-ZEZZACZP.js +90 -0
  156. package/dist/runtime-5EQN4GFM.js +45 -0
  157. package/dist/runtime-5LP7PUD4.js +45 -0
  158. package/dist/runtime-6BULDBR3.js +45 -0
  159. package/dist/runtime-6YEENDN3.js +45 -0
  160. package/dist/runtime-7LQFRG3B.js +45 -0
  161. package/dist/runtime-AMXJU2MB.js +45 -0
  162. package/dist/runtime-D6WSE7FG.js +45 -0
  163. package/dist/runtime-EYVN7NFJ.js +45 -0
  164. package/dist/runtime-F6RPWQVW.js +45 -0
  165. package/dist/runtime-FYMJURFC.js +45 -0
  166. package/dist/runtime-JRNBL4O4.js +45 -0
  167. package/dist/runtime-OM2NIBMI.js +45 -0
  168. package/dist/runtime-QWPVD7CY.js +45 -0
  169. package/dist/runtime-YLIIPTE4.js +45 -0
  170. package/dist/runtime-YU6P22CG.js +45 -0
  171. package/dist/screen-unlock-4RPZBHOI.js +118 -0
  172. package/dist/server-AMCSXINC.js +28 -0
  173. package/dist/server-CU6LVQS4.js +28 -0
  174. package/dist/server-DFYGH2CV.js +28 -0
  175. package/dist/server-EELWOC3X.js +28 -0
  176. package/dist/server-EN5E2OWQ.js +28 -0
  177. package/dist/server-GW2HYJYI.js +28 -0
  178. package/dist/server-J25NCRWJ.js +28 -0
  179. package/dist/server-JDGNOTFV.js +28 -0
  180. package/dist/server-NE5HD5DJ.js +28 -0
  181. package/dist/server-NQOT7W77.js +28 -0
  182. package/dist/server-PWE5PQTR.js +28 -0
  183. package/dist/server-Q2Q32H2B.js +28 -0
  184. package/dist/server-Q77ME7TL.js +28 -0
  185. package/dist/server-WLLH4WST.js +28 -0
  186. package/dist/server-WTUJ2O3F.js +28 -0
  187. package/dist/server-X4CJTHHF.js +28 -0
  188. package/dist/server-XK3ILCJC.js +28 -0
  189. package/dist/server-ZRD3NDJE.js +28 -0
  190. package/dist/setup-44VBAO4J.js +20 -0
  191. package/dist/setup-4ONNQBWB.js +20 -0
  192. package/dist/setup-4OSBXSCL.js +20 -0
  193. package/dist/setup-4QFGRBLZ.js +20 -0
  194. package/dist/setup-6766SGAR.js +20 -0
  195. package/dist/setup-AYY24DKM.js +20 -0
  196. package/dist/setup-B34N4HPU.js +20 -0
  197. package/dist/setup-E2YLC2EY.js +20 -0
  198. package/dist/setup-ER6NXTY5.js +20 -0
  199. package/dist/setup-H2AGCBW5.js +20 -0
  200. package/dist/setup-ICOZRKCX.js +20 -0
  201. package/dist/setup-JFTJH7UF.js +20 -0
  202. package/dist/setup-PRFNI6YW.js +20 -0
  203. package/dist/setup-RAHBMYHE.js +20 -0
  204. package/dist/setup-TXPR5UQX.js +20 -0
  205. package/dist/setup-XCJMELVU.js +20 -0
  206. package/dist/setup-XIYEIFVK.js +20 -0
  207. package/dist/setup-Z4PZSHBI.js +20 -0
  208. package/dist/skills-FR7I5V7H.js +16 -0
  209. package/dist/skills-HCVBA6PK.js +16 -0
  210. package/dist/system-prompts-TM7OA32C.js +913 -0
  211. package/dist/task-queue-O7IVZYUO.js +9 -0
  212. package/dist/transport-encryption-2T7PIXKG.js +25 -0
  213. package/logs/cloudflared-error.log +61 -0
  214. package/logs/cloudflared-out.log +0 -0
  215. package/logs/enterprise-error.log +0 -0
  216. package/logs/enterprise-out.log +3 -0
  217. package/logs/fola-error.log +0 -0
  218. package/logs/fola-out.log +0 -0
  219. package/logs/john-error.log +8 -0
  220. package/logs/john-out.log +0 -0
  221. package/package.json +31 -3
  222. package/src/agent-tools/tool-resolver.ts +50 -61
  223. package/src/agent-tools/tools/enterprise-database.ts +5 -5
  224. package/src/agent-tools/tools/local/dependency-manager.ts +2 -2
  225. package/src/agent-tools/tools/microsoft/graph-api.ts +137 -26
  226. package/src/agent-tools/tools/microsoft/outlook-mail.ts +392 -100
  227. package/src/agent-tools/tools/microsoft/teams.ts +267 -48
  228. package/src/auth/routes.ts +4 -4
  229. package/src/cli-agent.ts +108 -8
  230. package/src/cli-serve.ts +140 -0
  231. package/src/dashboard/app.js +9 -3
  232. package/src/dashboard/components/knowledge-link.js +15 -0
  233. package/src/dashboard/components/settings-help.js +4 -2
  234. package/src/dashboard/docs/agent-deployment.html +33 -1
  235. package/src/dashboard/docs/settings-network.html +321 -0
  236. package/src/dashboard/docs/settings-security.html +347 -0
  237. package/src/dashboard/docs/settings-tool-security.html +176 -0
  238. package/src/dashboard/docs/settings.html +36 -16
  239. package/src/dashboard/pages/agent-detail/deployment.js +39 -6
  240. package/src/dashboard/pages/agent-detail/tools.js +10 -0
  241. package/src/dashboard/pages/database-access.js +4 -3
  242. package/src/dashboard/pages/settings.js +174 -37
  243. package/src/dashboard/pages/task-pipeline.js +400 -843
  244. package/src/database-access/agent-tools.ts +78 -63
  245. package/src/database-access/connection-manager.ts +13 -2
  246. package/src/database-access/routes.ts +13 -1
  247. package/src/db/adapter.ts +1 -0
  248. package/src/engine/agent-memory.ts +2 -1
  249. package/src/engine/agent-notify.ts +50 -0
  250. package/src/engine/agent-routes.ts +257 -4
  251. package/src/engine/db-adapter.ts +16 -0
  252. package/src/engine/lifecycle.ts +4 -0
  253. package/src/engine/routes.ts +4 -3
  254. package/src/engine/screen-unlock.ts +136 -0
  255. package/src/engine/skills/database-access.ts +78 -0
  256. package/src/engine/skills/index.ts +3 -2
  257. package/src/engine/skills.ts +2 -0
  258. package/src/engine/task-queue-routes.ts +18 -0
  259. package/src/engine/task-queue.ts +15 -2
  260. package/src/middleware/transport-encryption.ts +1 -4
  261. package/src/runtime/agent-loop.ts +4 -0
  262. package/src/runtime/index.ts +15 -6
  263. package/src/server.ts +14 -1
  264. package/src/system-prompts/google/index.ts +1 -2
  265. package/src/system-prompts/index.ts +1 -1
  266. package/src/system-prompts/microsoft/contacts.ts +34 -0
  267. package/src/system-prompts/microsoft/excel.ts +52 -0
  268. package/src/system-prompts/microsoft/index.ts +31 -0
  269. package/src/system-prompts/microsoft/onedrive.ts +41 -0
  270. package/src/system-prompts/microsoft/onenote.ts +36 -0
  271. package/src/system-prompts/microsoft/outlook-calendar.ts +37 -0
  272. package/src/system-prompts/microsoft/outlook-mail.ts +46 -0
  273. package/src/system-prompts/microsoft/planner.ts +37 -0
  274. package/src/system-prompts/microsoft/powerbi.ts +38 -0
  275. package/src/system-prompts/microsoft/powerpoint.ts +35 -0
  276. package/src/system-prompts/microsoft/sharepoint.ts +44 -0
  277. package/src/system-prompts/microsoft/teams.ts +49 -0
  278. package/src/system-prompts/microsoft/todo.ts +37 -0
  279. package/src/types/hono-env.ts +4 -0
  280. package/.github/CODEOWNERS +0 -23
  281. package/.github/workflows/publish-community-skills.yml +0 -121
  282. package/.github/workflows/validate-community-skills.yml +0 -172
  283. package/agriculture_southwest_nigeria_research.txt +0 -10
  284. package/boa_credit_cards_research.txt +0 -10
  285. package/customer_support_research_feb2026.txt +0 -10
  286. package/dist/agent-tools-LRA7PPXG.js +0 -13922
  287. package/dist/agent-tools-VAU5DOQB.js +0 -13910
  288. package/dist/agent-tools-VWV7OWXU.js +0 -13922
  289. package/dist/chunk-2Z7MWTCX.js +0 -4977
  290. package/dist/chunk-3T4XU3VV.js +0 -5010
  291. package/dist/chunk-445QM4NX.js +0 -5061
  292. package/dist/chunk-5TW3Y7DJ.js +0 -1519
  293. package/dist/chunk-6I7VY3LT.js +0 -5060
  294. package/dist/chunk-6W5EK3UP.js +0 -4977
  295. package/dist/chunk-AQMSHJQT.js +0 -5069
  296. package/dist/chunk-ASSQW7HX.js +0 -5051
  297. package/dist/chunk-CIN27FGC.js +0 -5037
  298. package/dist/chunk-CMXY3NUB.js +0 -4977
  299. package/dist/chunk-DRLMRUDP.js +0 -5052
  300. package/dist/chunk-EHI7Z446.js +0 -1519
  301. package/dist/chunk-FEAILFAQ.js +0 -1519
  302. package/dist/chunk-GA3PYBZL.js +0 -1519
  303. package/dist/chunk-GWX63G5J.js +0 -1519
  304. package/dist/chunk-HHMZ4UY6.js +0 -1519
  305. package/dist/chunk-HVQMNF7E.js +0 -4921
  306. package/dist/chunk-HXM7F3YN.js +0 -1519
  307. package/dist/chunk-K6NGOUXG.js +0 -5060
  308. package/dist/chunk-KPG5WINJ.js +0 -4977
  309. package/dist/chunk-LBCUBYDL.js +0 -1519
  310. package/dist/chunk-LIRQSWLR.js +0 -5014
  311. package/dist/chunk-LRCKO5KE.js +0 -1519
  312. package/dist/chunk-M7XL3DJD.js +0 -5069
  313. package/dist/chunk-MHJULEIQ.js +0 -1519
  314. package/dist/chunk-MJGGW6MC.js +0 -106
  315. package/dist/chunk-MMYBDHDB.js +0 -4921
  316. package/dist/chunk-MQT5FXKD.js +0 -1519
  317. package/dist/chunk-OIMPEQF5.js +0 -4977
  318. package/dist/chunk-OOU7JUYE.js +0 -542
  319. package/dist/chunk-OW4GLBHP.js +0 -1519
  320. package/dist/chunk-Q4K4MMLU.js +0 -4977
  321. package/dist/chunk-RUK4CRPF.js +0 -1519
  322. package/dist/chunk-T7H65XQY.js +0 -1519
  323. package/dist/chunk-TQVFWG57.js +0 -5064
  324. package/dist/chunk-UEPK3IMC.js +0 -1519
  325. package/dist/chunk-VUWTXJH6.js +0 -1519
  326. package/dist/chunk-WCPGGSAD.js +0 -1519
  327. package/dist/chunk-WO63NZOJ.js +0 -1519
  328. package/dist/chunk-YPJDRVUM.js +0 -5064
  329. package/dist/chunk-ZROMH5DL.js +0 -4921
  330. package/src/dashboard/docs/_template.txt +0 -92
@@ -1,7 +1,9 @@
1
1
  /**
2
2
  * Microsoft Teams Tools
3
3
  *
4
- * Team/channel messaging, chat, and presence via Microsoft Graph API.
4
+ * Comprehensive team/channel messaging, chat, presence, and collaboration
5
+ * via Microsoft Graph API. 15 tools covering teams, channels, chats, messages,
6
+ * replies, reactions, members, file sharing, and presence.
5
7
  */
6
8
 
7
9
  import type { AnyAgentTool, ToolCreationOptions } from '../../types.js';
@@ -9,23 +11,45 @@ import { jsonResult, errorResult } from '../../common.js';
9
11
  import type { MicrosoftToolsConfig } from './index.js';
10
12
  import { graph } from './graph-api.js';
11
13
 
14
+ function mapMessage(m: any): any {
15
+ return {
16
+ id: m.id,
17
+ from: m.from?.user?.displayName || m.from?.application?.displayName,
18
+ fromEmail: m.from?.user?.email,
19
+ fromUserId: m.from?.user?.id,
20
+ body: m.body?.content,
21
+ bodyType: m.body?.contentType,
22
+ date: m.createdDateTime,
23
+ lastModified: m.lastModifiedDateTime,
24
+ importance: m.importance,
25
+ subject: m.subject,
26
+ attachments: m.attachments?.map((a: any) => ({
27
+ id: a.id, name: a.name, contentType: a.contentType, contentUrl: a.contentUrl,
28
+ })),
29
+ mentions: m.mentions?.map((mt: any) => ({ id: mt.id, text: mt.mentionText, userId: mt.mentioned?.user?.id })),
30
+ reactions: m.reactions?.map((r: any) => ({ type: r.reactionType, user: r.user?.user?.displayName })),
31
+ replyCount: m.replies?.length,
32
+ };
33
+ }
34
+
12
35
  export function createTeamsTools(config: MicrosoftToolsConfig, _options?: ToolCreationOptions): AnyAgentTool[] {
13
36
  const tp = config.tokenProvider;
14
37
 
15
38
  return [
16
39
  {
17
40
  name: 'teams_list_teams',
18
- description: 'List all Teams the agent is a member of.',
41
+ description: 'List all Teams the agent is a member of, with descriptions and visibility.',
19
42
  category: 'utility' as const,
20
43
  parameters: { type: 'object' as const, properties: {}, required: [] },
21
44
  async execute(_id: string) {
22
45
  try {
23
46
  const token = await tp.getAccessToken();
24
47
  const data = await graph(token, '/me/joinedTeams', {
25
- query: { '$select': 'id,displayName,description' }
48
+ query: { '$select': 'id,displayName,description,visibility,isArchived' }
26
49
  });
27
50
  const teams = (data.value || []).map((t: any) => ({
28
51
  id: t.id, name: t.displayName, description: t.description,
52
+ visibility: t.visibility, isArchived: t.isArchived,
29
53
  }));
30
54
  return jsonResult({ teams, count: teams.length });
31
55
  } catch (e: any) { return errorResult(e.message); }
@@ -34,12 +58,13 @@ export function createTeamsTools(config: MicrosoftToolsConfig, _options?: ToolCr
34
58
 
35
59
  {
36
60
  name: 'teams_list_channels',
37
- description: 'List channels in a Team.',
61
+ description: 'List channels in a Team with membership type and description.',
38
62
  category: 'utility' as const,
39
63
  parameters: {
40
64
  type: 'object' as const,
41
65
  properties: {
42
66
  teamId: { type: 'string', description: 'Team ID' },
67
+ includePrivate: { type: 'boolean', description: 'Include private/shared channels (default: true)' },
43
68
  },
44
69
  required: ['teamId'],
45
70
  },
@@ -47,20 +72,50 @@ export function createTeamsTools(config: MicrosoftToolsConfig, _options?: ToolCr
47
72
  try {
48
73
  const token = await tp.getAccessToken();
49
74
  const data = await graph(token, `/teams/${params.teamId}/channels`, {
50
- query: { '$select': 'id,displayName,description,membershipType' }
75
+ query: { '$select': 'id,displayName,description,membershipType,webUrl,createdDateTime' }
51
76
  });
52
77
  const channels = (data.value || []).map((c: any) => ({
53
78
  id: c.id, name: c.displayName, description: c.description,
54
- membershipType: c.membershipType,
79
+ membershipType: c.membershipType, webUrl: c.webUrl, created: c.createdDateTime,
55
80
  }));
56
81
  return jsonResult({ channels, count: channels.length });
57
82
  } catch (e: any) { return errorResult(e.message); }
58
83
  },
59
84
  },
60
85
 
86
+ {
87
+ name: 'teams_create_channel',
88
+ description: 'Create a new channel in a Team.',
89
+ category: 'utility' as const,
90
+ parameters: {
91
+ type: 'object' as const,
92
+ properties: {
93
+ teamId: { type: 'string', description: 'Team ID' },
94
+ name: { type: 'string', description: 'Channel display name' },
95
+ description: { type: 'string', description: 'Channel description' },
96
+ membershipType: { type: 'string', description: 'standard or private (default: standard)' },
97
+ },
98
+ required: ['teamId', 'name'],
99
+ },
100
+ async execute(_id: string, params: any) {
101
+ try {
102
+ const token = await tp.getAccessToken();
103
+ const channel = await graph(token, `/teams/${params.teamId}/channels`, {
104
+ method: 'POST',
105
+ body: {
106
+ displayName: params.name,
107
+ description: params.description || '',
108
+ membershipType: params.membershipType || 'standard',
109
+ },
110
+ });
111
+ return jsonResult({ id: channel.id, name: channel.displayName, created: true });
112
+ } catch (e: any) { return errorResult(e.message); }
113
+ },
114
+ },
115
+
61
116
  {
62
117
  name: 'teams_send_channel_message',
63
- description: 'Send a message to a Teams channel.',
118
+ description: 'Send a message to a Teams channel. Supports HTML, @mentions, and importance.',
64
119
  category: 'utility' as const,
65
120
  parameters: {
66
121
  type: 'object' as const,
@@ -69,29 +124,57 @@ export function createTeamsTools(config: MicrosoftToolsConfig, _options?: ToolCr
69
124
  channelId: { type: 'string', description: 'Channel ID' },
70
125
  message: { type: 'string', description: 'Message content (supports HTML)' },
71
126
  isHtml: { type: 'boolean', description: 'Whether message is HTML (default: false)' },
127
+ importance: { type: 'string', description: 'normal, high, or urgent' },
128
+ subject: { type: 'string', description: 'Message subject (creates a thread header)' },
72
129
  },
73
130
  required: ['teamId', 'channelId', 'message'],
74
131
  },
75
132
  async execute(_id: string, params: any) {
76
133
  try {
77
134
  const token = await tp.getAccessToken();
135
+ const body: any = {
136
+ body: { contentType: params.isHtml ? 'html' : 'text', content: params.message },
137
+ };
138
+ if (params.importance) body.importance = params.importance;
139
+ if (params.subject) body.subject = params.subject;
78
140
  const msg = await graph(token, `/teams/${params.teamId}/channels/${params.channelId}/messages`, {
79
- method: 'POST',
80
- body: {
81
- body: {
82
- contentType: params.isHtml ? 'html' : 'text',
83
- content: params.message,
84
- },
85
- },
141
+ method: 'POST', body,
86
142
  });
87
143
  return jsonResult({ id: msg.id, sent: true });
88
144
  } catch (e: any) { return errorResult(e.message); }
89
145
  },
90
146
  },
91
147
 
148
+ {
149
+ name: 'teams_reply_to_message',
150
+ description: 'Reply to a specific message in a Teams channel (threaded conversation).',
151
+ category: 'utility' as const,
152
+ parameters: {
153
+ type: 'object' as const,
154
+ properties: {
155
+ teamId: { type: 'string', description: 'Team ID' },
156
+ channelId: { type: 'string', description: 'Channel ID' },
157
+ messageId: { type: 'string', description: 'Parent message ID to reply to' },
158
+ message: { type: 'string', description: 'Reply content' },
159
+ isHtml: { type: 'boolean', description: 'Whether reply is HTML' },
160
+ },
161
+ required: ['teamId', 'channelId', 'messageId', 'message'],
162
+ },
163
+ async execute(_id: string, params: any) {
164
+ try {
165
+ const token = await tp.getAccessToken();
166
+ const reply = await graph(token, `/teams/${params.teamId}/channels/${params.channelId}/messages/${params.messageId}/replies`, {
167
+ method: 'POST',
168
+ body: { body: { contentType: params.isHtml ? 'html' : 'text', content: params.message } },
169
+ });
170
+ return jsonResult({ id: reply.id, sent: true, parentId: params.messageId });
171
+ } catch (e: any) { return errorResult(e.message); }
172
+ },
173
+ },
174
+
92
175
  {
93
176
  name: 'teams_read_channel_messages',
94
- description: 'Read recent messages from a Teams channel.',
177
+ description: 'Read recent messages from a Teams channel, including replies and reactions.',
95
178
  category: 'utility' as const,
96
179
  parameters: {
97
180
  type: 'object' as const,
@@ -99,25 +182,25 @@ export function createTeamsTools(config: MicrosoftToolsConfig, _options?: ToolCr
99
182
  teamId: { type: 'string', description: 'Team ID' },
100
183
  channelId: { type: 'string', description: 'Channel ID' },
101
184
  maxResults: { type: 'number', description: 'Max messages (default: 20)' },
185
+ includeReplies: { type: 'boolean', description: 'Include thread replies (default: false — heavier API call)' },
102
186
  },
103
187
  required: ['teamId', 'channelId'],
104
188
  },
105
189
  async execute(_id: string, params: any) {
106
190
  try {
107
191
  const token = await tp.getAccessToken();
108
- const data = await graph(token, `/teams/${params.teamId}/channels/${params.channelId}/messages`, {
109
- query: { '$top': String(params.maxResults || 20) }
192
+ const query: Record<string, string> = {
193
+ '$top': String(params.maxResults || 20),
194
+ };
195
+ if (params.includeReplies) query['$expand'] = 'replies';
196
+ const data = await graph(token, `/teams/${params.teamId}/channels/${params.channelId}/messages`, { query });
197
+ const messages = (data.value || []).map((m: any) => {
198
+ const msg = mapMessage(m);
199
+ if (params.includeReplies && m.replies?.length) {
200
+ msg.replies = m.replies.map((r: any) => mapMessage(r));
201
+ }
202
+ return msg;
110
203
  });
111
- const messages = (data.value || []).map((m: any) => ({
112
- id: m.id,
113
- from: m.from?.user?.displayName || m.from?.application?.displayName,
114
- fromEmail: m.from?.user?.email,
115
- body: m.body?.content,
116
- bodyType: m.body?.contentType,
117
- date: m.createdDateTime,
118
- importance: m.importance,
119
- replyCount: m.replies?.length,
120
- }));
121
204
  return jsonResult({ messages, count: messages.length });
122
205
  } catch (e: any) { return errorResult(e.message); }
123
206
  },
@@ -131,19 +214,20 @@ export function createTeamsTools(config: MicrosoftToolsConfig, _options?: ToolCr
131
214
  type: 'object' as const,
132
215
  properties: {
133
216
  maxResults: { type: 'number', description: 'Max chats to return (default: 20)' },
217
+ filter: { type: 'string', description: 'Filter: "oneOnOne", "group", or "meeting" (default: all)' },
134
218
  },
135
219
  required: [],
136
220
  },
137
221
  async execute(_id: string, params: any) {
138
222
  try {
139
223
  const token = await tp.getAccessToken();
140
- const data = await graph(token, '/me/chats', {
141
- query: {
142
- '$top': String(params.maxResults || 20),
143
- '$select': 'id,topic,chatType,createdDateTime,lastUpdatedDateTime',
144
- '$orderby': 'lastUpdatedDateTime desc',
145
- }
146
- });
224
+ const query: Record<string, string> = {
225
+ '$top': String(params.maxResults || 20),
226
+ '$select': 'id,topic,chatType,createdDateTime,lastUpdatedDateTime',
227
+ '$orderby': 'lastUpdatedDateTime desc',
228
+ };
229
+ if (params.filter) query['$filter'] = `chatType eq '${params.filter}'`;
230
+ const data = await graph(token, '/me/chats', { query });
147
231
  const chats = (data.value || []).map((c: any) => ({
148
232
  id: c.id, topic: c.topic, type: c.chatType,
149
233
  created: c.createdDateTime, lastUpdated: c.lastUpdatedDateTime,
@@ -171,9 +255,7 @@ export function createTeamsTools(config: MicrosoftToolsConfig, _options?: ToolCr
171
255
  const token = await tp.getAccessToken();
172
256
  const msg = await graph(token, `/chats/${params.chatId}/messages`, {
173
257
  method: 'POST',
174
- body: {
175
- body: { contentType: params.isHtml ? 'html' : 'text', content: params.message },
176
- },
258
+ body: { body: { contentType: params.isHtml ? 'html' : 'text', content: params.message } },
177
259
  });
178
260
  return jsonResult({ id: msg.id, sent: true });
179
261
  } catch (e: any) { return errorResult(e.message); }
@@ -198,21 +280,117 @@ export function createTeamsTools(config: MicrosoftToolsConfig, _options?: ToolCr
198
280
  const data = await graph(token, `/chats/${params.chatId}/messages`, {
199
281
  query: { '$top': String(params.maxResults || 20), '$orderby': 'createdDateTime desc' }
200
282
  });
201
- const messages = (data.value || []).map((m: any) => ({
202
- id: m.id,
203
- from: m.from?.user?.displayName,
204
- body: m.body?.content,
205
- bodyType: m.body?.contentType,
206
- date: m.createdDateTime,
207
- }));
283
+ const messages = (data.value || []).map((m: any) => mapMessage(m));
208
284
  return jsonResult({ messages, count: messages.length });
209
285
  } catch (e: any) { return errorResult(e.message); }
210
286
  },
211
287
  },
212
288
 
289
+ {
290
+ name: 'teams_list_members',
291
+ description: 'List members of a team or channel.',
292
+ category: 'utility' as const,
293
+ parameters: {
294
+ type: 'object' as const,
295
+ properties: {
296
+ teamId: { type: 'string', description: 'Team ID' },
297
+ channelId: { type: 'string', description: 'Channel ID (omit for team members)' },
298
+ },
299
+ required: ['teamId'],
300
+ },
301
+ async execute(_id: string, params: any) {
302
+ try {
303
+ const token = await tp.getAccessToken();
304
+ const path = params.channelId
305
+ ? `/teams/${params.teamId}/channels/${params.channelId}/members`
306
+ : `/teams/${params.teamId}/members`;
307
+ const data = await graph(token, path);
308
+ const members = (data.value || []).map((m: any) => ({
309
+ id: m.id, userId: m.userId,
310
+ name: m.displayName, email: m.email,
311
+ roles: m.roles, // ['owner'] or []
312
+ }));
313
+ return jsonResult({ members, count: members.length });
314
+ } catch (e: any) { return errorResult(e.message); }
315
+ },
316
+ },
317
+
318
+ {
319
+ name: 'teams_add_member',
320
+ description: 'Add a member to a team.',
321
+ category: 'utility' as const,
322
+ parameters: {
323
+ type: 'object' as const,
324
+ properties: {
325
+ teamId: { type: 'string', description: 'Team ID' },
326
+ userId: { type: 'string', description: 'User ID or email to add' },
327
+ role: { type: 'string', description: 'member or owner (default: member)' },
328
+ },
329
+ required: ['teamId', 'userId'],
330
+ },
331
+
332
+ async execute(_id: string, params: any) {
333
+ try {
334
+ const token = await tp.getAccessToken();
335
+ const body: any = {
336
+ '@odata.type': '#microsoft.graph.aadUserConversationMember',
337
+ 'user@odata.bind': `https://graph.microsoft.com/v1.0/users('${params.userId}')`,
338
+ roles: params.role === 'owner' ? ['owner'] : [],
339
+ };
340
+ await graph(token, `/teams/${params.teamId}/members`, { method: 'POST', body });
341
+ return jsonResult({ added: true, userId: params.userId, teamId: params.teamId });
342
+ } catch (e: any) { return errorResult(e.message); }
343
+ },
344
+ },
345
+
346
+ {
347
+ name: 'teams_share_file',
348
+ description: 'Share a file in a Teams channel by uploading it to the channel\'s SharePoint folder.',
349
+ category: 'utility' as const,
350
+ parameters: {
351
+ type: 'object' as const,
352
+ properties: {
353
+ teamId: { type: 'string', description: 'Team ID' },
354
+ channelId: { type: 'string', description: 'Channel ID' },
355
+ fileName: { type: 'string', description: 'File name (e.g., "report.pdf")' },
356
+ content: { type: 'string', description: 'File content (text or base64 for binary)' },
357
+ message: { type: 'string', description: 'Optional message to post with the file' },
358
+ },
359
+ required: ['teamId', 'channelId', 'fileName', 'content'],
360
+ },
361
+ async execute(_id: string, params: any) {
362
+ try {
363
+ const token = await tp.getAccessToken();
364
+ // Get the channel's files folder (SharePoint drive)
365
+ const folder = await graph(token, `/teams/${params.teamId}/channels/${params.channelId}/filesFolder`);
366
+ const driveId = folder.parentReference?.driveId;
367
+ const folderId = folder.id;
368
+ if (!driveId) throw new Error('Could not resolve channel files folder');
369
+ // Upload file
370
+ const uploadRes = await fetch(`https://graph.microsoft.com/v1.0/drives/${driveId}/items/${folderId}:/${encodeURIComponent(params.fileName)}:/content`, {
371
+ method: 'PUT',
372
+ headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/octet-stream' },
373
+ body: params.content,
374
+ });
375
+ if (!uploadRes.ok) throw new Error(`Upload failed: ${uploadRes.status}`);
376
+ const file = await uploadRes.json();
377
+ // Optionally post a message linking the file
378
+ if (params.message) {
379
+ await graph(token, `/teams/${params.teamId}/channels/${params.channelId}/messages`, {
380
+ method: 'POST',
381
+ body: {
382
+ body: { contentType: 'html', content: `${params.message}<br/><a href="${file.webUrl}">${params.fileName}</a>` },
383
+ },
384
+ });
385
+ }
386
+ return jsonResult({ fileId: file.id, name: file.name, webUrl: file.webUrl, uploaded: true });
387
+ } catch (e: any) { return errorResult(e.message); }
388
+ },
389
+ },
390
+
213
391
  {
214
392
  name: 'teams_presence',
215
- description: 'Get presence/availability status for users.',
393
+ description: 'Get presence/availability status for users (Available, Busy, DoNotDisturb, Away, Offline).',
216
394
  category: 'utility' as const,
217
395
  parameters: {
218
396
  type: 'object' as const,
@@ -226,12 +404,11 @@ export function createTeamsTools(config: MicrosoftToolsConfig, _options?: ToolCr
226
404
  const token = await tp.getAccessToken();
227
405
  if (params.userIds === 'me') {
228
406
  const p = await graph(token, '/me/presence');
229
- return jsonResult({ presence: [{ availability: p.availability, activity: p.activity }] });
407
+ return jsonResult({ presence: [{ availability: p.availability, activity: p.activity, statusMessage: p.statusMessage?.message?.content }] });
230
408
  }
231
409
  const ids = params.userIds.split(',').map((s: string) => s.trim());
232
410
  const data = await graph(token, '/communications/getPresencesByUserId', {
233
- method: 'POST',
234
- body: { ids },
411
+ method: 'POST', body: { ids },
235
412
  });
236
413
  const presence = (data.value || []).map((p: any) => ({
237
414
  userId: p.id, availability: p.availability, activity: p.activity,
@@ -240,5 +417,47 @@ export function createTeamsTools(config: MicrosoftToolsConfig, _options?: ToolCr
240
417
  } catch (e: any) { return errorResult(e.message); }
241
418
  },
242
419
  },
420
+
421
+ {
422
+ name: 'teams_set_status',
423
+ description: 'Set the agent\'s presence status message in Teams.',
424
+ category: 'utility' as const,
425
+ parameters: {
426
+ type: 'object' as const,
427
+ properties: {
428
+ message: { type: 'string', description: 'Status message text' },
429
+ expiry: { type: 'string', description: 'Expiry duration (ISO 8601 duration, e.g., "PT1H" for 1 hour, "P1D" for 1 day)' },
430
+ },
431
+ required: ['message'],
432
+ },
433
+ async execute(_id: string, params: any) {
434
+ try {
435
+ const token = await tp.getAccessToken();
436
+ const body: any = {
437
+ statusMessage: {
438
+ message: { content: params.message, contentType: 'text' },
439
+ },
440
+ };
441
+ if (params.expiry) {
442
+ body.statusMessage.expiryDateTime = {
443
+ dateTime: new Date(Date.now() + parseDuration(params.expiry)).toISOString(),
444
+ timeZone: 'UTC',
445
+ };
446
+ }
447
+ await graph(token, '/me/presence/setStatusMessage', { method: 'POST', body }, );
448
+ return jsonResult({ statusSet: true, message: params.message });
449
+ } catch (e: any) { return errorResult(e.message); }
450
+ },
451
+ },
243
452
  ];
244
453
  }
454
+
455
+ function parseDuration(iso: string): number {
456
+ // Simple ISO 8601 duration parser for common cases
457
+ const match = iso.match(/P(?:(\d+)D)?T?(?:(\d+)H)?(?:(\d+)M)?/);
458
+ if (!match) return 3600000;
459
+ const days = parseInt(match[1] || '0') * 86400000;
460
+ const hours = parseInt(match[2] || '0') * 3600000;
461
+ const mins = parseInt(match[3] || '0') * 60000;
462
+ return days + hours + mins;
463
+ }
@@ -730,11 +730,11 @@ export function createAuthRoutes(
730
730
  .sign(secret);
731
731
 
732
732
  // Set the impersonation token as the session cookie so all subsequent requests use it
733
- setCookie(c, 'em_session', impersonateToken, { path: '/', httpOnly: true, secure: isSecure, sameSite: 'Lax', maxAge: 3600 });
733
+ setCookie(c, 'em_session', impersonateToken, { path: '/', httpOnly: true, secure: isSecure(), sameSite: 'Lax', maxAge: 3600 });
734
734
 
735
735
  return c.json({
736
736
  token: impersonateToken,
737
- user: { id: target.id, email: target.email, name: target.name, role: target.role, totpEnabled: !!target.totpEnabled, clientOrgId: target.clientOrgId || null, permissions: target.permissions },
737
+ user: { id: target.id, email: target.email, name: target.name, role: target.role, totpEnabled: !!(target as any).totpEnabled, clientOrgId: (target as any).clientOrgId || null, permissions: (target as any).permissions },
738
738
  impersonatedBy: { id: caller.id, name: caller.name, email: caller.email },
739
739
  });
740
740
  } catch (e: any) {
@@ -744,11 +744,11 @@ export function createAuthRoutes(
744
744
 
745
745
  auth.post('/stop-impersonate', async (c) => {
746
746
  try {
747
- const impersonatedBy = c.get('impersonatedBy' as any);
747
+ const impersonatedBy = (c as any).get('impersonatedBy');
748
748
  if (!impersonatedBy) return c.json({ error: 'Not impersonating' }, 400);
749
749
  const owner = await db.getUser(impersonatedBy);
750
750
  if (!owner) return c.json({ error: 'Original user not found' }, 404);
751
- await setSessionCookies(c, owner.id, owner.email, owner.role, 'stop-impersonate', owner.clientOrgId);
751
+ await setSessionCookies(c, owner.id, owner.email, owner.role, 'stop-impersonate', (owner as any).clientOrgId);
752
752
  return c.json({ ok: true, user: { id: owner.id, email: owner.email, name: owner.name, role: owner.role } });
753
753
  } catch (e: any) {
754
754
  return c.json({ error: e.message }, 500);