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.
- agentui/.prettierrc +15 -0
- agentui/QUICKSTART.md +272 -0
- agentui/README.md +59 -0
- agentui/env.example +16 -0
- agentui/jsconfig.json +14 -0
- agentui/package-lock.json +4242 -0
- agentui/package.json +34 -0
- agentui/scripts/postinstall/apply-patches.mjs +260 -0
- agentui/src/app.css +61 -0
- agentui/src/app.d.ts +13 -0
- agentui/src/app.html +12 -0
- agentui/src/components/LoadingSpinner.svelte +64 -0
- agentui/src/components/ThemeSwitcher.svelte +159 -0
- agentui/src/components/index.js +4 -0
- agentui/src/lib/api/bots.ts +60 -0
- agentui/src/lib/api/chat.ts +22 -0
- agentui/src/lib/api/http.ts +25 -0
- agentui/src/lib/components/BotCard.svelte +33 -0
- agentui/src/lib/components/ChatBubble.svelte +63 -0
- agentui/src/lib/components/Toast.svelte +21 -0
- agentui/src/lib/config.ts +20 -0
- agentui/src/lib/stores/auth.svelte.ts +73 -0
- agentui/src/lib/stores/theme.svelte.js +64 -0
- agentui/src/lib/stores/toast.svelte.ts +31 -0
- agentui/src/lib/utils/conversation.ts +39 -0
- agentui/src/routes/+layout.svelte +20 -0
- agentui/src/routes/+page.svelte +232 -0
- agentui/src/routes/login/+page.svelte +200 -0
- agentui/src/routes/talk/[agentId]/+page.svelte +297 -0
- agentui/src/routes/talk/[agentId]/+page.ts +7 -0
- agentui/static/README.md +1 -0
- agentui/svelte.config.js +11 -0
- agentui/tailwind.config.ts +53 -0
- agentui/tsconfig.json +3 -0
- agentui/vite.config.ts +10 -0
- ai_parrot-0.17.2.dist-info/METADATA +472 -0
- ai_parrot-0.17.2.dist-info/RECORD +535 -0
- ai_parrot-0.17.2.dist-info/WHEEL +6 -0
- ai_parrot-0.17.2.dist-info/entry_points.txt +2 -0
- ai_parrot-0.17.2.dist-info/licenses/LICENSE +21 -0
- ai_parrot-0.17.2.dist-info/top_level.txt +6 -0
- crew-builder/.prettierrc +15 -0
- crew-builder/QUICKSTART.md +259 -0
- crew-builder/README.md +113 -0
- crew-builder/env.example +17 -0
- crew-builder/jsconfig.json +14 -0
- crew-builder/package-lock.json +4182 -0
- crew-builder/package.json +37 -0
- crew-builder/scripts/postinstall/apply-patches.mjs +260 -0
- crew-builder/src/app.css +62 -0
- crew-builder/src/app.d.ts +13 -0
- crew-builder/src/app.html +12 -0
- crew-builder/src/components/LoadingSpinner.svelte +64 -0
- crew-builder/src/components/ThemeSwitcher.svelte +149 -0
- crew-builder/src/components/index.js +9 -0
- crew-builder/src/lib/api/bots.ts +60 -0
- crew-builder/src/lib/api/chat.ts +80 -0
- crew-builder/src/lib/api/client.ts +56 -0
- crew-builder/src/lib/api/crew/crew.ts +136 -0
- crew-builder/src/lib/api/index.ts +5 -0
- crew-builder/src/lib/api/o365/auth.ts +65 -0
- crew-builder/src/lib/auth/auth.ts +54 -0
- crew-builder/src/lib/components/AgentNode.svelte +43 -0
- crew-builder/src/lib/components/BotCard.svelte +33 -0
- crew-builder/src/lib/components/ChatBubble.svelte +67 -0
- crew-builder/src/lib/components/ConfigPanel.svelte +278 -0
- crew-builder/src/lib/components/JsonTreeNode.svelte +76 -0
- crew-builder/src/lib/components/JsonViewer.svelte +24 -0
- crew-builder/src/lib/components/MarkdownEditor.svelte +48 -0
- crew-builder/src/lib/components/ThemeToggle.svelte +36 -0
- crew-builder/src/lib/components/Toast.svelte +67 -0
- crew-builder/src/lib/components/Toolbar.svelte +157 -0
- crew-builder/src/lib/components/index.ts +10 -0
- crew-builder/src/lib/config.ts +8 -0
- crew-builder/src/lib/stores/auth.svelte.ts +228 -0
- crew-builder/src/lib/stores/crewStore.ts +369 -0
- crew-builder/src/lib/stores/theme.svelte.js +145 -0
- crew-builder/src/lib/stores/toast.svelte.ts +69 -0
- crew-builder/src/lib/utils/conversation.ts +39 -0
- crew-builder/src/lib/utils/markdown.ts +122 -0
- crew-builder/src/lib/utils/talkHistory.ts +47 -0
- crew-builder/src/routes/+layout.svelte +20 -0
- crew-builder/src/routes/+page.svelte +539 -0
- crew-builder/src/routes/agents/+page.svelte +247 -0
- crew-builder/src/routes/agents/[agentId]/+page.svelte +288 -0
- crew-builder/src/routes/agents/[agentId]/+page.ts +7 -0
- crew-builder/src/routes/builder/+page.svelte +204 -0
- crew-builder/src/routes/crew/ask/+page.svelte +1052 -0
- crew-builder/src/routes/crew/ask/+page.ts +1 -0
- crew-builder/src/routes/integrations/o365/+page.svelte +304 -0
- crew-builder/src/routes/login/+page.svelte +197 -0
- crew-builder/src/routes/talk/[agentId]/+page.svelte +487 -0
- crew-builder/src/routes/talk/[agentId]/+page.ts +7 -0
- crew-builder/static/README.md +1 -0
- crew-builder/svelte.config.js +11 -0
- crew-builder/tailwind.config.ts +53 -0
- crew-builder/tsconfig.json +3 -0
- crew-builder/vite.config.ts +10 -0
- mcp_servers/calculator_server.py +309 -0
- parrot/__init__.py +27 -0
- parrot/__pycache__/__init__.cpython-310.pyc +0 -0
- parrot/__pycache__/version.cpython-310.pyc +0 -0
- parrot/_version.py +34 -0
- parrot/a2a/__init__.py +48 -0
- parrot/a2a/client.py +658 -0
- parrot/a2a/discovery.py +89 -0
- parrot/a2a/mixin.py +257 -0
- parrot/a2a/models.py +376 -0
- parrot/a2a/server.py +770 -0
- parrot/agents/__init__.py +29 -0
- parrot/bots/__init__.py +12 -0
- parrot/bots/a2a_agent.py +19 -0
- parrot/bots/abstract.py +3139 -0
- parrot/bots/agent.py +1129 -0
- parrot/bots/basic.py +9 -0
- parrot/bots/chatbot.py +669 -0
- parrot/bots/data.py +1618 -0
- parrot/bots/database/__init__.py +5 -0
- parrot/bots/database/abstract.py +3071 -0
- parrot/bots/database/cache.py +286 -0
- parrot/bots/database/models.py +468 -0
- parrot/bots/database/prompts.py +154 -0
- parrot/bots/database/retries.py +98 -0
- parrot/bots/database/router.py +269 -0
- parrot/bots/database/sql.py +41 -0
- parrot/bots/db/__init__.py +6 -0
- parrot/bots/db/abstract.py +556 -0
- parrot/bots/db/bigquery.py +602 -0
- parrot/bots/db/cache.py +85 -0
- parrot/bots/db/documentdb.py +668 -0
- parrot/bots/db/elastic.py +1014 -0
- parrot/bots/db/influx.py +898 -0
- parrot/bots/db/mock.py +96 -0
- parrot/bots/db/multi.py +783 -0
- parrot/bots/db/prompts.py +185 -0
- parrot/bots/db/sql.py +1255 -0
- parrot/bots/db/tools.py +212 -0
- parrot/bots/document.py +680 -0
- parrot/bots/hrbot.py +15 -0
- parrot/bots/kb.py +170 -0
- parrot/bots/mcp.py +36 -0
- parrot/bots/orchestration/README.md +463 -0
- parrot/bots/orchestration/__init__.py +1 -0
- parrot/bots/orchestration/agent.py +155 -0
- parrot/bots/orchestration/crew.py +3330 -0
- parrot/bots/orchestration/fsm.py +1179 -0
- parrot/bots/orchestration/hr.py +434 -0
- parrot/bots/orchestration/storage/__init__.py +4 -0
- parrot/bots/orchestration/storage/memory.py +100 -0
- parrot/bots/orchestration/storage/mixin.py +119 -0
- parrot/bots/orchestration/verify.py +202 -0
- parrot/bots/product.py +204 -0
- parrot/bots/prompts/__init__.py +96 -0
- parrot/bots/prompts/agents.py +155 -0
- parrot/bots/prompts/data.py +216 -0
- parrot/bots/prompts/output_generation.py +8 -0
- parrot/bots/scraper/__init__.py +3 -0
- parrot/bots/scraper/models.py +122 -0
- parrot/bots/scraper/scraper.py +1173 -0
- parrot/bots/scraper/templates.py +115 -0
- parrot/bots/stores/__init__.py +5 -0
- parrot/bots/stores/local.py +172 -0
- parrot/bots/webdev.py +81 -0
- parrot/cli.py +17 -0
- parrot/clients/__init__.py +16 -0
- parrot/clients/base.py +1491 -0
- parrot/clients/claude.py +1191 -0
- parrot/clients/factory.py +129 -0
- parrot/clients/google.py +4567 -0
- parrot/clients/gpt.py +1975 -0
- parrot/clients/grok.py +432 -0
- parrot/clients/groq.py +986 -0
- parrot/clients/hf.py +582 -0
- parrot/clients/models.py +18 -0
- parrot/conf.py +395 -0
- parrot/embeddings/__init__.py +9 -0
- parrot/embeddings/base.py +157 -0
- parrot/embeddings/google.py +98 -0
- parrot/embeddings/huggingface.py +74 -0
- parrot/embeddings/openai.py +84 -0
- parrot/embeddings/processor.py +88 -0
- parrot/exceptions.c +13868 -0
- parrot/exceptions.cpython-310-x86_64-linux-gnu.so +0 -0
- parrot/exceptions.pxd +22 -0
- parrot/exceptions.pxi +15 -0
- parrot/exceptions.pyx +44 -0
- parrot/generators/__init__.py +29 -0
- parrot/generators/base.py +200 -0
- parrot/generators/html.py +293 -0
- parrot/generators/react.py +205 -0
- parrot/generators/streamlit.py +203 -0
- parrot/generators/template.py +105 -0
- parrot/handlers/__init__.py +4 -0
- parrot/handlers/agent.py +861 -0
- parrot/handlers/agents/__init__.py +1 -0
- parrot/handlers/agents/abstract.py +900 -0
- parrot/handlers/bots.py +338 -0
- parrot/handlers/chat.py +915 -0
- parrot/handlers/creation.sql +192 -0
- parrot/handlers/crew/ARCHITECTURE.md +362 -0
- parrot/handlers/crew/README_BOTMANAGER_PERSISTENCE.md +303 -0
- parrot/handlers/crew/README_REDIS_PERSISTENCE.md +366 -0
- parrot/handlers/crew/__init__.py +0 -0
- parrot/handlers/crew/handler.py +801 -0
- parrot/handlers/crew/models.py +229 -0
- parrot/handlers/crew/redis_persistence.py +523 -0
- parrot/handlers/jobs/__init__.py +10 -0
- parrot/handlers/jobs/job.py +384 -0
- parrot/handlers/jobs/mixin.py +627 -0
- parrot/handlers/jobs/models.py +115 -0
- parrot/handlers/jobs/worker.py +31 -0
- parrot/handlers/models.py +596 -0
- parrot/handlers/o365_auth.py +105 -0
- parrot/handlers/stream.py +337 -0
- parrot/interfaces/__init__.py +6 -0
- parrot/interfaces/aws.py +143 -0
- parrot/interfaces/credentials.py +113 -0
- parrot/interfaces/database.py +27 -0
- parrot/interfaces/google.py +1123 -0
- parrot/interfaces/hierarchy.py +1227 -0
- parrot/interfaces/http.py +651 -0
- parrot/interfaces/images/__init__.py +0 -0
- parrot/interfaces/images/plugins/__init__.py +24 -0
- parrot/interfaces/images/plugins/abstract.py +58 -0
- parrot/interfaces/images/plugins/analisys.py +148 -0
- parrot/interfaces/images/plugins/classify.py +150 -0
- parrot/interfaces/images/plugins/classifybase.py +182 -0
- parrot/interfaces/images/plugins/detect.py +150 -0
- parrot/interfaces/images/plugins/exif.py +1103 -0
- parrot/interfaces/images/plugins/hash.py +52 -0
- parrot/interfaces/images/plugins/vision.py +104 -0
- parrot/interfaces/images/plugins/yolo.py +66 -0
- parrot/interfaces/images/plugins/zerodetect.py +197 -0
- parrot/interfaces/o365.py +978 -0
- parrot/interfaces/onedrive.py +822 -0
- parrot/interfaces/sharepoint.py +1435 -0
- parrot/interfaces/soap.py +257 -0
- parrot/loaders/__init__.py +8 -0
- parrot/loaders/abstract.py +1131 -0
- parrot/loaders/audio.py +199 -0
- parrot/loaders/basepdf.py +53 -0
- parrot/loaders/basevideo.py +1568 -0
- parrot/loaders/csv.py +409 -0
- parrot/loaders/docx.py +116 -0
- parrot/loaders/epubloader.py +316 -0
- parrot/loaders/excel.py +199 -0
- parrot/loaders/factory.py +55 -0
- parrot/loaders/files/__init__.py +0 -0
- parrot/loaders/files/abstract.py +39 -0
- parrot/loaders/files/html.py +26 -0
- parrot/loaders/files/text.py +63 -0
- parrot/loaders/html.py +152 -0
- parrot/loaders/markdown.py +442 -0
- parrot/loaders/pdf.py +373 -0
- parrot/loaders/pdfmark.py +320 -0
- parrot/loaders/pdftables.py +506 -0
- parrot/loaders/ppt.py +476 -0
- parrot/loaders/qa.py +63 -0
- parrot/loaders/splitters/__init__.py +10 -0
- parrot/loaders/splitters/base.py +138 -0
- parrot/loaders/splitters/md.py +228 -0
- parrot/loaders/splitters/token.py +143 -0
- parrot/loaders/txt.py +26 -0
- parrot/loaders/video.py +89 -0
- parrot/loaders/videolocal.py +218 -0
- parrot/loaders/videounderstanding.py +377 -0
- parrot/loaders/vimeo.py +167 -0
- parrot/loaders/web.py +599 -0
- parrot/loaders/youtube.py +504 -0
- parrot/manager/__init__.py +5 -0
- parrot/manager/manager.py +1030 -0
- parrot/mcp/__init__.py +28 -0
- parrot/mcp/adapter.py +105 -0
- parrot/mcp/cli.py +174 -0
- parrot/mcp/client.py +119 -0
- parrot/mcp/config.py +75 -0
- parrot/mcp/integration.py +842 -0
- parrot/mcp/oauth.py +933 -0
- parrot/mcp/server.py +225 -0
- parrot/mcp/transports/__init__.py +3 -0
- parrot/mcp/transports/base.py +279 -0
- parrot/mcp/transports/grpc_session.py +163 -0
- parrot/mcp/transports/http.py +312 -0
- parrot/mcp/transports/mcp.proto +108 -0
- parrot/mcp/transports/quic.py +1082 -0
- parrot/mcp/transports/sse.py +330 -0
- parrot/mcp/transports/stdio.py +309 -0
- parrot/mcp/transports/unix.py +395 -0
- parrot/mcp/transports/websocket.py +547 -0
- parrot/memory/__init__.py +16 -0
- parrot/memory/abstract.py +209 -0
- parrot/memory/agent.py +32 -0
- parrot/memory/cache.py +175 -0
- parrot/memory/core.py +555 -0
- parrot/memory/file.py +153 -0
- parrot/memory/mem.py +131 -0
- parrot/memory/redis.py +613 -0
- parrot/models/__init__.py +46 -0
- parrot/models/basic.py +118 -0
- parrot/models/compliance.py +208 -0
- parrot/models/crew.py +395 -0
- parrot/models/detections.py +654 -0
- parrot/models/generation.py +85 -0
- parrot/models/google.py +223 -0
- parrot/models/groq.py +23 -0
- parrot/models/openai.py +30 -0
- parrot/models/outputs.py +285 -0
- parrot/models/responses.py +938 -0
- parrot/notifications/__init__.py +743 -0
- parrot/openapi/__init__.py +3 -0
- parrot/openapi/components.yaml +641 -0
- parrot/openapi/config.py +322 -0
- parrot/outputs/__init__.py +32 -0
- parrot/outputs/formats/__init__.py +108 -0
- parrot/outputs/formats/altair.py +359 -0
- parrot/outputs/formats/application.py +122 -0
- parrot/outputs/formats/base.py +351 -0
- parrot/outputs/formats/bokeh.py +356 -0
- parrot/outputs/formats/card.py +424 -0
- parrot/outputs/formats/chart.py +436 -0
- parrot/outputs/formats/d3.py +255 -0
- parrot/outputs/formats/echarts.py +310 -0
- parrot/outputs/formats/generators/__init__.py +0 -0
- parrot/outputs/formats/generators/abstract.py +61 -0
- parrot/outputs/formats/generators/panel.py +145 -0
- parrot/outputs/formats/generators/streamlit.py +86 -0
- parrot/outputs/formats/generators/terminal.py +63 -0
- parrot/outputs/formats/holoviews.py +310 -0
- parrot/outputs/formats/html.py +147 -0
- parrot/outputs/formats/jinja2.py +46 -0
- parrot/outputs/formats/json.py +87 -0
- parrot/outputs/formats/map.py +933 -0
- parrot/outputs/formats/markdown.py +172 -0
- parrot/outputs/formats/matplotlib.py +237 -0
- parrot/outputs/formats/mixins/__init__.py +0 -0
- parrot/outputs/formats/mixins/emaps.py +855 -0
- parrot/outputs/formats/plotly.py +341 -0
- parrot/outputs/formats/seaborn.py +310 -0
- parrot/outputs/formats/table.py +397 -0
- parrot/outputs/formats/template_report.py +138 -0
- parrot/outputs/formats/yaml.py +125 -0
- parrot/outputs/formatter.py +152 -0
- parrot/outputs/templates/__init__.py +95 -0
- parrot/pipelines/__init__.py +0 -0
- parrot/pipelines/abstract.py +210 -0
- parrot/pipelines/detector.py +124 -0
- parrot/pipelines/models.py +90 -0
- parrot/pipelines/planogram.py +3002 -0
- parrot/pipelines/table.sql +97 -0
- parrot/plugins/__init__.py +106 -0
- parrot/plugins/importer.py +80 -0
- parrot/py.typed +0 -0
- parrot/registry/__init__.py +18 -0
- parrot/registry/registry.py +594 -0
- parrot/scheduler/__init__.py +1189 -0
- parrot/scheduler/models.py +60 -0
- parrot/security/__init__.py +16 -0
- parrot/security/prompt_injection.py +268 -0
- parrot/security/security_events.sql +25 -0
- parrot/services/__init__.py +1 -0
- parrot/services/mcp/__init__.py +8 -0
- parrot/services/mcp/config.py +13 -0
- parrot/services/mcp/server.py +295 -0
- parrot/services/o365_remote_auth.py +235 -0
- parrot/stores/__init__.py +7 -0
- parrot/stores/abstract.py +352 -0
- parrot/stores/arango.py +1090 -0
- parrot/stores/bigquery.py +1377 -0
- parrot/stores/cache.py +106 -0
- parrot/stores/empty.py +10 -0
- parrot/stores/faiss_store.py +1157 -0
- parrot/stores/kb/__init__.py +9 -0
- parrot/stores/kb/abstract.py +68 -0
- parrot/stores/kb/cache.py +165 -0
- parrot/stores/kb/doc.py +325 -0
- parrot/stores/kb/hierarchy.py +346 -0
- parrot/stores/kb/local.py +457 -0
- parrot/stores/kb/prompt.py +28 -0
- parrot/stores/kb/redis.py +659 -0
- parrot/stores/kb/store.py +115 -0
- parrot/stores/kb/user.py +374 -0
- parrot/stores/models.py +59 -0
- parrot/stores/pgvector.py +3 -0
- parrot/stores/postgres.py +2853 -0
- parrot/stores/utils/__init__.py +0 -0
- parrot/stores/utils/chunking.py +197 -0
- parrot/telemetry/__init__.py +3 -0
- parrot/telemetry/mixin.py +111 -0
- parrot/template/__init__.py +3 -0
- parrot/template/engine.py +259 -0
- parrot/tools/__init__.py +23 -0
- parrot/tools/abstract.py +644 -0
- parrot/tools/agent.py +363 -0
- parrot/tools/arangodbsearch.py +537 -0
- parrot/tools/arxiv_tool.py +188 -0
- parrot/tools/calculator/__init__.py +3 -0
- parrot/tools/calculator/operations/__init__.py +38 -0
- parrot/tools/calculator/operations/calculus.py +80 -0
- parrot/tools/calculator/operations/statistics.py +76 -0
- parrot/tools/calculator/tool.py +150 -0
- parrot/tools/cloudwatch.py +988 -0
- parrot/tools/codeinterpreter/__init__.py +127 -0
- parrot/tools/codeinterpreter/executor.py +371 -0
- parrot/tools/codeinterpreter/internals.py +473 -0
- parrot/tools/codeinterpreter/models.py +643 -0
- parrot/tools/codeinterpreter/prompts.py +224 -0
- parrot/tools/codeinterpreter/tool.py +664 -0
- parrot/tools/company_info/__init__.py +6 -0
- parrot/tools/company_info/tool.py +1138 -0
- parrot/tools/correlationanalysis.py +437 -0
- parrot/tools/database/abstract.py +286 -0
- parrot/tools/database/bq.py +115 -0
- parrot/tools/database/cache.py +284 -0
- parrot/tools/database/models.py +95 -0
- parrot/tools/database/pg.py +343 -0
- parrot/tools/databasequery.py +1159 -0
- parrot/tools/db.py +1800 -0
- parrot/tools/ddgo.py +370 -0
- parrot/tools/decorators.py +271 -0
- parrot/tools/dftohtml.py +282 -0
- parrot/tools/document.py +549 -0
- parrot/tools/ecs.py +819 -0
- parrot/tools/edareport.py +368 -0
- parrot/tools/elasticsearch.py +1049 -0
- parrot/tools/employees.py +462 -0
- parrot/tools/epson/__init__.py +96 -0
- parrot/tools/excel.py +683 -0
- parrot/tools/file/__init__.py +13 -0
- parrot/tools/file/abstract.py +76 -0
- parrot/tools/file/gcs.py +378 -0
- parrot/tools/file/local.py +284 -0
- parrot/tools/file/s3.py +511 -0
- parrot/tools/file/tmp.py +309 -0
- parrot/tools/file/tool.py +501 -0
- parrot/tools/file_reader.py +129 -0
- parrot/tools/flowtask/__init__.py +19 -0
- parrot/tools/flowtask/tool.py +761 -0
- parrot/tools/gittoolkit.py +508 -0
- parrot/tools/google/__init__.py +18 -0
- parrot/tools/google/base.py +169 -0
- parrot/tools/google/tools.py +1251 -0
- parrot/tools/googlelocation.py +5 -0
- parrot/tools/googleroutes.py +5 -0
- parrot/tools/googlesearch.py +5 -0
- parrot/tools/googlesitesearch.py +5 -0
- parrot/tools/googlevoice.py +2 -0
- parrot/tools/gvoice.py +695 -0
- parrot/tools/ibisworld/README.md +225 -0
- parrot/tools/ibisworld/__init__.py +11 -0
- parrot/tools/ibisworld/tool.py +366 -0
- parrot/tools/jiratoolkit.py +1718 -0
- parrot/tools/manager.py +1098 -0
- parrot/tools/math.py +152 -0
- parrot/tools/metadata.py +476 -0
- parrot/tools/msteams.py +1621 -0
- parrot/tools/msword.py +635 -0
- parrot/tools/multidb.py +580 -0
- parrot/tools/multistoresearch.py +369 -0
- parrot/tools/networkninja.py +167 -0
- parrot/tools/nextstop/__init__.py +4 -0
- parrot/tools/nextstop/base.py +286 -0
- parrot/tools/nextstop/employee.py +733 -0
- parrot/tools/nextstop/store.py +462 -0
- parrot/tools/notification.py +435 -0
- parrot/tools/o365/__init__.py +42 -0
- parrot/tools/o365/base.py +295 -0
- parrot/tools/o365/bundle.py +522 -0
- parrot/tools/o365/events.py +554 -0
- parrot/tools/o365/mail.py +992 -0
- parrot/tools/o365/onedrive.py +497 -0
- parrot/tools/o365/sharepoint.py +641 -0
- parrot/tools/openapi_toolkit.py +904 -0
- parrot/tools/openweather.py +527 -0
- parrot/tools/pdfprint.py +1001 -0
- parrot/tools/powerbi.py +518 -0
- parrot/tools/powerpoint.py +1113 -0
- parrot/tools/pricestool.py +146 -0
- parrot/tools/products/__init__.py +246 -0
- parrot/tools/prophet_tool.py +171 -0
- parrot/tools/pythonpandas.py +630 -0
- parrot/tools/pythonrepl.py +910 -0
- parrot/tools/qsource.py +436 -0
- parrot/tools/querytoolkit.py +395 -0
- parrot/tools/quickeda.py +827 -0
- parrot/tools/resttool.py +553 -0
- parrot/tools/retail/__init__.py +0 -0
- parrot/tools/retail/bby.py +528 -0
- parrot/tools/sandboxtool.py +703 -0
- parrot/tools/sassie/__init__.py +352 -0
- parrot/tools/scraping/__init__.py +7 -0
- parrot/tools/scraping/docs/select.md +466 -0
- parrot/tools/scraping/documentation.md +1278 -0
- parrot/tools/scraping/driver.py +436 -0
- parrot/tools/scraping/models.py +576 -0
- parrot/tools/scraping/options.py +85 -0
- parrot/tools/scraping/orchestrator.py +517 -0
- parrot/tools/scraping/readme.md +740 -0
- parrot/tools/scraping/tool.py +3115 -0
- parrot/tools/seasonaldetection.py +642 -0
- parrot/tools/shell_tool/__init__.py +5 -0
- parrot/tools/shell_tool/actions.py +408 -0
- parrot/tools/shell_tool/engine.py +155 -0
- parrot/tools/shell_tool/models.py +322 -0
- parrot/tools/shell_tool/tool.py +442 -0
- parrot/tools/site_search.py +214 -0
- parrot/tools/textfile.py +418 -0
- parrot/tools/think.py +378 -0
- parrot/tools/toolkit.py +298 -0
- parrot/tools/webapp_tool.py +187 -0
- parrot/tools/whatif.py +1279 -0
- parrot/tools/workday/MULTI_WSDL_EXAMPLE.md +249 -0
- parrot/tools/workday/__init__.py +6 -0
- parrot/tools/workday/models.py +1389 -0
- parrot/tools/workday/tool.py +1293 -0
- parrot/tools/yfinance_tool.py +306 -0
- parrot/tools/zipcode.py +217 -0
- parrot/utils/__init__.py +2 -0
- parrot/utils/helpers.py +73 -0
- parrot/utils/parsers/__init__.py +5 -0
- parrot/utils/parsers/toml.c +12078 -0
- parrot/utils/parsers/toml.cpython-310-x86_64-linux-gnu.so +0 -0
- parrot/utils/parsers/toml.pyx +21 -0
- parrot/utils/toml.py +11 -0
- parrot/utils/types.cpp +20936 -0
- parrot/utils/types.cpython-310-x86_64-linux-gnu.so +0 -0
- parrot/utils/types.pyx +213 -0
- parrot/utils/uv.py +11 -0
- parrot/version.py +10 -0
- parrot/yaml-rs/Cargo.lock +350 -0
- parrot/yaml-rs/Cargo.toml +19 -0
- parrot/yaml-rs/pyproject.toml +19 -0
- parrot/yaml-rs/python/yaml_rs/__init__.py +81 -0
- parrot/yaml-rs/src/lib.rs +222 -0
- requirements/docker-compose.yml +24 -0
- 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
|
+
]
|