@_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,200 @@
1
+ """Edit images with Gemini or OpenAI image models."""
2
+
3
+ from typing import Literal
4
+
5
+ import os
6
+ from openai import OpenAI
7
+ from pydantic import Field, field_validator, model_validator
8
+
9
+ from agency_swarm import BaseTool
10
+
11
+ from .utils.image_io import (
12
+ get_images_dir,
13
+ build_variant_output_name,
14
+ resolve_image_reference,
15
+ save_image,
16
+ image_to_base64_jpeg,
17
+ build_multimodal_outputs,
18
+ extract_gemini_image_and_usage,
19
+ extract_openai_images_and_usage,
20
+ run_parallel_variants_sync,
21
+ validate_aspect_ratio_for_model,
22
+ get_openai_size_for_aspect_ratio,
23
+ )
24
+
25
+
26
+ class EditImages(BaseTool):
27
+ """
28
+ Edit an existing image using a text instruction.
29
+
30
+ Supports local path, URL, or generated image name references.
31
+ Outputs are saved to: mnt/{product_name}/generated_images/
32
+ """
33
+
34
+ product_name: str = Field(..., description="Product namespace for output files.")
35
+ input_image_ref: str = Field(
36
+ ...,
37
+ description="Input image reference (URL, absolute path, or generated image name).",
38
+ )
39
+ edit_prompt: str = Field(..., description="Instruction describing how to edit the image.")
40
+ output_file_name: str = Field(
41
+ ...,
42
+ description=(
43
+ "Output image name (without extension) or output path. "
44
+ "If a path is provided, the image is saved at that path."
45
+ ),
46
+ )
47
+ model: Literal["gemini-2.5-flash-image", "gemini-3-pro-image-preview", "gpt-image-1.5"] = Field(
48
+ default="gemini-2.5-flash-image",
49
+ description="Image model to use.",
50
+ )
51
+ num_variants: int = Field(default=1, description="Number of variants to generate (1-4).")
52
+ aspect_ratio: Literal["1:1", "2:3", "3:2", "3:4", "4:3", "4:5", "5:4", "9:16", "16:9", "21:9"] = Field(
53
+ default="1:1",
54
+ description="Target aspect ratio. Model compatibility is validated automatically.",
55
+ )
56
+
57
+ @field_validator("product_name", "input_image_ref", "edit_prompt", "output_file_name")
58
+ @classmethod
59
+ def _not_blank(cls, value: str) -> str:
60
+ if not value.strip():
61
+ raise ValueError("value must not be empty")
62
+ return value
63
+
64
+ @field_validator("num_variants")
65
+ @classmethod
66
+ def _validate_variants(cls, value: int) -> int:
67
+ if value < 1 or value > 4:
68
+ raise ValueError("num_variants must be between 1 and 4")
69
+ return value
70
+
71
+ @model_validator(mode="after")
72
+ def _validate_model_aspect_ratio(self) -> "EditImages":
73
+ validate_aspect_ratio_for_model(self.model, self.aspect_ratio)
74
+ return self
75
+
76
+ def run(self) -> list:
77
+ images_dir = get_images_dir(self.product_name)
78
+ input_image, source = resolve_image_reference(self.product_name, self.input_image_ref)
79
+
80
+ if self.model.startswith("gemini-"):
81
+ results, usage_metadata = self._run_gemini(images_dir, input_image)
82
+ return build_multimodal_outputs(results, "Image editing complete")
83
+
84
+ results, usage_metadata = self._run_openai(images_dir, input_image)
85
+ return build_multimodal_outputs(results, "Image editing complete")
86
+
87
+ def _run_gemini(self, images_dir, input_image):
88
+ from google import genai
89
+ from google.genai.types import GenerateContentConfig, ImageConfig
90
+
91
+ api_key = os.getenv("GOOGLE_API_KEY")
92
+ if not api_key:
93
+ raise ValueError("GOOGLE_API_KEY is not set. Add it to your .env to use image editing.")
94
+
95
+ client = genai.Client(api_key=api_key)
96
+ results: list[dict] = []
97
+ total_prompt_tokens = 0.0
98
+ total_candidate_tokens = 0.0
99
+
100
+ def edit_single_variant(idx: int):
101
+ response = client.models.generate_content(
102
+ model=self.model,
103
+ contents=[self.edit_prompt, input_image],
104
+ config=GenerateContentConfig(
105
+ image_config=ImageConfig(aspect_ratio=self.aspect_ratio),
106
+ ),
107
+ )
108
+ image, usage = extract_gemini_image_and_usage(response)
109
+ if image is None:
110
+ return None
111
+
112
+ variant_name = build_variant_output_name(self.output_file_name, idx, self.num_variants)
113
+ image_name, file_path = save_image(image, variant_name, images_dir)
114
+ return {
115
+ "image_name": image_name,
116
+ "file_path": file_path,
117
+ "preview_b64": image_to_base64_jpeg(image),
118
+ "prompt_tokens": float(usage.get("prompt_token_count") or 0),
119
+ "candidate_tokens": float(usage.get("candidates_token_count") or 0),
120
+ }
121
+
122
+ raw_results = run_parallel_variants_sync(edit_single_variant, self.num_variants)
123
+ if not raw_results:
124
+ raise RuntimeError("Gemini did not return any edited images.")
125
+
126
+ for item in raw_results:
127
+ total_prompt_tokens += item.pop("prompt_tokens")
128
+ total_candidate_tokens += item.pop("candidate_tokens")
129
+ results.append(item)
130
+
131
+ usage_metadata = {
132
+ "prompt_token_count": total_prompt_tokens,
133
+ "candidates_token_count": total_candidate_tokens,
134
+ }
135
+ return results, usage_metadata
136
+
137
+ def _run_openai(self, images_dir, input_image):
138
+ api_key = os.getenv("OPENAI_API_KEY")
139
+ if not api_key:
140
+ raise RuntimeError("OPENAI_API_KEY is required for OpenAI image editing.")
141
+
142
+ size = get_openai_size_for_aspect_ratio(self.aspect_ratio)
143
+
144
+ from io import BytesIO
145
+
146
+ buffer = BytesIO()
147
+ input_image.save(buffer, format="PNG")
148
+ buffer.seek(0)
149
+ buffer.name = "input.png"
150
+
151
+ try:
152
+ client = OpenAI(api_key=api_key)
153
+ response = client.images.edit(
154
+ model=self.model,
155
+ image=buffer,
156
+ prompt=self.edit_prompt,
157
+ size=size,
158
+ n=self.num_variants,
159
+ )
160
+ finally:
161
+ buffer.close()
162
+
163
+ images, usage_metadata = extract_openai_images_and_usage(response)
164
+ if not images:
165
+ raise RuntimeError("OpenAI image edit API did not return images.")
166
+
167
+ results: list[dict] = []
168
+ for idx, image in enumerate(images, start=1):
169
+ variant_name = build_variant_output_name(self.output_file_name, idx, len(images))
170
+ image_name, file_path = save_image(image, variant_name, images_dir)
171
+ results.append(
172
+ {
173
+ "image_name": image_name,
174
+ "file_path": file_path,
175
+ "preview_b64": image_to_base64_jpeg(image),
176
+ }
177
+ )
178
+
179
+ return results, usage_metadata
180
+
181
+
182
+ if __name__ == "__main__":
183
+ # Example test scenario
184
+ tool = EditImages(
185
+ product_name="Test_Product",
186
+ input_image_ref="hero_image_example_oai_hero",
187
+ edit_prompt=(
188
+ "Replace the background with a black wall, slightly illuminated with a white neon light"
189
+ ),
190
+ output_file_name="edited_image_example",
191
+ model="gpt-image-1.5",
192
+ aspect_ratio="1:1",
193
+ num_variants=1,
194
+ )
195
+ try:
196
+ result = tool.run()
197
+ print(result)
198
+ except Exception as exc:
199
+ print(f"Image editing failed: {exc}")
200
+
@@ -0,0 +1,184 @@
1
+ """Generate images with Gemini or OpenAI image models."""
2
+
3
+ from typing import Literal
4
+
5
+ import os
6
+ from openai import OpenAI
7
+ from pydantic import Field, field_validator, model_validator
8
+
9
+ from agency_swarm import BaseTool
10
+
11
+ from .utils.image_io import (
12
+ get_images_dir,
13
+ build_variant_output_name,
14
+ save_image,
15
+ image_to_base64_jpeg,
16
+ build_multimodal_outputs,
17
+ extract_gemini_image_and_usage,
18
+ extract_openai_images_and_usage,
19
+ run_parallel_variants_sync,
20
+ validate_aspect_ratio_for_model,
21
+ get_openai_size_for_aspect_ratio,
22
+ )
23
+
24
+
25
+ class GenerateImages(BaseTool):
26
+ """
27
+ Generate one or more images from a prompt using Gemini or OpenAI image models.
28
+
29
+ Outputs are saved to: mnt/{product_name}/generated_images/
30
+ """
31
+
32
+ product_name: str = Field(..., description="Product namespace for output files.")
33
+ prompt: str = Field(..., description="Detailed prompt describing the desired image.")
34
+ file_name: str = Field(
35
+ ...,
36
+ description=(
37
+ "Output file name (without extension) or output path. "
38
+ "If a path is provided, the image is saved at that path."
39
+ ),
40
+ )
41
+ model: Literal["gemini-2.5-flash-image", "gemini-3-pro-image-preview", "gpt-image-1.5"] = Field(
42
+ default="gemini-2.5-flash-image",
43
+ description="Image model to use.",
44
+ )
45
+ num_variants: int = Field(default=1, description="Number of variants to generate (1-4).")
46
+ aspect_ratio: Literal["1:1", "2:3", "3:2", "3:4", "4:3", "4:5", "5:4", "9:16", "16:9", "21:9"] = Field(
47
+ default="1:1",
48
+ description="Target aspect ratio.",
49
+ )
50
+
51
+ @field_validator("prompt", "product_name", "file_name")
52
+ @classmethod
53
+ def _not_blank(cls, value: str) -> str:
54
+ if not value.strip():
55
+ raise ValueError("value must not be empty")
56
+ return value
57
+
58
+ @field_validator("num_variants")
59
+ @classmethod
60
+ def _validate_variants(cls, value: int) -> int:
61
+ if value < 1 or value > 4:
62
+ raise ValueError("num_variants must be between 1 and 4")
63
+ return value
64
+
65
+ @model_validator(mode="after")
66
+ def _validate_model_aspect_ratio(self) -> "GenerateImages":
67
+ validate_aspect_ratio_for_model(self.model, self.aspect_ratio)
68
+ return self
69
+
70
+ def run(self) -> list:
71
+ images_dir = get_images_dir(self.product_name)
72
+
73
+ if self.model.startswith("gemini-"):
74
+ results, usage_metadata = self._run_gemini(images_dir)
75
+ return build_multimodal_outputs(results, "Image generation complete")
76
+
77
+ results, usage_metadata = self._run_openai(images_dir)
78
+ return build_multimodal_outputs(results, "Image generation complete")
79
+
80
+ def _run_gemini(self, images_dir):
81
+ from google import genai
82
+ from google.genai.types import GenerateContentConfig, ImageConfig
83
+
84
+ api_key = os.getenv("GOOGLE_API_KEY")
85
+ if not api_key:
86
+ raise ValueError("GOOGLE_API_KEY is not set. Add it to your .env to use image generation.")
87
+
88
+ client = genai.Client(api_key=api_key)
89
+ results: list[dict] = []
90
+ total_prompt_tokens = 0.0
91
+ total_candidate_tokens = 0.0
92
+
93
+ def generate_single_variant(idx: int):
94
+ response = client.models.generate_content(
95
+ model=self.model,
96
+ contents=self.prompt,
97
+ config=GenerateContentConfig(
98
+ image_config=ImageConfig(aspect_ratio=self.aspect_ratio),
99
+ ),
100
+ )
101
+ image, usage = extract_gemini_image_and_usage(response)
102
+ if image is None:
103
+ return None
104
+
105
+ variant_name = build_variant_output_name(self.file_name, idx, self.num_variants)
106
+ image_name, file_path = save_image(image, variant_name, images_dir)
107
+ return {
108
+ "image_name": image_name,
109
+ "file_path": file_path,
110
+ "preview_b64": image_to_base64_jpeg(image),
111
+ "prompt_tokens": float(usage.get("prompt_token_count") or 0),
112
+ "candidate_tokens": float(usage.get("candidates_token_count") or 0),
113
+ }
114
+
115
+ raw_results = run_parallel_variants_sync(generate_single_variant, self.num_variants)
116
+ if not raw_results:
117
+ raise RuntimeError("Gemini did not return any images.")
118
+
119
+ for item in raw_results:
120
+ total_prompt_tokens += item.pop("prompt_tokens")
121
+ total_candidate_tokens += item.pop("candidate_tokens")
122
+ results.append(item)
123
+
124
+ usage_metadata = {
125
+ "prompt_token_count": total_prompt_tokens,
126
+ "candidates_token_count": total_candidate_tokens,
127
+ }
128
+ return results, usage_metadata
129
+
130
+ def _run_openai(self, images_dir):
131
+ api_key = os.getenv("OPENAI_API_KEY")
132
+ if not api_key:
133
+ raise RuntimeError("OPENAI_API_KEY is required for OpenAI image generation.")
134
+
135
+ size = get_openai_size_for_aspect_ratio(self.aspect_ratio)
136
+
137
+ client = OpenAI(api_key=api_key)
138
+ response = client.images.generate(
139
+ model=self.model,
140
+ prompt=self.prompt,
141
+ size=size,
142
+ n=self.num_variants,
143
+ )
144
+ images, usage_metadata = extract_openai_images_and_usage(response)
145
+ if not images:
146
+ raise RuntimeError("OpenAI image API did not return images.")
147
+
148
+ results: list[dict] = []
149
+ for idx, image in enumerate(images, start=1):
150
+ variant_name = build_variant_output_name(self.file_name, idx, len(images))
151
+ image_name, file_path = save_image(image, variant_name, images_dir)
152
+ results.append(
153
+ {
154
+ "image_name": image_name,
155
+ "file_path": file_path,
156
+ "preview_b64": image_to_base64_jpeg(image),
157
+ }
158
+ )
159
+ return results, usage_metadata
160
+
161
+
162
+ if __name__ == "__main__":
163
+ # Example test scenario
164
+ tool = GenerateImages(
165
+ product_name="Test_Product",
166
+ prompt=(
167
+ "A premium product hero shot of a minimalist glass skincare bottle on a "
168
+ "clean marble surface, soft studio lighting, subtle reflections, "
169
+ "high-end commercial photography style."
170
+ ),
171
+ # prompt=(
172
+ # "Create a logo for a skincare product that includes a leaf and a drop of water"
173
+ # ),
174
+ file_name="hero_image_example_oai_hero",
175
+ model="gpt-image-1.5",
176
+ aspect_ratio="1:1",
177
+ num_variants=1,
178
+ )
179
+ try:
180
+ result = tool.run()
181
+ print(result)
182
+ except Exception as exc:
183
+ print(f"Image generation failed: {exc}")
184
+
@@ -0,0 +1,108 @@
1
+ """Remove image backgrounds using the Pixelcut model via fal.ai."""
2
+
3
+ import io
4
+ import os
5
+ from pathlib import Path
6
+ from urllib.parse import urlparse
7
+
8
+ import fal_client
9
+ import requests
10
+ from PIL import Image
11
+ from pydantic import Field, field_validator
12
+
13
+ from agency_swarm import BaseTool
14
+
15
+ from .utils.image_io import (
16
+ find_image_path_from_name,
17
+ get_images_dir,
18
+ save_image,
19
+ )
20
+
21
+ FAL_ENDPOINT = "pixelcut/background-removal"
22
+
23
+
24
+ class RemoveBackground(BaseTool):
25
+ """
26
+ Remove the background from an image using Pixelcut via fal.ai.
27
+
28
+ The output is a transparent PNG saved to: mnt/{product_name}/generated_images/
29
+ Supports local path, URL, or generated image name as input.
30
+ """
31
+
32
+ product_name: str = Field(..., description="Product namespace for output files.")
33
+ input_image_ref: str = Field(
34
+ ...,
35
+ description="Input image reference (URL, absolute path, or generated image name).",
36
+ )
37
+ output_file_name: str = Field(
38
+ ...,
39
+ description=(
40
+ "Output image name (without extension) or output path. "
41
+ "If a path is provided, the image is saved at that path."
42
+ ),
43
+ )
44
+
45
+ @field_validator("product_name", "input_image_ref", "output_file_name")
46
+ @classmethod
47
+ def _not_blank(cls, value: str) -> str:
48
+ if not value.strip():
49
+ raise ValueError("value must not be empty")
50
+ return value
51
+
52
+ def run(self) -> list:
53
+ api_key = os.getenv("FAL_KEY")
54
+ if not api_key:
55
+ raise ValueError("FAL_KEY is not set. Add it to your .env to use background removal.")
56
+ fal = fal_client.SyncClient(key=api_key)
57
+
58
+ images_dir = get_images_dir(self.product_name)
59
+ image_url = self._resolve_to_upload_url(images_dir, fal)
60
+ result = fal.subscribe(
61
+ FAL_ENDPOINT,
62
+ arguments={"image_url": image_url, "output_format": "rgba", "sync_mode": False},
63
+ )
64
+
65
+ result_url = (result.get("image") or {}).get("url")
66
+ if not result_url:
67
+ raise RuntimeError("fal.ai background removal returned no image URL.")
68
+
69
+ rgba_image = self._download_rgba(result_url)
70
+ image_name, file_path = save_image(rgba_image, self.output_file_name, images_dir)
71
+
72
+ return f"Background removal complete.\nImage name: {image_name}\nPath: {file_path}"
73
+
74
+ def _resolve_to_upload_url(self, images_dir: Path, fal: fal_client.SyncClient) -> str:
75
+ ref = self.input_image_ref.strip()
76
+
77
+ parsed = urlparse(ref)
78
+ if parsed.scheme in ("http", "https"):
79
+ return ref
80
+
81
+ candidate = Path(ref).expanduser().resolve()
82
+ if candidate.exists():
83
+ return fal.upload_file(str(candidate))
84
+
85
+ by_name = find_image_path_from_name(images_dir, ref)
86
+ if by_name is not None:
87
+ return fal.upload_file(str(by_name))
88
+
89
+ raise FileNotFoundError(
90
+ f"Could not resolve image reference '{ref}' as URL, path, or name in {images_dir}."
91
+ )
92
+
93
+ def _download_rgba(self, url: str) -> Image.Image:
94
+ response = requests.get(url, timeout=30)
95
+ response.raise_for_status()
96
+ return Image.open(io.BytesIO(response.content)).convert("RGBA")
97
+
98
+ if __name__ == "__main__":
99
+ tool = RemoveBackground(
100
+ product_name="Test_Product",
101
+ input_image_ref="test_image.jpg",
102
+ output_file_name="hero_no_bg",
103
+ )
104
+ try:
105
+ result = tool.run()
106
+ print(result)
107
+ except Exception as exc:
108
+ print(f"Background removal failed: {exc}")
@@ -0,0 +1,2 @@
1
+ """Tools for the image generation agent."""
2
+
@@ -0,0 +1,2 @@
1
+ """Utility helpers for image generation tools."""
2
+