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,549 @@
1
+ """
2
+ AbstractDocumentTool - Base class for document generation tools.
3
+
4
+ This extends AbstractTool with common functionality for document generators like:
5
+ - PowerPoint, Word, Excel, PDF tools
6
+ - Standard document output management
7
+ - File path validation and generation
8
+ - Async file operations
9
+ - Template management
10
+ """
11
+ from abc import abstractmethod
12
+ from typing import Any, Dict, Optional, Union, List
13
+ import re
14
+ from pathlib import Path
15
+ from datetime import datetime
16
+ import aiofiles
17
+ import aiofiles.os
18
+ import pandas as pd
19
+ from pydantic import BaseModel, Field, field_validator
20
+ from .abstract import AbstractTool
21
+
22
+
23
+ class DocumentGenerationArgs(BaseModel):
24
+ """Base arguments schema for document generation tools."""
25
+
26
+ content: str = Field(
27
+ ...,
28
+ description="Content to be converted to document (text, markdown, HTML, etc.)"
29
+ )
30
+ output_filename: Optional[str] = Field(
31
+ None,
32
+ description="Custom filename for the output document (without extension). If None, auto-generates with timestamp"
33
+ )
34
+ file_prefix: str = Field(
35
+ "document",
36
+ description="Prefix for auto-generated filenames"
37
+ )
38
+ output_dir: Optional[str] = Field(
39
+ None,
40
+ description="Custom output directory. If None, uses tool's default directory"
41
+ )
42
+ overwrite_existing: bool = Field(
43
+ False,
44
+ description="Whether to overwrite existing files with the same name"
45
+ )
46
+
47
+ @field_validator('output_filename')
48
+ @classmethod
49
+ def validate_filename(cls, v):
50
+ if v is not None:
51
+ # Remove invalid filename characters
52
+ invalid_chars = r'[<>:"/\\|?*]'
53
+ if re.search(invalid_chars, v):
54
+ raise ValueError(f"Filename contains invalid characters: {invalid_chars}")
55
+ return v
56
+
57
+ @field_validator('file_prefix')
58
+ @classmethod
59
+ def validate_file_prefix(cls, v):
60
+ # Clean file prefix
61
+ return re.sub(r'[<>:"/\\|?*]', '_', v) if v else "document"
62
+
63
+
64
+ class DocumentMetadata(BaseModel):
65
+ """Metadata for generated documents."""
66
+
67
+ filename: str = Field(
68
+ ...,
69
+ description="Name of the generated document file"
70
+ )
71
+ file_path: str = Field(
72
+ ...,
73
+ description="Full path to the generated document file"
74
+ )
75
+ file_url: str = Field(
76
+ ...,
77
+ description="Public URL to access the generated document file"
78
+ )
79
+ relative_url: str = Field(
80
+ ...,
81
+ description="Relative URL to access the generated document file"
82
+ )
83
+ file_size: int = Field(
84
+ ...,
85
+ description="Size of the generated document file in bytes"
86
+ )
87
+ file_size_mb: float = Field(
88
+ ...,
89
+ description="Size of the generated document file in megabytes"
90
+ )
91
+ file_extension: str = Field(
92
+ ...,
93
+ description="File extension of the generated document"
94
+ )
95
+ created_at: str = Field(
96
+ ...,
97
+ description="Timestamp when the document was created"
98
+ )
99
+ content_length: int = Field(
100
+ ...,
101
+ description="Length of the document content in characters"
102
+ )
103
+
104
+
105
+ class AbstractDocumentTool(AbstractTool):
106
+ """
107
+ Abstract base class for document generation tools.
108
+
109
+ This class provides common functionality for tools that generate documents
110
+ like PowerPoint presentations, Word documents, Excel spreadsheets, PDFs, etc.
111
+
112
+ Features:
113
+ - Standardized document output management
114
+ - File path validation and generation
115
+ - Async file operations with aiofiles
116
+ - Template management support
117
+ - Duplicate file handling
118
+ - Comprehensive metadata generation
119
+ """
120
+
121
+ # Document-specific configuration
122
+ document_type: str = "document" # Override in subclasses (e.g., "presentation", "spreadsheet")
123
+ default_extension: str = "txt" # Override in subclasses (e.g., "pptx", "docx", "xlsx")
124
+ supported_extensions: List[str] = [] # Override in subclasses
125
+
126
+ def __init__(
127
+ self,
128
+ templates_dir: Optional[Path] = None,
129
+ output_dir: Optional[Union[str, Path]] = None,
130
+ default_template_name: Optional[str] = None,
131
+ max_file_size_mb: float = 100.0,
132
+ overwrite_existing: bool = False,
133
+ **kwargs
134
+ ):
135
+ """
136
+ Initialize the AbstractDocumentTool.
137
+
138
+ Args:
139
+ templates_dir: Directory containing document templates
140
+ default_template_name: Default template file name
141
+ max_file_size_mb: Maximum allowed file size in MB
142
+ **kwargs: Additional arguments for AbstractTool
143
+ """
144
+ # Set output_dir in kwargs if provided, so AbstractTool can use it
145
+ if output_dir:
146
+ kwargs['output_dir'] = Path(output_dir).resolve()
147
+
148
+ super().__init__(**kwargs)
149
+
150
+ self.overwrite_existing = overwrite_existing
151
+
152
+ # Template management
153
+ self.templates_dir = templates_dir
154
+ self.default_template_name = default_template_name
155
+ self.max_file_size_mb = max_file_size_mb
156
+
157
+ # Initialize templates directory if provided
158
+ if self.templates_dir:
159
+ self.templates_dir = Path(self.templates_dir)
160
+ if not self.templates_dir.exists():
161
+ self.templates_dir.mkdir(parents=True, exist_ok=True)
162
+ self.logger.info(
163
+ f"Created templates directory: {self.templates_dir}"
164
+ )
165
+
166
+ # If output_dir was provided, ensure it exists
167
+ if output_dir and not self.output_dir.exists():
168
+ self.output_dir.mkdir(parents=True, exist_ok=True)
169
+ self.logger.info(
170
+ f"Created output directory: {self.output_dir}"
171
+ )
172
+
173
+ def _default_output_dir(self) -> Path:
174
+ """Get the default output directory for this document type."""
175
+ return self.static_dir / "documents" / self.document_type
176
+
177
+ async def _ensure_output_directory(self, custom_dir: Optional[str] = None) -> Path:
178
+ """
179
+ Ensure output directory exists and return the path.
180
+
181
+ Args:
182
+ custom_dir: Custom output directory path
183
+
184
+ Returns:
185
+ Path object for the output directory
186
+ """
187
+ if custom_dir:
188
+ output_dir = Path(custom_dir).resolve()
189
+ else:
190
+ output_dir = self.output_dir
191
+
192
+ # Create directory if it doesn't exist
193
+ if not await aiofiles.os.path.exists(output_dir):
194
+ await aiofiles.os.makedirs(output_dir, exist_ok=True)
195
+ self.logger.info(f"Created output directory: {output_dir}")
196
+
197
+ return output_dir
198
+
199
+ def _generate_document_filename(
200
+ self,
201
+ output_filename: Optional[str],
202
+ file_prefix: str,
203
+ extension: Optional[str] = None
204
+ ) -> str:
205
+ """
206
+ Generate a filename for the document.
207
+
208
+ Args:
209
+ output_filename: User-provided filename (without extension)
210
+ file_prefix: Prefix for auto-generated names
211
+ extension: File extension (without dot)
212
+
213
+ Returns:
214
+ Complete filename with extension
215
+ """
216
+ # Use default extension if not provided
217
+ if not extension:
218
+ extension = self.default_extension
219
+
220
+ # Ensure extension doesn't have a leading dot
221
+ extension = extension.lstrip('.')
222
+
223
+ if output_filename:
224
+ # Use provided filename
225
+ if not output_filename.endswith(f'.{extension}'):
226
+ filename = f"{output_filename}.{extension}"
227
+ else:
228
+ filename = output_filename
229
+ else:
230
+ # Generate filename with timestamp
231
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
232
+ filename = f"{file_prefix}_{timestamp}.{extension}"
233
+
234
+ return filename
235
+
236
+ async def _check_file_exists(
237
+ self,
238
+ file_path: Path,
239
+ overwrite_existing: bool
240
+ ) -> None:
241
+ """
242
+ Check if file exists and handle according to overwrite setting.
243
+
244
+ Args:
245
+ file_path: Path to the file
246
+ overwrite_existing: Whether to overwrite existing files
247
+
248
+ Raises:
249
+ FileExistsError: If file exists and overwrite is False
250
+ """
251
+ if await aiofiles.os.path.exists(file_path):
252
+ if not overwrite_existing:
253
+ self.logger.warning(
254
+ f"File already exists: {file_path}"
255
+ )
256
+ raise FileExistsError(
257
+ f"File already exists: {file_path.name}. "
258
+ f"Set overwrite_existing=True to overwrite."
259
+ )
260
+ else:
261
+ self.logger.info(
262
+ f"Will overwrite existing file: {file_path}"
263
+ )
264
+
265
+ async def _save_document_content(
266
+ self,
267
+ content: Union[bytes, str],
268
+ file_path: Path,
269
+ encoding: Optional[str] = None
270
+ ) -> None:
271
+ """
272
+ Save document content to file using aiofiles.
273
+
274
+ Args:
275
+ content: Content to save (bytes or string)
276
+ file_path: Path where to save the file
277
+ encoding: Text encoding (only used for string content)
278
+ """
279
+ try:
280
+ if isinstance(content, bytes):
281
+ # Binary content (e.g., Excel, PowerPoint files)
282
+ async with aiofiles.open(file_path, 'wb') as f:
283
+ await f.write(content)
284
+ else:
285
+ # Text content (e.g., HTML, markdown, plain text)
286
+ encoding = encoding or 'utf-8'
287
+ async with aiofiles.open(file_path, 'w', encoding=encoding) as f:
288
+ await f.write(content)
289
+
290
+ self.logger.info(
291
+ f"Document saved successfully: {file_path}"
292
+ )
293
+
294
+ except Exception as e:
295
+ self.logger.error(
296
+ f"Error saving document to {file_path}: {e}"
297
+ )
298
+ raise
299
+
300
+ async def _get_file_size(self, file_path: Path) -> int:
301
+ """
302
+ Get file size in bytes.
303
+
304
+ Args:
305
+ file_path: Path to the file
306
+
307
+ Returns:
308
+ File size in bytes
309
+ """
310
+ try:
311
+ stat = await aiofiles.os.stat(file_path)
312
+ return stat.st_size
313
+ except Exception as e:
314
+ self.logger.error(f"Error getting file size for {file_path}: {e}")
315
+ return 0
316
+
317
+ async def _validate_file_size(self, file_path: Path) -> None:
318
+ """
319
+ Validate that file size is within limits.
320
+
321
+ Args:
322
+ file_path: Path to the file
323
+
324
+ Raises:
325
+ ValueError: If file is too large
326
+ """
327
+ file_size = await self._get_file_size(file_path)
328
+ file_size_mb = file_size / (1024 * 1024)
329
+
330
+ if file_size_mb > self.max_file_size_mb:
331
+ raise ValueError(
332
+ f"Generated file is too large: {file_size_mb:.2f}MB "
333
+ f"(max allowed: {self.max_file_size_mb}MB)"
334
+ )
335
+
336
+ async def _generate_document_metadata(
337
+ self,
338
+ file_path: Path,
339
+ content_length: int
340
+ ) -> DocumentMetadata:
341
+ """
342
+ Generate metadata for the created document.
343
+
344
+ Args:
345
+ file_path: Path to the generated file
346
+ content_length: Length of original content
347
+
348
+ Returns:
349
+ DocumentMetadata object
350
+ """
351
+ file_size = await self._get_file_size(file_path)
352
+ file_url = self.to_static_url(file_path)
353
+
354
+ return DocumentMetadata(
355
+ filename=file_path.name,
356
+ file_path=str(file_path),
357
+ file_url=file_url,
358
+ relative_url=self.relative_url(file_url),
359
+ file_size=file_size,
360
+ file_size_mb=round(file_size / (1024 * 1024), 2),
361
+ file_extension=file_path.suffix.lstrip('.'),
362
+ created_at=datetime.now().isoformat(),
363
+ content_length=content_length
364
+ )
365
+
366
+ def _get_template_path(
367
+ self,
368
+ template_name: Optional[str]
369
+ ) -> Optional[Path]:
370
+ """
371
+ Get the full path to a template file.
372
+
373
+ Args:
374
+ template_name: Name of the template file
375
+
376
+ Returns:
377
+ Path to template file or None if not found
378
+ """
379
+ if not template_name or not self.templates_dir:
380
+ return None
381
+
382
+ template_path = self.templates_dir / template_name
383
+
384
+ if template_path.exists():
385
+ return template_path
386
+ else:
387
+ self.logger.warning(f"Template not found: {template_path}")
388
+ return None
389
+
390
+ def _list_available_templates(
391
+ self,
392
+ extensions: Optional[List[str]] = None
393
+ ) -> List[str]:
394
+ """
395
+ List available template files.
396
+
397
+ Args:
398
+ extensions: File extensions to filter by (e.g., ['.pptx', '.potx'])
399
+
400
+ Returns:
401
+ List of template filenames
402
+ """
403
+ if not self.templates_dir or not self.templates_dir.exists():
404
+ return []
405
+
406
+ templates = []
407
+ extensions = extensions or self.supported_extensions or [f'.{self.default_extension}']
408
+
409
+ for ext in extensions:
410
+ ext = ext if ext.startswith('.') else f'.{ext}'
411
+ templates.extend([
412
+ f.name for f in self.templates_dir.glob(f'*{ext}')
413
+ if f.is_file()
414
+ ])
415
+
416
+ return sorted(templates)
417
+
418
+ async def _create_document_safely(
419
+ self,
420
+ content: str,
421
+ output_filename: Optional[str] = None,
422
+ file_prefix: str = "document",
423
+ output_dir: Optional[str] = None,
424
+ overwrite_existing: bool = False,
425
+ extension: Optional[str] = None,
426
+ **kwargs
427
+ ) -> Dict[str, Any]:
428
+ """
429
+ Safely create a document with all error handling and validation.
430
+
431
+ This method provides a complete workflow for document creation:
432
+ 1. Validate input
433
+ 2. Ensure output directory exists
434
+ 3. Generate filename
435
+ 4. Check for file conflicts
436
+ 5. Create the document content
437
+ 6. Save the file
438
+ 7. Validate file size
439
+ 8. Generate metadata
440
+
441
+ Args:
442
+ content: Content to convert to document
443
+ output_filename: Custom filename (without extension)
444
+ file_prefix: Prefix for auto-generated filenames
445
+ output_dir: Custom output directory
446
+ overwrite_existing: Whether to overwrite existing files
447
+ extension: File extension override
448
+ **kwargs: Additional arguments for document creation
449
+
450
+ Returns:
451
+ Dictionary with document metadata and status
452
+ """
453
+ try:
454
+ # 1. Validate input
455
+ if isinstance(content, pd.DataFrame):
456
+ if content.empty:
457
+ raise ValueError("DataFrame content cannot be empty")
458
+ elif isinstance(content, str):
459
+ if not content.strip():
460
+ raise ValueError("Content cannot be empty")
461
+ elif not content:
462
+ raise ValueError("Content cannot be empty")
463
+
464
+ # 2. Ensure output directory exists
465
+ output_directory = await self._ensure_output_directory(output_dir)
466
+
467
+ # 3. Generate filename
468
+ filename = self._generate_document_filename(
469
+ output_filename, file_prefix, extension
470
+ )
471
+ file_path = output_directory / filename
472
+ # 4. Check for file conflicts
473
+ await self._check_file_exists(file_path, overwrite_existing)
474
+ # 5. Create document content (implemented by subclasses)
475
+ document_content = await self._generate_document_content(content, **kwargs)
476
+ # 6. Save the file
477
+ await self._save_document_content(document_content, file_path)
478
+ # 7. Validate file size
479
+ await self._validate_file_size(file_path)
480
+ # 8. Generate metadata
481
+ metadata = await self._generate_document_metadata(file_path, len(content))
482
+ self.logger.info(f"Document created successfully: {filename}")
483
+
484
+ return {
485
+ "status": "success",
486
+ "message": f"{self.document_type.title()} created successfully",
487
+ "metadata": metadata.model_dump(),
488
+ **metadata.model_dump() # For backward compatibility
489
+ }
490
+
491
+ except Exception as e:
492
+ self.logger.error(f"Error creating {self.document_type}: {e}")
493
+ return {
494
+ "status": "error",
495
+ "error": str(e),
496
+ "message": f"Failed to create {self.document_type}: {str(e)}"
497
+ }
498
+
499
+ @abstractmethod
500
+ async def _generate_document_content(self, content: str, **kwargs) -> Union[bytes, str]:
501
+ """
502
+ Generate the actual document content.
503
+
504
+ This method must be implemented by subclasses to create the specific
505
+ document format (PowerPoint, Word, Excel, etc.).
506
+
507
+ Args:
508
+ content: Input content to convert
509
+ **kwargs: Additional arguments specific to the document type
510
+
511
+ Returns:
512
+ Document content as bytes (for binary formats) or string (for text formats)
513
+ """
514
+ pass
515
+
516
+ # Utility methods for subclasses
517
+
518
+ def get_supported_extensions(self) -> List[str]:
519
+ """Get list of supported file extensions for this document type."""
520
+ return self.supported_extensions or [self.default_extension]
521
+
522
+ def get_available_templates(self) -> List[str]:
523
+ """Get list of available template files."""
524
+ return self._list_available_templates()
525
+
526
+ async def template_exists(self, template_name: str) -> bool:
527
+ """Check if a template file exists."""
528
+ template_path = self._get_template_path(template_name)
529
+ return template_path is not None and await aiofiles.os.path.exists(template_path)
530
+
531
+ def get_document_info(self) -> Dict[str, Any]:
532
+ """Get information about this document tool."""
533
+ return {
534
+ "document_type": self.document_type,
535
+ "default_extension": self.default_extension,
536
+ "supported_extensions": self.get_supported_extensions(),
537
+ "templates_dir": str(self.templates_dir) if self.templates_dir else None,
538
+ "available_templates": self.get_available_templates(),
539
+ "output_dir": str(self.output_dir),
540
+ "max_file_size_mb": self.max_file_size_mb
541
+ }
542
+
543
+ def _get_current_date(self) -> str:
544
+ """Get current date in YYYY-MM-DD format."""
545
+ return datetime.now().strftime('%Y-%m-%d')
546
+
547
+ def _get_current_timestamp(self) -> str:
548
+ """Get current timestamp in ISO format."""
549
+ return datetime.now().isoformat()