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,435 @@
|
|
|
1
|
+
"""
|
|
2
|
+
NotificationTool - Send notifications via email, Telegram, Slack, or MS Teams.
|
|
3
|
+
|
|
4
|
+
A unified tool for LLM agents to send notifications through various channels
|
|
5
|
+
using the async-notify library.
|
|
6
|
+
"""
|
|
7
|
+
from typing import Optional, List, Dict, Any, Union
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from enum import Enum
|
|
10
|
+
import mimetypes
|
|
11
|
+
from pydantic import BaseModel, Field
|
|
12
|
+
from notify.models import Actor, Channel, Chat
|
|
13
|
+
from notify.providers.email import Email
|
|
14
|
+
from notify.providers.slack import Slack
|
|
15
|
+
from notify.providers.telegram import Telegram
|
|
16
|
+
from notify.providers.teams import Teams
|
|
17
|
+
from .abstract import AbstractTool
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class NotificationType(str, Enum):
|
|
21
|
+
"""Supported notification types."""
|
|
22
|
+
EMAIL = "email"
|
|
23
|
+
SLACK = "slack"
|
|
24
|
+
TELEGRAM = "telegram"
|
|
25
|
+
TEAMS = "teams"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class FileType(Enum):
|
|
29
|
+
"""File types for smart handling."""
|
|
30
|
+
IMAGE = "image"
|
|
31
|
+
DOCUMENT = "document"
|
|
32
|
+
VIDEO = "video"
|
|
33
|
+
AUDIO = "audio"
|
|
34
|
+
UNKNOWN = "unknown"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class NotificationInput(BaseModel):
|
|
38
|
+
"""Input schema for notification tool."""
|
|
39
|
+
message: str = Field(
|
|
40
|
+
...,
|
|
41
|
+
description="The message content to send"
|
|
42
|
+
)
|
|
43
|
+
type: str = Field(
|
|
44
|
+
...,
|
|
45
|
+
description="Notification type: 'email', 'slack', 'telegram', or 'teams'"
|
|
46
|
+
)
|
|
47
|
+
recipients: str = Field(
|
|
48
|
+
...,
|
|
49
|
+
description=(
|
|
50
|
+
"Recipients for the notification. Format depends on type: "
|
|
51
|
+
"email: 'user@example.com' or comma-separated list; "
|
|
52
|
+
"telegram: chat_id (e.g., '123456789'); "
|
|
53
|
+
"slack: channel_id (e.g., 'C123456') or #channel-name; "
|
|
54
|
+
"teams: user email or channel ID"
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
subject: Optional[str] = Field(
|
|
58
|
+
None,
|
|
59
|
+
description="Subject line (mainly for email notifications)"
|
|
60
|
+
)
|
|
61
|
+
files: Optional[str] = Field(
|
|
62
|
+
None,
|
|
63
|
+
description="Comma-separated list of file paths to attach"
|
|
64
|
+
)
|
|
65
|
+
disable_notification: bool = Field(
|
|
66
|
+
False,
|
|
67
|
+
description="Disable notification sound (Telegram only)"
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class NotificationTool(AbstractTool):
|
|
72
|
+
"""
|
|
73
|
+
Unified notification tool for sending messages through multiple channels.
|
|
74
|
+
|
|
75
|
+
Supports:
|
|
76
|
+
- Email: Send emails with attachments
|
|
77
|
+
- Telegram: Smart file handling (images as photos, docs as documents)
|
|
78
|
+
- Slack: Channel messages
|
|
79
|
+
- MS Teams: Team messages with file references
|
|
80
|
+
|
|
81
|
+
Examples:
|
|
82
|
+
# Email with subject
|
|
83
|
+
send(message="Report ready", type="email",
|
|
84
|
+
recipients="user@example.com", subject="Daily Report")
|
|
85
|
+
|
|
86
|
+
# Telegram with image
|
|
87
|
+
send(message="Check this chart", type="telegram",
|
|
88
|
+
recipients="123456789", files="/path/to/chart.png")
|
|
89
|
+
|
|
90
|
+
# Slack channel
|
|
91
|
+
send(message="Deployment complete", type="slack",
|
|
92
|
+
recipients="C123456")
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
args_schema = NotificationInput
|
|
96
|
+
|
|
97
|
+
def __init__(self, teams_config: Optional[Dict[str, str]] = None):
|
|
98
|
+
"""
|
|
99
|
+
Initialize notification tool.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
teams_config: Optional Teams configuration with keys:
|
|
103
|
+
- tenant_id
|
|
104
|
+
- client_id
|
|
105
|
+
- client_secret
|
|
106
|
+
- username
|
|
107
|
+
- password
|
|
108
|
+
"""
|
|
109
|
+
super().__init__()
|
|
110
|
+
self.name = "send_notification"
|
|
111
|
+
self.description = (
|
|
112
|
+
"Send notifications to users via email, Telegram, Slack, or MS Teams. "
|
|
113
|
+
"Supports file attachments with smart handling (images sent as photos "
|
|
114
|
+
"in Telegram, documents as files, etc.)"
|
|
115
|
+
)
|
|
116
|
+
self.teams_config = teams_config or {}
|
|
117
|
+
|
|
118
|
+
def _classify_file(self, file_path: Path) -> FileType:
|
|
119
|
+
"""Classify file type based on extension and MIME type."""
|
|
120
|
+
if not file_path.exists():
|
|
121
|
+
return FileType.UNKNOWN
|
|
122
|
+
|
|
123
|
+
mime_type, _ = mimetypes.guess_type(str(file_path))
|
|
124
|
+
|
|
125
|
+
if mime_type:
|
|
126
|
+
if mime_type.startswith('image/'):
|
|
127
|
+
return FileType.IMAGE
|
|
128
|
+
elif mime_type.startswith('video/'):
|
|
129
|
+
return FileType.VIDEO
|
|
130
|
+
elif mime_type.startswith('audio/'):
|
|
131
|
+
return FileType.AUDIO
|
|
132
|
+
|
|
133
|
+
ext = file_path.suffix.lower()
|
|
134
|
+
image_extensions = {'.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.svg'}
|
|
135
|
+
video_extensions = {'.mp4', '.avi', '.mov', '.wmv', '.flv', '.webm', '.mkv'}
|
|
136
|
+
audio_extensions = {'.mp3', '.wav', '.ogg', '.m4a', '.flac', '.aac'}
|
|
137
|
+
|
|
138
|
+
if ext in image_extensions:
|
|
139
|
+
return FileType.IMAGE
|
|
140
|
+
elif ext in video_extensions:
|
|
141
|
+
return FileType.VIDEO
|
|
142
|
+
elif ext in audio_extensions:
|
|
143
|
+
return FileType.AUDIO
|
|
144
|
+
else:
|
|
145
|
+
return FileType.DOCUMENT
|
|
146
|
+
|
|
147
|
+
def _categorize_files(self, files: List[Path]) -> Dict[FileType, List[Path]]:
|
|
148
|
+
"""Categorize files by type."""
|
|
149
|
+
categorized = {
|
|
150
|
+
FileType.IMAGE: [],
|
|
151
|
+
FileType.DOCUMENT: [],
|
|
152
|
+
FileType.VIDEO: [],
|
|
153
|
+
FileType.AUDIO: []
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
for file in files:
|
|
157
|
+
file_type = self._classify_file(file)
|
|
158
|
+
if file_type != FileType.UNKNOWN:
|
|
159
|
+
categorized[file_type].append(file)
|
|
160
|
+
|
|
161
|
+
return categorized
|
|
162
|
+
|
|
163
|
+
def _parse_recipients(
|
|
164
|
+
self,
|
|
165
|
+
recipients_str: str,
|
|
166
|
+
notification_type: NotificationType
|
|
167
|
+
) -> Union[Actor, List[Actor], Channel, Chat]:
|
|
168
|
+
"""Parse recipient string into appropriate format."""
|
|
169
|
+
recipients_str = recipients_str.strip()
|
|
170
|
+
|
|
171
|
+
# Email: support comma-separated
|
|
172
|
+
if notification_type == NotificationType.EMAIL:
|
|
173
|
+
if ',' not in recipients_str:
|
|
174
|
+
return Actor(
|
|
175
|
+
name=recipients_str.split('@')[0],
|
|
176
|
+
account={"address": recipients_str}
|
|
177
|
+
)
|
|
178
|
+
emails = [email.strip() for email in recipients_str.split(',')]
|
|
179
|
+
return [
|
|
180
|
+
Actor(
|
|
181
|
+
name=email.split('@')[0],
|
|
182
|
+
account={"address": email}
|
|
183
|
+
)
|
|
184
|
+
for email in emails if '@' in email
|
|
185
|
+
]
|
|
186
|
+
|
|
187
|
+
# Telegram: chat_id
|
|
188
|
+
elif notification_type == NotificationType.TELEGRAM:
|
|
189
|
+
return Chat(chat_id=recipients_str)
|
|
190
|
+
|
|
191
|
+
# Slack: channel_id or #channel-name
|
|
192
|
+
elif notification_type == NotificationType.SLACK:
|
|
193
|
+
channel_name = recipients_str.lstrip('#')
|
|
194
|
+
return Channel(
|
|
195
|
+
channel_id=None if recipients_str.startswith('#') else recipients_str,
|
|
196
|
+
channel_name=channel_name
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
# Teams: email or channel
|
|
200
|
+
elif notification_type == NotificationType.TEAMS:
|
|
201
|
+
if '@' in recipients_str:
|
|
202
|
+
return Actor(
|
|
203
|
+
name=recipients_str.split('@')[0],
|
|
204
|
+
account={"address": recipients_str}
|
|
205
|
+
)
|
|
206
|
+
return Channel(channel_id=recipients_str)
|
|
207
|
+
|
|
208
|
+
return recipients_str
|
|
209
|
+
|
|
210
|
+
def _parse_files(self, files_str: Optional[str]) -> List[Path]:
|
|
211
|
+
"""Parse comma-separated file paths into Path objects."""
|
|
212
|
+
if not files_str:
|
|
213
|
+
return []
|
|
214
|
+
|
|
215
|
+
file_paths = [
|
|
216
|
+
Path(f.strip())
|
|
217
|
+
for f in files_str.split(',')
|
|
218
|
+
if f.strip()
|
|
219
|
+
]
|
|
220
|
+
|
|
221
|
+
# Filter to existing files
|
|
222
|
+
valid_files = [f for f in file_paths if f.exists()]
|
|
223
|
+
|
|
224
|
+
if len(valid_files) < len(file_paths):
|
|
225
|
+
missing = [str(f) for f in file_paths if not f.exists()]
|
|
226
|
+
self.logger.warning(f"Some files not found: {missing}")
|
|
227
|
+
|
|
228
|
+
return valid_files
|
|
229
|
+
|
|
230
|
+
async def _execute(self, **kwargs) -> str:
|
|
231
|
+
"""
|
|
232
|
+
Execute notification sending.
|
|
233
|
+
|
|
234
|
+
Args:
|
|
235
|
+
**kwargs: Contains message, type, recipients, subject, files, etc.
|
|
236
|
+
|
|
237
|
+
Returns:
|
|
238
|
+
Status message with delivery information
|
|
239
|
+
"""
|
|
240
|
+
try:
|
|
241
|
+
# Extract parameters
|
|
242
|
+
message = kwargs.get('message')
|
|
243
|
+
notification_type = NotificationType(kwargs.get('type').lower())
|
|
244
|
+
recipients_str = kwargs.get('recipients')
|
|
245
|
+
subject = kwargs.get('subject')
|
|
246
|
+
files_str = kwargs.get('files')
|
|
247
|
+
disable_notification = kwargs.get('disable_notification', False)
|
|
248
|
+
|
|
249
|
+
# Parse recipients
|
|
250
|
+
recipients = self._parse_recipients(recipients_str, notification_type)
|
|
251
|
+
|
|
252
|
+
# Parse files
|
|
253
|
+
files = self._parse_files(files_str)
|
|
254
|
+
|
|
255
|
+
# Route to appropriate provider
|
|
256
|
+
if notification_type == NotificationType.EMAIL:
|
|
257
|
+
result = await self._send_email(
|
|
258
|
+
message=message,
|
|
259
|
+
recipients=recipients,
|
|
260
|
+
subject=subject,
|
|
261
|
+
files=files
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
elif notification_type == NotificationType.SLACK:
|
|
265
|
+
result = await self._send_slack(
|
|
266
|
+
message=message,
|
|
267
|
+
recipients=recipients
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
elif notification_type == NotificationType.TELEGRAM:
|
|
271
|
+
result = await self._send_telegram(
|
|
272
|
+
message=message,
|
|
273
|
+
recipients=recipients,
|
|
274
|
+
files=files,
|
|
275
|
+
disable_notification=disable_notification
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
elif notification_type == NotificationType.TEAMS:
|
|
279
|
+
result = await self._send_teams(
|
|
280
|
+
message=message,
|
|
281
|
+
recipients=recipients,
|
|
282
|
+
files=files
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
else:
|
|
286
|
+
return f"❌ Unsupported notification type: {notification_type}"
|
|
287
|
+
|
|
288
|
+
# Format success message
|
|
289
|
+
recipient_count = len(recipients) if isinstance(recipients, list) else 1
|
|
290
|
+
file_info = f" with {len(files)} file(s)" if files else ""
|
|
291
|
+
|
|
292
|
+
return (
|
|
293
|
+
f"✅ Notification sent via {notification_type.value}\n"
|
|
294
|
+
f"Recipients: {recipient_count}\n"
|
|
295
|
+
f"Files: {len(files) if files else 0}{file_info}\n"
|
|
296
|
+
f"Status: {result.get('status', 'sent')}"
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
except Exception as e:
|
|
300
|
+
self.logger.error(f"Notification failed: {e}", exc_info=True)
|
|
301
|
+
return f"❌ Failed to send notification: {str(e)}"
|
|
302
|
+
|
|
303
|
+
async def _send_email(
|
|
304
|
+
self,
|
|
305
|
+
message: str,
|
|
306
|
+
recipients: Union[Actor, List[Actor]],
|
|
307
|
+
subject: Optional[str],
|
|
308
|
+
files: List[Path]
|
|
309
|
+
) -> Dict[str, Any]:
|
|
310
|
+
"""Send email with attachments."""
|
|
311
|
+
email = Email()
|
|
312
|
+
async with email as conn:
|
|
313
|
+
result = await conn.send(
|
|
314
|
+
message=message,
|
|
315
|
+
recipient=recipients,
|
|
316
|
+
subject=subject or "Notification",
|
|
317
|
+
attachments=files or None
|
|
318
|
+
)
|
|
319
|
+
return {"status": "sent", "result": result}
|
|
320
|
+
|
|
321
|
+
async def _send_slack(
|
|
322
|
+
self,
|
|
323
|
+
message: str,
|
|
324
|
+
recipients: Channel
|
|
325
|
+
) -> Dict[str, Any]:
|
|
326
|
+
"""Send Slack message."""
|
|
327
|
+
slack = Slack()
|
|
328
|
+
async with slack as conn:
|
|
329
|
+
result = await conn.send(
|
|
330
|
+
message=message,
|
|
331
|
+
recipient=recipients
|
|
332
|
+
)
|
|
333
|
+
return {"status": "sent", "result": result}
|
|
334
|
+
|
|
335
|
+
async def _send_telegram(
|
|
336
|
+
self,
|
|
337
|
+
message: str,
|
|
338
|
+
recipients: Chat,
|
|
339
|
+
files: List[Path],
|
|
340
|
+
disable_notification: bool
|
|
341
|
+
) -> Dict[str, Any]:
|
|
342
|
+
"""Send Telegram message with smart file handling."""
|
|
343
|
+
telegram = Telegram()
|
|
344
|
+
results = []
|
|
345
|
+
|
|
346
|
+
async with telegram as conn:
|
|
347
|
+
if files:
|
|
348
|
+
# Categorize files for smart sending
|
|
349
|
+
categorized = self._categorize_files(files)
|
|
350
|
+
|
|
351
|
+
# Send images as photos
|
|
352
|
+
for image in categorized[FileType.IMAGE]:
|
|
353
|
+
try:
|
|
354
|
+
result = await conn.send_photo(
|
|
355
|
+
photo=image,
|
|
356
|
+
caption=message[:1024],
|
|
357
|
+
disable_notification=disable_notification
|
|
358
|
+
)
|
|
359
|
+
results.append({"type": "photo", "file": image.name})
|
|
360
|
+
except Exception as e:
|
|
361
|
+
self.logger.error(f"Failed to send image {image}: {e}")
|
|
362
|
+
|
|
363
|
+
# Send videos
|
|
364
|
+
for video in categorized[FileType.VIDEO]:
|
|
365
|
+
try:
|
|
366
|
+
result = await conn.send_video(
|
|
367
|
+
video=video,
|
|
368
|
+
caption=message[:1024],
|
|
369
|
+
disable_notification=disable_notification
|
|
370
|
+
)
|
|
371
|
+
results.append({"type": "video", "file": video.name})
|
|
372
|
+
except Exception as e:
|
|
373
|
+
self.logger.error(f"Failed to send video {video}: {e}")
|
|
374
|
+
|
|
375
|
+
# Send audio
|
|
376
|
+
for audio in categorized[FileType.AUDIO]:
|
|
377
|
+
try:
|
|
378
|
+
result = await conn.send_audio(
|
|
379
|
+
audio=audio,
|
|
380
|
+
caption=message[:1024],
|
|
381
|
+
disable_notification=disable_notification
|
|
382
|
+
)
|
|
383
|
+
results.append({"type": "audio", "file": audio.name})
|
|
384
|
+
except Exception as e:
|
|
385
|
+
self.logger.error(f"Failed to send audio {audio}: {e}")
|
|
386
|
+
|
|
387
|
+
# Send documents
|
|
388
|
+
for doc in categorized[FileType.DOCUMENT]:
|
|
389
|
+
try:
|
|
390
|
+
result = await conn.send_document(
|
|
391
|
+
document=doc,
|
|
392
|
+
caption=message[:1024],
|
|
393
|
+
disable_notification=disable_notification
|
|
394
|
+
)
|
|
395
|
+
results.append({"type": "document", "file": doc.name})
|
|
396
|
+
except Exception as e:
|
|
397
|
+
self.logger.error(f"Failed to send document {doc}: {e}")
|
|
398
|
+
|
|
399
|
+
# Send text if no captions were used
|
|
400
|
+
if not any(categorized.values()):
|
|
401
|
+
result = await conn.send(message=message, recipient=recipients)
|
|
402
|
+
results.append({"type": "text"})
|
|
403
|
+
else:
|
|
404
|
+
# No files, just text
|
|
405
|
+
result = await conn.send(message=message, recipient=recipients)
|
|
406
|
+
results.append({"type": "text"})
|
|
407
|
+
|
|
408
|
+
return {"status": "sent", "results": results}
|
|
409
|
+
|
|
410
|
+
async def _send_teams(
|
|
411
|
+
self,
|
|
412
|
+
message: str,
|
|
413
|
+
recipients: Union[Actor, Channel],
|
|
414
|
+
files: List[Path]
|
|
415
|
+
) -> Dict[str, Any]:
|
|
416
|
+
"""Send MS Teams message."""
|
|
417
|
+
teams = Teams(
|
|
418
|
+
as_user=True,
|
|
419
|
+
**self.teams_config
|
|
420
|
+
)
|
|
421
|
+
|
|
422
|
+
# Add file references to message
|
|
423
|
+
if files:
|
|
424
|
+
file_list = "\n".join([f"- {f.name}" for f in files])
|
|
425
|
+
enhanced_message = f"{message}\n\n**Attached Files:**\n{file_list}"
|
|
426
|
+
else:
|
|
427
|
+
enhanced_message = message
|
|
428
|
+
|
|
429
|
+
async with teams as conn:
|
|
430
|
+
result = await conn.send(
|
|
431
|
+
message=enhanced_message,
|
|
432
|
+
recipient=recipients
|
|
433
|
+
)
|
|
434
|
+
|
|
435
|
+
return {"status": "sent", "result": result}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Office 365 Tools and Toolkit integration.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from .mail import (
|
|
6
|
+
CreateDraftMessageTool,
|
|
7
|
+
SearchEmailTool,
|
|
8
|
+
SendEmailTool,
|
|
9
|
+
GetMessageTool,
|
|
10
|
+
ListMessagesTool,
|
|
11
|
+
DownloadAttachmentTool,
|
|
12
|
+
)
|
|
13
|
+
from .events import (
|
|
14
|
+
CreateEventTool,
|
|
15
|
+
UpdateEventTool,
|
|
16
|
+
GetEventTool,
|
|
17
|
+
ListEventsTool,
|
|
18
|
+
)
|
|
19
|
+
from .onedrive import (
|
|
20
|
+
ListOneDriveFilesTool,
|
|
21
|
+
SearchOneDriveFilesTool,
|
|
22
|
+
DownloadOneDriveFileTool,
|
|
23
|
+
UploadOneDriveFileTool
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
__all__ = (
|
|
28
|
+
"CreateDraftMessageTool",
|
|
29
|
+
"SearchEmailTool",
|
|
30
|
+
"SendEmailTool",
|
|
31
|
+
"GetMessageTool",
|
|
32
|
+
"ListMessagesTool",
|
|
33
|
+
"DownloadAttachmentTool",
|
|
34
|
+
"CreateEventTool",
|
|
35
|
+
"UpdateEventTool",
|
|
36
|
+
"GetEventTool",
|
|
37
|
+
"ListEventsTool",
|
|
38
|
+
"ListOneDriveFilesTool",
|
|
39
|
+
"SearchOneDriveFilesTool",
|
|
40
|
+
"DownloadOneDriveFileTool",
|
|
41
|
+
"UploadOneDriveFileTool",
|
|
42
|
+
)
|