ai-parrot 0.17.2__cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

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 (535) hide show
  1. agentui/.prettierrc +15 -0
  2. agentui/QUICKSTART.md +272 -0
  3. agentui/README.md +59 -0
  4. agentui/env.example +16 -0
  5. agentui/jsconfig.json +14 -0
  6. agentui/package-lock.json +4242 -0
  7. agentui/package.json +34 -0
  8. agentui/scripts/postinstall/apply-patches.mjs +260 -0
  9. agentui/src/app.css +61 -0
  10. agentui/src/app.d.ts +13 -0
  11. agentui/src/app.html +12 -0
  12. agentui/src/components/LoadingSpinner.svelte +64 -0
  13. agentui/src/components/ThemeSwitcher.svelte +159 -0
  14. agentui/src/components/index.js +4 -0
  15. agentui/src/lib/api/bots.ts +60 -0
  16. agentui/src/lib/api/chat.ts +22 -0
  17. agentui/src/lib/api/http.ts +25 -0
  18. agentui/src/lib/components/BotCard.svelte +33 -0
  19. agentui/src/lib/components/ChatBubble.svelte +63 -0
  20. agentui/src/lib/components/Toast.svelte +21 -0
  21. agentui/src/lib/config.ts +20 -0
  22. agentui/src/lib/stores/auth.svelte.ts +73 -0
  23. agentui/src/lib/stores/theme.svelte.js +64 -0
  24. agentui/src/lib/stores/toast.svelte.ts +31 -0
  25. agentui/src/lib/utils/conversation.ts +39 -0
  26. agentui/src/routes/+layout.svelte +20 -0
  27. agentui/src/routes/+page.svelte +232 -0
  28. agentui/src/routes/login/+page.svelte +200 -0
  29. agentui/src/routes/talk/[agentId]/+page.svelte +297 -0
  30. agentui/src/routes/talk/[agentId]/+page.ts +7 -0
  31. agentui/static/README.md +1 -0
  32. agentui/svelte.config.js +11 -0
  33. agentui/tailwind.config.ts +53 -0
  34. agentui/tsconfig.json +3 -0
  35. agentui/vite.config.ts +10 -0
  36. ai_parrot-0.17.2.dist-info/METADATA +472 -0
  37. ai_parrot-0.17.2.dist-info/RECORD +535 -0
  38. ai_parrot-0.17.2.dist-info/WHEEL +6 -0
  39. ai_parrot-0.17.2.dist-info/entry_points.txt +2 -0
  40. ai_parrot-0.17.2.dist-info/licenses/LICENSE +21 -0
  41. ai_parrot-0.17.2.dist-info/top_level.txt +6 -0
  42. crew-builder/.prettierrc +15 -0
  43. crew-builder/QUICKSTART.md +259 -0
  44. crew-builder/README.md +113 -0
  45. crew-builder/env.example +17 -0
  46. crew-builder/jsconfig.json +14 -0
  47. crew-builder/package-lock.json +4182 -0
  48. crew-builder/package.json +37 -0
  49. crew-builder/scripts/postinstall/apply-patches.mjs +260 -0
  50. crew-builder/src/app.css +62 -0
  51. crew-builder/src/app.d.ts +13 -0
  52. crew-builder/src/app.html +12 -0
  53. crew-builder/src/components/LoadingSpinner.svelte +64 -0
  54. crew-builder/src/components/ThemeSwitcher.svelte +149 -0
  55. crew-builder/src/components/index.js +9 -0
  56. crew-builder/src/lib/api/bots.ts +60 -0
  57. crew-builder/src/lib/api/chat.ts +80 -0
  58. crew-builder/src/lib/api/client.ts +56 -0
  59. crew-builder/src/lib/api/crew/crew.ts +136 -0
  60. crew-builder/src/lib/api/index.ts +5 -0
  61. crew-builder/src/lib/api/o365/auth.ts +65 -0
  62. crew-builder/src/lib/auth/auth.ts +54 -0
  63. crew-builder/src/lib/components/AgentNode.svelte +43 -0
  64. crew-builder/src/lib/components/BotCard.svelte +33 -0
  65. crew-builder/src/lib/components/ChatBubble.svelte +67 -0
  66. crew-builder/src/lib/components/ConfigPanel.svelte +278 -0
  67. crew-builder/src/lib/components/JsonTreeNode.svelte +76 -0
  68. crew-builder/src/lib/components/JsonViewer.svelte +24 -0
  69. crew-builder/src/lib/components/MarkdownEditor.svelte +48 -0
  70. crew-builder/src/lib/components/ThemeToggle.svelte +36 -0
  71. crew-builder/src/lib/components/Toast.svelte +67 -0
  72. crew-builder/src/lib/components/Toolbar.svelte +157 -0
  73. crew-builder/src/lib/components/index.ts +10 -0
  74. crew-builder/src/lib/config.ts +8 -0
  75. crew-builder/src/lib/stores/auth.svelte.ts +228 -0
  76. crew-builder/src/lib/stores/crewStore.ts +369 -0
  77. crew-builder/src/lib/stores/theme.svelte.js +145 -0
  78. crew-builder/src/lib/stores/toast.svelte.ts +69 -0
  79. crew-builder/src/lib/utils/conversation.ts +39 -0
  80. crew-builder/src/lib/utils/markdown.ts +122 -0
  81. crew-builder/src/lib/utils/talkHistory.ts +47 -0
  82. crew-builder/src/routes/+layout.svelte +20 -0
  83. crew-builder/src/routes/+page.svelte +539 -0
  84. crew-builder/src/routes/agents/+page.svelte +247 -0
  85. crew-builder/src/routes/agents/[agentId]/+page.svelte +288 -0
  86. crew-builder/src/routes/agents/[agentId]/+page.ts +7 -0
  87. crew-builder/src/routes/builder/+page.svelte +204 -0
  88. crew-builder/src/routes/crew/ask/+page.svelte +1052 -0
  89. crew-builder/src/routes/crew/ask/+page.ts +1 -0
  90. crew-builder/src/routes/integrations/o365/+page.svelte +304 -0
  91. crew-builder/src/routes/login/+page.svelte +197 -0
  92. crew-builder/src/routes/talk/[agentId]/+page.svelte +487 -0
  93. crew-builder/src/routes/talk/[agentId]/+page.ts +7 -0
  94. crew-builder/static/README.md +1 -0
  95. crew-builder/svelte.config.js +11 -0
  96. crew-builder/tailwind.config.ts +53 -0
  97. crew-builder/tsconfig.json +3 -0
  98. crew-builder/vite.config.ts +10 -0
  99. mcp_servers/calculator_server.py +309 -0
  100. parrot/__init__.py +27 -0
  101. parrot/__pycache__/__init__.cpython-310.pyc +0 -0
  102. parrot/__pycache__/version.cpython-310.pyc +0 -0
  103. parrot/_version.py +34 -0
  104. parrot/a2a/__init__.py +48 -0
  105. parrot/a2a/client.py +658 -0
  106. parrot/a2a/discovery.py +89 -0
  107. parrot/a2a/mixin.py +257 -0
  108. parrot/a2a/models.py +376 -0
  109. parrot/a2a/server.py +770 -0
  110. parrot/agents/__init__.py +29 -0
  111. parrot/bots/__init__.py +12 -0
  112. parrot/bots/a2a_agent.py +19 -0
  113. parrot/bots/abstract.py +3139 -0
  114. parrot/bots/agent.py +1129 -0
  115. parrot/bots/basic.py +9 -0
  116. parrot/bots/chatbot.py +669 -0
  117. parrot/bots/data.py +1618 -0
  118. parrot/bots/database/__init__.py +5 -0
  119. parrot/bots/database/abstract.py +3071 -0
  120. parrot/bots/database/cache.py +286 -0
  121. parrot/bots/database/models.py +468 -0
  122. parrot/bots/database/prompts.py +154 -0
  123. parrot/bots/database/retries.py +98 -0
  124. parrot/bots/database/router.py +269 -0
  125. parrot/bots/database/sql.py +41 -0
  126. parrot/bots/db/__init__.py +6 -0
  127. parrot/bots/db/abstract.py +556 -0
  128. parrot/bots/db/bigquery.py +602 -0
  129. parrot/bots/db/cache.py +85 -0
  130. parrot/bots/db/documentdb.py +668 -0
  131. parrot/bots/db/elastic.py +1014 -0
  132. parrot/bots/db/influx.py +898 -0
  133. parrot/bots/db/mock.py +96 -0
  134. parrot/bots/db/multi.py +783 -0
  135. parrot/bots/db/prompts.py +185 -0
  136. parrot/bots/db/sql.py +1255 -0
  137. parrot/bots/db/tools.py +212 -0
  138. parrot/bots/document.py +680 -0
  139. parrot/bots/hrbot.py +15 -0
  140. parrot/bots/kb.py +170 -0
  141. parrot/bots/mcp.py +36 -0
  142. parrot/bots/orchestration/README.md +463 -0
  143. parrot/bots/orchestration/__init__.py +1 -0
  144. parrot/bots/orchestration/agent.py +155 -0
  145. parrot/bots/orchestration/crew.py +3330 -0
  146. parrot/bots/orchestration/fsm.py +1179 -0
  147. parrot/bots/orchestration/hr.py +434 -0
  148. parrot/bots/orchestration/storage/__init__.py +4 -0
  149. parrot/bots/orchestration/storage/memory.py +100 -0
  150. parrot/bots/orchestration/storage/mixin.py +119 -0
  151. parrot/bots/orchestration/verify.py +202 -0
  152. parrot/bots/product.py +204 -0
  153. parrot/bots/prompts/__init__.py +96 -0
  154. parrot/bots/prompts/agents.py +155 -0
  155. parrot/bots/prompts/data.py +216 -0
  156. parrot/bots/prompts/output_generation.py +8 -0
  157. parrot/bots/scraper/__init__.py +3 -0
  158. parrot/bots/scraper/models.py +122 -0
  159. parrot/bots/scraper/scraper.py +1173 -0
  160. parrot/bots/scraper/templates.py +115 -0
  161. parrot/bots/stores/__init__.py +5 -0
  162. parrot/bots/stores/local.py +172 -0
  163. parrot/bots/webdev.py +81 -0
  164. parrot/cli.py +17 -0
  165. parrot/clients/__init__.py +16 -0
  166. parrot/clients/base.py +1491 -0
  167. parrot/clients/claude.py +1191 -0
  168. parrot/clients/factory.py +129 -0
  169. parrot/clients/google.py +4567 -0
  170. parrot/clients/gpt.py +1975 -0
  171. parrot/clients/grok.py +432 -0
  172. parrot/clients/groq.py +986 -0
  173. parrot/clients/hf.py +582 -0
  174. parrot/clients/models.py +18 -0
  175. parrot/conf.py +395 -0
  176. parrot/embeddings/__init__.py +9 -0
  177. parrot/embeddings/base.py +157 -0
  178. parrot/embeddings/google.py +98 -0
  179. parrot/embeddings/huggingface.py +74 -0
  180. parrot/embeddings/openai.py +84 -0
  181. parrot/embeddings/processor.py +88 -0
  182. parrot/exceptions.c +13868 -0
  183. parrot/exceptions.cpython-310-x86_64-linux-gnu.so +0 -0
  184. parrot/exceptions.pxd +22 -0
  185. parrot/exceptions.pxi +15 -0
  186. parrot/exceptions.pyx +44 -0
  187. parrot/generators/__init__.py +29 -0
  188. parrot/generators/base.py +200 -0
  189. parrot/generators/html.py +293 -0
  190. parrot/generators/react.py +205 -0
  191. parrot/generators/streamlit.py +203 -0
  192. parrot/generators/template.py +105 -0
  193. parrot/handlers/__init__.py +4 -0
  194. parrot/handlers/agent.py +861 -0
  195. parrot/handlers/agents/__init__.py +1 -0
  196. parrot/handlers/agents/abstract.py +900 -0
  197. parrot/handlers/bots.py +338 -0
  198. parrot/handlers/chat.py +915 -0
  199. parrot/handlers/creation.sql +192 -0
  200. parrot/handlers/crew/ARCHITECTURE.md +362 -0
  201. parrot/handlers/crew/README_BOTMANAGER_PERSISTENCE.md +303 -0
  202. parrot/handlers/crew/README_REDIS_PERSISTENCE.md +366 -0
  203. parrot/handlers/crew/__init__.py +0 -0
  204. parrot/handlers/crew/handler.py +801 -0
  205. parrot/handlers/crew/models.py +229 -0
  206. parrot/handlers/crew/redis_persistence.py +523 -0
  207. parrot/handlers/jobs/__init__.py +10 -0
  208. parrot/handlers/jobs/job.py +384 -0
  209. parrot/handlers/jobs/mixin.py +627 -0
  210. parrot/handlers/jobs/models.py +115 -0
  211. parrot/handlers/jobs/worker.py +31 -0
  212. parrot/handlers/models.py +596 -0
  213. parrot/handlers/o365_auth.py +105 -0
  214. parrot/handlers/stream.py +337 -0
  215. parrot/interfaces/__init__.py +6 -0
  216. parrot/interfaces/aws.py +143 -0
  217. parrot/interfaces/credentials.py +113 -0
  218. parrot/interfaces/database.py +27 -0
  219. parrot/interfaces/google.py +1123 -0
  220. parrot/interfaces/hierarchy.py +1227 -0
  221. parrot/interfaces/http.py +651 -0
  222. parrot/interfaces/images/__init__.py +0 -0
  223. parrot/interfaces/images/plugins/__init__.py +24 -0
  224. parrot/interfaces/images/plugins/abstract.py +58 -0
  225. parrot/interfaces/images/plugins/analisys.py +148 -0
  226. parrot/interfaces/images/plugins/classify.py +150 -0
  227. parrot/interfaces/images/plugins/classifybase.py +182 -0
  228. parrot/interfaces/images/plugins/detect.py +150 -0
  229. parrot/interfaces/images/plugins/exif.py +1103 -0
  230. parrot/interfaces/images/plugins/hash.py +52 -0
  231. parrot/interfaces/images/plugins/vision.py +104 -0
  232. parrot/interfaces/images/plugins/yolo.py +66 -0
  233. parrot/interfaces/images/plugins/zerodetect.py +197 -0
  234. parrot/interfaces/o365.py +978 -0
  235. parrot/interfaces/onedrive.py +822 -0
  236. parrot/interfaces/sharepoint.py +1435 -0
  237. parrot/interfaces/soap.py +257 -0
  238. parrot/loaders/__init__.py +8 -0
  239. parrot/loaders/abstract.py +1131 -0
  240. parrot/loaders/audio.py +199 -0
  241. parrot/loaders/basepdf.py +53 -0
  242. parrot/loaders/basevideo.py +1568 -0
  243. parrot/loaders/csv.py +409 -0
  244. parrot/loaders/docx.py +116 -0
  245. parrot/loaders/epubloader.py +316 -0
  246. parrot/loaders/excel.py +199 -0
  247. parrot/loaders/factory.py +55 -0
  248. parrot/loaders/files/__init__.py +0 -0
  249. parrot/loaders/files/abstract.py +39 -0
  250. parrot/loaders/files/html.py +26 -0
  251. parrot/loaders/files/text.py +63 -0
  252. parrot/loaders/html.py +152 -0
  253. parrot/loaders/markdown.py +442 -0
  254. parrot/loaders/pdf.py +373 -0
  255. parrot/loaders/pdfmark.py +320 -0
  256. parrot/loaders/pdftables.py +506 -0
  257. parrot/loaders/ppt.py +476 -0
  258. parrot/loaders/qa.py +63 -0
  259. parrot/loaders/splitters/__init__.py +10 -0
  260. parrot/loaders/splitters/base.py +138 -0
  261. parrot/loaders/splitters/md.py +228 -0
  262. parrot/loaders/splitters/token.py +143 -0
  263. parrot/loaders/txt.py +26 -0
  264. parrot/loaders/video.py +89 -0
  265. parrot/loaders/videolocal.py +218 -0
  266. parrot/loaders/videounderstanding.py +377 -0
  267. parrot/loaders/vimeo.py +167 -0
  268. parrot/loaders/web.py +599 -0
  269. parrot/loaders/youtube.py +504 -0
  270. parrot/manager/__init__.py +5 -0
  271. parrot/manager/manager.py +1030 -0
  272. parrot/mcp/__init__.py +28 -0
  273. parrot/mcp/adapter.py +105 -0
  274. parrot/mcp/cli.py +174 -0
  275. parrot/mcp/client.py +119 -0
  276. parrot/mcp/config.py +75 -0
  277. parrot/mcp/integration.py +842 -0
  278. parrot/mcp/oauth.py +933 -0
  279. parrot/mcp/server.py +225 -0
  280. parrot/mcp/transports/__init__.py +3 -0
  281. parrot/mcp/transports/base.py +279 -0
  282. parrot/mcp/transports/grpc_session.py +163 -0
  283. parrot/mcp/transports/http.py +312 -0
  284. parrot/mcp/transports/mcp.proto +108 -0
  285. parrot/mcp/transports/quic.py +1082 -0
  286. parrot/mcp/transports/sse.py +330 -0
  287. parrot/mcp/transports/stdio.py +309 -0
  288. parrot/mcp/transports/unix.py +395 -0
  289. parrot/mcp/transports/websocket.py +547 -0
  290. parrot/memory/__init__.py +16 -0
  291. parrot/memory/abstract.py +209 -0
  292. parrot/memory/agent.py +32 -0
  293. parrot/memory/cache.py +175 -0
  294. parrot/memory/core.py +555 -0
  295. parrot/memory/file.py +153 -0
  296. parrot/memory/mem.py +131 -0
  297. parrot/memory/redis.py +613 -0
  298. parrot/models/__init__.py +46 -0
  299. parrot/models/basic.py +118 -0
  300. parrot/models/compliance.py +208 -0
  301. parrot/models/crew.py +395 -0
  302. parrot/models/detections.py +654 -0
  303. parrot/models/generation.py +85 -0
  304. parrot/models/google.py +223 -0
  305. parrot/models/groq.py +23 -0
  306. parrot/models/openai.py +30 -0
  307. parrot/models/outputs.py +285 -0
  308. parrot/models/responses.py +938 -0
  309. parrot/notifications/__init__.py +743 -0
  310. parrot/openapi/__init__.py +3 -0
  311. parrot/openapi/components.yaml +641 -0
  312. parrot/openapi/config.py +322 -0
  313. parrot/outputs/__init__.py +32 -0
  314. parrot/outputs/formats/__init__.py +108 -0
  315. parrot/outputs/formats/altair.py +359 -0
  316. parrot/outputs/formats/application.py +122 -0
  317. parrot/outputs/formats/base.py +351 -0
  318. parrot/outputs/formats/bokeh.py +356 -0
  319. parrot/outputs/formats/card.py +424 -0
  320. parrot/outputs/formats/chart.py +436 -0
  321. parrot/outputs/formats/d3.py +255 -0
  322. parrot/outputs/formats/echarts.py +310 -0
  323. parrot/outputs/formats/generators/__init__.py +0 -0
  324. parrot/outputs/formats/generators/abstract.py +61 -0
  325. parrot/outputs/formats/generators/panel.py +145 -0
  326. parrot/outputs/formats/generators/streamlit.py +86 -0
  327. parrot/outputs/formats/generators/terminal.py +63 -0
  328. parrot/outputs/formats/holoviews.py +310 -0
  329. parrot/outputs/formats/html.py +147 -0
  330. parrot/outputs/formats/jinja2.py +46 -0
  331. parrot/outputs/formats/json.py +87 -0
  332. parrot/outputs/formats/map.py +933 -0
  333. parrot/outputs/formats/markdown.py +172 -0
  334. parrot/outputs/formats/matplotlib.py +237 -0
  335. parrot/outputs/formats/mixins/__init__.py +0 -0
  336. parrot/outputs/formats/mixins/emaps.py +855 -0
  337. parrot/outputs/formats/plotly.py +341 -0
  338. parrot/outputs/formats/seaborn.py +310 -0
  339. parrot/outputs/formats/table.py +397 -0
  340. parrot/outputs/formats/template_report.py +138 -0
  341. parrot/outputs/formats/yaml.py +125 -0
  342. parrot/outputs/formatter.py +152 -0
  343. parrot/outputs/templates/__init__.py +95 -0
  344. parrot/pipelines/__init__.py +0 -0
  345. parrot/pipelines/abstract.py +210 -0
  346. parrot/pipelines/detector.py +124 -0
  347. parrot/pipelines/models.py +90 -0
  348. parrot/pipelines/planogram.py +3002 -0
  349. parrot/pipelines/table.sql +97 -0
  350. parrot/plugins/__init__.py +106 -0
  351. parrot/plugins/importer.py +80 -0
  352. parrot/py.typed +0 -0
  353. parrot/registry/__init__.py +18 -0
  354. parrot/registry/registry.py +594 -0
  355. parrot/scheduler/__init__.py +1189 -0
  356. parrot/scheduler/models.py +60 -0
  357. parrot/security/__init__.py +16 -0
  358. parrot/security/prompt_injection.py +268 -0
  359. parrot/security/security_events.sql +25 -0
  360. parrot/services/__init__.py +1 -0
  361. parrot/services/mcp/__init__.py +8 -0
  362. parrot/services/mcp/config.py +13 -0
  363. parrot/services/mcp/server.py +295 -0
  364. parrot/services/o365_remote_auth.py +235 -0
  365. parrot/stores/__init__.py +7 -0
  366. parrot/stores/abstract.py +352 -0
  367. parrot/stores/arango.py +1090 -0
  368. parrot/stores/bigquery.py +1377 -0
  369. parrot/stores/cache.py +106 -0
  370. parrot/stores/empty.py +10 -0
  371. parrot/stores/faiss_store.py +1157 -0
  372. parrot/stores/kb/__init__.py +9 -0
  373. parrot/stores/kb/abstract.py +68 -0
  374. parrot/stores/kb/cache.py +165 -0
  375. parrot/stores/kb/doc.py +325 -0
  376. parrot/stores/kb/hierarchy.py +346 -0
  377. parrot/stores/kb/local.py +457 -0
  378. parrot/stores/kb/prompt.py +28 -0
  379. parrot/stores/kb/redis.py +659 -0
  380. parrot/stores/kb/store.py +115 -0
  381. parrot/stores/kb/user.py +374 -0
  382. parrot/stores/models.py +59 -0
  383. parrot/stores/pgvector.py +3 -0
  384. parrot/stores/postgres.py +2853 -0
  385. parrot/stores/utils/__init__.py +0 -0
  386. parrot/stores/utils/chunking.py +197 -0
  387. parrot/telemetry/__init__.py +3 -0
  388. parrot/telemetry/mixin.py +111 -0
  389. parrot/template/__init__.py +3 -0
  390. parrot/template/engine.py +259 -0
  391. parrot/tools/__init__.py +23 -0
  392. parrot/tools/abstract.py +644 -0
  393. parrot/tools/agent.py +363 -0
  394. parrot/tools/arangodbsearch.py +537 -0
  395. parrot/tools/arxiv_tool.py +188 -0
  396. parrot/tools/calculator/__init__.py +3 -0
  397. parrot/tools/calculator/operations/__init__.py +38 -0
  398. parrot/tools/calculator/operations/calculus.py +80 -0
  399. parrot/tools/calculator/operations/statistics.py +76 -0
  400. parrot/tools/calculator/tool.py +150 -0
  401. parrot/tools/cloudwatch.py +988 -0
  402. parrot/tools/codeinterpreter/__init__.py +127 -0
  403. parrot/tools/codeinterpreter/executor.py +371 -0
  404. parrot/tools/codeinterpreter/internals.py +473 -0
  405. parrot/tools/codeinterpreter/models.py +643 -0
  406. parrot/tools/codeinterpreter/prompts.py +224 -0
  407. parrot/tools/codeinterpreter/tool.py +664 -0
  408. parrot/tools/company_info/__init__.py +6 -0
  409. parrot/tools/company_info/tool.py +1138 -0
  410. parrot/tools/correlationanalysis.py +437 -0
  411. parrot/tools/database/abstract.py +286 -0
  412. parrot/tools/database/bq.py +115 -0
  413. parrot/tools/database/cache.py +284 -0
  414. parrot/tools/database/models.py +95 -0
  415. parrot/tools/database/pg.py +343 -0
  416. parrot/tools/databasequery.py +1159 -0
  417. parrot/tools/db.py +1800 -0
  418. parrot/tools/ddgo.py +370 -0
  419. parrot/tools/decorators.py +271 -0
  420. parrot/tools/dftohtml.py +282 -0
  421. parrot/tools/document.py +549 -0
  422. parrot/tools/ecs.py +819 -0
  423. parrot/tools/edareport.py +368 -0
  424. parrot/tools/elasticsearch.py +1049 -0
  425. parrot/tools/employees.py +462 -0
  426. parrot/tools/epson/__init__.py +96 -0
  427. parrot/tools/excel.py +683 -0
  428. parrot/tools/file/__init__.py +13 -0
  429. parrot/tools/file/abstract.py +76 -0
  430. parrot/tools/file/gcs.py +378 -0
  431. parrot/tools/file/local.py +284 -0
  432. parrot/tools/file/s3.py +511 -0
  433. parrot/tools/file/tmp.py +309 -0
  434. parrot/tools/file/tool.py +501 -0
  435. parrot/tools/file_reader.py +129 -0
  436. parrot/tools/flowtask/__init__.py +19 -0
  437. parrot/tools/flowtask/tool.py +761 -0
  438. parrot/tools/gittoolkit.py +508 -0
  439. parrot/tools/google/__init__.py +18 -0
  440. parrot/tools/google/base.py +169 -0
  441. parrot/tools/google/tools.py +1251 -0
  442. parrot/tools/googlelocation.py +5 -0
  443. parrot/tools/googleroutes.py +5 -0
  444. parrot/tools/googlesearch.py +5 -0
  445. parrot/tools/googlesitesearch.py +5 -0
  446. parrot/tools/googlevoice.py +2 -0
  447. parrot/tools/gvoice.py +695 -0
  448. parrot/tools/ibisworld/README.md +225 -0
  449. parrot/tools/ibisworld/__init__.py +11 -0
  450. parrot/tools/ibisworld/tool.py +366 -0
  451. parrot/tools/jiratoolkit.py +1718 -0
  452. parrot/tools/manager.py +1098 -0
  453. parrot/tools/math.py +152 -0
  454. parrot/tools/metadata.py +476 -0
  455. parrot/tools/msteams.py +1621 -0
  456. parrot/tools/msword.py +635 -0
  457. parrot/tools/multidb.py +580 -0
  458. parrot/tools/multistoresearch.py +369 -0
  459. parrot/tools/networkninja.py +167 -0
  460. parrot/tools/nextstop/__init__.py +4 -0
  461. parrot/tools/nextstop/base.py +286 -0
  462. parrot/tools/nextstop/employee.py +733 -0
  463. parrot/tools/nextstop/store.py +462 -0
  464. parrot/tools/notification.py +435 -0
  465. parrot/tools/o365/__init__.py +42 -0
  466. parrot/tools/o365/base.py +295 -0
  467. parrot/tools/o365/bundle.py +522 -0
  468. parrot/tools/o365/events.py +554 -0
  469. parrot/tools/o365/mail.py +992 -0
  470. parrot/tools/o365/onedrive.py +497 -0
  471. parrot/tools/o365/sharepoint.py +641 -0
  472. parrot/tools/openapi_toolkit.py +904 -0
  473. parrot/tools/openweather.py +527 -0
  474. parrot/tools/pdfprint.py +1001 -0
  475. parrot/tools/powerbi.py +518 -0
  476. parrot/tools/powerpoint.py +1113 -0
  477. parrot/tools/pricestool.py +146 -0
  478. parrot/tools/products/__init__.py +246 -0
  479. parrot/tools/prophet_tool.py +171 -0
  480. parrot/tools/pythonpandas.py +630 -0
  481. parrot/tools/pythonrepl.py +910 -0
  482. parrot/tools/qsource.py +436 -0
  483. parrot/tools/querytoolkit.py +395 -0
  484. parrot/tools/quickeda.py +827 -0
  485. parrot/tools/resttool.py +553 -0
  486. parrot/tools/retail/__init__.py +0 -0
  487. parrot/tools/retail/bby.py +528 -0
  488. parrot/tools/sandboxtool.py +703 -0
  489. parrot/tools/sassie/__init__.py +352 -0
  490. parrot/tools/scraping/__init__.py +7 -0
  491. parrot/tools/scraping/docs/select.md +466 -0
  492. parrot/tools/scraping/documentation.md +1278 -0
  493. parrot/tools/scraping/driver.py +436 -0
  494. parrot/tools/scraping/models.py +576 -0
  495. parrot/tools/scraping/options.py +85 -0
  496. parrot/tools/scraping/orchestrator.py +517 -0
  497. parrot/tools/scraping/readme.md +740 -0
  498. parrot/tools/scraping/tool.py +3115 -0
  499. parrot/tools/seasonaldetection.py +642 -0
  500. parrot/tools/shell_tool/__init__.py +5 -0
  501. parrot/tools/shell_tool/actions.py +408 -0
  502. parrot/tools/shell_tool/engine.py +155 -0
  503. parrot/tools/shell_tool/models.py +322 -0
  504. parrot/tools/shell_tool/tool.py +442 -0
  505. parrot/tools/site_search.py +214 -0
  506. parrot/tools/textfile.py +418 -0
  507. parrot/tools/think.py +378 -0
  508. parrot/tools/toolkit.py +298 -0
  509. parrot/tools/webapp_tool.py +187 -0
  510. parrot/tools/whatif.py +1279 -0
  511. parrot/tools/workday/MULTI_WSDL_EXAMPLE.md +249 -0
  512. parrot/tools/workday/__init__.py +6 -0
  513. parrot/tools/workday/models.py +1389 -0
  514. parrot/tools/workday/tool.py +1293 -0
  515. parrot/tools/yfinance_tool.py +306 -0
  516. parrot/tools/zipcode.py +217 -0
  517. parrot/utils/__init__.py +2 -0
  518. parrot/utils/helpers.py +73 -0
  519. parrot/utils/parsers/__init__.py +5 -0
  520. parrot/utils/parsers/toml.c +12078 -0
  521. parrot/utils/parsers/toml.cpython-310-x86_64-linux-gnu.so +0 -0
  522. parrot/utils/parsers/toml.pyx +21 -0
  523. parrot/utils/toml.py +11 -0
  524. parrot/utils/types.cpp +20936 -0
  525. parrot/utils/types.cpython-310-x86_64-linux-gnu.so +0 -0
  526. parrot/utils/types.pyx +213 -0
  527. parrot/utils/uv.py +11 -0
  528. parrot/version.py +10 -0
  529. parrot/yaml-rs/Cargo.lock +350 -0
  530. parrot/yaml-rs/Cargo.toml +19 -0
  531. parrot/yaml-rs/pyproject.toml +19 -0
  532. parrot/yaml-rs/python/yaml_rs/__init__.py +81 -0
  533. parrot/yaml-rs/src/lib.rs +222 -0
  534. requirements/docker-compose.yml +24 -0
  535. requirements/requirements-dev.txt +21 -0
@@ -0,0 +1,511 @@
1
+ from typing import BinaryIO, Optional, List, Union
2
+ import asyncio
3
+ import contextlib
4
+ from pathlib import Path
5
+ import mimetypes
6
+ from datetime import datetime
7
+ from io import BytesIO, StringIO
8
+ import fnmatch
9
+ import aioboto3
10
+ from botocore.exceptions import ClientError
11
+ from .abstract import FileManagerInterface, FileMetadata
12
+ from ...conf import AWS_CREDENTIALS
13
+
14
+
15
+ class S3FileManager(FileManagerInterface):
16
+ """File manager for AWS S3 bucket operations"""
17
+
18
+ # Multipart upload configuration
19
+ MULTIPART_THRESHOLD = 100 * 1024 * 1024 # 100MB
20
+ MULTIPART_CHUNKSIZE = 10 * 1024 * 1024 # 10MB per part
21
+ MAX_CONCURRENCY = 10 # Concurrent part uploads
22
+
23
+ def __init__(
24
+ self,
25
+ bucket_name: Optional[str] = None,
26
+ aws_id: str = 'default',
27
+ region_name: Optional[str] = None,
28
+ prefix: str = "",
29
+ multipart_threshold: Optional[int] = None,
30
+ multipart_chunksize: Optional[int] = None,
31
+ max_concurrency: Optional[int] = None,
32
+ **kwargs
33
+ ):
34
+ """
35
+ Initialize S3 file manager.
36
+
37
+ Args:
38
+ bucket_name: S3 bucket name (if None, read from credentials)
39
+ aws_id: Identifier for credentials in AWS_CREDENTIALS dict
40
+ region_name: AWS region (if None, read from credentials)
41
+ prefix: Default prefix/folder for all operations
42
+ multipart_threshold: File size threshold for multipart upload (bytes)
43
+ multipart_chunksize: Size of each part in multipart upload (bytes)
44
+ max_concurrency: Max concurrent part uploads
45
+ **kwargs: Additional arguments, including 'credentials' override
46
+ """
47
+ # Get credentials from config or kwargs
48
+ credentials = kwargs.get('credentials', AWS_CREDENTIALS.get(aws_id, 'default'))
49
+
50
+ if isinstance(credentials, str) and credentials == 'default':
51
+ credentials = AWS_CREDENTIALS.get('default', {})
52
+
53
+ # Extract bucket_name from credentials if not provided
54
+ self.bucket_name = bucket_name or credentials.get('bucket_name')
55
+ if not self.bucket_name:
56
+ raise ValueError("bucket_name must be provided or present in credentials")
57
+
58
+ # Build AWS config
59
+ self.aws_config = {
60
+ 'aws_access_key_id': credentials.get('aws_access_key_id'),
61
+ 'aws_secret_access_key': credentials.get('aws_secret_access_key'),
62
+ 'region_name': region_name or credentials.get('region_name', 'us-east-1'),
63
+ }
64
+
65
+ # Add optional session token if present
66
+ if 'aws_session_token' in credentials:
67
+ self.aws_config['aws_session_token'] = credentials['aws_session_token']
68
+
69
+ # Remove None values
70
+ self.aws_config = {k: v for k, v in self.aws_config.items() if v is not None}
71
+
72
+ self.prefix = prefix.rstrip('/') + '/' if prefix else ''
73
+ self.session = aioboto3.Session(**self.aws_config)
74
+
75
+ # Multipart upload configuration
76
+ self.multipart_threshold = multipart_threshold or self.MULTIPART_THRESHOLD
77
+ self.multipart_chunksize = multipart_chunksize or self.MULTIPART_CHUNKSIZE
78
+ self.max_concurrency = max_concurrency or self.MAX_CONCURRENCY
79
+
80
+ def _resolve_path(self, path: str) -> str:
81
+ """Resolve path with prefix"""
82
+ path = path.lstrip('/')
83
+
84
+ if self.prefix and not path.startswith(self.prefix):
85
+ path = self.prefix + path
86
+
87
+ return path
88
+
89
+ def _strip_prefix(self, path: str) -> str:
90
+ """Remove prefix from path for display"""
91
+ if self.prefix and path.startswith(self.prefix):
92
+ return path[len(self.prefix):]
93
+ return path
94
+
95
+ async def _get_object_metadata(self, key: str) -> FileMetadata:
96
+ """Get metadata for an S3 object"""
97
+ async with self.session.client('s3') as s3:
98
+ try:
99
+ response = await s3.head_object(Bucket=self.bucket_name, Key=key)
100
+
101
+ url = await s3.generate_presigned_url(
102
+ 'get_object',
103
+ Params={'Bucket': self.bucket_name, 'Key': key},
104
+ ExpiresIn=3600
105
+ )
106
+
107
+ return FileMetadata(
108
+ name=Path(key).name,
109
+ path=self._strip_prefix(key),
110
+ size=response['ContentLength'],
111
+ content_type=response.get('ContentType'),
112
+ modified_at=response['LastModified'],
113
+ url=url
114
+ )
115
+ except ClientError as e:
116
+ if e.response['Error']['Code'] == '404':
117
+ raise FileNotFoundError(
118
+ f"File not found: {key}"
119
+ ) from e
120
+ raise
121
+
122
+ async def _upload_part(
123
+ self,
124
+ s3_client,
125
+ upload_id: str,
126
+ key: str,
127
+ part_number: int,
128
+ data: bytes
129
+ ) -> dict:
130
+ """Upload a single part in multipart upload"""
131
+ response = await s3_client.upload_part(
132
+ Bucket=self.bucket_name,
133
+ Key=key,
134
+ UploadId=upload_id,
135
+ PartNumber=part_number,
136
+ Body=data
137
+ )
138
+
139
+ return {
140
+ 'PartNumber': part_number,
141
+ 'ETag': response['ETag']
142
+ }
143
+
144
+ async def _multipart_upload(
145
+ self,
146
+ source: Path | BinaryIO,
147
+ key: str,
148
+ content_type: Optional[str]
149
+ ) -> FileMetadata:
150
+ """Perform multipart upload for large files"""
151
+ async with self.session.client('s3') as s3:
152
+ # Initiate multipart upload
153
+ extra_args = {}
154
+ if content_type:
155
+ extra_args['ContentType'] = content_type
156
+
157
+ response = await s3.create_multipart_upload(
158
+ Bucket=self.bucket_name,
159
+ Key=key,
160
+ **extra_args
161
+ )
162
+ upload_id = response['UploadId']
163
+
164
+ parts = []
165
+ part_number = 1
166
+
167
+ try:
168
+ # Open file for reading
169
+ if isinstance(source, Path):
170
+ file_obj = open(source, 'rb')
171
+ should_close = True
172
+ else:
173
+ source.seek(0)
174
+ file_obj = source
175
+ should_close = False
176
+
177
+ # Create upload tasks with concurrency limit
178
+ semaphore = asyncio.Semaphore(self.max_concurrency)
179
+ upload_tasks = []
180
+
181
+ async def upload_with_semaphore(part_num: int, chunk: bytes):
182
+ async with semaphore:
183
+ return await self._upload_part(
184
+ s3, upload_id, key, part_num, chunk
185
+ )
186
+
187
+ # Read and upload chunks
188
+ while True:
189
+ chunk = file_obj.read(self.multipart_chunksize)
190
+ if not chunk:
191
+ break
192
+
193
+ task = asyncio.create_task(
194
+ upload_with_semaphore(part_number, chunk)
195
+ )
196
+ upload_tasks.append(task)
197
+ part_number += 1
198
+
199
+ # Wait for all uploads to complete
200
+ parts = await asyncio.gather(*upload_tasks)
201
+
202
+ # Close file if we opened it
203
+ if should_close:
204
+ file_obj.close()
205
+
206
+ # Complete multipart upload
207
+ await s3.complete_multipart_upload(
208
+ Bucket=self.bucket_name,
209
+ Key=key,
210
+ UploadId=upload_id,
211
+ MultipartUpload={'Parts': parts}
212
+ )
213
+
214
+ return await self._get_object_metadata(key)
215
+
216
+ except Exception as e:
217
+ # Abort multipart upload on error
218
+ with contextlib.suppress(Exception):
219
+ await s3.abort_multipart_upload(
220
+ Bucket=self.bucket_name,
221
+ Key=key,
222
+ UploadId=upload_id
223
+ )
224
+ raise IOError(f"Multipart upload failed: {e}")
225
+
226
+ async def upload_file(
227
+ self,
228
+ source: BinaryIO | Path,
229
+ destination: str
230
+ ) -> FileMetadata:
231
+ """
232
+ Upload file to S3 with automatic multipart upload for large files.
233
+
234
+ Files larger than multipart_threshold will use multipart upload
235
+ with concurrent part uploads for better performance.
236
+ """
237
+ key = self._resolve_path(destination)
238
+
239
+ # Guess content type
240
+ content_type, _ = mimetypes.guess_type(destination)
241
+ extra_args = {}
242
+ if content_type:
243
+ extra_args['ContentType'] = content_type
244
+
245
+ # Determine file size
246
+ if isinstance(source, Path):
247
+ file_size = source.stat().st_size
248
+ else:
249
+ # For file objects, try to get size
250
+ current_pos = source.tell()
251
+ source.seek(0, 2) # Seek to end
252
+ file_size = source.tell()
253
+ source.seek(current_pos) # Reset position
254
+
255
+ # Use multipart upload for large files
256
+ if file_size >= self.multipart_threshold:
257
+ return await self._multipart_upload(source, key, content_type)
258
+
259
+ # Use standard upload for small files
260
+ async with self.session.client('s3') as s3:
261
+ try:
262
+ if isinstance(source, Path):
263
+ await s3.upload_file(
264
+ str(source),
265
+ self.bucket_name,
266
+ key,
267
+ ExtraArgs=extra_args
268
+ )
269
+ else:
270
+ source.seek(0)
271
+ await s3.upload_fileobj(
272
+ source,
273
+ self.bucket_name,
274
+ key,
275
+ ExtraArgs=extra_args
276
+ )
277
+
278
+ return await self._get_object_metadata(key)
279
+
280
+ except ClientError as e:
281
+ raise IOError(
282
+ f"Failed to upload file: {e}"
283
+ ) from e
284
+
285
+ async def list_files(
286
+ self,
287
+ path: str = "",
288
+ pattern: str = "*"
289
+ ) -> List[FileMetadata]:
290
+ """List files matching pattern in S3 bucket/prefix"""
291
+ prefix = self._resolve_path(path)
292
+
293
+ async with self.session.client('s3') as s3:
294
+ try:
295
+ paginator = s3.get_paginator('list_objects_v2')
296
+ files = []
297
+
298
+ async for page in paginator.paginate(
299
+ Bucket=self.bucket_name,
300
+ Prefix=prefix
301
+ ):
302
+ if 'Contents' not in page:
303
+ continue
304
+
305
+ for obj in page['Contents']:
306
+ key = obj['Key']
307
+ name = Path(key).name
308
+
309
+ if key.endswith('/'):
310
+ continue
311
+
312
+ if fnmatch.fnmatch(name, pattern):
313
+ url = await s3.generate_presigned_url(
314
+ 'get_object',
315
+ Params={'Bucket': self.bucket_name, 'Key': key},
316
+ ExpiresIn=3600
317
+ )
318
+
319
+ files.append(FileMetadata(
320
+ name=name,
321
+ path=self._strip_prefix(key),
322
+ size=obj['Size'],
323
+ content_type=None,
324
+ modified_at=obj['LastModified'],
325
+ url=url
326
+ ))
327
+
328
+ return sorted(files, key=lambda x: x.name)
329
+
330
+ except ClientError as e:
331
+ if e.response['Error']['Code'] == 'NoSuchBucket':
332
+ raise ValueError(
333
+ f"Bucket not found: {self.bucket_name}"
334
+ ) from e
335
+ raise
336
+
337
+ async def get_file_url(self, path: str, expiry: int = 3600) -> str:
338
+ """Get presigned URL for S3 object"""
339
+ key = self._resolve_path(path)
340
+
341
+ async with self.session.client('s3') as s3:
342
+ try:
343
+ return await s3.generate_presigned_url(
344
+ 'get_object',
345
+ Params={'Bucket': self.bucket_name, 'Key': key},
346
+ ExpiresIn=expiry
347
+ )
348
+ except ClientError as e:
349
+ if e.response['Error']['Code'] == '404':
350
+ raise FileNotFoundError(
351
+ f"File not found: {path}"
352
+ ) from e
353
+ raise
354
+
355
+ async def download_file(
356
+ self,
357
+ source: str,
358
+ destination: Path | BinaryIO
359
+ ) -> Path:
360
+ """Download file from S3"""
361
+ key = self._resolve_path(source)
362
+
363
+ async with self.session.client('s3') as s3:
364
+ try:
365
+ if isinstance(destination, Path):
366
+ destination.parent.mkdir(parents=True, exist_ok=True)
367
+ await s3.download_file(
368
+ self.bucket_name,
369
+ key,
370
+ str(destination)
371
+ )
372
+ return destination
373
+ else:
374
+ response = await s3.get_object(
375
+ Bucket=self.bucket_name,
376
+ Key=key
377
+ )
378
+ async with response['Body'] as stream:
379
+ data = await stream.read()
380
+ destination.write(data)
381
+ return Path(key)
382
+
383
+ except ClientError as e:
384
+ if e.response['Error']['Code'] == 'NoSuchKey':
385
+ raise FileNotFoundError(
386
+ f"File not found: {source}"
387
+ ) from e
388
+ raise
389
+
390
+ async def copy_file(self, source: str, destination: str) -> FileMetadata:
391
+ """Copy file within S3 bucket"""
392
+ source_key = self._resolve_path(source)
393
+ dest_key = self._resolve_path(destination)
394
+
395
+ copy_source = {
396
+ 'Bucket': self.bucket_name,
397
+ 'Key': source_key
398
+ }
399
+
400
+ async with self.session.client('s3') as s3:
401
+ try:
402
+ await s3.copy_object(
403
+ CopySource=copy_source,
404
+ Bucket=self.bucket_name,
405
+ Key=dest_key
406
+ )
407
+
408
+ return await self._get_object_metadata(dest_key)
409
+
410
+ except ClientError as e:
411
+ if e.response['Error']['Code'] == 'NoSuchKey':
412
+ raise FileNotFoundError(
413
+ f"Source file not found: {source}"
414
+ ) from e
415
+ raise
416
+
417
+ async def delete_file(self, path: str) -> bool:
418
+ """Delete file from S3"""
419
+ key = self._resolve_path(path)
420
+
421
+ async with self.session.client('s3') as s3:
422
+ try:
423
+ await s3.delete_object(
424
+ Bucket=self.bucket_name,
425
+ Key=key
426
+ )
427
+ return True
428
+ except ClientError:
429
+ return False
430
+
431
+ async def exists(self, path: str) -> bool:
432
+ """Check if file exists in S3"""
433
+ key = self._resolve_path(path)
434
+
435
+ async with self.session.client('s3') as s3:
436
+ try:
437
+ await s3.head_object(Bucket=self.bucket_name, Key=key)
438
+ return True
439
+ except ClientError:
440
+ return False
441
+
442
+ async def get_file_metadata(self, path: str) -> FileMetadata:
443
+ """Get metadata of S3 object"""
444
+ key = self._resolve_path(path)
445
+ return await self._get_object_metadata(key)
446
+
447
+ async def create_file(self, path: str, content: bytes) -> bool:
448
+ """Create file in S3 with content"""
449
+ key = self._resolve_path(path)
450
+
451
+ content_type, _ = mimetypes.guess_type(path)
452
+ extra_args = {}
453
+ if content_type:
454
+ extra_args['ContentType'] = content_type
455
+
456
+ async with self.session.client('s3') as s3:
457
+ try:
458
+ await s3.put_object(
459
+ Bucket=self.bucket_name,
460
+ Key=key,
461
+ Body=content,
462
+ **extra_args
463
+ )
464
+ return True
465
+ except ClientError as e:
466
+ raise IOError(
467
+ f"Failed to create file: {e}"
468
+ ) from e
469
+
470
+ async def create_from_bytes(
471
+ self,
472
+ path: str,
473
+ source: Union[bytes, BytesIO, StringIO],
474
+ encoding: str = 'utf-8'
475
+ ) -> FileMetadata:
476
+ """Create S3 object from bytes, BytesIO, or StringIO"""
477
+ key = self._resolve_path(path)
478
+
479
+ content_type, _ = mimetypes.guess_type(path)
480
+ extra_args = {}
481
+ if content_type:
482
+ extra_args['ContentType'] = content_type
483
+
484
+ async with self.session.client('s3') as s3:
485
+ try:
486
+ if isinstance(source, bytes):
487
+ body = source
488
+ elif isinstance(source, BytesIO):
489
+ source.seek(0)
490
+ body = source.read()
491
+ elif isinstance(source, StringIO):
492
+ source.seek(0)
493
+ body = source.read().encode(encoding)
494
+ else:
495
+ raise TypeError(
496
+ f"source must be bytes, BytesIO, or StringIO, got {type(source)}"
497
+ )
498
+
499
+ await s3.put_object(
500
+ Bucket=self.bucket_name,
501
+ Key=key,
502
+ Body=body,
503
+ **extra_args
504
+ )
505
+
506
+ return await self._get_object_metadata(key)
507
+
508
+ except ClientError as e:
509
+ raise IOError(
510
+ f"Failed to create file: {e}"
511
+ ) from e