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,98 @@
|
|
|
1
|
+
from typing import Optional, List, Tuple
|
|
2
|
+
import re
|
|
3
|
+
from sqlalchemy import text
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class QueryRetryConfig:
|
|
7
|
+
"""Configuration for SQL query retry mechanism."""
|
|
8
|
+
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
max_retries: int = 3,
|
|
12
|
+
retry_on_errors: List[str] = None,
|
|
13
|
+
sample_data_on_error: bool = True,
|
|
14
|
+
max_sample_rows: int = 3
|
|
15
|
+
):
|
|
16
|
+
self.max_retries = max_retries
|
|
17
|
+
self.retry_on_errors = retry_on_errors or [
|
|
18
|
+
'InvalidTextRepresentationError',
|
|
19
|
+
'DataError',
|
|
20
|
+
'ProgrammingError',
|
|
21
|
+
'invalid input syntax',
|
|
22
|
+
'column does not exist',
|
|
23
|
+
'relation does not exist',
|
|
24
|
+
'type',
|
|
25
|
+
'cast',
|
|
26
|
+
'convert'
|
|
27
|
+
]
|
|
28
|
+
self.sample_data_on_error = sample_data_on_error
|
|
29
|
+
self.max_sample_rows = max_sample_rows
|
|
30
|
+
|
|
31
|
+
class SQLRetryHandler:
|
|
32
|
+
"""Handles SQL query retries with error learning."""
|
|
33
|
+
|
|
34
|
+
def __init__(self, agent, config: Optional[QueryRetryConfig] = None):
|
|
35
|
+
self.agent = agent
|
|
36
|
+
self.config = config or QueryRetryConfig()
|
|
37
|
+
self.logger = agent.logger
|
|
38
|
+
|
|
39
|
+
def _is_retryable_error(self, error: Exception) -> bool:
|
|
40
|
+
"""Determine if an error is worth retrying."""
|
|
41
|
+
error_str = str(error).lower()
|
|
42
|
+
error_type = type(error).__name__
|
|
43
|
+
|
|
44
|
+
# Check if error type or message contains retryable patterns
|
|
45
|
+
for pattern in self.config.retry_on_errors:
|
|
46
|
+
if pattern.lower() in error_str or pattern.lower() in error_type.lower():
|
|
47
|
+
return True
|
|
48
|
+
return False
|
|
49
|
+
|
|
50
|
+
async def _get_sample_data_for_error(self, schema_name: str, table_name: str, column_name: str) -> str:
|
|
51
|
+
"""Get sample data from the problematic column."""
|
|
52
|
+
if not self.config.sample_data_on_error:
|
|
53
|
+
return ""
|
|
54
|
+
|
|
55
|
+
try:
|
|
56
|
+
sample_query = f'''
|
|
57
|
+
SELECT "{column_name}"
|
|
58
|
+
FROM "{schema_name}"."{table_name}"
|
|
59
|
+
WHERE "{column_name}" IS NOT NULL
|
|
60
|
+
LIMIT {self.config.max_sample_rows};
|
|
61
|
+
'''
|
|
62
|
+
|
|
63
|
+
async with self.agent.engine.begin() as conn:
|
|
64
|
+
result = await conn.execute(text(sample_query))
|
|
65
|
+
samples = [row[0] for row in result]
|
|
66
|
+
|
|
67
|
+
if samples:
|
|
68
|
+
return f"Sample values from {column_name}: {samples}"
|
|
69
|
+
except Exception as e:
|
|
70
|
+
self.logger.debug(f"Could not fetch sample data: {e}")
|
|
71
|
+
|
|
72
|
+
return ""
|
|
73
|
+
|
|
74
|
+
def _extract_table_column_from_error(self, sql_query: str, error: Exception) -> Tuple[Optional[str], Optional[str]]:
|
|
75
|
+
"""Extract problematic table and column from SQL and error."""
|
|
76
|
+
try:
|
|
77
|
+
# Try to find table name in FROM clause
|
|
78
|
+
from_match = re.search(r'FROM\s+(?:"?(\w+)"?\.)?"?(\w+)"?', sql_query, re.IGNORECASE)
|
|
79
|
+
table_name = from_match.group(2) if from_match else None
|
|
80
|
+
|
|
81
|
+
# Try to find problematic column from error or ORDER BY clause
|
|
82
|
+
error_str = str(error).lower()
|
|
83
|
+
|
|
84
|
+
# Look for column in ORDER BY clause (common for type conversion errors)
|
|
85
|
+
order_match = re.search(r'ORDER BY\s+.*?(\w+)', sql_query, re.IGNORECASE)
|
|
86
|
+
column_name = order_match.group(1) if order_match else None
|
|
87
|
+
|
|
88
|
+
# Or look for CAST function usage
|
|
89
|
+
cast_match = re.search(r'CAST\([^,]+,\s*[\'"]([^\'"]+)[\'"]', sql_query, re.IGNORECASE)
|
|
90
|
+
if cast_match:
|
|
91
|
+
# Find the column being cast
|
|
92
|
+
cast_col_match = re.search(r'CAST\(\s*(?:REPLACE\([^,]+,\s*)?[\'"]?(\w+)[\'"]?', sql_query, re.IGNORECASE)
|
|
93
|
+
if cast_col_match:
|
|
94
|
+
column_name = cast_col_match.group(1)
|
|
95
|
+
|
|
96
|
+
return table_name, column_name
|
|
97
|
+
except Exception:
|
|
98
|
+
return None, None
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
# ============================================================================
|
|
2
|
+
# INTELLIGENT QUERY ROUTER
|
|
3
|
+
# ============================================================================
|
|
4
|
+
from typing import Any, Dict, List, Optional
|
|
5
|
+
import re
|
|
6
|
+
from .models import (
|
|
7
|
+
UserRole,
|
|
8
|
+
QueryIntent,
|
|
9
|
+
RouteDecision,
|
|
10
|
+
OutputComponent,
|
|
11
|
+
get_default_components,
|
|
12
|
+
INTENT_COMPONENT_MAPPING
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
class SchemaQueryRouter:
|
|
16
|
+
"""Routes queries with multi-schema awareness and "show me" pattern recognition."""
|
|
17
|
+
|
|
18
|
+
def __init__(self, primary_schema: str, allowed_schemas: List[str]):
|
|
19
|
+
self.primary_schema = primary_schema
|
|
20
|
+
self.allowed_schemas = allowed_schemas
|
|
21
|
+
# Enhanced pattern matching
|
|
22
|
+
self.patterns = {
|
|
23
|
+
# Data retrieval patterns - EXPANDED
|
|
24
|
+
'show_data': [
|
|
25
|
+
r'\bshow\s+me\b', r'\bdisplay\b', r'\blist\s+all\b',
|
|
26
|
+
r'\bget\s+all\b', r'\bfind\s+all\b', r'\breturn\s+all\b',
|
|
27
|
+
r'\bselect\s+.*\s+from\b',
|
|
28
|
+
# ADD THESE MISSING PATTERNS:
|
|
29
|
+
r'\bget\s+\w+\s+\d+\s+records?\b', # "get last 5 records"
|
|
30
|
+
r'\bget\s+(last|first|top)\s+\d+\b', # "get last 5", "get top 10"
|
|
31
|
+
r'\bshow\s+\d+\s+records?\b', # "show 5 records"
|
|
32
|
+
r'\bfetch\s+\d+\s+records?\b', # "fetch 10 records"
|
|
33
|
+
r'\breturn\s+\d+\s+records?\b', # "return 5 records"
|
|
34
|
+
r'\bget\s+records?\s+from\b', # "get records from"
|
|
35
|
+
r'\bselect\s+from\b', # "select from table"
|
|
36
|
+
r'\blist\s+data\b', # "list data"
|
|
37
|
+
r'\bshow\s+data\b', # "show data"
|
|
38
|
+
],
|
|
39
|
+
# Query generation patterns - EXPANDED
|
|
40
|
+
'generate_query': [
|
|
41
|
+
r'\bget\s+\w+\s+and\s+\w+\b', r'\bfind\s+\w+\s+where\b',
|
|
42
|
+
r'\bcalculate\b', r'\bcount\b', r'\bsum\b', r'\baverage\b',
|
|
43
|
+
# ADD THESE:
|
|
44
|
+
r'\bget\s+.*\s+where\b', # "get users where"
|
|
45
|
+
r'\bfind\s+.*\s+with\b', # "find records with"
|
|
46
|
+
r'\bretrieve\s+.*\s+from\b', # "retrieve data from"
|
|
47
|
+
r'\bquery\s+.*\s+for\b', # "query table for"
|
|
48
|
+
],
|
|
49
|
+
# Schema exploration patterns - NARROWED DOWN
|
|
50
|
+
'explore_schema': [
|
|
51
|
+
r'\bwhat\s+tables?\b', r'\blist\s+tables?\b', r'\bshow\s+tables?\b',
|
|
52
|
+
r'\bwhat\s+.*\s+available\b', r'\bschema\s+structure\b',
|
|
53
|
+
r'\bdatabase\s+schema\b', r'\btable\s+structure\b',
|
|
54
|
+
# REMOVE patterns that conflict with data retrieval
|
|
55
|
+
# Don't include generic "describe", "metadata" here
|
|
56
|
+
],
|
|
57
|
+
# Documentation/Metadata requests - SPECIFIC
|
|
58
|
+
'explain_metadata': [
|
|
59
|
+
r'\bmetadata\s+of\s+table\b', # "metadata of table X"
|
|
60
|
+
r'\bdescribe\s+table\b', # "describe table X"
|
|
61
|
+
r'\btable\s+.*\s+metadata\b', # "table X metadata"
|
|
62
|
+
r'\bin\s+markdown\s+format\b', # "in markdown format"
|
|
63
|
+
r'\bformat.*metadata\b',
|
|
64
|
+
r'\bdocument\w*.*table\b', # "document table X"
|
|
65
|
+
r'\bexplain\s+.*\s+structure\b', # "explain table structure"
|
|
66
|
+
],
|
|
67
|
+
# Rest of patterns...
|
|
68
|
+
'analyze_data': [
|
|
69
|
+
r'\banalyze\b', r'\banalysis\b', r'\btrends?\b',
|
|
70
|
+
r'\binsights?\b', r'\bpatterns?\b', r'\bstatistics\b',
|
|
71
|
+
r'\bcorrelation\b', r'\bdistribution\b', r'\bcompare\b'
|
|
72
|
+
],
|
|
73
|
+
'optimize_query': [
|
|
74
|
+
r'\btable\s+.*\s+metadata\b', # "table X metadata"
|
|
75
|
+
r'\bin\s+markdown\s+format\b', # "in markdown format"
|
|
76
|
+
r'\bformat.*metadata\b',
|
|
77
|
+
r'\bdocument\w*.*table\b', # "document table X"
|
|
78
|
+
r'\bexplain\s+.*\s+structure\b', # "explain table structure"
|
|
79
|
+
],
|
|
80
|
+
'analyze_data': [
|
|
81
|
+
r'\banalyze\b', r'\banalysis\b', r'\btrends?\b',
|
|
82
|
+
r'\binsights?\b', r'\bpatterns?\b', r'\bstatistics\b',
|
|
83
|
+
r'\bcorrelation\b', r'\bdistribution\b', r'\bcompare\b',
|
|
84
|
+
r'\boptimiz\w+\b', r'\bperformance\b', r'\bslow\b',
|
|
85
|
+
r'\bindex\b', r'\btuning?\b', r'\bexplain\s+analyze\b'
|
|
86
|
+
],
|
|
87
|
+
'create_examples': [
|
|
88
|
+
r'\bexamples?\b', r'\bhow\s+to\s+use\b', r'\busage\b',
|
|
89
|
+
r'\bshow.*examples?\b'
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async def route(
|
|
94
|
+
self,
|
|
95
|
+
query: str,
|
|
96
|
+
user_role: UserRole,
|
|
97
|
+
output_components: Optional[OutputComponent] = None,
|
|
98
|
+
intent_override: Optional[QueryIntent] = None
|
|
99
|
+
) -> RouteDecision:
|
|
100
|
+
"""Enhanced routing with component-based decisions."""
|
|
101
|
+
|
|
102
|
+
# Step 1: Determine intent
|
|
103
|
+
if intent_override:
|
|
104
|
+
intent = intent_override
|
|
105
|
+
else:
|
|
106
|
+
intent = self._detect_intent(query)
|
|
107
|
+
|
|
108
|
+
# Step 2: Get base components for role
|
|
109
|
+
if output_components is None:
|
|
110
|
+
# Use role defaults + intent additions
|
|
111
|
+
base_components = get_default_components(user_role)
|
|
112
|
+
intent_components = INTENT_COMPONENT_MAPPING.get(intent, OutputComponent.NONE)
|
|
113
|
+
final_components = base_components | intent_components
|
|
114
|
+
else:
|
|
115
|
+
final_components = output_components
|
|
116
|
+
|
|
117
|
+
# Step 3: Configure execution parameters
|
|
118
|
+
execution_config = self._configure_execution(intent, user_role, final_components)
|
|
119
|
+
|
|
120
|
+
# Step 4: Special handling for specific roles
|
|
121
|
+
execution_config = self._apply_role_specific_config(
|
|
122
|
+
execution_config, user_role, final_components
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
return RouteDecision(
|
|
126
|
+
intent=intent,
|
|
127
|
+
components=final_components,
|
|
128
|
+
user_role=user_role,
|
|
129
|
+
primary_schema=self.primary_schema,
|
|
130
|
+
allowed_schemas=self.allowed_schemas,
|
|
131
|
+
**execution_config
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
def _is_raw_sql(self, query: str) -> bool:
|
|
135
|
+
"""Check if query is raw SQL."""
|
|
136
|
+
sql_keywords = ['select', 'insert', 'update', 'delete', 'with', 'explain']
|
|
137
|
+
query_lower = query.strip().lower()
|
|
138
|
+
return any(query_lower.startswith(keyword) for keyword in sql_keywords)
|
|
139
|
+
|
|
140
|
+
def _detect_intent(self, query: str) -> QueryIntent:
|
|
141
|
+
"""Detect query intent from patterns."""
|
|
142
|
+
query_lower = query.lower().strip()
|
|
143
|
+
|
|
144
|
+
# Check if query contains raw SQL
|
|
145
|
+
if self._is_raw_sql(query):
|
|
146
|
+
return QueryIntent.VALIDATE_QUERY
|
|
147
|
+
|
|
148
|
+
# Pattern matching for different intents
|
|
149
|
+
for intent_name, patterns in self.patterns.items():
|
|
150
|
+
if any(re.search(pattern, query_lower) for pattern in patterns):
|
|
151
|
+
return QueryIntent(intent_name)
|
|
152
|
+
|
|
153
|
+
# Default to query generation
|
|
154
|
+
return QueryIntent.GENERATE_QUERY
|
|
155
|
+
|
|
156
|
+
def _configure_execution(
|
|
157
|
+
self,
|
|
158
|
+
intent: QueryIntent,
|
|
159
|
+
user_role: UserRole,
|
|
160
|
+
components: OutputComponent
|
|
161
|
+
) -> Dict[str, Any]:
|
|
162
|
+
"""Configure execution parameters based on intent, role, and components."""
|
|
163
|
+
|
|
164
|
+
config = {
|
|
165
|
+
'needs_metadata_discovery': True,
|
|
166
|
+
'needs_query_generation': True,
|
|
167
|
+
'needs_execution': True,
|
|
168
|
+
'needs_plan_analysis': False,
|
|
169
|
+
'data_limit': 1000,
|
|
170
|
+
'include_full_data': False,
|
|
171
|
+
'convert_to_dataframe': False,
|
|
172
|
+
'execution_options': {
|
|
173
|
+
'timeout': 30,
|
|
174
|
+
'explain_analyze': False
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
# Determine if we need query generation
|
|
179
|
+
# ANY component that requires data needs query generation
|
|
180
|
+
data_requiring_components = {
|
|
181
|
+
OutputComponent.DATA_RESULTS,
|
|
182
|
+
OutputComponent.DATAFRAME_OUTPUT,
|
|
183
|
+
OutputComponent.SAMPLE_DATA,
|
|
184
|
+
OutputComponent.SQL_QUERY # Obviously needs query generation
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
# Intent-based configuration
|
|
188
|
+
if intent == QueryIntent.VALIDATE_QUERY:
|
|
189
|
+
config['needs_query_generation'] = False
|
|
190
|
+
config['needs_metadata_discovery'] = False
|
|
191
|
+
|
|
192
|
+
elif intent == QueryIntent.EXPLORE_SCHEMA:
|
|
193
|
+
config['needs_execution'] = False
|
|
194
|
+
config['needs_query_generation'] = False
|
|
195
|
+
|
|
196
|
+
elif intent == QueryIntent.OPTIMIZE_QUERY:
|
|
197
|
+
config['needs_plan_analysis'] = True
|
|
198
|
+
config['execution_options']['explain_analyze'] = True
|
|
199
|
+
|
|
200
|
+
# Component-based configuration
|
|
201
|
+
if OutputComponent.EXECUTION_PLAN in components:
|
|
202
|
+
config['needs_plan_analysis'] = True
|
|
203
|
+
config['execution_options']['explain_analyze'] = True
|
|
204
|
+
|
|
205
|
+
if OutputComponent.DATAFRAME_OUTPUT in components:
|
|
206
|
+
config['convert_to_dataframe'] = True
|
|
207
|
+
|
|
208
|
+
if OutputComponent.DATA_RESULTS not in components:
|
|
209
|
+
config['needs_execution'] = False
|
|
210
|
+
|
|
211
|
+
if any(comp in components for comp in data_requiring_components):
|
|
212
|
+
config['needs_query_generation'] = True
|
|
213
|
+
|
|
214
|
+
# Components that require actual query execution
|
|
215
|
+
execution_requiring_components = {
|
|
216
|
+
OutputComponent.DATA_RESULTS,
|
|
217
|
+
OutputComponent.DATAFRAME_OUTPUT,
|
|
218
|
+
OutputComponent.SAMPLE_DATA,
|
|
219
|
+
OutputComponent.EXECUTION_PLAN,
|
|
220
|
+
OutputComponent.PERFORMANCE_METRICS
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if any(comp in components for comp in execution_requiring_components):
|
|
224
|
+
config['needs_execution'] = True
|
|
225
|
+
|
|
226
|
+
# Intent-specific configuration
|
|
227
|
+
if intent == QueryIntent.SHOW_DATA:
|
|
228
|
+
config['execution_options']['timeout'] = 30
|
|
229
|
+
elif intent == QueryIntent.ANALYZE_DATA:
|
|
230
|
+
config['execution_options']['timeout'] = 60 # More time for complex analysis
|
|
231
|
+
|
|
232
|
+
return config
|
|
233
|
+
|
|
234
|
+
def _apply_role_specific_config(
|
|
235
|
+
self,
|
|
236
|
+
config: Dict[str, Any],
|
|
237
|
+
user_role: UserRole,
|
|
238
|
+
components: OutputComponent
|
|
239
|
+
) -> Dict[str, Any]:
|
|
240
|
+
"""Apply role-specific configuration overrides."""
|
|
241
|
+
|
|
242
|
+
if user_role == UserRole.BUSINESS_USER:
|
|
243
|
+
# Business users want all data, no limits
|
|
244
|
+
config['include_full_data'] = True
|
|
245
|
+
config['data_limit'] = None
|
|
246
|
+
|
|
247
|
+
elif user_role == UserRole.DATA_SCIENTIST:
|
|
248
|
+
# Data scientists get DataFrame output by default
|
|
249
|
+
if OutputComponent.DATAFRAME_OUTPUT in components:
|
|
250
|
+
config['convert_to_dataframe'] = True
|
|
251
|
+
config['data_limit'] = 10000 # Larger limit for analysis
|
|
252
|
+
|
|
253
|
+
elif user_role == UserRole.DATABASE_ADMIN:
|
|
254
|
+
# DBAs get performance analysis
|
|
255
|
+
config['needs_plan_analysis'] = True
|
|
256
|
+
config['execution_options']['explain_analyze'] = True
|
|
257
|
+
config['execution_options']['timeout'] = 60 # Longer timeout
|
|
258
|
+
config['data_limit'] = 100 # Limited data, focus on performance
|
|
259
|
+
|
|
260
|
+
elif user_role == UserRole.DEVELOPER:
|
|
261
|
+
# Developers don't need data execution by default
|
|
262
|
+
if OutputComponent.DATA_RESULTS not in components:
|
|
263
|
+
config['needs_execution'] = False
|
|
264
|
+
|
|
265
|
+
elif user_role == UserRole.DATA_ANALYST:
|
|
266
|
+
# Analysts get balanced configuration
|
|
267
|
+
config['data_limit'] = 5000
|
|
268
|
+
|
|
269
|
+
return config
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from typing import List, Optional, Union
|
|
2
|
+
from querysource.conf import async_default_dsn
|
|
3
|
+
from ...stores.abstract import AbstractStore
|
|
4
|
+
from .abstract import AbstractDBAgent
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SQLAgent(AbstractDBAgent):
|
|
8
|
+
"""SQL Database Agent using LLMs to interact with SQL databases."""
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
name: str = "DBAgent",
|
|
12
|
+
dsn: str = async_default_dsn,
|
|
13
|
+
allowed_schemas: Union[str, List[str]] = "public",
|
|
14
|
+
primary_schema: Optional[str] = None,
|
|
15
|
+
vector_store: Optional[AbstractStore] = None,
|
|
16
|
+
auto_analyze_schema: bool = True,
|
|
17
|
+
client_id: Optional[str] = None, # For per-client agents
|
|
18
|
+
**kwargs
|
|
19
|
+
):
|
|
20
|
+
super().__init__(
|
|
21
|
+
name=name,
|
|
22
|
+
dsn=dsn or async_default_dsn,
|
|
23
|
+
allowed_schemas=allowed_schemas,
|
|
24
|
+
primary_schema=primary_schema,
|
|
25
|
+
vector_store=vector_store,
|
|
26
|
+
auto_analyze_schema=auto_analyze_schema,
|
|
27
|
+
client_id=client_id,
|
|
28
|
+
**kwargs)
|
|
29
|
+
|
|
30
|
+
def _ensure_async_driver(self, dsn: str) -> str:
|
|
31
|
+
# Ensure async driver
|
|
32
|
+
if self.database_type == 'postgresql':
|
|
33
|
+
if '+asyncpg' not in dsn:
|
|
34
|
+
connection_string = dsn.replace(
|
|
35
|
+
'postgresql://', 'postgresql+asyncpg://'
|
|
36
|
+
)
|
|
37
|
+
else:
|
|
38
|
+
connection_string = dsn
|
|
39
|
+
else:
|
|
40
|
+
connection_string = dsn
|
|
41
|
+
return connection_string
|