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,462 @@
1
+ """
2
+ Employee Hierarchy Tool for AI-Parrot.
3
+
4
+ Provides employee hierarchy operations as a unified tool interface
5
+ for AI agents and chatbots.
6
+ """
7
+ from typing import Dict, Any, Optional
8
+ from enum import Enum
9
+ from pydantic import Field
10
+ from navconfig.logging import logging
11
+
12
+ from parrot.tools.abstract import AbstractTool, AbstractToolArgsSchema, ToolResult
13
+ from parrot.interfaces.hierarchy import EmployeeHierarchyManager
14
+
15
+
16
+ class EmployeeAction(str, Enum):
17
+ """Available employee hierarchy actions."""
18
+ GET_SUPERIORS = "get_superiors"
19
+ GET_DIRECT_MANAGER = "get_direct_manager"
20
+ GET_COLLEAGUES = "get_colleagues"
21
+ GET_DIRECT_REPORTS = "get_direct_reports"
22
+ GET_ALL_SUBORDINATES = "get_all_subordinates"
23
+ GET_DEPARTMENT_CONTEXT = "get_department_context"
24
+ DOES_REPORT_TO = "does_report_to"
25
+ ARE_COLLEAGUES = "are_colleagues"
26
+ GET_EMPLOYEE_INFO = "get_employee_info"
27
+
28
+
29
+ class EmployeesToolArgsSchema(AbstractToolArgsSchema):
30
+ """Arguments schema for EmployeesTool."""
31
+
32
+ action: EmployeeAction = Field(
33
+ description=(
34
+ "Action to perform. Options:\n"
35
+ "- get_superiors: Get all superiors in the chain of command\n"
36
+ "- get_direct_manager: Get the immediate manager\n"
37
+ "- get_colleagues: Get colleagues with the same manager\n"
38
+ "- get_direct_reports: Get direct reports (if manager)\n"
39
+ "- get_all_subordinates: Get all subordinates recursively\n"
40
+ "- get_department_context: Get complete department context\n"
41
+ "- does_report_to: Check if employee_id reports to other_employee_id\n"
42
+ "- are_colleagues: Check if two employees are colleagues\n"
43
+ "- get_employee_info: Get basic employee information"
44
+ )
45
+ )
46
+
47
+ employee_id: str = Field(
48
+ description="Employee ID or associate_oid (e.g., 'E12345', 'EMP001', 'A123')"
49
+ )
50
+
51
+ other_employee_id: Optional[str] = Field(
52
+ default=None,
53
+ description=(
54
+ "Second employee ID for comparative operations "
55
+ "(required for 'does_report_to' and 'are_colleagues' actions)"
56
+ )
57
+ )
58
+
59
+ include_details: bool = Field(
60
+ default=True,
61
+ description="Include detailed employee information (name, email, position)"
62
+ )
63
+
64
+ max_depth: Optional[int] = Field(
65
+ default=None,
66
+ description="Maximum depth for hierarchical queries (for get_all_subordinates)"
67
+ )
68
+
69
+
70
+ class EmployeesTool(AbstractTool):
71
+ """
72
+ Employee Hierarchy Tool for querying organizational structure.
73
+
74
+ This tool provides unified access to employee hierarchy operations through
75
+ the EmployeeHierarchyManager interface. It supports various queries including:
76
+ - Reporting relationships (managers, subordinates)
77
+ - Peer relationships (colleagues)
78
+ - Department and organizational context
79
+ - Hierarchical comparisons
80
+
81
+ Example Usage:
82
+ ```python
83
+ # Initialize the tool
84
+ hierarchy_manager = EmployeeHierarchyManager(...)
85
+ employees_tool = EmployeesTool(hierarchy_manager=hierarchy_manager)
86
+
87
+ # Register with an agent
88
+ agent.add_tool(employees_tool)
89
+
90
+ # Query examples:
91
+ # "Who is John's manager?"
92
+ # "Get all employees reporting to Mary"
93
+ # "Are Alice and Bob colleagues?"
94
+ # "Show me the department context for employee E12345"
95
+ ```
96
+
97
+ Args:
98
+ hierarchy_manager: Instance of EmployeeHierarchyManager
99
+ name: Tool name (default: "employees_hierarchy")
100
+ description: Tool description
101
+ **kwargs: Additional arguments passed to AbstractTool
102
+ """
103
+
104
+ name: str = "employees_hierarchy"
105
+ description: str = (
106
+ "Query employee hierarchy and organizational structure. "
107
+ "Get information about managers, subordinates, colleagues, "
108
+ "and reporting relationships."
109
+ )
110
+ args_schema = EmployeesToolArgsSchema
111
+ return_direct: bool = False
112
+
113
+ def __init__(
114
+ self,
115
+ hierarchy_manager: EmployeeHierarchyManager,
116
+ name: Optional[str] = None,
117
+ description: Optional[str] = None,
118
+ **kwargs
119
+ ):
120
+ """
121
+ Initialize the EmployeesTool.
122
+
123
+ Args:
124
+ hierarchy_manager: EmployeeHierarchyManager instance
125
+ name: Optional tool name override
126
+ description: Optional description override
127
+ **kwargs: Additional arguments for AbstractTool
128
+ """
129
+ super().__init__(
130
+ name=name or self.name,
131
+ description=description or self.description,
132
+ **kwargs
133
+ )
134
+
135
+ self.hierarchy_manager = hierarchy_manager
136
+ self.logger = logging.getLogger(f"Parrot.Tools.{self.name}")
137
+
138
+ async def _ensure_connection(self) -> None:
139
+ """Ensure the hierarchy manager is connected."""
140
+ if not getattr(self.hierarchy_manager, "db", None):
141
+ try:
142
+ await self.hierarchy_manager.connection()
143
+ except Exception as e:
144
+ self.logger.error(f"Failed to connect hierarchy manager: {e}")
145
+ raise RuntimeError(
146
+ f"Could not establish connection to hierarchy service: {e}"
147
+ ) from e
148
+
149
+ async def _execute(
150
+ self,
151
+ action: EmployeeAction,
152
+ employee_id: str,
153
+ other_employee_id: Optional[str] = None,
154
+ include_details: bool = True,
155
+ max_depth: Optional[int] = None,
156
+ **kwargs
157
+ ) -> Any:
158
+ """
159
+ Execute the employee hierarchy operation.
160
+
161
+ Args:
162
+ action: The action to perform
163
+ employee_id: Primary employee ID
164
+ other_employee_id: Secondary employee ID (for comparative operations)
165
+ include_details: Include detailed information
166
+ max_depth: Maximum depth for recursive queries
167
+ **kwargs: Additional arguments
168
+
169
+ Returns:
170
+ Result data depending on the action performed
171
+ """
172
+ # Ensure connection
173
+ await self._ensure_connection()
174
+
175
+ # Route to appropriate handler
176
+ action_handlers = {
177
+ EmployeeAction.GET_SUPERIORS: self._get_superiors,
178
+ EmployeeAction.GET_DIRECT_MANAGER: self._get_direct_manager,
179
+ EmployeeAction.GET_COLLEAGUES: self._get_colleagues,
180
+ EmployeeAction.GET_DIRECT_REPORTS: self._get_direct_reports,
181
+ EmployeeAction.GET_ALL_SUBORDINATES: self._get_all_subordinates,
182
+ EmployeeAction.GET_DEPARTMENT_CONTEXT: self._get_department_context,
183
+ EmployeeAction.DOES_REPORT_TO: self._does_report_to,
184
+ EmployeeAction.ARE_COLLEAGUES: self._are_colleagues,
185
+ EmployeeAction.GET_EMPLOYEE_INFO: self._get_employee_info,
186
+ }
187
+
188
+ if handler := action_handlers.get(action):
189
+ # Execute the handler
190
+ return await handler(
191
+ employee_id=employee_id,
192
+ other_employee_id=other_employee_id,
193
+ include_details=include_details,
194
+ max_depth=max_depth,
195
+ **kwargs
196
+ )
197
+ raise ValueError(
198
+ f"Unknown action: {action}"
199
+ )
200
+
201
+ async def _get_department_context(
202
+ self,
203
+ employee_id: str,
204
+ **kwargs
205
+ ) -> Dict[str, Any]:
206
+ """Get complete department context for an employee."""
207
+ try:
208
+ context = await self.hierarchy_manager.get_department_context(employee_id)
209
+ if not context or 'employee' not in context:
210
+ return {
211
+ "employee_id": employee_id,
212
+ "found": False,
213
+ "message": f"No context found for employee {employee_id}"
214
+ }
215
+
216
+ return {
217
+ "employee_id": employee_id,
218
+ "found": True,
219
+ "employee": context.get('employee', {}),
220
+ "department": context.get('department'),
221
+ "program": context.get('program'),
222
+ "reports_to_chain": context.get('reports_to_chain', []),
223
+ "colleagues": context.get('colleagues', []),
224
+ "direct_reports": context.get('manages', []),
225
+ "all_subordinates": context.get('all_subordinates', []),
226
+ "direct_reports_count": context.get('direct_reports_count', 0),
227
+ "total_subordinates": context.get('total_subordinates', 0),
228
+ }
229
+ except Exception as e:
230
+ self.logger.error(f"Error getting department context: {e}")
231
+ raise
232
+
233
+ async def _get_superiors(
234
+ self,
235
+ employee_id: str,
236
+ include_details: bool = True,
237
+ **kwargs
238
+ ) -> Dict[str, Any]:
239
+ """Get all superiors in the chain of command."""
240
+ context = await self._get_department_context(employee_id)
241
+
242
+ if not context.get('found'):
243
+ return context
244
+
245
+ reports_chain = context.get('reports_to_chain', [])
246
+
247
+ return {
248
+ "employee_id": employee_id,
249
+ "found": True,
250
+ "superiors": reports_chain,
251
+ "chain_length": len(reports_chain),
252
+ "direct_manager": reports_chain[0] if reports_chain else None,
253
+ }
254
+
255
+ async def _get_direct_manager(
256
+ self,
257
+ employee_id: str,
258
+ **kwargs
259
+ ) -> Dict[str, Any]:
260
+ """Get the immediate/direct manager."""
261
+ context = await self._get_department_context(employee_id)
262
+
263
+ if not context.get('found'):
264
+ return context
265
+
266
+ reports_chain = context.get('reports_to_chain', [])
267
+ direct_manager = reports_chain[0] if reports_chain else None
268
+
269
+ return {
270
+ "employee_id": employee_id,
271
+ "found": True,
272
+ "direct_manager": direct_manager,
273
+ "has_manager": direct_manager is not None,
274
+ }
275
+
276
+ async def _get_colleagues(
277
+ self,
278
+ employee_id: str,
279
+ **kwargs
280
+ ) -> Dict[str, Any]:
281
+ """Get colleagues with the same manager."""
282
+ context = await self._get_department_context(employee_id)
283
+
284
+ if not context.get('found'):
285
+ return context
286
+
287
+ colleagues = context.get('colleagues', [])
288
+
289
+ return {
290
+ "employee_id": employee_id,
291
+ "found": True,
292
+ "colleagues": colleagues,
293
+ "colleagues_count": len(colleagues),
294
+ }
295
+
296
+ async def _get_direct_reports(
297
+ self,
298
+ employee_id: str,
299
+ **kwargs
300
+ ) -> Dict[str, Any]:
301
+ """Get direct reports (employees directly managed)."""
302
+ context = await self._get_department_context(employee_id)
303
+
304
+ if not context.get('found'):
305
+ return context
306
+
307
+ direct_reports = context.get('direct_reports', [])
308
+
309
+ return {
310
+ "employee_id": employee_id,
311
+ "found": True,
312
+ "is_manager": len(direct_reports) > 0,
313
+ "direct_reports": direct_reports,
314
+ "direct_reports_count": len(direct_reports),
315
+ }
316
+
317
+ async def _get_all_subordinates(
318
+ self,
319
+ employee_id: str,
320
+ max_depth: Optional[int] = None,
321
+ **kwargs
322
+ ) -> Dict[str, Any]:
323
+ """Get all subordinates recursively."""
324
+ context = await self._get_department_context(employee_id)
325
+
326
+ if not context.get('found'):
327
+ return context
328
+
329
+ all_subordinates = context.get('all_subordinates', [])
330
+ direct_reports = context.get('direct_reports', [])
331
+
332
+ # If max_depth is specified, we'd need to implement depth filtering
333
+ # For now, return all subordinates from the context
334
+
335
+ return {
336
+ "employee_id": employee_id,
337
+ "found": True,
338
+ "is_manager": len(direct_reports) > 0,
339
+ "direct_reports": direct_reports,
340
+ "all_subordinates": all_subordinates,
341
+ "direct_reports_count": len(direct_reports),
342
+ "total_subordinates": len(all_subordinates),
343
+ }
344
+
345
+ async def _does_report_to(
346
+ self,
347
+ employee_id: str,
348
+ other_employee_id: Optional[str] = None,
349
+ **kwargs
350
+ ) -> Dict[str, Any]:
351
+ """Check if employee_id reports to other_employee_id."""
352
+ if not other_employee_id:
353
+ return {
354
+ "employee_id": employee_id,
355
+ "found": False,
356
+ "error": "other_employee_id is required for 'does_report_to' action"
357
+ }
358
+
359
+ # Get the employee's superiors
360
+ superiors_result = await self._get_superiors(employee_id)
361
+
362
+ if not superiors_result.get('found'):
363
+ return superiors_result
364
+
365
+ superiors = superiors_result.get('superiors', [])
366
+ reports_to = other_employee_id in superiors
367
+
368
+ # Determine relationship level
369
+ relationship = "none"
370
+ if reports_to:
371
+ try:
372
+ level = superiors.index(other_employee_id) + 1
373
+ relationship = "direct_manager" if level == 1 else f"reports_to_level_{level}"
374
+ except ValueError:
375
+ relationship = "reports_to"
376
+
377
+ return {
378
+ "employee_id": employee_id,
379
+ "other_employee_id": other_employee_id,
380
+ "found": True,
381
+ "reports_to": reports_to,
382
+ "relationship": relationship,
383
+ }
384
+
385
+ async def _are_colleagues(
386
+ self,
387
+ employee_id: str,
388
+ other_employee_id: Optional[str] = None,
389
+ **kwargs
390
+ ) -> Dict[str, Any]:
391
+ """Check if two employees are colleagues (same manager)."""
392
+ if not other_employee_id:
393
+ return {
394
+ "employee_id": employee_id,
395
+ "found": False,
396
+ "error": "other_employee_id is required for 'are_colleagues' action"
397
+ }
398
+
399
+ # Get both employees' contexts
400
+ context1 = await self._get_department_context(employee_id)
401
+ context2 = await self._get_department_context(other_employee_id)
402
+
403
+ if not context1.get('found') or not context2.get('found'):
404
+ return {
405
+ "employee_id": employee_id,
406
+ "other_employee_id": other_employee_id,
407
+ "found": False,
408
+ "error": "Could not find one or both employees"
409
+ }
410
+
411
+ # Check if they have the same direct manager
412
+ manager1 = (context1.get('reports_to_chain') or [None])[0]
413
+ manager2 = (context2.get('reports_to_chain') or [None])[0]
414
+
415
+ are_colleagues = manager1 is not None and manager1 == manager2
416
+
417
+ # Also check department
418
+ same_department = (
419
+ context1.get('department') == context2.get('department')
420
+ if context1.get('department') and context2.get('department')
421
+ else False
422
+ )
423
+
424
+ return {
425
+ "employee_id": employee_id,
426
+ "other_employee_id": other_employee_id,
427
+ "found": True,
428
+ "are_colleagues": are_colleagues,
429
+ "same_manager": are_colleagues,
430
+ "same_department": same_department,
431
+ "employee1_manager": manager1,
432
+ "employee2_manager": manager2,
433
+ }
434
+
435
+ async def _get_employee_info(
436
+ self,
437
+ employee_id: str,
438
+ **kwargs
439
+ ) -> Dict[str, Any]:
440
+ """Get basic employee information."""
441
+ context = await self._get_department_context(employee_id)
442
+
443
+ if not context.get('found'):
444
+ return context
445
+
446
+ employee = context.get('employee', {})
447
+
448
+ return {
449
+ "employee_id": employee_id,
450
+ "found": True,
451
+ "employee": {
452
+ "associate_oid": employee.get('associate_oid'),
453
+ "employee_id": employee.get('employee_id'),
454
+ "display_name": employee.get('display_name'),
455
+ "email": employee.get('email'),
456
+ "position_id": employee.get('position_id'),
457
+ "job_code": employee.get('job_code'),
458
+ },
459
+ "department": context.get('department'),
460
+ "program": context.get('program'),
461
+ "direct_manager": (context.get('reports_to_chain') or [None])[0],
462
+ }
@@ -0,0 +1,96 @@
1
+ from typing import Optional, List, Dict, Union
2
+ from pydantic import BaseModel, Field, ConfigDict
3
+ from ..decorators import tool_schema
4
+ from ..querytoolkit import QueryToolkit
5
+ from ...exceptions import ToolError # pylint: disable=E0611 # noqa
6
+
7
+
8
+ class ProductInput(BaseModel):
9
+ """Input schema for querying Epson product information."""
10
+ model: Optional[str] = Field(
11
+ default=None,
12
+ description="The unique identifier for the Epson product."
13
+ )
14
+ product_name: Optional[str] = Field(
15
+ default=None,
16
+ description="The name of the Epson product."
17
+ )
18
+ output_format: Optional[str] = Field(
19
+ default='structured',
20
+ description="Output format for the employee data"
21
+ )
22
+
23
+ # Add a model_config to prevent additional properties
24
+ model_config = ConfigDict(
25
+ arbitrary_types_allowed=False,
26
+ extra="forbid",
27
+ )
28
+
29
+
30
+ class ProductInfo(BaseModel):
31
+ """Schema for the product information returned by the query."""
32
+ name: str
33
+ model: str
34
+ description: str
35
+ picture_url: str
36
+ brand: str
37
+ pricing: str
38
+ customer_satisfaction: Optional[str] = None
39
+ product_evaluation: Optional[str] = None
40
+ product_compliant: Optional[str] = None
41
+ specifications: Dict[str, Union[dict, list]] = Field(
42
+ default_factory=dict,
43
+ description="Specifications of the product, can be a dict or list."
44
+ )
45
+ review_average: float
46
+ reviews: int
47
+
48
+ # Add a model_config to prevent additional properties
49
+ model_config = ConfigDict(
50
+ arbitrary_types_allowed=False,
51
+ extra="forbid",
52
+ )
53
+
54
+
55
+ class EpsonProductToolkit(QueryToolkit):
56
+ """Toolkit for managing Epson-related operations.
57
+
58
+ This toolkit provides tools to:
59
+ - get_product_information: Get basic product information.
60
+ """
61
+
62
+ @tool_schema(ProductInput)
63
+ async def get_product_information(
64
+ self,
65
+ model: str,
66
+ product_name: Optional[str] = None,
67
+ output_format: str = 'structured',
68
+ structured_obj: Optional[ProductInfo] = ProductInfo
69
+ ) -> ProductInfo:
70
+ """
71
+ Retrieve product information for a given Epson product Model.
72
+ """
73
+ try:
74
+ data = await self._get_queryslug(
75
+ slug='epson360_products_unified',
76
+ conditions={'model': model},
77
+ output_format=output_format,
78
+ structured_obj=structured_obj
79
+ )
80
+ if not data:
81
+ raise ToolError(
82
+ f"No Product data found for model {model}."
83
+ )
84
+ return data
85
+ except ToolError as te:
86
+ raise ValueError(
87
+ f"No Product data found for model {model}, error: {te}"
88
+ )
89
+ except ValueError as ve:
90
+ raise ValueError(
91
+ f"Invalid data format, error: {ve}"
92
+ )
93
+ except Exception as e:
94
+ raise ValueError(
95
+ f"Error fetching Product data: {e}"
96
+ )