@_vrsen/openswarm 0.1.0

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 (316) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +152 -0
  3. package/bin/openswarm.js +38 -0
  4. package/config.py +34 -0
  5. package/data_analyst_agent/.cursor/rules/data_analyst.mdc +43 -0
  6. package/data_analyst_agent/__init__.py +3 -0
  7. package/data_analyst_agent/__pycache__/__init__.cpython-312.pyc +0 -0
  8. package/data_analyst_agent/__pycache__/data_analyst_agent.cpython-312.pyc +0 -0
  9. package/data_analyst_agent/data_analyst_agent.py +45 -0
  10. package/data_analyst_agent/instructions.md +173 -0
  11. package/data_analyst_agent/test_files/test_file.csv +21 -0
  12. package/data_analyst_agent/tools/__init__.py +6 -0
  13. package/deep_research/__init__.py +1 -0
  14. package/deep_research/__pycache__/__init__.cpython-312.pyc +0 -0
  15. package/deep_research/__pycache__/deep_research.cpython-312.pyc +0 -0
  16. package/deep_research/deep_research.py +27 -0
  17. package/deep_research/instructions.md +104 -0
  18. package/deep_research/tools/__init__.py +1 -0
  19. package/docs_agent/__init__.py +3 -0
  20. package/docs_agent/__pycache__/__init__.cpython-312.pyc +0 -0
  21. package/docs_agent/__pycache__/docs_agent.cpython-312.pyc +0 -0
  22. package/docs_agent/docs_agent.py +61 -0
  23. package/docs_agent/instructions.md +418 -0
  24. package/docs_agent/tools/ConvertDocument.py +323 -0
  25. package/docs_agent/tools/CreateDocument.py +287 -0
  26. package/docs_agent/tools/ListDocuments.py +134 -0
  27. package/docs_agent/tools/ModifyDocument.py +247 -0
  28. package/docs_agent/tools/RestoreDocument.py +79 -0
  29. package/docs_agent/tools/ViewDocument.py +153 -0
  30. package/docs_agent/tools/__init__.py +1 -0
  31. package/docs_agent/tools/__pycache__/ConvertDocument.cpython-312.pyc +0 -0
  32. package/docs_agent/tools/__pycache__/CreateDocument.cpython-312.pyc +0 -0
  33. package/docs_agent/tools/__pycache__/ListDocuments.cpython-312.pyc +0 -0
  34. package/docs_agent/tools/__pycache__/ModifyDocument.cpython-312.pyc +0 -0
  35. package/docs_agent/tools/__pycache__/RestoreDocument.cpython-312.pyc +0 -0
  36. package/docs_agent/tools/__pycache__/ViewDocument.cpython-312.pyc +0 -0
  37. package/docs_agent/tools/__pycache__/__init__.cpython-312.pyc +0 -0
  38. package/docs_agent/tools/utils/__init__.py +1 -0
  39. package/docs_agent/tools/utils/__pycache__/__init__.cpython-312.pyc +0 -0
  40. package/docs_agent/tools/utils/__pycache__/doc_file_utils.cpython-312.pyc +0 -0
  41. package/docs_agent/tools/utils/__pycache__/html_docx_blocks.cpython-312.pyc +0 -0
  42. package/docs_agent/tools/utils/__pycache__/html_docx_constants.cpython-312.pyc +0 -0
  43. package/docs_agent/tools/utils/__pycache__/html_docx_core.cpython-312.pyc +0 -0
  44. package/docs_agent/tools/utils/__pycache__/html_docx_css.cpython-312.pyc +0 -0
  45. package/docs_agent/tools/utils/__pycache__/html_docx_images.cpython-312.pyc +0 -0
  46. package/docs_agent/tools/utils/__pycache__/html_docx_page.cpython-312.pyc +0 -0
  47. package/docs_agent/tools/utils/__pycache__/html_docx_paragraphs.cpython-312.pyc +0 -0
  48. package/docs_agent/tools/utils/__pycache__/html_docx_playwright.cpython-312.pyc +0 -0
  49. package/docs_agent/tools/utils/__pycache__/html_docx_selectors.cpython-312.pyc +0 -0
  50. package/docs_agent/tools/utils/__pycache__/html_docx_shared.cpython-312.pyc +0 -0
  51. package/docs_agent/tools/utils/__pycache__/html_validation.cpython-312.pyc +0 -0
  52. package/docs_agent/tools/utils/doc_file_utils.py +29 -0
  53. package/docs_agent/tools/utils/html_docx_blocks.py +262 -0
  54. package/docs_agent/tools/utils/html_docx_constants.py +78 -0
  55. package/docs_agent/tools/utils/html_docx_core.py +138 -0
  56. package/docs_agent/tools/utils/html_docx_css.py +262 -0
  57. package/docs_agent/tools/utils/html_docx_images.py +293 -0
  58. package/docs_agent/tools/utils/html_docx_page.py +185 -0
  59. package/docs_agent/tools/utils/html_docx_paragraphs.py +342 -0
  60. package/docs_agent/tools/utils/html_docx_playwright.py +184 -0
  61. package/docs_agent/tools/utils/html_docx_selectors.py +196 -0
  62. package/docs_agent/tools/utils/html_docx_shared.py +23 -0
  63. package/docs_agent/tools/utils/html_docx_tables.py +942 -0
  64. package/docs_agent/tools/utils/html_validation.py +102 -0
  65. package/helpers.py +59 -0
  66. package/image_generation_agent/__init__.py +1 -0
  67. package/image_generation_agent/__pycache__/__init__.cpython-312.pyc +0 -0
  68. package/image_generation_agent/__pycache__/image_generation_agent.cpython-312.pyc +0 -0
  69. package/image_generation_agent/image_generation_agent.py +31 -0
  70. package/image_generation_agent/instructions.md +80 -0
  71. package/image_generation_agent/tools/CombineImages.py +211 -0
  72. package/image_generation_agent/tools/EditImages.py +200 -0
  73. package/image_generation_agent/tools/GenerateImages.py +184 -0
  74. package/image_generation_agent/tools/RemoveBackground.py +108 -0
  75. package/image_generation_agent/tools/__init__.py +2 -0
  76. package/image_generation_agent/tools/__pycache__/CombineImages.cpython-312.pyc +0 -0
  77. package/image_generation_agent/tools/__pycache__/EditImages.cpython-312.pyc +0 -0
  78. package/image_generation_agent/tools/__pycache__/GenerateImages.cpython-312.pyc +0 -0
  79. package/image_generation_agent/tools/__pycache__/RemoveBackground.cpython-312.pyc +0 -0
  80. package/image_generation_agent/tools/utils/__init__.py +2 -0
  81. package/image_generation_agent/tools/utils/__pycache__/__init__.cpython-312.pyc +0 -0
  82. package/image_generation_agent/tools/utils/__pycache__/image_io.cpython-312.pyc +0 -0
  83. package/image_generation_agent/tools/utils/image_io.py +308 -0
  84. package/onboard.py +325 -0
  85. package/orchestrator/__init__.py +3 -0
  86. package/orchestrator/__pycache__/__init__.cpython-312.pyc +0 -0
  87. package/orchestrator/__pycache__/orchestrator.cpython-312.pyc +0 -0
  88. package/orchestrator/instructions.md +90 -0
  89. package/orchestrator/orchestrator.py +33 -0
  90. package/package.json +49 -0
  91. package/patches/__init__.py +1 -0
  92. package/patches/__pycache__/__init__.cpython-312.pyc +0 -0
  93. package/patches/__pycache__/patch_agency_swarm_dual_comms.cpython-312.pyc +0 -0
  94. package/patches/__pycache__/patch_file_attachment_refs.cpython-312.pyc +0 -0
  95. package/patches/__pycache__/patch_ipython_interpreter_composio.cpython-312.pyc +0 -0
  96. package/patches/dom-to-pptx+1.1.5.patch +133440 -0
  97. package/patches/patch_agency_swarm_dual_comms.py +199 -0
  98. package/patches/patch_file_attachment_refs.py +74 -0
  99. package/patches/patch_ipython_interpreter_composio.py +54 -0
  100. package/pyproject.toml +67 -0
  101. package/run.py +343 -0
  102. package/server.py +26 -0
  103. package/shared_instructions.md +119 -0
  104. package/shared_tools/CopyFile.py +68 -0
  105. package/shared_tools/ExecuteTool.py +184 -0
  106. package/shared_tools/FindTools.py +101 -0
  107. package/shared_tools/ManageConnections.py +43 -0
  108. package/shared_tools/SearchTools.py +44 -0
  109. package/shared_tools/__init__.py +7 -0
  110. package/shared_tools/__pycache__/CopyFile.cpython-312.pyc +0 -0
  111. package/shared_tools/__pycache__/ExecuteTool.cpython-312.pyc +0 -0
  112. package/shared_tools/__pycache__/FindTools.cpython-312.pyc +0 -0
  113. package/shared_tools/__pycache__/ManageConnections.cpython-312.pyc +0 -0
  114. package/shared_tools/__pycache__/SearchTools.cpython-312.pyc +0 -0
  115. package/shared_tools/__pycache__/__init__.cpython-312.pyc +0 -0
  116. package/slides_agent/.cursor/rules/slides-agent-workflow.mdc +9 -0
  117. package/slides_agent/__init__.py +1 -0
  118. package/slides_agent/__pycache__/__init__.cpython-312.pyc +0 -0
  119. package/slides_agent/__pycache__/slides_agent.cpython-312.pyc +0 -0
  120. package/slides_agent/instructions.md +298 -0
  121. package/slides_agent/pptx/SKILL.md +528 -0
  122. package/slides_agent/pptx/html2pptx.md +625 -0
  123. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  124. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  125. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  126. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  127. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  128. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  129. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  130. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  131. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  132. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  133. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  134. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  135. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  136. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  137. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  138. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  139. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  140. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  141. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  142. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  143. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  144. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  145. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  146. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  147. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  148. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  149. package/slides_agent/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  150. package/slides_agent/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  151. package/slides_agent/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  152. package/slides_agent/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  153. package/slides_agent/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  154. package/slides_agent/pptx/ooxml/schemas/mce/mc.xsd +75 -0
  155. package/slides_agent/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  156. package/slides_agent/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  157. package/slides_agent/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  158. package/slides_agent/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  159. package/slides_agent/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  160. package/slides_agent/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  161. package/slides_agent/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  162. package/slides_agent/pptx/ooxml/scripts/pack.py +169 -0
  163. package/slides_agent/pptx/ooxml/scripts/unpack.py +29 -0
  164. package/slides_agent/pptx/ooxml/scripts/validate.py +69 -0
  165. package/slides_agent/pptx/ooxml/scripts/validation/__init__.py +15 -0
  166. package/slides_agent/pptx/ooxml/scripts/validation/base.py +951 -0
  167. package/slides_agent/pptx/ooxml/scripts/validation/docx.py +274 -0
  168. package/slides_agent/pptx/ooxml/scripts/validation/pptx.py +315 -0
  169. package/slides_agent/pptx/ooxml/scripts/validation/redlining.py +279 -0
  170. package/slides_agent/pptx/ooxml.md +427 -0
  171. package/slides_agent/pptx/scripts/html2pptx.js +1092 -0
  172. package/slides_agent/pptx/scripts/inventory.py +1020 -0
  173. package/slides_agent/pptx/scripts/rearrange.py +231 -0
  174. package/slides_agent/pptx/scripts/replace.py +385 -0
  175. package/slides_agent/pptx/scripts/thumbnail.py +451 -0
  176. package/slides_agent/slides_agent.py +109 -0
  177. package/slides_agent/test_deck/_theme.css +92 -0
  178. package/slides_agent/test_deck/assets/placeholder.svg +11 -0
  179. package/slides_agent/test_deck/slide_01_title.html +10 -0
  180. package/slides_agent/test_deck/slide_02_image_split.html +23 -0
  181. package/slides_agent/test_deck/slide_03_kpi.html +21 -0
  182. package/slides_agent/tools/ApplyPptxTextReplacements.py +91 -0
  183. package/slides_agent/tools/BuildPptxFromHtmlSlides.py +221 -0
  184. package/slides_agent/tools/CheckSlide.py +218 -0
  185. package/slides_agent/tools/CheckSlideCanvasOverflow.py +221 -0
  186. package/slides_agent/tools/CreateImageMontage.py +261 -0
  187. package/slides_agent/tools/CreatePptxThumbnailGrid.py +168 -0
  188. package/slides_agent/tools/DeleteSlide.py +78 -0
  189. package/slides_agent/tools/DownloadImage.py +79 -0
  190. package/slides_agent/tools/EnsureRasterImage.py +157 -0
  191. package/slides_agent/tools/ExtractPptxTextInventory.py +104 -0
  192. package/slides_agent/tools/GenerateImage.py +189 -0
  193. package/slides_agent/tools/ImageSearch.py +127 -0
  194. package/slides_agent/tools/InsertNewSlides.py +393 -0
  195. package/slides_agent/tools/ManageTheme.py +112 -0
  196. package/slides_agent/tools/ModifySlide.py +563 -0
  197. package/slides_agent/tools/ReadSlide.py +26 -0
  198. package/slides_agent/tools/RearrangePptxSlidesFromTemplate.py +114 -0
  199. package/slides_agent/tools/RestoreSnapshot.py +89 -0
  200. package/slides_agent/tools/SlideScreenshot.py +66 -0
  201. package/slides_agent/tools/__init__.py +54 -0
  202. package/slides_agent/tools/__pycache__/ApplyPptxTextReplacements.cpython-312.pyc +0 -0
  203. package/slides_agent/tools/__pycache__/BuildPptxFromHtmlSlides.cpython-312.pyc +0 -0
  204. package/slides_agent/tools/__pycache__/CheckSlide.cpython-312.pyc +0 -0
  205. package/slides_agent/tools/__pycache__/CheckSlideCanvasOverflow.cpython-312.pyc +0 -0
  206. package/slides_agent/tools/__pycache__/CreateImageMontage.cpython-312.pyc +0 -0
  207. package/slides_agent/tools/__pycache__/CreatePptxThumbnailGrid.cpython-312.pyc +0 -0
  208. package/slides_agent/tools/__pycache__/DeleteSlide.cpython-312.pyc +0 -0
  209. package/slides_agent/tools/__pycache__/DownloadImage.cpython-312.pyc +0 -0
  210. package/slides_agent/tools/__pycache__/EnsureRasterImage.cpython-312.pyc +0 -0
  211. package/slides_agent/tools/__pycache__/ExtractPptxTextInventory.cpython-312.pyc +0 -0
  212. package/slides_agent/tools/__pycache__/GenerateImage.cpython-312.pyc +0 -0
  213. package/slides_agent/tools/__pycache__/ImageSearch.cpython-312.pyc +0 -0
  214. package/slides_agent/tools/__pycache__/InsertNewSlides.cpython-312.pyc +0 -0
  215. package/slides_agent/tools/__pycache__/ManageTheme.cpython-312.pyc +0 -0
  216. package/slides_agent/tools/__pycache__/ModifySlide.cpython-312.pyc +0 -0
  217. package/slides_agent/tools/__pycache__/ReadSlide.cpython-312.pyc +0 -0
  218. package/slides_agent/tools/__pycache__/RearrangePptxSlidesFromTemplate.cpython-312.pyc +0 -0
  219. package/slides_agent/tools/__pycache__/RestoreSnapshot.cpython-312.pyc +0 -0
  220. package/slides_agent/tools/__pycache__/SlideScreenshot.cpython-312.pyc +0 -0
  221. package/slides_agent/tools/__pycache__/__init__.cpython-312.pyc +0 -0
  222. package/slides_agent/tools/__pycache__/slide_file_utils.cpython-312.pyc +0 -0
  223. package/slides_agent/tools/__pycache__/slide_html_utils.cpython-312.pyc +0 -0
  224. package/slides_agent/tools/__pycache__/template_registry.cpython-312.pyc +0 -0
  225. package/slides_agent/tools/deck_utils.py +31 -0
  226. package/slides_agent/tools/html2pptx_runner.js +1183 -0
  227. package/slides_agent/tools/html_writer_instructions.md +149 -0
  228. package/slides_agent/tools/slide_file_utils.py +108 -0
  229. package/slides_agent/tools/slide_html_utils.py +354 -0
  230. package/slides_agent/tools/template_registry.py +55 -0
  231. package/swarm.py +82 -0
  232. package/video_generation_agent/__init__.py +1 -0
  233. package/video_generation_agent/__pycache__/__init__.cpython-312.pyc +0 -0
  234. package/video_generation_agent/__pycache__/video_generation_agent.cpython-312.pyc +0 -0
  235. package/video_generation_agent/instructions.md +178 -0
  236. package/video_generation_agent/tools/AddSubtitles.py +425 -0
  237. package/video_generation_agent/tools/CombineImages.py +166 -0
  238. package/video_generation_agent/tools/CombineVideos.py +113 -0
  239. package/video_generation_agent/tools/EditAudio.py +297 -0
  240. package/video_generation_agent/tools/EditImage.py +144 -0
  241. package/video_generation_agent/tools/EditVideoContent.py +369 -0
  242. package/video_generation_agent/tools/GenerateImage.py +133 -0
  243. package/video_generation_agent/tools/GenerateVideo.py +556 -0
  244. package/video_generation_agent/tools/TrimVideo.py +233 -0
  245. package/video_generation_agent/tools/__init__.py +1 -0
  246. package/video_generation_agent/tools/__pycache__/AddSubtitles.cpython-312.pyc +0 -0
  247. package/video_generation_agent/tools/__pycache__/CombineImages.cpython-312.pyc +0 -0
  248. package/video_generation_agent/tools/__pycache__/CombineVideos.cpython-312.pyc +0 -0
  249. package/video_generation_agent/tools/__pycache__/EditAudio.cpython-312.pyc +0 -0
  250. package/video_generation_agent/tools/__pycache__/EditImage.cpython-312.pyc +0 -0
  251. package/video_generation_agent/tools/__pycache__/EditVideoContent.cpython-312.pyc +0 -0
  252. package/video_generation_agent/tools/__pycache__/GenerateImage.cpython-312.pyc +0 -0
  253. package/video_generation_agent/tools/__pycache__/GenerateVideo.cpython-312.pyc +0 -0
  254. package/video_generation_agent/tools/__pycache__/TrimVideo.cpython-312.pyc +0 -0
  255. package/video_generation_agent/tools/utils/__init__.py +1 -0
  256. package/video_generation_agent/tools/utils/__pycache__/__init__.cpython-312.pyc +0 -0
  257. package/video_generation_agent/tools/utils/__pycache__/image_utils.cpython-312.pyc +0 -0
  258. package/video_generation_agent/tools/utils/__pycache__/video_utils.cpython-312.pyc +0 -0
  259. package/video_generation_agent/tools/utils/image_utils.py +174 -0
  260. package/video_generation_agent/tools/utils/video_utils.py +522 -0
  261. package/video_generation_agent/video_generation_agent.py +26 -0
  262. package/virtual_assistant/__init__.py +1 -0
  263. package/virtual_assistant/__pycache__/__init__.cpython-312.pyc +0 -0
  264. package/virtual_assistant/__pycache__/virtual_assistant.cpython-312.pyc +0 -0
  265. package/virtual_assistant/instructions.md +206 -0
  266. package/virtual_assistant/tools/AddLabelToEmail.py +154 -0
  267. package/virtual_assistant/tools/CheckEventsForDate.py +218 -0
  268. package/virtual_assistant/tools/CheckUnreadSlackMessages.py +216 -0
  269. package/virtual_assistant/tools/CreateCalendarEvent.py +261 -0
  270. package/virtual_assistant/tools/DeleteCalendarEvent.py +137 -0
  271. package/virtual_assistant/tools/DeleteDraft.py +95 -0
  272. package/virtual_assistant/tools/DraftEmail.py +239 -0
  273. package/virtual_assistant/tools/EditFile.py +113 -0
  274. package/virtual_assistant/tools/FindEmails.py +330 -0
  275. package/virtual_assistant/tools/GetCurrentTime.py +69 -0
  276. package/virtual_assistant/tools/GetSlackUserInfo.py +117 -0
  277. package/virtual_assistant/tools/ListDirectory.py +113 -0
  278. package/virtual_assistant/tools/ListSkills.py +94 -0
  279. package/virtual_assistant/tools/ManageLabels.py +295 -0
  280. package/virtual_assistant/tools/ProductSearch.py +254 -0
  281. package/virtual_assistant/tools/ReadEmail.py +251 -0
  282. package/virtual_assistant/tools/ReadFile.py +108 -0
  283. package/virtual_assistant/tools/ReadSlackMessages.py +191 -0
  284. package/virtual_assistant/tools/RemoveLabelFromEmail.py +137 -0
  285. package/virtual_assistant/tools/RescheduleCalendarEvent.py +227 -0
  286. package/virtual_assistant/tools/ScholarSearch.py +216 -0
  287. package/virtual_assistant/tools/SendDraft.py +101 -0
  288. package/virtual_assistant/tools/SendSlackMessage.py +148 -0
  289. package/virtual_assistant/tools/WriteFile.py +95 -0
  290. package/virtual_assistant/tools/__init__.py +1 -0
  291. package/virtual_assistant/tools/__pycache__/AddLabelToEmail.cpython-312.pyc +0 -0
  292. package/virtual_assistant/tools/__pycache__/CheckEventsForDate.cpython-312.pyc +0 -0
  293. package/virtual_assistant/tools/__pycache__/CheckUnreadSlackMessages.cpython-312.pyc +0 -0
  294. package/virtual_assistant/tools/__pycache__/CreateCalendarEvent.cpython-312.pyc +0 -0
  295. package/virtual_assistant/tools/__pycache__/DeleteCalendarEvent.cpython-312.pyc +0 -0
  296. package/virtual_assistant/tools/__pycache__/DeleteDraft.cpython-312.pyc +0 -0
  297. package/virtual_assistant/tools/__pycache__/DraftEmail.cpython-312.pyc +0 -0
  298. package/virtual_assistant/tools/__pycache__/EditFile.cpython-312.pyc +0 -0
  299. package/virtual_assistant/tools/__pycache__/FindEmails.cpython-312.pyc +0 -0
  300. package/virtual_assistant/tools/__pycache__/GetCurrentTime.cpython-312.pyc +0 -0
  301. package/virtual_assistant/tools/__pycache__/GetSlackUserInfo.cpython-312.pyc +0 -0
  302. package/virtual_assistant/tools/__pycache__/ListDirectory.cpython-312.pyc +0 -0
  303. package/virtual_assistant/tools/__pycache__/ListSkills.cpython-312.pyc +0 -0
  304. package/virtual_assistant/tools/__pycache__/ManageLabels.cpython-312.pyc +0 -0
  305. package/virtual_assistant/tools/__pycache__/ProductSearch.cpython-312.pyc +0 -0
  306. package/virtual_assistant/tools/__pycache__/ReadEmail.cpython-312.pyc +0 -0
  307. package/virtual_assistant/tools/__pycache__/ReadFile.cpython-312.pyc +0 -0
  308. package/virtual_assistant/tools/__pycache__/ReadSlackMessages.cpython-312.pyc +0 -0
  309. package/virtual_assistant/tools/__pycache__/RemoveLabelFromEmail.cpython-312.pyc +0 -0
  310. package/virtual_assistant/tools/__pycache__/RescheduleCalendarEvent.cpython-312.pyc +0 -0
  311. package/virtual_assistant/tools/__pycache__/ScholarSearch.cpython-312.pyc +0 -0
  312. package/virtual_assistant/tools/__pycache__/SendDraft.cpython-312.pyc +0 -0
  313. package/virtual_assistant/tools/__pycache__/SendSlackMessage.cpython-312.pyc +0 -0
  314. package/virtual_assistant/tools/__pycache__/WriteFile.cpython-312.pyc +0 -0
  315. package/virtual_assistant/tools/__pycache__/__init__.cpython-312.pyc +0 -0
  316. package/virtual_assistant/virtual_assistant.py +52 -0
@@ -0,0 +1,206 @@
1
+ # Your Role
2
+
3
+ You are an elite executive assistant for busy business owners and entrepreneurs. Your main goal is to save the user as much time as possible by handling administrative tasks.
4
+
5
+ # North Star Principles
6
+
7
+ 1. **Protect the User's Time:** Filter requests and prioritize what matters most.
8
+ 2. **Efficiency:** Be clear, committed, and always include context.
9
+ 3. **Responsive:** Every request deserves a clear, timely response.
10
+ 4. **Read the Play:** Be preemptive. Anticipate needs before they're stated.
11
+ 5. **Prioritize Revenue:** Order tasks based on what generates the biggest outcome.
12
+ 6. **Capture Preferences:** Questions should only be asked once. Remember and reference for the future.
13
+
14
+ # Communication Flows
15
+
16
+ - **Handoff to Deep Research:** For comprehensive research tasks (market analysis, competitor research, literature reviews, background investigation)
17
+ - **Handoff to Data Analyst:** For data analysis tasks (metrics, revenue analysis, dashboards, KPIs, visualizations, business intelligence)
18
+
19
+ Handle general administrative tasks (email, calendar, messaging, documents) yourself.
20
+
21
+ # Primary Workflow
22
+
23
+ Follow this general process for all tasks:
24
+
25
+ ## 1. Gather Context
26
+
27
+ For tasks that are not straightforward and require multiple tool calls:
28
+
29
+ 1. **Ask clarifying questions** before taking action
30
+ 2. Understand the full scope: Who, What, Where, When, Why, How
31
+ 3. Confirm preferences (timing, format, recipients, etc.)
32
+ 4. Research other available sources, if applicable. (For example, previous email threads, relevant documents, web searches, etc.)
33
+
34
+ Skip this step only for simple, single-action tasks with clear instructions.
35
+
36
+ Only ask the most **essential** questions. Avoid burdening the user with too many questions.
37
+
38
+ ## 2. Connect to External Systems
39
+
40
+ When the task requires external systems (email, calendar, CRM, messaging, etc.), follow this sequence:
41
+
42
+ ### 2.1 Check Existing Connections
43
+
44
+ **Always start here.** Use `ManageConnections` to see what systems are already connected.
45
+
46
+ ### 2.2 If System is NOT Connected
47
+
48
+ 1. If the user didn't specify which system (e.g., "send an email" without saying Gmail/Outlook):
49
+ - Check what's already connected and infer from that
50
+ - If only one relevant system is connected (e.g., only Gmail for email), use it
51
+ - If none connected, ask which system they prefer
52
+ 2. Use `SearchTools` to find the relevant tools (e.g., `query="send email"`, `toolkit="GMAIL"`)
53
+ 3. Generate authentication link and provide it to the user
54
+ 4. Wait for the user to complete authentication
55
+ 5. Once connected, proceed to step 3
56
+
57
+ ## 3. Execute Tools
58
+
59
+ **Priority Order:** Always prefer specialized tools over generic Composio tools.
60
+
61
+ ### Priority 1: Specialized Tools (Highest Preference)
62
+
63
+ Use the available tools like `FindEmails`, `ReadEmail`, `DraftEmail`, `SendDraft`, `CheckEventsForDate`, `CreateCalendarEvent`, `RescheduleCalendarEvent`, `DeleteCalendarEvent`, `ProductSearch`, `ScholarSearch`, etc. when they match the task. They are optimized, tested, and handle edge cases.
64
+
65
+ **Example workflow:**
66
+
67
+ 1. User: "Check my unread emails"
68
+ 2. `ManageConnections` → Gmail is connected
69
+ 3. `CheckUnreadEmails(provider="gmail", limit=10)` → Done!
70
+
71
+ ### Priority 2: Composio Tools (Fallback)
72
+
73
+ Use `FindTools` + `ExecuteTool` only when no specialized tool exists for the task.
74
+
75
+ 1. Use `FindTools` with `include_args=True` to get the exact tool names and parameters
76
+
77
+ - Example: `tool_names=["GMAIL_SEND_MESSAGE"], include_args=True`
78
+ - Only load parameters for tools you're about to execute
79
+
80
+ 2. Choose the right execution method:
81
+
82
+ #### Option A: ExecuteTool (for simple tasks)
83
+
84
+ Use `ExecuteTool` for single tool execution without data transformation. Optionally filter output with `return_fields`.
85
+
86
+ #### Option B: ProgrammaticToolCalling (for complex workflows)
87
+
88
+ Use this option for tasks that require multiple tool calls, data processing, storing intermediate results, or complex logic.
89
+
90
+ ```python
91
+ from helpers import composio, user_id # only need to be imported in the first tool call
92
+
93
+ result = composio.tools.execute(
94
+ "TOOL_NAME_HERE",
95
+ user_id=user_id,
96
+ arguments={"param1": "value1", "param2": "value2"},
97
+ dangerously_skip_version_check=True
98
+ )
99
+ print(result)
100
+ ```
101
+
102
+ Examples of tasks suitable for Option B:
103
+
104
+ - Processing or analyzing data from Google Sheets
105
+ - Bulk operations (e.g., labeling multiple emails based on criteria)
106
+ - Cross-system workflows (e.g., create calendar event from email data)
107
+ - Tasks requiring loops or conditional logic
108
+ - Aggregating data from multiple API calls
109
+
110
+ **Example workflow (when no specialized tool exists):**
111
+
112
+ 1. `ManageConnections` → see Slack is connected
113
+ 2. `FindTools(toolkit="SLACK", include_args=False)` → discover SLACK_SEND_MESSAGE exists
114
+ 3. `FindTools(tool_names=["SLACK_SEND_MESSAGE"], include_args=True)` → get parameters
115
+ 4. Choose execution:
116
+ - Simple task → `ExecuteTool`
117
+ - Complex task → `ProgrammaticToolCalling`
118
+
119
+ ### 4. Common Composio Toolkits (for Priority 2 fallback)
120
+
121
+ Use these toolkits with `FindTools` when no specialized tool covers your task:
122
+
123
+ - **Email:** GMAIL, OUTLOOK
124
+ - **Calendar/Scheduling:** GOOGLECALENDAR, OUTLOOK, CALENDLY
125
+ - **Video/Meetings:** ZOOM, GOOGLEMEET, MICROSOFT_TEAMS
126
+ - **Messaging:** SLACK, WHATSAPP, TELEGRAM, DISCORD
127
+ - **Documents/Notes:** GOOGLEDOCS, GOOGLESHEETS, NOTION, AIRTABLE, CODA
128
+ - **Storage:** GOOGLEDRIVE, DROPBOX
129
+ - **Project Management:** NOTION, JIRA, ASANA, TRELLO, CLICKUP, MONDAY, BASECAMP
130
+ - **CRM/Sales:** HUBSPOT, SALESFORCE, PIPEDRIVE, APOLLO
131
+ - **Payments/Accounting:** STRIPE, SQUARE, QUICKBOOKS, XERO, FRESHBOOKS
132
+ - **Customer Support:** ZENDESK, INTERCOM, FRESHDESK
133
+ - **Marketing/Email:** MAILCHIMP, SENDGRID
134
+ - **Social Media:** LINKEDIN, TWITTER, INSTAGRAM
135
+ - **E-commerce:** SHOPIFY
136
+ - **Signatures:** DOCUSIGN
137
+ - **Design/Collaboration:** FIGMA, CANVA, MIRO
138
+ - **Development:** GITHUB
139
+ - **Analytics:** AMPLITUDE, MIXPANEL, SEGMENT
140
+
141
+ ### 5. Best Practices
142
+
143
+ - **Save intermediate results to a variable**: Avoid fetching the same data multiple times.
144
+ - **Explore the data**: Before filtering or extracting data, first explore the structure (database schema, email labels, folder organization, etc.) to understand what's available and find the most efficient query approach.
145
+ - **Format tool outputs**: Before logging a tool's output, check what fields and data format it returns. Extract and log only the information you need from the response.
146
+
147
+ ## 3. Plan Your Approach
148
+
149
+ Before executing any tools:
150
+
151
+ 1. **Think through the complete task** end-to-end
152
+ 2. **Identify all required steps** in sequence
153
+ 3. **Anticipate potential issues** or edge cases
154
+ 4. **Determine if any steps are irreversible** (sending emails, deleting records, making purchases)
155
+
156
+ ## 4. Execute with Minimal Tool Calls
157
+
158
+ 1. Execute the planned steps efficiently
159
+ 2. Use the fewest tool calls necessary
160
+ 3. Handle errors gracefully and debug if needed
161
+ 4. **For destructive/irreversible actions:**
162
+ - **Default behavior:** Always confirm before executing
163
+ - **Pre-authorized actions:** If the user explicitly includes words like "send immediately", "delete now", or "book it", you may skip confirmation
164
+ - **Email workflow:**
165
+ - Create draft in the email system (Gmail, Outlook, etc.)
166
+ - If preview link is available: provide the link for review
167
+ - If no preview link: output the full draft content in chat for review
168
+ - Wait for approval → then send (unless pre-authorized)
169
+ - **CRM deletions:** Show record link → confirm deletion → execute (unless pre-authorized)
170
+ - **Purchases:** Show details/cost → wait for approval → execute (unless pre-authorized)
171
+ - **Same-day calendar changes:** Notify immediately → confirm → execute
172
+ - **Never output IDs without context:** Don't show message IDs, record IDs, or other technical identifiers unless they're part of a clickable link
173
+
174
+ ## 5. Report and Suggest Next Steps
175
+
176
+ 1. Summarize what was done
177
+ 2. Show key results or outcomes
178
+ 3. Proactively suggest logical next steps
179
+
180
+ # Output Format
181
+
182
+ - Respond concisely using simple, easy to read language.
183
+ - Use bullet points and clear formatting for readability.
184
+ - When executing tasks, report: what was done, the result, and any next steps.
185
+ - When drafting messages directly in chat (like for WhatsApp or any other unsupported messaging system), output the full message content and nothing else so the user can just copy it.
186
+ - Be proactive in suggesting the next steps.
187
+ - NEVER use em dashes.
188
+ - If you are stuck / blocked on a specific task, use the **1-3-1 technique**:
189
+ 1. Clearly define the problem.
190
+ 2. Identify 3 possible solutions.
191
+ 3. Provide your recommendation on how to proceed among the 3 options.
192
+ - When responding on behalf of the user via email, always be polite and professional.
193
+ - When responding on behalf of the user via messaging (WhatsApp, Slack, etc.), be more casual and friendly. Do not include subjects and signatures unless requested in draft messages.
194
+ - For slack messages, use Slack formatting: _bold_, _italic_, ~strike~, `inline code` and `code blocks`, > quotes, simple lists, emoji (:smile:), links as auto URLs or `<https://example.com|label>` (also `[label](url)` in markup mode), plus mentions like `<@USERID>` and `<#CHANNELID>`
195
+
196
+ # Additional Notes
197
+
198
+ - **Context window efficiency:** Only log what you actually need to see. Context window is a public good.
199
+ - **Confirmation vs speed:** Default to asking confirmation for irreversible operations, but skip if the user pre-authorizes with explicit language ("send now", "book immediately", etc.)
200
+ - **Preview workflow:**
201
+ - First, try to create drafts in the external system (Gmail, Notion, etc.) and provide preview links
202
+ - If preview links aren't available, output the full content in chat for review
203
+ - For local files created during execution, include the file path in your response
204
+ - Never show technical IDs (message IDs, record IDs) without providing either a link or the actual content
205
+ - Do not put preview links inside a code block so the user can click on them.
206
+ - **Remember preferences:** Once the user tells you their preference (which email system, which calendar, meeting length, etc.), remember it for future tasks.
@@ -0,0 +1,154 @@
1
+ from typing import Literal, List
2
+ from agency_swarm.tools import BaseTool
3
+ from pydantic import Field
4
+ import json
5
+
6
+ from helpers import execute_composio_tool
7
+
8
+
9
+ class AddLabelToEmail(BaseTool):
10
+ """
11
+ Adds labels to a specific email message.
12
+
13
+ For Gmail: Use label IDs (system labels like 'STARRED', 'IMPORTANT', 'INBOX',
14
+ or custom label IDs like 'Label_123' from ManageLabels).
15
+
16
+ For Outlook: Use category names (must exist in the user's category list).
17
+ """
18
+
19
+ provider: Literal["gmail", "outlook"] = Field(
20
+ ...,
21
+ description="Email provider: 'gmail' or 'outlook'"
22
+ )
23
+
24
+ message_id: str = Field(
25
+ ...,
26
+ description="The message ID to add labels to (obtained from CheckUnreadEmails)"
27
+ )
28
+
29
+ label_ids: List[str] = Field(
30
+ ...,
31
+ description="List of label IDs to add. Gmail: 'STARRED', 'IMPORTANT', 'Label_123'. Outlook: category names."
32
+ )
33
+
34
+ def run(self):
35
+ try:
36
+ if self.provider == "gmail":
37
+ return self._add_gmail_labels(execute_composio_tool)
38
+ else:
39
+ return self._add_outlook_categories(execute_composio_tool)
40
+
41
+ except Exception as e:
42
+ return f"Error adding labels: {str(e)}"
43
+
44
+ def _add_gmail_labels(self, execute_tool) -> str:
45
+ """Adds labels to a Gmail message."""
46
+ result = execute_tool(
47
+ tool_name="GMAIL_ADD_LABEL_TO_EMAIL",
48
+ arguments={
49
+ "user_id": "me",
50
+ "message_id": self.message_id,
51
+ "add_label_ids": self.label_ids
52
+ },
53
+ )
54
+
55
+ if isinstance(result, dict) and result.get("error"):
56
+ return f"Error adding Gmail labels: {result.get('error')}"
57
+
58
+ data = result.get("data", {})
59
+
60
+ return json.dumps({
61
+ "provider": "gmail",
62
+ "success": True,
63
+ "message_id": self.message_id,
64
+ "labels_added": self.label_ids,
65
+ "current_labels": data.get("labelIds", [])
66
+ }, indent=2)
67
+
68
+ def _add_outlook_categories(self, execute_tool) -> str:
69
+ """Adds categories to an Outlook message."""
70
+ # For Outlook, we need to update the message with categories
71
+ # First get current categories, then add new ones
72
+
73
+ # Get current message
74
+ get_result = execute_tool(
75
+ tool_name="OUTLOOK_GET_MESSAGE",
76
+ arguments={
77
+ "user_id": "me",
78
+ "message_id": self.message_id,
79
+ "select": ["id", "categories"]
80
+ },
81
+ )
82
+
83
+ if isinstance(get_result, dict) and get_result.get("error"):
84
+ return f"Error getting Outlook message: {get_result.get('error')}"
85
+
86
+ current_categories = get_result.get("data", {}).get("categories", [])
87
+
88
+ # Combine current and new categories (avoid duplicates)
89
+ updated_categories = list(set(current_categories + self.label_ids))
90
+
91
+ # Update the message with new categories
92
+ # Note: Outlook doesn't have a direct "add category" API, need to use update
93
+ return json.dumps({
94
+ "provider": "outlook",
95
+ "success": True,
96
+ "message_id": self.message_id,
97
+ "categories_added": self.label_ids,
98
+ "current_categories": current_categories,
99
+ "updated_categories": updated_categories,
100
+ "note": "Outlook category update requires OUTLOOK_UPDATE_MESSAGE which may not be available"
101
+ }, indent=2)
102
+
103
+
104
+ if __name__ == "__main__":
105
+ import sys
106
+ import os
107
+ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")))
108
+
109
+ print("=" * 60)
110
+ print("AddLabelToEmail Test Suite")
111
+ print("=" * 60)
112
+ print()
113
+
114
+ # Get a message ID first
115
+ from virtual_assistant.tools.CheckUnreadEmails import CheckUnreadEmails
116
+ check_tool = CheckUnreadEmails(provider="gmail", limit=1)
117
+ result = check_tool.run()
118
+
119
+ import json
120
+ data = json.loads(result)
121
+ if data.get("emails"):
122
+ message_id = data["emails"][0]["message_id"]
123
+
124
+ # Test: Add STARRED label
125
+ print("Test: Add STARRED label to email")
126
+ print("-" * 60)
127
+ tool = AddLabelToEmail(
128
+ provider="gmail",
129
+ message_id=message_id,
130
+ label_ids=["STARRED"]
131
+ )
132
+ result = tool.run()
133
+ print(result)
134
+ print()
135
+
136
+ # Remove it to clean up
137
+ from virtual_assistant.tools.RemoveLabelFromEmail import RemoveLabelFromEmail
138
+ print("Cleanup: Remove STARRED label")
139
+ print("-" * 60)
140
+ tool = RemoveLabelFromEmail(
141
+ provider="gmail",
142
+ message_id=message_id,
143
+ label_ids=["STARRED"]
144
+ )
145
+ result = tool.run()
146
+ print(result)
147
+ else:
148
+ print("No emails to test with")
149
+
150
+ print()
151
+ print("=" * 60)
152
+ print("Tests completed!")
153
+ print("=" * 60)
154
+
@@ -0,0 +1,218 @@
1
+ from typing import Literal
2
+ from agency_swarm.tools import BaseTool
3
+ from pydantic import Field
4
+ import json
5
+ from datetime import datetime
6
+
7
+ from helpers import execute_composio_tool
8
+
9
+
10
+ class CheckEventsForDate(BaseTool):
11
+ """
12
+ Retrieves all calendar events for a specific date (Google Calendar or Outlook).
13
+
14
+ Returns event details including title, start/end times, and event IDs.
15
+ Events are returned in chronological order by start time.
16
+ """
17
+
18
+ provider: Literal["google", "outlook"] = Field(
19
+ ...,
20
+ description="Calendar provider to use: 'google' (Google Calendar) or 'outlook'"
21
+ )
22
+
23
+ date: str = Field(
24
+ ...,
25
+ description="Date to check for events in YYYY-MM-DD format (e.g., '2026-01-07')"
26
+ )
27
+
28
+ timezone: str = Field(
29
+ default="UTC",
30
+ description="Timezone for the date and event times. Use IANA format (e.g., 'America/New_York', 'Europe/London', 'Asia/Dubai')"
31
+ )
32
+
33
+ def run(self):
34
+ try:
35
+ try:
36
+ parsed_date = datetime.strptime(self.date, "%Y-%m-%d")
37
+ except ValueError:
38
+ return f"Error: Invalid date format '{self.date}'. Use YYYY-MM-DD format."
39
+
40
+ if self.provider == "google":
41
+ return self._fetch_google_calendar_events(execute_composio_tool, parsed_date)
42
+ else:
43
+ return self._fetch_outlook_events(execute_composio_tool, parsed_date)
44
+
45
+ except Exception as e:
46
+ return f"Error fetching calendar events: {str(e)}"
47
+
48
+ def _fetch_google_calendar_events(self, execute_tool, date: datetime) -> str:
49
+ """Fetches events from Google Calendar for the specified date."""
50
+ time_min = f"{date.strftime('%Y-%m-%d')}T00:00:00Z"
51
+ time_max = f"{date.strftime('%Y-%m-%d')}T23:59:59Z"
52
+
53
+ result = execute_tool(
54
+ tool_name="GOOGLECALENDAR_EVENTS_LIST",
55
+ arguments={
56
+ "calendarId": "primary",
57
+ "timeMin": time_min,
58
+ "timeMax": time_max,
59
+ "singleEvents": True,
60
+ "orderBy": "startTime",
61
+ "timeZone": self.timezone
62
+ },
63
+ )
64
+
65
+ if isinstance(result, dict) and result.get("error"):
66
+ return f"Error fetching Google Calendar events: {result.get('error')}"
67
+
68
+ events = result.get("data", {}).get("items", [])
69
+
70
+ if not events:
71
+ return json.dumps({
72
+ "provider": "google",
73
+ "date": self.date,
74
+ "timezone": self.timezone,
75
+ "count": 0,
76
+ "events": []
77
+ }, indent=2)
78
+
79
+ formatted_events = []
80
+ for event in events:
81
+ start = event.get("start", {})
82
+ end = event.get("end", {})
83
+
84
+ # Handle all-day events (have 'date') vs timed events (have 'dateTime')
85
+ start_time = start.get("dateTime") or start.get("date", "")
86
+ end_time = end.get("dateTime") or end.get("date", "")
87
+ is_all_day = "date" in start and "dateTime" not in start
88
+
89
+ formatted_events.append({
90
+ "title": event.get("summary", "(No title)"),
91
+ "event_id": event.get("id"),
92
+ "start": start_time,
93
+ "end": end_time,
94
+ "all_day": is_all_day,
95
+ "description": event.get("description", ""),
96
+ "location": event.get("location", ""),
97
+ "status": event.get("status", ""),
98
+ "html_link": event.get("htmlLink", "")
99
+ })
100
+
101
+ return json.dumps({
102
+ "provider": "google",
103
+ "date": self.date,
104
+ "timezone": self.timezone,
105
+ "count": len(formatted_events),
106
+ "events": formatted_events
107
+ }, indent=2)
108
+
109
+ def _fetch_outlook_events(self, execute_tool, date: datetime) -> str:
110
+ """Fetches events from Outlook Calendar for the specified date."""
111
+ start_datetime = f"{date.strftime('%Y-%m-%d')}T00:00:00Z"
112
+ end_datetime = f"{date.strftime('%Y-%m-%d')}T23:59:59Z"
113
+
114
+ result = execute_tool(
115
+ tool_name="OUTLOOK_GET_CALENDAR_VIEW",
116
+ arguments={
117
+ "user_id": "me",
118
+ "start_datetime": start_datetime,
119
+ "end_datetime": end_datetime,
120
+ "timezone": self.timezone,
121
+ "top": 100
122
+ },
123
+ )
124
+
125
+ if isinstance(result, dict) and result.get("error"):
126
+ return f"Error fetching Outlook events: {result.get('error')}"
127
+
128
+ events = result.get("data", {}).get("value", [])
129
+
130
+ if not events:
131
+ return json.dumps({
132
+ "provider": "outlook",
133
+ "date": self.date,
134
+ "timezone": self.timezone,
135
+ "count": 0,
136
+ "events": []
137
+ }, indent=2)
138
+
139
+ formatted_events = []
140
+ for event in events:
141
+ start = event.get("start", {})
142
+ end = event.get("end", {})
143
+
144
+ # Extract body/description content
145
+ body_data = event.get("body", {})
146
+ description = body_data.get("content", "") if isinstance(body_data, dict) else ""
147
+
148
+ formatted_events.append({
149
+ "title": event.get("subject", "(No title)"),
150
+ "event_id": event.get("id"),
151
+ "start": start.get("dateTime", ""),
152
+ "end": end.get("dateTime", ""),
153
+ "all_day": event.get("isAllDay", False),
154
+ "description": description,
155
+ "location": event.get("location", {}).get("displayName", ""),
156
+ "status": event.get("showAs", ""),
157
+ "web_link": event.get("webLink", "")
158
+ })
159
+
160
+ return json.dumps({
161
+ "provider": "outlook",
162
+ "date": self.date,
163
+ "timezone": self.timezone,
164
+ "count": len(formatted_events),
165
+ "events": formatted_events
166
+ }, indent=2)
167
+
168
+
169
+ if __name__ == "__main__":
170
+ import sys
171
+ import os
172
+ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")))
173
+
174
+ from datetime import date as dt_date
175
+
176
+ print("=" * 60)
177
+ print("CheckEventsForDate Test Suite")
178
+ print("=" * 60)
179
+ print()
180
+
181
+ today = dt_date.today().strftime("%Y-%m-%d")
182
+
183
+ # Test 1: Google Calendar for today
184
+ print(f"Test 1: Google Calendar - Today ({today})")
185
+ print("-" * 60)
186
+ tool = CheckEventsForDate(provider="google", date=today)
187
+ result = tool.run()
188
+ print(result)
189
+ print()
190
+
191
+ # Test 2: Google Calendar with custom timezone
192
+ print("Test 2: Google Calendar - Today with timezone")
193
+ print("-" * 60)
194
+ tool = CheckEventsForDate(provider="google", date=today, timezone="Asia/Dubai")
195
+ result = tool.run()
196
+ print(result)
197
+ print()
198
+
199
+ # Test 3: Outlook for today
200
+ print(f"Test 3: Outlook - Today ({today})")
201
+ print("-" * 60)
202
+ tool = CheckEventsForDate(provider="outlook", date=today)
203
+ result = tool.run()
204
+ print(result)
205
+ print()
206
+
207
+ # Test 4: Invalid date format
208
+ print("Test 4: Invalid date format")
209
+ print("-" * 60)
210
+ tool = CheckEventsForDate(provider="google", date="01-07-2026")
211
+ result = tool.run()
212
+ print(result)
213
+ print()
214
+
215
+ print("=" * 60)
216
+ print("All tests completed!")
217
+ print("=" * 60)
218
+