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,680 @@
1
+ """
2
+ DocumentAgent - Specialized agent for document processing without Langchain.
3
+
4
+ Migrated from NotebookAgent to use native Parrot architecture:
5
+ - Extends BasicAgent from parrot.bots.agent
6
+ - Uses AbstractTool-based tools (WordToMarkdownTool, GoogleVoiceTool, ExcelTool)
7
+ - Native conversation() and invoke() methods
8
+ - Async-first architecture
9
+ - Integrated with ToolManager
10
+ """
11
+ import os
12
+ import re
13
+ import json
14
+ from pathlib import Path
15
+ from datetime import datetime, timezone
16
+ from typing import List, Optional, Dict, Any, Union
17
+ from navconfig import BASE_DIR
18
+ from navconfig.logging import logging
19
+
20
+ from parrot.conf import BASE_STATIC_URL
21
+ from parrot.bots.agent import BasicAgent
22
+ from parrot.tools.abstract import AbstractTool
23
+ from parrot.tools.excel import ExcelTool
24
+ from parrot.tools.msword import WordToMarkdownTool, MSWordTool
25
+ from parrot.tools.gvoice import GoogleVoiceTool
26
+ from parrot.models.responses import AIMessage, AgentResponse
27
+
28
+
29
+ # Define format instructions
30
+ FORMAT_INSTRUCTIONS = """
31
+ FORMAT INSTRUCTIONS:
32
+ When responding to user queries, follow these formatting guidelines:
33
+ 1. Use markdown for structured responses
34
+ 2. Use bullet points for lists
35
+ 3. Use headers for sections (# for main headers, ## for subheaders)
36
+ 4. Include code blocks with triple backticks when showing code
37
+ 5. Format tables using markdown table syntax
38
+ 6. For document analysis, highlight key findings and insights
39
+ 7. When generating summaries, organize by main themes or sections
40
+ """
41
+
42
+
43
+ # System prompt for document processing
44
+ DOCUMENT_AGENT_SYSTEM_PROMPT = """You are {name}, a document assistant specialized in analysis,
45
+ summarization, and extraction of key information from text documents.
46
+
47
+ Current date: {today_date}
48
+
49
+ ## Your Capabilities
50
+
51
+ You have access to the following tools:
52
+ {tools_list}
53
+
54
+ ## Document Analysis Guidelines
55
+
56
+ When analyzing documents, follow these comprehensive guidelines:
57
+
58
+ 1. **Document Conversion and Processing**
59
+ - Use word_to_markdown_tool to convert Word documents to Markdown format
60
+ - Use excel_tool to work with Excel spreadsheets
61
+ - Process the resulting markdown to identify structure, sections, and key elements
62
+ - Preserve document formatting and structure when relevant to understanding
63
+
64
+ 2. **Content Analysis**
65
+ - Identify key themes, topics, and main arguments in the document
66
+ - Extract important facts, figures, quotes, and statistics
67
+ - Recognize patterns in the content and logical structure
68
+ - Analyze tone, style, and language used in the document
69
+
70
+ 3. **Summarization Techniques**
71
+ - Create executive summaries capturing the essential points
72
+ - Develop section-by-section summaries for longer documents
73
+ - Use bullet points for key takeaways
74
+ - Preserve the author's original intent and meaning
75
+ - Highlight the most important insights and conclusions
76
+
77
+ 4. **Audio Narration**
78
+ - When requested, generate clear, well-structured audio summaries
79
+ - Format text for natural-sounding speech using google_tts_service tool
80
+ - Structure narration with clear introduction, body, and conclusion
81
+ - Use transitions between major points and sections
82
+ - Emphasize key information through pacing and structure
83
+
84
+ 5. **Special Document Elements**
85
+ - Properly handle tables, charts, and figures by describing their content
86
+ - Extract and process lists, bullet points, and numbered items
87
+ - Identify and analyze headers, footers, and metadata
88
+ - Process citations, references, and bibliographic information
89
+
90
+ 6. **Output Formatting**
91
+ - Use markdown formatting for structured responses
92
+ - Organize information hierarchically with headers and subheaders
93
+ - Present extracted information in tables when appropriate
94
+ - Use code blocks for technical content or examples
95
+ - Highlight key quotes or important excerpts
96
+
97
+ {format_instructions}
98
+
99
+ Always begin by understanding what the user wants to do with their document.
100
+ Ask for clarification if needed. Be helpful, professional, and thorough in your document analysis.
101
+ """
102
+
103
+
104
+ class DocumentAgent(BasicAgent):
105
+ """
106
+ A specialized agent for document processing - converting Word docs to Markdown,
107
+ analyzing content, processing Excel files, and generating narrated summaries.
108
+
109
+ This agent extends BasicAgent and integrates document-specific tools without
110
+ relying on Langchain dependencies.
111
+ """
112
+
113
+ def __init__(
114
+ self,
115
+ name: str = 'Document Assistant',
116
+ llm: Optional[str] = None,
117
+ tools: List[AbstractTool] = None,
118
+ system_prompt: str = None,
119
+ document_url: Optional[str] = None,
120
+ **kwargs
121
+ ):
122
+ """
123
+ Initialize the DocumentAgent.
124
+
125
+ Args:
126
+ name: Agent name
127
+ llm: LLM client to use (e.g., 'google', 'openai', 'anthropic')
128
+ tools: List of tools to use (will add document tools automatically)
129
+ system_prompt: Custom system prompt (uses default if None)
130
+ document_url: Optional URL to a document to process
131
+ **kwargs: Additional arguments for BasicAgent
132
+ """
133
+ self._document_url = document_url
134
+ self._document_content = None
135
+ self._document_metadata = {}
136
+
137
+ # Format instructions
138
+ self._format_instructions: str = kwargs.pop('format_instructions', FORMAT_INSTRUCTIONS)
139
+
140
+ # Set up directories for outputs
141
+ self._static_path = BASE_DIR.joinpath('static', self.agent_id)
142
+ self.agent_audio_dir = self._static_path.joinpath('audio', 'agents')
143
+ self.agent_docs_dir = self._static_path.joinpath('docs', 'agents')
144
+
145
+ # Ensure directories exist
146
+ os.makedirs(str(self.agent_audio_dir), exist_ok=True)
147
+ os.makedirs(str(self.agent_docs_dir), exist_ok=True)
148
+
149
+ # Initialize logger
150
+ self.logger = logging.getLogger(f'Parrot.DocumentAgent.{name}')
151
+
152
+ # Initialize tools list if None
153
+ if tools is None:
154
+ tools = []
155
+
156
+ # Add document-specific tools
157
+ self._init_document_tools(tools)
158
+
159
+ # Create system prompt
160
+ if system_prompt is None:
161
+ system_prompt = self._create_system_prompt()
162
+
163
+ # Initialize parent BasicAgent
164
+ super().__init__(
165
+ name=name,
166
+ llm=llm,
167
+ system_prompt=system_prompt,
168
+ tools=tools,
169
+ **kwargs
170
+ )
171
+
172
+ self.description = (
173
+ "A specialized agent for document processing, analysis, and summarization. "
174
+ "Can convert Word documents to Markdown, process Excel files, and generate audio summaries."
175
+ )
176
+
177
+ def _init_document_tools(self, tools: List[AbstractTool]) -> None:
178
+ """Initialize document-specific tools if not already present."""
179
+ # Check existing tools
180
+ tool_names = {tool.name for tool in tools}
181
+
182
+ # Add MSWordTool if not present
183
+ if "ms_word_tool" not in tool_names:
184
+ try:
185
+ msword_tool = MSWordTool(
186
+ output_dir=str(self.agent_docs_dir)
187
+ )
188
+ tools.append(msword_tool)
189
+ self.logger.info("Added MSWordTool")
190
+ except Exception as e:
191
+ self.logger.warning(f"Could not add MSWordTool: {e}")
192
+
193
+ # Add WordToMarkdownTool if not present
194
+ if "word_to_markdown_tool" not in tool_names:
195
+ try:
196
+ word_tool = WordToMarkdownTool()
197
+ tools.append(word_tool)
198
+ self.logger.info("Added WordToMarkdownTool")
199
+ except Exception as e:
200
+ self.logger.warning(f"Could not add WordToMarkdownTool: {e}")
201
+
202
+ # Add GoogleVoiceTool (TTS) if not present
203
+ if "google_tts_service" not in tool_names:
204
+ try:
205
+ voice_tool = GoogleVoiceTool(
206
+ output_dir=str(self.agent_audio_dir)
207
+ )
208
+ tools.append(voice_tool)
209
+ self.logger.info(f"Added GoogleVoiceTool with name: {voice_tool.name}")
210
+ except Exception as e:
211
+ self.logger.warning(f"Could not add GoogleVoiceTool: {e}")
212
+
213
+ # Add ExcelTool if available and not present
214
+ if "excel_tool" not in tool_names:
215
+ try:
216
+ excel_tool = ExcelTool(
217
+ output_dir=str(self.agent_docs_dir)
218
+ )
219
+ tools.append(excel_tool)
220
+ self.logger.info("Added ExcelTool")
221
+ except ImportError:
222
+ self.logger.debug("ExcelTool not available")
223
+ except Exception as e:
224
+ self.logger.warning(f"Could not add ExcelTool: {e}")
225
+
226
+ def _create_system_prompt(self) -> str:
227
+ """Create the system prompt for the document agent."""
228
+ now = datetime.now(timezone.utc).strftime("%Y-%m-%d")
229
+
230
+ # Build tools list
231
+ tools_list = ""
232
+ for tool in self.tools:
233
+ tools_list += f"- **{tool.name}**: {tool.description}\n"
234
+
235
+ # Format the prompt
236
+ system_prompt = DOCUMENT_AGENT_SYSTEM_PROMPT.format(
237
+ name=self.name,
238
+ today_date=now,
239
+ tools_list=tools_list,
240
+ format_instructions=self._format_instructions
241
+ )
242
+
243
+ return system_prompt
244
+
245
+ async def configure(self, app=None) -> None:
246
+ """
247
+ Configure the DocumentAgent with necessary setup.
248
+
249
+ Args:
250
+ app: Optional aiohttp application for web integrations
251
+ """
252
+ await super().configure(app)
253
+ self.logger.info(f"DocumentAgent '{self.name}' configured with {len(self.tools)} tools")
254
+
255
+ async def load_document(self, url: str) -> Dict[str, Any]:
256
+ """
257
+ Load a document from a URL using WordToMarkdownTool.
258
+
259
+ Args:
260
+ url: URL of the Word document to load
261
+
262
+ Returns:
263
+ Dictionary with document content and metadata
264
+ """
265
+ if not url:
266
+ return {"error": "No document URL provided", "success": False}
267
+
268
+ # Find the Word tool
269
+ word_tool = self.get_tool("word_to_markdown_tool")
270
+
271
+ if not word_tool:
272
+ return {"error": "WordToMarkdownTool not available", "success": False}
273
+
274
+ try:
275
+ # Use the tool to load and convert the document
276
+ result = await word_tool._arun(url)
277
+
278
+ if isinstance(result, str):
279
+ try:
280
+ result = json.loads(result)
281
+ except:
282
+ result = {"markdown": result}
283
+
284
+ if not result.get("success", False):
285
+ return {
286
+ "error": result.get("error", "Unknown error loading document"),
287
+ "success": False
288
+ }
289
+
290
+ self._document_content = result.get("markdown", "")
291
+ self._document_metadata = {
292
+ "source_url": url,
293
+ "loaded_at": datetime.now().isoformat(),
294
+ "format": "markdown"
295
+ }
296
+
297
+ self.logger.info(
298
+ f"Document loaded successfully: {len(self._document_content)} characters"
299
+ )
300
+
301
+ return {
302
+ "content": self._document_content,
303
+ "metadata": self._document_metadata,
304
+ "success": True
305
+ }
306
+ except Exception as e:
307
+ self.logger.error(f"Error loading document: {e}")
308
+ return {"error": f"Error loading document: {str(e)}", "success": False}
309
+
310
+ async def generate_summary(self, max_length: int = 500) -> Dict[str, Any]:
311
+ """
312
+ Generate a summary of the loaded document using the LLM.
313
+
314
+ Args:
315
+ max_length: Maximum length hint for summary (not strict)
316
+
317
+ Returns:
318
+ Dictionary with summary text and success status
319
+ """
320
+ if not self._document_content:
321
+ self.logger.error("No document content available to summarize")
322
+ return {"error": "No document content available to summarize", "success": False}
323
+
324
+ content_length = len(self._document_content)
325
+ self.logger.info(f"Generating summary for document with {content_length} characters")
326
+
327
+ try:
328
+ # Create summarization prompt
329
+ prompt = f"""
330
+ Please analyze this document and create a comprehensive summary.
331
+
332
+ {self._document_content[:15000]} # Limit to ~15k chars to avoid token issues
333
+
334
+ Your summary should:
335
+ 1. Capture the main points and themes
336
+ 2. Be well-structured with headers for major sections
337
+ 3. Use bullet points for key details when appropriate
338
+ 4. Be suitable for audio narration (clear and flowing)
339
+ 5. Highlight the most important insights and conclusions
340
+
341
+ Focus on providing value and clarity in your summary.
342
+ """
343
+
344
+ # Use the agent's conversation method for context-aware summarization
345
+ response = await self.invoke(
346
+ question=prompt,
347
+ user_id="document_processor",
348
+ session_id=f"doc_summary_{datetime.now().timestamp()}",
349
+ use_conversation_history=False # Stateless for summary
350
+ )
351
+
352
+ if isinstance(response, AIMessage):
353
+ summary_text = response.content
354
+ elif isinstance(response, AgentResponse):
355
+ summary_text = response.output
356
+ else:
357
+ summary_text = str(response)
358
+
359
+ if not summary_text or len(summary_text.strip()) < 10:
360
+ self.logger.warning("Generated summary is too short or empty")
361
+ return {"error": "Failed to generate summary", "success": False}
362
+
363
+ self.logger.info(f"Summary generated successfully: {len(summary_text)} characters")
364
+
365
+ return {
366
+ "summary": summary_text,
367
+ "success": True
368
+ }
369
+ except Exception as e:
370
+ self.logger.error(f"Error generating summary: {e}", exc_info=True)
371
+ return {"error": f"Error generating summary: {str(e)}", "success": False}
372
+
373
+ async def _preprocess_text_for_speech(self, text: str) -> str:
374
+ """
375
+ Preprocess text to make it suitable for speech synthesis.
376
+ Removes Markdown formatting while preserving natural flow.
377
+
378
+ Args:
379
+ text: Text in Markdown format
380
+
381
+ Returns:
382
+ Clean text optimized for speech synthesis
383
+ """
384
+ # Remove bold/italic marks without adding explanatory text
385
+ text = re.sub(r'\*\*(.*?)\*\*', r'\1', text) # Remove **bold**
386
+ text = re.sub(r'\*(.*?)\*', r'\1', text) # Remove *italic*
387
+ text = re.sub(r'__(.*?)__', r'\1', text) # Remove __bold__
388
+ text = re.sub(r'_(.*?)_', r'\1', text) # Remove _italic_
389
+
390
+ # Improve lists for natural speech
391
+ text = re.sub(r'^\s*[\*\-\+]\s+', '', text, flags=re.MULTILINE) # Unordered lists
392
+ text = re.sub(r'^\s*(\d+)\.\s+', '', text, flags=re.MULTILINE) # Numbered lists
393
+
394
+ # Convert headers maintaining original text
395
+ text = re.sub(r'^#{1,6}\s+(.*)', r'\1', text, flags=re.MULTILINE)
396
+
397
+ # Clean other Markdown elements
398
+ text = re.sub(r'\[(.*?)\]\(.*?\)', r'\1', text) # Links: keep only text
399
+ text = re.sub(r'`(.*?)`', r'\1', text) # Remove `code`
400
+ text = re.sub(r'~~(.*?)~~', r'\1', text) # Remove ~~strikethrough~~
401
+
402
+ # Remove code blocks
403
+ text = re.sub(r'```.*?```', '', text, flags=re.DOTALL)
404
+
405
+ # Remove special characters
406
+ text = re.sub(r'[|]', ' ', text) # Remove pipes (common in tables)
407
+
408
+ # Handle colons and bullets for better flow
409
+ text = re.sub(r':\s*\n', '. ', text) # Convert ":" followed by newline to period
410
+
411
+ # Add natural pauses after paragraphs
412
+ text = re.sub(r'\n{2,}', '. ', text)
413
+
414
+ # Normalize spaces and punctuation
415
+ text = re.sub(r'\s{2,}', ' ', text) # Limit consecutive spaces
416
+ text = re.sub(r'\.{2,}', '.', text) # Convert multiple periods to one
417
+ text = re.sub(r'\.\s*\.', '.', text) # Remove double periods
418
+
419
+ # Ensure space after punctuation
420
+ text = re.sub(r'([.!?])\s+([A-Z])', r'\1 \2', text)
421
+
422
+ self.logger.debug(f"Preprocessed text for speech: {len(text)} characters")
423
+
424
+ return text.strip()
425
+
426
+ async def generate_audio(
427
+ self,
428
+ text: str,
429
+ voice_gender: str = "FEMALE",
430
+ language_code: str = "en-US"
431
+ ) -> Dict[str, Any]:
432
+ """
433
+ Generate audio narration from text using GoogleVoiceTool.
434
+
435
+ Args:
436
+ text: Text to convert to audio
437
+ voice_gender: Gender of the voice (MALE or FEMALE)
438
+ language_code: BCP-47 language code (e.g., 'en-US', 'es-ES')
439
+
440
+ Returns:
441
+ Dictionary with audio file information
442
+ """
443
+ try:
444
+ # Find the voice tool
445
+ voice_tool = self.get_tool("google_tts_service")
446
+
447
+ if not voice_tool:
448
+ self.logger.error("Google TTS tool not found")
449
+ available_tools = [t.name for t in self.tools]
450
+ self.logger.info(f"Available tools: {', '.join(available_tools)}")
451
+ return {"error": "Google TTS tool not available", "success": False}
452
+
453
+ # Preprocess text for speech
454
+ self.logger.info("Preprocessing text for speech synthesis...")
455
+ processed_text = await self._preprocess_text_for_speech(text)
456
+
457
+ self.logger.info(f"Generating audio using {voice_tool.name}...")
458
+
459
+ # Call the tool with proper parameters
460
+ result = await voice_tool._arun(
461
+ text=processed_text,
462
+ voice_gender=voice_gender,
463
+ language_code=language_code,
464
+ file_prefix="document_summary"
465
+ )
466
+
467
+ # Process result
468
+ if isinstance(result, str):
469
+ try:
470
+ result = json.loads(result)
471
+ except:
472
+ result = {"message": result}
473
+
474
+ self.logger.info(f"Voice tool result: {result}")
475
+
476
+ # Verify file exists and construct URL
477
+ if "file_path" in result and os.path.exists(result["file_path"]):
478
+ file_path = result["file_path"]
479
+ # Construct URL for web access
480
+ url = str(file_path).replace(str(self._static_path), BASE_STATIC_URL)
481
+ result["url"] = url
482
+ result["filename"] = os.path.basename(file_path)
483
+ result["success"] = True
484
+ self.logger.info(f"Audio generated successfully at: {file_path}")
485
+ self.logger.info(f"Audio URL: {url}")
486
+ else:
487
+ self.logger.warning("Audio file path not found in result or file doesn't exist")
488
+ if "file_path" in result:
489
+ self.logger.debug(f"Expected path: {result['file_path']}")
490
+ result["success"] = False
491
+
492
+ return result
493
+ except Exception as e:
494
+ self.logger.error(f"Error generating audio: {e}", exc_info=True)
495
+ return {"error": f"Error generating audio: {str(e)}", "success": False}
496
+
497
+ async def process_document_workflow(
498
+ self,
499
+ document_url: str,
500
+ generate_audio_summary: bool = True
501
+ ) -> Dict[str, Any]:
502
+ """
503
+ Run a complete document processing workflow:
504
+ 1. Load and convert document
505
+ 2. Generate a summary
506
+ 3. Optionally create an audio narration
507
+
508
+ Args:
509
+ document_url: URL to the Word document
510
+ generate_audio_summary: Whether to generate audio narration
511
+
512
+ Returns:
513
+ Dictionary with document content, summary, and optional audio information
514
+ """
515
+ self.logger.info(f"Starting document workflow for: {document_url}")
516
+
517
+ # Step 1: Load the document
518
+ document_result = await self.load_document(document_url)
519
+
520
+ if not document_result.get("success"):
521
+ return document_result
522
+
523
+ # Step 2: Generate summary
524
+ try:
525
+ summary_result = await self.generate_summary()
526
+ except Exception as e:
527
+ self.logger.error(f"Error generating summary: {e}")
528
+ summary_result = {"error": str(e), "summary": "", "success": False}
529
+
530
+ # Combine results
531
+ workflow_result = {
532
+ "document": {
533
+ "content_preview": (
534
+ self._document_content[:500] + "..."
535
+ if len(self._document_content) > 500
536
+ else self._document_content
537
+ ),
538
+ "full_content_length": len(self._document_content),
539
+ "metadata": self._document_metadata
540
+ },
541
+ "summary": summary_result.get("summary", ""),
542
+ "success": summary_result.get("success", False)
543
+ }
544
+
545
+ # Step 3: Generate audio if requested and summary succeeded
546
+ if generate_audio_summary and summary_result.get("success"):
547
+ try:
548
+ audio_result = await self.generate_audio(summary_result["summary"])
549
+ workflow_result["audio"] = audio_result
550
+ except Exception as e:
551
+ self.logger.error(f"Error generating audio: {e}")
552
+ workflow_result["audio"] = {"error": str(e), "success": False}
553
+
554
+ return workflow_result
555
+
556
+ def extract_filenames(self, response: Union[AIMessage, AgentResponse]) -> Dict[str, Dict[str, Any]]:
557
+ """
558
+ Extract filenames from agent response.
559
+
560
+ Args:
561
+ response: Agent response object
562
+
563
+ Returns:
564
+ Dictionary mapping filenames to their metadata
565
+ """
566
+ if isinstance(response, AIMessage):
567
+ output = response.content
568
+ elif isinstance(response, AgentResponse):
569
+ output = response.output
570
+ else:
571
+ output = str(response)
572
+
573
+ # Split the content by lines
574
+ output_lines = output.splitlines()
575
+ filenames = {}
576
+
577
+ for line in output_lines:
578
+ if 'filename:' in line.lower():
579
+ filename = line.split('filename:')[1].strip()
580
+ if filename:
581
+ try:
582
+ filename_path = Path(filename).resolve()
583
+ if filename_path.is_file():
584
+ content_type = self._mimetype_from_ext(filename_path.suffix)
585
+ url = str(filename_path).replace(str(self._static_path), BASE_STATIC_URL)
586
+ filenames[filename_path.name] = {
587
+ 'content_type': content_type,
588
+ 'file_path': str(filename_path),
589
+ 'filename': filename_path.name,
590
+ 'url': url
591
+ }
592
+ except (AttributeError, OSError):
593
+ pass
594
+
595
+ return filenames
596
+
597
+ def _mimetype_from_ext(self, ext: str) -> str:
598
+ """Get the MIME type from file extension."""
599
+ mime_types = {
600
+ '.csv': 'text/csv',
601
+ '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
602
+ '.xls': 'application/vnd.ms-excel',
603
+ '.json': 'application/json',
604
+ '.txt': 'text/plain',
605
+ '.html': 'text/html',
606
+ '.htm': 'text/html',
607
+ '.pdf': 'application/pdf',
608
+ '.png': 'image/png',
609
+ '.jpg': 'image/jpeg',
610
+ '.jpeg': 'image/jpeg',
611
+ '.gif': 'image/gif',
612
+ '.svg': 'image/svg+xml',
613
+ '.md': 'text/markdown',
614
+ '.ogg': 'audio/ogg',
615
+ '.wav': 'audio/wav',
616
+ '.mp3': 'audio/mpeg',
617
+ '.mp4': 'video/mp4',
618
+ '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
619
+ }
620
+ return mime_types.get(ext.lower(), 'application/octet-stream')
621
+
622
+ async def analyze_document(
623
+ self,
624
+ document_url: str,
625
+ analysis_type: str = "comprehensive"
626
+ ) -> Dict[str, Any]:
627
+ """
628
+ Analyze a document with specific analysis type.
629
+
630
+ Args:
631
+ document_url: URL to the document
632
+ analysis_type: Type of analysis ('comprehensive', 'summary', 'key_points', 'themes')
633
+
634
+ Returns:
635
+ Analysis results
636
+ """
637
+ # Load document if not already loaded
638
+ if not self._document_content or self._document_metadata.get("source_url") != document_url:
639
+ load_result = await self.load_document(document_url)
640
+ if not load_result.get("success"):
641
+ return load_result
642
+
643
+ # Create analysis prompt based on type
644
+ analysis_prompts = {
645
+ "comprehensive": "Provide a comprehensive analysis of this document, including themes, key arguments, evidence, and conclusions.",
646
+ "summary": "Provide a concise summary of the main points in this document.",
647
+ "key_points": "Extract and list the key points, facts, and takeaways from this document.",
648
+ "themes": "Identify and analyze the main themes and topics discussed in this document."
649
+ }
650
+
651
+ prompt = f"""{analysis_prompts.get(analysis_type, analysis_prompts['comprehensive'])}
652
+
653
+ Document Content:
654
+ {self._document_content[:10000]}
655
+ """
656
+
657
+ try:
658
+ response = await self.invoke(
659
+ question=prompt,
660
+ user_id="document_analyzer",
661
+ session_id=f"analysis_{datetime.now().timestamp()}",
662
+ use_conversation_history=False
663
+ )
664
+
665
+ if isinstance(response, AIMessage):
666
+ analysis = response.content
667
+ elif isinstance(response, AgentResponse):
668
+ analysis = response.output
669
+ else:
670
+ analysis = str(response)
671
+
672
+ return {
673
+ "analysis_type": analysis_type,
674
+ "analysis": analysis,
675
+ "document_metadata": self._document_metadata,
676
+ "success": True
677
+ }
678
+ except Exception as e:
679
+ self.logger.error(f"Error analyzing document: {e}", exc_info=True)
680
+ return {"error": f"Error analyzing document: {str(e)}", "success": False}
parrot/bots/hrbot.py ADDED
@@ -0,0 +1,15 @@
1
+ from .chatbot import Chatbot
2
+
3
+ class HRAgent(Chatbot):
4
+ """Represents an Human Resources agent in Navigator.
5
+
6
+ Each agent has a name, a role, a goal, a backstory,
7
+ and an optional language model (llm).
8
+ """
9
+ name: str = 'TROCers'
10
+ company: str = 'T-ROC Global'
11
+ company_website: str = 'https://www.trocglobal.com'
12
+ contact_information = 'communications@trocglobal.com'
13
+ contact_form = 'https://www.surveymonkey.com/r/TROC_Suggestion_Box'
14
+ role: str = 'Human Resources Assistant'
15
+ goal = 'Bring useful information to employees'