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,523 @@
1
+ """
2
+ Redis Persistence for AgentsCrew Definitions.
3
+
4
+ Provides async-based persistence layer for storing and retrieving
5
+ Crew definitions from Redis using JSON serialization.
6
+ """
7
+ from typing import List, Optional, Dict, Any
8
+ from datetime import datetime
9
+ import json
10
+ from redis.asyncio import Redis
11
+ from navconfig.logging import logging
12
+
13
+ from .models import CrewDefinition
14
+ from ...conf import REDIS_URL
15
+
16
+
17
+ class CrewRedis:
18
+ """Redis-based persistence for AgentsCrew definitions."""
19
+
20
+ def __init__(
21
+ self,
22
+ redis_url: str = None,
23
+ key_prefix: str = "crew",
24
+ db: int = 2 # Use DB 2 for crew persistence
25
+ ):
26
+ """
27
+ Initialize Redis persistence for crews.
28
+
29
+ Args:
30
+ redis_url: Redis connection URL (default from config)
31
+ key_prefix: Prefix for Redis keys (default: 'crew')
32
+ db: Redis database number (default: 2)
33
+ """
34
+ self.logger = logging.getLogger('CrewRedis')
35
+ self.key_prefix = key_prefix
36
+
37
+ # Build Redis URL with specific DB if not provided
38
+ if redis_url is None:
39
+ from ...conf import REDIS_HOST, REDIS_PORT
40
+ redis_url = f"redis://{REDIS_HOST}:{REDIS_PORT}/{db}"
41
+
42
+ self.redis_url = redis_url
43
+ self.redis = Redis.from_url(
44
+ self.redis_url,
45
+ decode_responses=True,
46
+ encoding="utf-8",
47
+ socket_connect_timeout=5,
48
+ socket_timeout=5,
49
+ retry_on_timeout=True
50
+ )
51
+ self.logger.info(f"CrewRedis initialized with URL: {self.redis_url}")
52
+
53
+ def _get_key(self, name: str) -> str:
54
+ """
55
+ Generate Redis key for crew definition.
56
+
57
+ Args:
58
+ name: Name of the crew
59
+
60
+ Returns:
61
+ Redis key in format 'crew:{name}'
62
+ """
63
+ return f"{self.key_prefix}:{name}"
64
+
65
+ def _get_list_key(self) -> str:
66
+ """Get the key for the set of all crew names."""
67
+ return f"{self.key_prefix}:list"
68
+
69
+ def _get_id_mapping_key(self, crew_id: str) -> str:
70
+ """
71
+ Generate Redis key for crew_id to name mapping.
72
+
73
+ Args:
74
+ crew_id: UUID of the crew
75
+
76
+ Returns:
77
+ Redis key in format 'crew:id:{crew_id}'
78
+ """
79
+ return f"{self.key_prefix}:id:{crew_id}"
80
+
81
+ def _serialize_crew(self, crew: CrewDefinition) -> str:
82
+ """
83
+ Serialize CrewDefinition to JSON string.
84
+
85
+ Args:
86
+ crew: CrewDefinition instance
87
+
88
+ Returns:
89
+ JSON string representation
90
+ """
91
+ try:
92
+ # Use Pydantic's model_dump to get dictionary
93
+ crew_dict = crew.model_dump(mode='json')
94
+
95
+ # Convert datetime objects to ISO format
96
+ if isinstance(crew_dict.get('created_at'), datetime):
97
+ crew_dict['created_at'] = crew_dict['created_at'].isoformat()
98
+ if isinstance(crew_dict.get('updated_at'), datetime):
99
+ crew_dict['updated_at'] = crew_dict['updated_at'].isoformat()
100
+
101
+ return json.dumps(crew_dict, ensure_ascii=False, separators=(',', ':'))
102
+ except Exception as e:
103
+ self.logger.error(f"Serialization error: {e}")
104
+ raise
105
+
106
+ def _deserialize_crew(self, data: str) -> CrewDefinition:
107
+ """
108
+ Deserialize JSON string to CrewDefinition.
109
+
110
+ Args:
111
+ data: JSON string
112
+
113
+ Returns:
114
+ CrewDefinition instance
115
+ """
116
+ try:
117
+ crew_dict = json.loads(data)
118
+
119
+ # Convert ISO format strings back to datetime
120
+ if 'created_at' in crew_dict and isinstance(crew_dict['created_at'], str):
121
+ crew_dict['created_at'] = datetime.fromisoformat(crew_dict['created_at'])
122
+ if 'updated_at' in crew_dict and isinstance(crew_dict['updated_at'], str):
123
+ crew_dict['updated_at'] = datetime.fromisoformat(crew_dict['updated_at'])
124
+
125
+ return CrewDefinition(**crew_dict)
126
+ except Exception as e:
127
+ self.logger.error(f"Deserialization error: {e}")
128
+ self.logger.error(f"Problematic data: {data[:200]}")
129
+ raise
130
+
131
+ async def save_crew(self, crew: CrewDefinition) -> bool:
132
+ """
133
+ Save crew definition to Redis.
134
+
135
+ Stores the crew definition with key format 'crew:{name}'.
136
+ Also maintains a set of all crew names and a crew_id to name mapping.
137
+
138
+ Args:
139
+ crew: CrewDefinition instance to save
140
+
141
+ Returns:
142
+ True if saved successfully, False otherwise
143
+ """
144
+ try:
145
+ # Update the updated_at timestamp
146
+ crew.updated_at = datetime.utcnow()
147
+
148
+ key = self._get_key(crew.name)
149
+ serialized = self._serialize_crew(crew)
150
+
151
+ # Save crew definition
152
+ await self.redis.set(key, serialized)
153
+
154
+ # Add to crew list (set of all crew names)
155
+ await self.redis.sadd(self._get_list_key(), crew.name)
156
+
157
+ # Create crew_id to name mapping for lookup by ID
158
+ id_key = self._get_id_mapping_key(crew.crew_id)
159
+ await self.redis.set(id_key, crew.name)
160
+
161
+ self.logger.info(f"Crew '{crew.name}' (ID: {crew.crew_id}) saved successfully")
162
+ return True
163
+ except Exception as e:
164
+ self.logger.error(f"Error saving crew '{crew.name}': {e}")
165
+ return False
166
+
167
+ async def load_crew(self, name: str) -> Optional[CrewDefinition]:
168
+ """
169
+ Load crew definition from Redis by name.
170
+
171
+ Args:
172
+ name: Name of the crew to load
173
+
174
+ Returns:
175
+ CrewDefinition instance if found, None otherwise
176
+ """
177
+ try:
178
+ key = self._get_key(name)
179
+ data = await self.redis.get(key)
180
+
181
+ if data is None:
182
+ self.logger.warning(f"Crew '{name}' not found in Redis")
183
+ return None
184
+
185
+ crew = self._deserialize_crew(data)
186
+ self.logger.info(f"Crew '{name}' loaded successfully")
187
+ return crew
188
+ except Exception as e:
189
+ self.logger.error(f"Error loading crew '{name}': {e}")
190
+ return None
191
+
192
+ async def load_crew_by_id(self, crew_id: str) -> Optional[CrewDefinition]:
193
+ """
194
+ Load crew definition from Redis by crew_id.
195
+
196
+ Args:
197
+ crew_id: UUID of the crew to load
198
+
199
+ Returns:
200
+ CrewDefinition instance if found, None otherwise
201
+ """
202
+ try:
203
+ # First, look up the crew name from the ID
204
+ id_key = self._get_id_mapping_key(crew_id)
205
+ name = await self.redis.get(id_key)
206
+
207
+ if name is None:
208
+ self.logger.warning(f"Crew with ID '{crew_id}' not found in Redis")
209
+ return None
210
+
211
+ # Then load the crew by name
212
+ return await self.load_crew(name)
213
+ except Exception as e:
214
+ self.logger.error(f"Error loading crew by ID '{crew_id}': {e}")
215
+ return None
216
+
217
+ async def delete_crew(self, name: str) -> bool:
218
+ """
219
+ Delete crew definition from Redis.
220
+
221
+ Args:
222
+ name: Name of the crew to delete
223
+
224
+ Returns:
225
+ True if deleted successfully, False otherwise
226
+ """
227
+ try:
228
+ # First, get the crew to extract the ID
229
+ crew = await self.load_crew(name)
230
+
231
+ key = self._get_key(name)
232
+ result = await self.redis.delete(key)
233
+
234
+ # Remove from crew list
235
+ await self.redis.srem(self._get_list_key(), name)
236
+
237
+ # Remove ID mapping if crew was found
238
+ if crew:
239
+ id_key = self._get_id_mapping_key(crew.crew_id)
240
+ await self.redis.delete(id_key)
241
+
242
+ if result > 0:
243
+ self.logger.info(f"Crew '{name}' deleted successfully")
244
+ return True
245
+ else:
246
+ self.logger.warning(f"Crew '{name}' not found for deletion")
247
+ return False
248
+ except Exception as e:
249
+ self.logger.error(f"Error deleting crew '{name}': {e}")
250
+ return False
251
+
252
+ async def list_crews(self) -> List[str]:
253
+ """
254
+ List all crew names in Redis.
255
+
256
+ Returns:
257
+ List of crew names
258
+ """
259
+ try:
260
+ crews = await self.redis.smembers(self._get_list_key())
261
+ return sorted(list(crews))
262
+ except Exception as e:
263
+ self.logger.error(f"Error listing crews: {e}")
264
+ return []
265
+
266
+ async def crew_exists(self, name: str) -> bool:
267
+ """
268
+ Check if a crew exists in Redis.
269
+
270
+ Args:
271
+ name: Name of the crew
272
+
273
+ Returns:
274
+ True if crew exists, False otherwise
275
+ """
276
+ try:
277
+ key = self._get_key(name)
278
+ exists = await self.redis.exists(key)
279
+ return exists > 0
280
+ except Exception as e:
281
+ self.logger.error(f"Error checking crew existence '{name}': {e}")
282
+ return False
283
+
284
+ async def get_all_crews(self) -> List[CrewDefinition]:
285
+ """
286
+ Get all crew definitions from Redis.
287
+
288
+ Returns:
289
+ List of CrewDefinition instances
290
+ """
291
+ try:
292
+ crew_names = await self.list_crews()
293
+ crews = []
294
+
295
+ for name in crew_names:
296
+ crew = await self.load_crew(name)
297
+ if crew:
298
+ crews.append(crew)
299
+
300
+ self.logger.info(f"Retrieved {len(crews)} crews from Redis")
301
+ return crews
302
+ except Exception as e:
303
+ self.logger.error(f"Error getting all crews: {e}")
304
+ return []
305
+
306
+ async def get_crew_metadata(self, name: str) -> Optional[Dict[str, Any]]:
307
+ """
308
+ Get crew metadata without loading the full definition.
309
+
310
+ Args:
311
+ name: Name of the crew
312
+
313
+ Returns:
314
+ Dictionary with crew metadata (name, crew_id, description, etc.)
315
+ """
316
+ try:
317
+ crew = await self.load_crew(name)
318
+ if crew:
319
+ return {
320
+ 'crew_id': crew.crew_id,
321
+ 'name': crew.name,
322
+ 'description': crew.description,
323
+ 'execution_mode': crew.execution_mode.value,
324
+ 'agent_count': len(crew.agents),
325
+ 'created_at': crew.created_at.isoformat(),
326
+ 'updated_at': crew.updated_at.isoformat(),
327
+ 'metadata': crew.metadata
328
+ }
329
+ return None
330
+ except Exception as e:
331
+ self.logger.error(f"Error getting crew metadata '{name}': {e}")
332
+ return None
333
+
334
+ async def update_crew_metadata(
335
+ self,
336
+ name: str,
337
+ metadata: Dict[str, Any]
338
+ ) -> bool:
339
+ """
340
+ Update crew metadata without modifying agents or configuration.
341
+
342
+ Args:
343
+ name: Name of the crew
344
+ metadata: Metadata dictionary to update
345
+
346
+ Returns:
347
+ True if updated successfully, False otherwise
348
+ """
349
+ try:
350
+ crew = await self.load_crew(name)
351
+ if crew is None:
352
+ self.logger.warning(f"Cannot update metadata: crew '{name}' not found")
353
+ return False
354
+
355
+ # Update metadata
356
+ crew.metadata.update(metadata)
357
+ crew.updated_at = datetime.utcnow()
358
+
359
+ # Save back to Redis
360
+ return await self.save_crew(crew)
361
+ except Exception as e:
362
+ self.logger.error(f"Error updating crew metadata '{name}': {e}")
363
+ return False
364
+
365
+ async def ping(self) -> bool:
366
+ """
367
+ Test Redis connection.
368
+
369
+ Returns:
370
+ True if connection is healthy, False otherwise
371
+ """
372
+ try:
373
+ await self.redis.ping()
374
+ return True
375
+ except Exception as e:
376
+ self.logger.error(f"Error pinging Redis: {e}")
377
+ return False
378
+
379
+ async def close(self):
380
+ """Close the Redis connection."""
381
+ try:
382
+ await self.redis.close()
383
+ self.logger.info("Redis connection closed")
384
+ except Exception as e:
385
+ self.logger.error(f"Error closing Redis connection: {e}")
386
+
387
+ async def clear_all_crews(self) -> int:
388
+ """
389
+ Delete all crews from Redis (use with caution).
390
+
391
+ Returns:
392
+ Number of crews deleted
393
+ """
394
+ try:
395
+ crew_names = await self.list_crews()
396
+ deleted_count = 0
397
+
398
+ for name in crew_names:
399
+ if await self.delete_crew(name):
400
+ deleted_count += 1
401
+
402
+ self.logger.warning(f"Cleared {deleted_count} crews from Redis")
403
+ return deleted_count
404
+ except Exception as e:
405
+ self.logger.error(f"Error clearing all crews: {e}")
406
+ return 0
407
+
408
+
409
+ # Example usage and testing
410
+ async def test_crew_redis():
411
+ """Test the CrewRedis persistence layer."""
412
+ from .models import AgentDefinition, ExecutionMode
413
+
414
+ crew_redis = CrewRedis()
415
+
416
+ if not await crew_redis.ping():
417
+ print("❌ Redis connection failed!")
418
+ return
419
+
420
+ print("✓ Redis connection successful")
421
+
422
+ try:
423
+ # Test 1: Create and save a crew
424
+ print("\n=== Test 1: Save Crew ===")
425
+ crew_def = CrewDefinition(
426
+ name="test_crew",
427
+ description="A test crew for Redis persistence",
428
+ execution_mode=ExecutionMode.SEQUENTIAL,
429
+ agents=[
430
+ AgentDefinition(
431
+ agent_id="agent_1",
432
+ agent_class="BasicAgent",
433
+ name="Researcher",
434
+ config={"model": "gpt-4", "temperature": 0.7},
435
+ tools=["search", "summarize"],
436
+ system_prompt="You are a research agent."
437
+ ),
438
+ AgentDefinition(
439
+ agent_id="agent_2",
440
+ agent_class="BasicAgent",
441
+ name="Writer",
442
+ config={"model": "gpt-4", "temperature": 0.9},
443
+ tools=["write", "edit"],
444
+ system_prompt="You are a writing agent."
445
+ )
446
+ ],
447
+ shared_tools=["calculator"],
448
+ metadata={"version": "1.0", "author": "test"}
449
+ )
450
+
451
+ saved = await crew_redis.save_crew(crew_def)
452
+ print(f"Crew saved: {saved}")
453
+ print(f"Crew ID: {crew_def.crew_id}")
454
+
455
+ # Test 2: Load crew by name
456
+ print("\n=== Test 2: Load Crew by Name ===")
457
+ loaded_crew = await crew_redis.load_crew("test_crew")
458
+ if loaded_crew:
459
+ print(f"✓ Loaded crew: {loaded_crew.name}")
460
+ print(f" - Description: {loaded_crew.description}")
461
+ print(f" - Execution mode: {loaded_crew.execution_mode}")
462
+ print(f" - Agents: {len(loaded_crew.agents)}")
463
+ print(f" - Agent 1: {loaded_crew.agents[0].name}")
464
+ print(f" - Agent 2: {loaded_crew.agents[1].name}")
465
+ else:
466
+ print("❌ Failed to load crew")
467
+
468
+ # Test 3: Load crew by ID
469
+ print("\n=== Test 3: Load Crew by ID ===")
470
+ loaded_by_id = await crew_redis.load_crew_by_id(crew_def.crew_id)
471
+ if loaded_by_id:
472
+ print(f"✓ Loaded crew by ID: {loaded_by_id.name}")
473
+ else:
474
+ print("❌ Failed to load crew by ID")
475
+
476
+ # Test 4: List crews
477
+ print("\n=== Test 4: List Crews ===")
478
+ crews = await crew_redis.list_crews()
479
+ print(f"All crews: {crews}")
480
+
481
+ # Test 5: Check crew existence
482
+ print("\n=== Test 5: Check Existence ===")
483
+ exists = await crew_redis.crew_exists("test_crew")
484
+ print(f"Crew exists: {exists}")
485
+
486
+ not_exists = await crew_redis.crew_exists("nonexistent_crew")
487
+ print(f"Nonexistent crew exists: {not_exists}")
488
+
489
+ # Test 6: Get crew metadata
490
+ print("\n=== Test 6: Get Crew Metadata ===")
491
+ metadata = await crew_redis.get_crew_metadata("test_crew")
492
+ if metadata:
493
+ print(f"Crew metadata:")
494
+ for key, value in metadata.items():
495
+ print(f" - {key}: {value}")
496
+
497
+ # Test 7: Update metadata
498
+ print("\n=== Test 7: Update Metadata ===")
499
+ updated = await crew_redis.update_crew_metadata(
500
+ "test_crew",
501
+ {"version": "1.1", "last_test": datetime.utcnow().isoformat()}
502
+ )
503
+ print(f"Metadata updated: {updated}")
504
+
505
+ # Test 8: Get all crews
506
+ print("\n=== Test 8: Get All Crews ===")
507
+ all_crews = await crew_redis.get_all_crews()
508
+ print(f"Total crews: {len(all_crews)}")
509
+
510
+ # Cleanup
511
+ print("\n=== Cleanup ===")
512
+ deleted = await crew_redis.delete_crew("test_crew")
513
+ print(f"Crew deleted: {deleted}")
514
+
515
+ print("\n✓ All tests passed!")
516
+
517
+ finally:
518
+ await crew_redis.close()
519
+
520
+
521
+ if __name__ == "__main__":
522
+ import asyncio
523
+ asyncio.run(test_crew_redis())
@@ -0,0 +1,10 @@
1
+ from .mixin import JobManagerMixin, AsyncJobManagerMixin
2
+ from .job import JobStatus, JobManager
3
+
4
+
5
+ __all__ = (
6
+ "JobManagerMixin",
7
+ "AsyncJobManagerMixin",
8
+ "JobStatus",
9
+ "JobManager",
10
+ )