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,596 @@
1
+ """
2
+ Database model for Managing Chatbots and Agents.
3
+ """
4
+ from typing import List, Union, Optional
5
+ import uuid
6
+ import time
7
+ from datetime import datetime
8
+ from pathlib import Path, PurePath
9
+ from enum import Enum
10
+ from datamodel import Field
11
+ from asyncdb.models import Model
12
+ from ..bots.basic import BasicBot
13
+
14
+
15
+ def default_embed_model():
16
+ return {
17
+ "model_name": "sentence-transformers/all-MiniLM-L12-v2",
18
+ "model_type": "huggingface"
19
+ }
20
+
21
+
22
+ def created_at(*args, **kwargs) -> int:
23
+ return int(time.time()) * 1000
24
+
25
+
26
+ # Chatbot Model:
27
+ class BotModel(Model):
28
+ """
29
+ Unified Bot Model combining chatbot and agent functionality.
30
+
31
+ This model represents any AI bot that can operate in conversational mode,
32
+ agentic mode, or adaptive mode based on the question content.
33
+
34
+ SQL Table Creation:
35
+
36
+ CREATE TABLE IF NOT EXISTS navigator.ai_bots (
37
+ chatbot_id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
38
+ name VARCHAR NOT NULL,
39
+ description VARCHAR,
40
+ avatar TEXT,
41
+ enabled BOOLEAN NOT NULL DEFAULT TRUE,
42
+ timezone VARCHAR DEFAULT 'UTC',
43
+
44
+ -- Bot personality and behavior
45
+ role VARCHAR DEFAULT 'AI Assistant',
46
+ goal VARCHAR NOT NULL DEFAULT 'Help users accomplish their tasks effectively.',
47
+ backstory VARCHAR NOT NULL DEFAULT 'I am an AI assistant created to help users with various tasks.',
48
+ rationale VARCHAR NOT NULL DEFAULT 'I maintain a professional tone and provide accurate, helpful information.',
49
+ capabilities VARCHAR DEFAULT 'I can engage in conversation, answer questions, and use tools when needed.',
50
+
51
+ -- Prompt configuration
52
+ system_prompt_template TEXT,
53
+ human_prompt_template VARCHAR,
54
+ pre_instructions JSONB DEFAULT '[]'::JSONB,
55
+
56
+ -- LLM configuration
57
+ llm VARCHAR DEFAULT 'google',
58
+ model_name VARCHAR DEFAULT 'gemini-2.0-flash-001',
59
+ temperature FLOAT DEFAULT 0.1,
60
+ max_tokens INTEGER DEFAULT 1024,
61
+ top_k INTEGER DEFAULT 41,
62
+ top_p FLOAT DEFAULT 0.9,
63
+ model_config JSONB DEFAULT '{}'::JSONB,
64
+
65
+ -- Tool and agent configuration
66
+ tools_enabled BOOLEAN DEFAULT TRUE,
67
+ auto_tool_detection BOOLEAN DEFAULT TRUE,
68
+ tool_threshold FLOAT DEFAULT 0.7,
69
+ available_tools JSONB DEFAULT '[]'::JSONB,
70
+ operation_mode VARCHAR DEFAULT 'adaptive' CHECK (operation_mode IN ('conversational', 'agentic', 'adaptive')),
71
+
72
+ -- Vector store and retrieval configuration
73
+ use_vector_context BOOLEAN DEFAULT FALSE,
74
+ vector_store_config JSONB DEFAULT '{}'::JSONB,
75
+ embedding_model JSONB DEFAULT '{"model_name": "sentence-transformers/all-MiniLM-L12-v2", "model_type": "huggingface"}',
76
+ context_search_limit INTEGER DEFAULT 10,
77
+ context_score_threshold FLOAT DEFAULT 0.7,
78
+
79
+ -- Memory and conversation configuration
80
+ memory_type VARCHAR DEFAULT 'memory' CHECK (memory_type IN ('memory', 'file', 'redis')),
81
+ memory_config JSONB DEFAULT '{}'::JSONB,
82
+ max_context_turns INTEGER DEFAULT 5,
83
+ use_conversation_history BOOLEAN DEFAULT TRUE,
84
+
85
+ -- Security and permissions
86
+ permissions JSONB DEFAULT '{}'::JSONB,
87
+
88
+ --- knowledge base:
89
+ use_kb BOOLEAN DEFAULT FALSE,
90
+ kb JSONB DEFAULT '[]'::JSONB,
91
+
92
+ -- Metadata
93
+ language VARCHAR DEFAULT 'en',
94
+ disclaimer TEXT,
95
+ created_at TIMESTAMPTZ DEFAULT NOW(),
96
+ created_by INTEGER,
97
+ updated_at TIMESTAMPTZ DEFAULT NOW()
98
+ );
99
+
100
+ -- Indexes for better performance
101
+ CREATE INDEX IF NOT EXISTS idx_ai_bots_name ON navigator.ai_bots(name);
102
+ CREATE INDEX IF NOT EXISTS idx_ai_bots_enabled ON navigator.ai_bots(enabled);
103
+ CREATE INDEX IF NOT EXISTS idx_ai_bots_operation_mode ON navigator.ai_bots(operation_mode);
104
+ CREATE INDEX IF NOT EXISTS idx_ai_bots_tools_enabled ON navigator.ai_bots(tools_enabled);
105
+
106
+ -- Unique constraint on name
107
+ ALTER TABLE navigator.ai_bots
108
+ ADD CONSTRAINT unq_navigator_ai_bots_name UNIQUE (name);
109
+ """
110
+
111
+ # Primary key
112
+ chatbot_id: uuid.UUID = Field(
113
+ primary_key=True,
114
+ required=False,
115
+ default_factory=uuid.uuid4,
116
+ ui_help="The bot’s unique identifier."
117
+ )
118
+
119
+ # Basic bot information
120
+ name: str = Field(required=True)
121
+ description: str = Field(required=False)
122
+ avatar: str = Field(required=False)
123
+ enabled: bool = Field(required=True, default=True)
124
+ timezone: str = Field(required=False, max=75, default="UTC")
125
+
126
+ # Bot personality and behavior
127
+ role: str = Field(
128
+ default="AI Assistant",
129
+ ui_help="The bot’s function or identity from the user’s perspective.",
130
+ required=False
131
+ )
132
+ goal: str = Field(
133
+ default="Help users accomplish their tasks effectively.",
134
+ required=True,
135
+ ui_help="primary outcome the bot is designed to achieve. Keep it clear and specific. "
136
+ )
137
+ backstory: str = Field(
138
+ default="I am an AI assistant created to help users with various tasks.",
139
+ required=True,
140
+ ui_help="Outlines the bot’s knowledge base, data sources, restrictions, and configuration rules (both technical and non-technical). Also, what is prohibited or undesirable behavior for the bot. "
141
+ )
142
+ rationale: str = Field(
143
+ default="I maintain a professional tone and provide accurate, helpful information.",
144
+ required=True,
145
+ ui_help="Defines how the bot behaves in conversation — its tone, style, error handling, and hot it deals with off-topic inputs."
146
+ )
147
+ capabilities: str = Field(
148
+ default="I can engage in conversation, answer questions, and use tools when needed.",
149
+ required=False,
150
+ ui_help="The bot’s capabilities and features."
151
+ )
152
+
153
+ # Prompt configuration
154
+ system_prompt_template: Optional[str] = Field(
155
+ default=None,
156
+ required=False,
157
+ ui_help="The bot’s system prompt template, which defines its role and behavior."
158
+ )
159
+ human_prompt_template: Optional[str] = Field(
160
+ default=None,
161
+ required=False
162
+ )
163
+ pre_instructions: List[str] = Field(
164
+ default_factory=list,
165
+ required=False,
166
+ ui_help="Guidelines for consistent behavior and proper use of context. These ensure the bot uses only the predefined context to generate responses."
167
+ )
168
+
169
+ # LLM configuration
170
+ llm: str = Field(default='google', required=False, ui_help="Large Language Model powering the bot. ")
171
+ model_name: str = Field(default='gemini-2.5-flash', required=False, ui_help="Exact version or identifier of the model being used.")
172
+ temperature: float = Field(default=0.1, required=False, ui_help="Controls how creative or constrained the bot’s responses are. Lower values (e.g., 0.1) keep answers close to the context. Higher values increase variation and creativity.")
173
+ max_tokens: int = Field(default=1024, required=False, ui_help="The bot’s maximum number of tokens.")
174
+ top_k: int = Field(default=41, required=False, ui_help="The bot’s top-k parameter.")
175
+ top_p: float = Field(default=0.9, required=False, ui_help="The bot’s top-p parameter.")
176
+ model_config: dict = Field(default_factory=dict, required=False, ui_help="The bot’s model configuration.")
177
+
178
+ # Tool and agent configuration
179
+ tools_enabled: bool = Field(default=True, required=False, ui_help="Whether the bot’s tools are enabled or not.")
180
+ auto_tool_detection: bool = Field(default=True, required=False, ui_help="Whether the bot’s auto tool detection is enabled or not.")
181
+ tool_threshold: float = Field(
182
+ default=0.7,
183
+ required=False,
184
+ ui_help="The bot’s tool threshold."
185
+ )
186
+ tools: List[str] = Field(default_factory=list, required=False, ui_help="The bot’s tools.")
187
+ operation_mode: str = Field(default='adaptive', required=False, ui_help="The bot’s operation mode.") # 'conversational', 'agentic', 'adaptive'
188
+
189
+ # Knowledge Base
190
+ use_kb: bool = Field(
191
+ default=False,
192
+ required=False,
193
+ ui_help="Whether the bot’s knowledge base is enabled or not."
194
+ )
195
+ kb: List[dict] = Field(
196
+ default_factory=list,
197
+ required=False,
198
+ ui_help="The bot’s knowledge base facts."
199
+ )
200
+ custom_kbs: List[str] = Field(nullable=True, default=None)
201
+ # Vector store and retrieval configuration
202
+ use_vector: bool = Field(
203
+ default=False,
204
+ required=False,
205
+ ui_help="Whether the bot’s vector store is enabled or not."
206
+ )
207
+ vector_store_config: dict = Field(
208
+ default_factory=dict,
209
+ required=False,
210
+ ui_help="The bot’s vector store configuration."
211
+ )
212
+ embedding_model: dict = Field(
213
+ default=default_embed_model,
214
+ required=False,
215
+ ui_help="The bot’s embedding model."
216
+ )
217
+ context_search_limit: int = Field(
218
+ default=10,
219
+ required=False,
220
+ ui_help="The bot’s context search limit."
221
+ )
222
+ context_score_threshold: float = Field(
223
+ default=0.7,
224
+ required=False,
225
+ ui_help="The bot’s context score threshold."
226
+ )
227
+
228
+ # Memory and conversation configuration
229
+ memory_type: str = Field(
230
+ default='memory',
231
+ required=False,
232
+ ui_help="The bot’s memory type."
233
+ ) # 'memory', 'file', 'redis'
234
+ memory_config: dict = Field(
235
+ default_factory=dict,
236
+ required=False,
237
+ ui_help="The bot’s memory configuration."
238
+ )
239
+ max_context_turns: int = Field(
240
+ default=5, required=False, ui_help="The bot’s maximum context turns."
241
+ )
242
+ use_conversation_history: bool = Field(
243
+ default=True,
244
+ required=False,
245
+ ui_help="Whether the bot’s conversation history is enabled or not."
246
+ )
247
+ # advanced: Bot Class
248
+ bot_class: Optional[str] = Field(
249
+ required=False,
250
+ default='BasicBot',
251
+ ui_help="The bot’s class path, e.g., 'parrot.bots.unified.UnifiedBot'."
252
+ )
253
+
254
+ # Security and permissions
255
+ permissions: dict = Field(
256
+ required=False,
257
+ default_factory=dict,
258
+ ui_help="The bot’s user and group permissions."
259
+ )
260
+
261
+ # Metadata
262
+ language: str = Field(
263
+ default='en',
264
+ required=False,
265
+ ui_help="The bot’s language."
266
+ )
267
+ disclaimer: Optional[str] = Field(
268
+ required=False,
269
+ ui_help="Message shown to users before interacting with the bot. Use it for usage tips, limitations, or important notices."
270
+ )
271
+ created_at: datetime = Field(
272
+ required=False,
273
+ default=datetime.now,
274
+ ui_help="The bot’s creation timestamp."
275
+ )
276
+ created_by: Optional[int] = Field(
277
+ required=False,
278
+ ui_help="The bot’s creator."
279
+ )
280
+ updated_at: datetime = Field(
281
+ required=False,
282
+ default=datetime.now,
283
+ ui_help="The bot’s last update timestamp."
284
+ )
285
+
286
+ def __post_init__(self) -> None:
287
+ super(BotModel, self).__post_init__()
288
+
289
+ # Validate operation_mode
290
+ valid_modes = ['conversational', 'agentic', 'adaptive']
291
+ if self.operation_mode not in valid_modes:
292
+ raise ValueError(f"operation_mode must be one of {valid_modes}")
293
+
294
+ # Validate memory_type
295
+ valid_memory_types = ['memory', 'file', 'redis']
296
+ if self.memory_type not in valid_memory_types:
297
+ raise ValueError(f"memory_type must be one of {valid_memory_types}")
298
+
299
+ # Ensure tool_threshold is between 0 and 1
300
+ if not 0 <= self.tool_threshold <= 1:
301
+ raise ValueError("tool_threshold must be between 0 and 1")
302
+
303
+ def to_bot_config(self) -> dict:
304
+ """Convert model instance to bot configuration dictionary."""
305
+ return {
306
+ 'name': self.name,
307
+ 'description': self.description,
308
+ 'role': self.role,
309
+ 'goal': self.goal,
310
+ 'backstory': self.backstory,
311
+ 'rationale': self.rationale,
312
+ 'capabilities': self.capabilities,
313
+ 'system_prompt': self.system_prompt_template,
314
+ 'human_prompt': self.human_prompt_template,
315
+ 'pre_instructions': self.pre_instructions,
316
+ 'llm': self.llm,
317
+ 'model': self.model_name,
318
+ 'temperature': self.temperature,
319
+ 'max_tokens': self.max_tokens,
320
+ 'top_k': self.top_k,
321
+ 'top_p': self.top_p,
322
+ 'model_config': self.model_config,
323
+ 'tools_enabled': self.tools_enabled,
324
+ 'auto_tool_detection': self.auto_tool_detection,
325
+ 'tool_threshold': self.tool_threshold,
326
+ 'tools': self.tools,
327
+ 'operation_mode': self.operation_mode,
328
+ 'use_vector': self.use_vector,
329
+ 'vector_store_config': self.vector_store_config,
330
+ 'embedding_model': self.embedding_model,
331
+ 'context_search_limit': self.context_search_limit,
332
+ 'context_score_threshold': self.context_score_threshold,
333
+ 'memory_type': self.memory_type,
334
+ 'memory_config': self.memory_config,
335
+ 'max_context_turns': self.max_context_turns,
336
+ 'use_conversation_history': self.use_conversation_history,
337
+ 'permissions': self.permissions,
338
+ 'language': self.language,
339
+ 'disclaimer': self.disclaimer,
340
+ }
341
+
342
+ def is_agent_enabled(self) -> bool:
343
+ """Check if this bot has agent capabilities enabled."""
344
+ return self.tools_enabled and len(self.tools) > 0
345
+
346
+ def get_available_tool_names(self) -> List[str]:
347
+ """Get list of available tool names."""
348
+ return self.tools if self.tools else []
349
+
350
+ def add_tool(self, tool_name: str) -> None:
351
+ """Add a tool to the available tools list."""
352
+ if tool_name not in self.tools:
353
+ self.tools.append(tool_name)
354
+ self.updated_at = datetime.now()
355
+
356
+ def remove_tool(self, tool_name: str) -> bool:
357
+ """Remove a tool from the available tools list."""
358
+ if tool_name in self.tools:
359
+ self.tools.remove(tool_name)
360
+ self.updated_at = datetime.now()
361
+ return True
362
+ return False
363
+
364
+ def enable_vector_store(self, config: dict) -> None:
365
+ """Enable vector store with given configuration."""
366
+ self.use_vector = True
367
+ self.vector_store_config = config
368
+ self.updated_at = datetime.now()
369
+
370
+ def disable_vector_store(self) -> None:
371
+ """Disable vector store."""
372
+ self.use_vector = False
373
+ self.vector_store_config = {}
374
+ self.updated_at = datetime.now()
375
+
376
+ class Meta:
377
+ """Meta Bot Model."""
378
+ driver = 'pg'
379
+ name = "ai_bots"
380
+ schema = "navigator"
381
+ strict = True
382
+ frozen = False
383
+
384
+
385
+ class ChatbotUsage(Model):
386
+ """ChatbotUsage.
387
+
388
+ Saving information about Chatbot Usage.
389
+
390
+ -- ScyllaDB CREATE TABLE Syntax --
391
+ CREATE TABLE IF NOT EXISTS navigator.chatbots_usage (
392
+ chatbot_id TEXT,
393
+ user_id SMALLINT,
394
+ sid TEXT,
395
+ source_path TEXT,
396
+ platform TEXT,
397
+ origin inet,
398
+ user_agent TEXT,
399
+ question TEXT,
400
+ response TEXT,
401
+ used_at BIGINT,
402
+ at TEXT,
403
+ PRIMARY KEY ((chatbot_id, sid, at), used_at)
404
+ ) WITH CLUSTERING ORDER BY (used_at DESC)
405
+ AND default_time_to_live = 10368000;
406
+
407
+ """
408
+ chatbot_id: uuid.UUID = Field(primary_key=True, required=False)
409
+ user_id: int = Field(primary_key=True, required=False)
410
+ sid: uuid.UUID = Field(primary_key=True, required=False, default=uuid.uuid4)
411
+ source_path: str = Field(required=False, default='web')
412
+ platform: str = Field(required=False, default='web')
413
+ origin: str = Field(required=False)
414
+ user_agent: str = Field(required=False)
415
+ question: str = Field(required=False)
416
+ response: str = Field(required=False)
417
+ used_at: int = Field(required=False, default=created_at)
418
+ event_timestamp: datetime = Field(required=False, default=datetime.now)
419
+ _at: str = Field(primary_key=True, required=False)
420
+
421
+ class Meta:
422
+ """Meta Chatbot."""
423
+ driver = 'bigquery'
424
+ name = "chatbots_usage"
425
+ schema = "navigator"
426
+ ttl = 10368000 # 120 days in seconds
427
+ strict = True
428
+ frozen = False
429
+
430
+ def __post_init__(self) -> None:
431
+ if not self._at:
432
+ # Generate a unique session id
433
+ self._at = f'{self.sid}:{self.used_at}'
434
+ super(ChatbotUsage, self).__post_init__()
435
+
436
+
437
+ class FeedbackType(Enum):
438
+ """FeedbackType."""
439
+ # Good Feedback
440
+ GOOD_COMPLETE = "Completeness"
441
+ GOOD_CORRECT = "Correct"
442
+ GOOD_FOLLOW = "Follow the instructions"
443
+ GOOD_UNDERSTAND = "Understandable"
444
+ GOOD_USEFUL = "very useful"
445
+ GOOD_OTHER = "Please Explain"
446
+ # Bad Feedback
447
+ BAD_DONTLIKE = "Don't like the style"
448
+ BAD_INCORRECT = "Incorrect"
449
+ BAD_NOTFOLLOW = "Didn't follow the instructions"
450
+ BAD_LAZY = "Being lazy"
451
+ BAD_NOTUSEFUL = "Not useful"
452
+ BAD_UNSAFE = "Unsafe or problematic"
453
+ BAD_OTHER = "Other"
454
+
455
+ @classmethod
456
+ def list_feedback(cls, feedback_category):
457
+ """Return a list of feedback types based on the given category (Good or Bad)."""
458
+ prefix = feedback_category.upper() + "_"
459
+ return [feedback for feedback in cls if feedback.name.startswith(prefix)]
460
+
461
+ class ChatbotFeedback(Model):
462
+ """ChatbotFeedback.
463
+
464
+ Saving information about Chatbot Feedback.
465
+
466
+ -- ScyllaDB CREATE TABLE Syntax --
467
+ CREATE TABLE IF NOT EXISTS navigator.chatbots_feedback (
468
+ chatbot_id UUID,
469
+ user_id INT,
470
+ sid UUID,
471
+ at TEXT,
472
+ rating TINYINT,
473
+ like BOOLEAN,
474
+ dislike BOOLEAN,
475
+ feedback_type TEXT,
476
+ feedback TEXT,
477
+ created_at BIGINT,
478
+ PRIMARY KEY ((chatbot_id, user_id, sid), created_at)
479
+ ) WITH CLUSTERING ORDER BY (created_at DESC)
480
+ AND default_time_to_live = 7776000;
481
+
482
+ """
483
+ chatbot_id: uuid.UUID = Field(primary_key=True, required=False)
484
+ user_id: int = Field(required=False)
485
+ sid: uuid.UUID = Field(primary_key=True, required=False)
486
+ _at: str = Field(primary_key=True, required=False)
487
+ # feedback information:
488
+ rating: int = Field(required=False, default=0)
489
+ _like: bool = Field(required=False, default=False)
490
+ _dislike: bool = Field(required=False, default=False)
491
+ feedback_type: FeedbackType = Field(required=False)
492
+ feedback: str = Field(required=False)
493
+ created_at: int = Field(required=False, default=created_at)
494
+ expiration_timestamp: datetime = Field(required=False, default=datetime.now)
495
+
496
+ class Meta:
497
+ """Meta Chatbot."""
498
+ driver = 'bigquery'
499
+ name = "chatbots_feedback"
500
+ schema = "navigator"
501
+ ttl = 7776000 # 3 months in seconds
502
+ strict = True
503
+ frozen = False
504
+
505
+ def __post_init__(self) -> None:
506
+ if not self._at:
507
+ # Generate a unique session id
508
+ if not self.created_at:
509
+ self.created_at = created_at()
510
+ self._at = f'{self.sid}:{self.created_at}'
511
+ super(ChatbotFeedback, self).__post_init__()
512
+
513
+
514
+ ## Prompt Library:
515
+
516
+ class PromptCategory(Enum):
517
+ """
518
+ Prompt Category.
519
+
520
+ Categorization of Prompts, as "tech",
521
+ "tech-or-explain", "idea", "explain", "action", "command", "other".
522
+ """
523
+ TECH = "tech"
524
+ TECH_OR_EXPLAIN = "tech-or-explain"
525
+ IDEA = "idea"
526
+ EXPLAIN = "explain"
527
+ ACTION = "action"
528
+ COMMAND = "command"
529
+ OTHER = "other"
530
+
531
+ class PromptLibrary(Model):
532
+ """PromptLibrary.
533
+
534
+ Saving information about Prompt Library.
535
+
536
+ -- PostgreSQL CREATE TABLE Syntax --
537
+ CREATE TABLE IF NOT EXISTS navigator.prompt_library (
538
+ prompt_id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
539
+ chatbot_id UUID,
540
+ title varchar,
541
+ query varchar,
542
+ description TEXT,
543
+ prompt_category varchar,
544
+ prompt_tags varchar[],
545
+ created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
546
+ created_by INTEGER,
547
+ updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
548
+ );
549
+ """
550
+ prompt_id: uuid.UUID = Field(primary_key=True, required=False, default_factory=uuid.uuid4)
551
+ chatbot_id: uuid.UUID = Field(required=True)
552
+ title: str = Field(required=True)
553
+ query: str = Field(required=True)
554
+ description: str = Field(required=False)
555
+ prompt_category: str = Field(required=False, default=PromptCategory.OTHER)
556
+ prompt_tags: list = Field(required=False, default_factory=list)
557
+ created_at: datetime = Field(required=False, default=datetime.now)
558
+ created_by: int = Field(required=False)
559
+ updated_at: datetime = Field(required=False, default=datetime.now)
560
+
561
+ class Meta:
562
+ """Meta Prompt Library."""
563
+ driver = 'pg'
564
+ name = "prompt_library"
565
+ schema = "navigator"
566
+ strict = True
567
+ frozen = False
568
+
569
+
570
+ def __post_init__(self) -> None:
571
+ super(PromptLibrary, self).__post_init__()
572
+
573
+
574
+ # Factory function to create bot instances from database records
575
+ def create_bot(bot_model: BotModel, bot_class=None):
576
+ """
577
+ Create a BasicBot instance from a BotModel database record.
578
+
579
+ Args:
580
+ bot_model: BotModel instance from database
581
+ bot_class: Optional bot class to use (defaults to UnifiedBot)
582
+
583
+ Returns:
584
+ Configured bot instance
585
+ """
586
+ if bot_class is None:
587
+ bot_class = BasicBot
588
+
589
+ # Convert model to configuration
590
+ config = bot_model.to_bot_config()
591
+
592
+ # Create and return bot instance
593
+ bot = bot_class(**config)
594
+ bot.model_id = bot_model.chatbot_id
595
+
596
+ return bot
@@ -0,0 +1,105 @@
1
+ """HTTP handlers for remote Office 365 interactive authentication."""
2
+ from typing import Any, Dict
3
+
4
+ from navigator_auth.decorators import is_authenticated, user_session
5
+ from navigator.views import BaseView
6
+
7
+ from ..services.o365_remote_auth import RemoteAuthManager
8
+
9
+
10
+ def _get_manager(app) -> RemoteAuthManager:
11
+ manager = app.get("o365_auth_manager")
12
+ if manager is None:
13
+ manager = RemoteAuthManager()
14
+ app["o365_auth_manager"] = manager
15
+ return manager
16
+
17
+
18
+ @is_authenticated()
19
+ @user_session()
20
+ class O365InteractiveAuthSessions(BaseView):
21
+ """Create remote Office 365 interactive login sessions."""
22
+
23
+ async def post(self):
24
+ manager = _get_manager(self.request.app)
25
+ try:
26
+ payload: Dict[str, Any] = await self.request.json()
27
+ except Exception:
28
+ payload = {}
29
+
30
+ scopes = payload.get("scopes")
31
+ if scopes is not None and not isinstance(scopes, list):
32
+ return self.error(
33
+ response={"message": "'scopes' must be a list of strings"},
34
+ status=400,
35
+ )
36
+
37
+ redirect_uri = payload.get("redirect_uri")
38
+ credentials = payload.get("credentials")
39
+ if credentials is not None and not isinstance(credentials, dict):
40
+ return self.error(
41
+ response={"message": "'credentials' must be an object"},
42
+ status=400,
43
+ )
44
+
45
+ try:
46
+ session = await manager.start_session(
47
+ credentials=credentials,
48
+ scopes=scopes,
49
+ redirect_uri=redirect_uri,
50
+ )
51
+ except Exception as exc: # pragma: no cover - defensive
52
+ return self.error(
53
+ response={"message": f"Failed to start interactive login: {exc}"},
54
+ status=500,
55
+ )
56
+
57
+ return self.json_response(session, status=201)
58
+
59
+
60
+ @is_authenticated()
61
+ @user_session()
62
+ class O365InteractiveAuthSessionDetail(BaseView):
63
+ """Manage a specific Office 365 interactive login session."""
64
+
65
+ async def get(self):
66
+ session_id = self.request.match_info.get("session_id")
67
+ if not session_id:
68
+ return self.error(
69
+ response={"message": "Missing session_id"},
70
+ status=400,
71
+ )
72
+
73
+ manager = _get_manager(self.request.app)
74
+ session = await manager.get_session(session_id)
75
+ if not session:
76
+ return self.error(
77
+ response={"message": "Session not found"},
78
+ status=404,
79
+ )
80
+
81
+ return self.json_response(session)
82
+
83
+ async def delete(self):
84
+ session_id = self.request.match_info.get("session_id")
85
+ if not session_id:
86
+ return self.error(
87
+ response={"message": "Missing session_id"},
88
+ status=400,
89
+ )
90
+
91
+ manager = _get_manager(self.request.app)
92
+ cancelled = await manager.cancel_session(session_id)
93
+ if not cancelled:
94
+ return self.error(
95
+ response={"message": "Session not found"},
96
+ status=404,
97
+ )
98
+
99
+ return self.json_response({"session_id": session_id, "status": "cancelled"})
100
+
101
+
102
+ __all__ = [
103
+ "O365InteractiveAuthSessions",
104
+ "O365InteractiveAuthSessionDetail",
105
+ ]