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,641 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SharePoint Tools for AI-Parrot.
|
|
3
|
+
|
|
4
|
+
Tools for interacting with SharePoint document libraries:
|
|
5
|
+
- List files in folders
|
|
6
|
+
- Search for files
|
|
7
|
+
- Download files
|
|
8
|
+
- Upload files
|
|
9
|
+
"""
|
|
10
|
+
from typing import Dict, Any, Optional, List, Type
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from pydantic import BaseModel, Field
|
|
13
|
+
|
|
14
|
+
from .base import O365Tool, O365ToolArgsSchema
|
|
15
|
+
from ...interfaces.sharepoint import SharepointClient
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# ============================================================================
|
|
19
|
+
# LIST SHAREPOINT FILES TOOL
|
|
20
|
+
# ============================================================================
|
|
21
|
+
|
|
22
|
+
class ListSharePointFilesArgs(O365ToolArgsSchema):
|
|
23
|
+
"""Arguments for listing SharePoint files."""
|
|
24
|
+
site: str = Field(
|
|
25
|
+
description="SharePoint site name (e.g., 'TeamSite', 'ProjectSite')"
|
|
26
|
+
)
|
|
27
|
+
library: Optional[str] = Field(
|
|
28
|
+
default="Documents",
|
|
29
|
+
description="Document library name (default: 'Documents')"
|
|
30
|
+
)
|
|
31
|
+
folder_path: Optional[str] = Field(
|
|
32
|
+
default="",
|
|
33
|
+
description="Folder path within the library (e.g., 'Project/Reports'). Empty for library root."
|
|
34
|
+
)
|
|
35
|
+
recursive: bool = Field(
|
|
36
|
+
default=False,
|
|
37
|
+
description="Whether to list files recursively in subfolders"
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class ListSharePointFilesTool(O365Tool):
|
|
42
|
+
"""
|
|
43
|
+
Tool for listing files in SharePoint document libraries.
|
|
44
|
+
|
|
45
|
+
This tool lists all files in a specified SharePoint location, with options
|
|
46
|
+
for recursive listing and filtering by file type.
|
|
47
|
+
|
|
48
|
+
Examples:
|
|
49
|
+
# List files in root of Documents library
|
|
50
|
+
result = await tool.run(
|
|
51
|
+
site="TeamSite",
|
|
52
|
+
library="Documents"
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# List files in specific folder
|
|
56
|
+
result = await tool.run(
|
|
57
|
+
site="ProjectSite",
|
|
58
|
+
library="Documents",
|
|
59
|
+
folder_path="Reports/2025"
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# Recursive listing
|
|
63
|
+
result = await tool.run(
|
|
64
|
+
site="TeamSite",
|
|
65
|
+
folder_path="Project Management",
|
|
66
|
+
recursive=True
|
|
67
|
+
)
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
name: str = "list_sharepoint_files"
|
|
71
|
+
description: str = (
|
|
72
|
+
"List files in a SharePoint document library or folder. "
|
|
73
|
+
"Returns file names, paths, sizes, and modification dates."
|
|
74
|
+
)
|
|
75
|
+
args_schema: Type[BaseModel] = ListSharePointFilesArgs
|
|
76
|
+
|
|
77
|
+
async def _execute_graph_operation(
|
|
78
|
+
self,
|
|
79
|
+
client: SharepointClient,
|
|
80
|
+
**kwargs
|
|
81
|
+
) -> Dict[str, Any]:
|
|
82
|
+
"""
|
|
83
|
+
List SharePoint files using the SharepointClient.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
client: Authenticated SharepointClient instance
|
|
87
|
+
**kwargs: Tool parameters
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
Dict with file listing
|
|
91
|
+
"""
|
|
92
|
+
site = kwargs.get('site')
|
|
93
|
+
library = kwargs.get('library', 'Documents')
|
|
94
|
+
folder_path = kwargs.get('folder_path', '')
|
|
95
|
+
recursive = kwargs.get('recursive', False)
|
|
96
|
+
|
|
97
|
+
try:
|
|
98
|
+
# Configure client
|
|
99
|
+
client.site = site
|
|
100
|
+
client.credentials['tenant'] = site
|
|
101
|
+
|
|
102
|
+
# Build full path
|
|
103
|
+
full_path = f"{library}/{folder_path}".strip('/') if folder_path else library
|
|
104
|
+
|
|
105
|
+
self.logger.info(f"Listing files in: {site}/{full_path}")
|
|
106
|
+
|
|
107
|
+
# Resolve site and drive
|
|
108
|
+
await client.verify_sharepoint_access()
|
|
109
|
+
drive_info = await client._resolve_drive(library)
|
|
110
|
+
|
|
111
|
+
# Get folder contents
|
|
112
|
+
if folder_path:
|
|
113
|
+
folder_item = await client.graph_client.drives.by_drive_id(drive_info.id)\
|
|
114
|
+
.items.by_drive_item_id(f"root:/{folder_path}:").get()
|
|
115
|
+
else:
|
|
116
|
+
folder_item = await client.graph_client.drives.by_drive_id(drive_info.id).root.get()
|
|
117
|
+
|
|
118
|
+
files = []
|
|
119
|
+
|
|
120
|
+
if recursive:
|
|
121
|
+
# Recursive listing
|
|
122
|
+
files = await self._list_recursive(
|
|
123
|
+
client,
|
|
124
|
+
drive_info.id,
|
|
125
|
+
folder_item.id,
|
|
126
|
+
folder_path
|
|
127
|
+
)
|
|
128
|
+
else:
|
|
129
|
+
# Single level listing
|
|
130
|
+
children = await client.graph_client.drives.by_drive_id(drive_info.id)\
|
|
131
|
+
.items.by_drive_item_id(folder_item.id).children.get()
|
|
132
|
+
|
|
133
|
+
if children and children.value:
|
|
134
|
+
for item in children.value:
|
|
135
|
+
file_info = {
|
|
136
|
+
"name": item.name,
|
|
137
|
+
"path": f"{folder_path}/{item.name}".strip('/'),
|
|
138
|
+
"is_folder": item.folder is not None,
|
|
139
|
+
"size": item.size or 0,
|
|
140
|
+
"modified": item.last_modified_date_time.isoformat() if item.last_modified_date_time else None,
|
|
141
|
+
"web_url": item.web_url,
|
|
142
|
+
"id": item.id
|
|
143
|
+
}
|
|
144
|
+
files.append(file_info)
|
|
145
|
+
|
|
146
|
+
self.logger.info(f"Found {len(files)} items")
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
"site": site,
|
|
150
|
+
"library": library,
|
|
151
|
+
"folder_path": folder_path,
|
|
152
|
+
"total_items": len(files),
|
|
153
|
+
"files": files,
|
|
154
|
+
"recursive": recursive
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
except Exception as e:
|
|
158
|
+
self.logger.error(f"Failed to list SharePoint files: {e}")
|
|
159
|
+
raise
|
|
160
|
+
|
|
161
|
+
async def _list_recursive(
|
|
162
|
+
self,
|
|
163
|
+
client: SharepointClient,
|
|
164
|
+
drive_id: str,
|
|
165
|
+
folder_id: str,
|
|
166
|
+
base_path: str
|
|
167
|
+
) -> List[Dict[str, Any]]:
|
|
168
|
+
"""Recursively list all files in a folder."""
|
|
169
|
+
files = []
|
|
170
|
+
|
|
171
|
+
children = await client.graph_client.drives.by_drive_id(drive_id)\
|
|
172
|
+
.items.by_drive_item_id(folder_id).children.get()
|
|
173
|
+
|
|
174
|
+
if children and children.value:
|
|
175
|
+
for item in children.value:
|
|
176
|
+
item_path = f"{base_path}/{item.name}".strip('/')
|
|
177
|
+
|
|
178
|
+
file_info = {
|
|
179
|
+
"name": item.name,
|
|
180
|
+
"path": item_path,
|
|
181
|
+
"is_folder": item.folder is not None,
|
|
182
|
+
"size": item.size or 0,
|
|
183
|
+
"modified": item.last_modified_date_time.isoformat() if item.last_modified_date_time else None,
|
|
184
|
+
"web_url": item.web_url,
|
|
185
|
+
"id": item.id
|
|
186
|
+
}
|
|
187
|
+
files.append(file_info)
|
|
188
|
+
|
|
189
|
+
# Recurse into folders
|
|
190
|
+
if item.folder:
|
|
191
|
+
subfolder_files = await self._list_recursive(
|
|
192
|
+
client,
|
|
193
|
+
drive_id,
|
|
194
|
+
item.id,
|
|
195
|
+
item_path
|
|
196
|
+
)
|
|
197
|
+
files.extend(subfolder_files)
|
|
198
|
+
|
|
199
|
+
return files
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
# ============================================================================
|
|
203
|
+
# SEARCH SHAREPOINT FILES TOOL
|
|
204
|
+
# ============================================================================
|
|
205
|
+
|
|
206
|
+
class SearchSharePointFilesArgs(O365ToolArgsSchema):
|
|
207
|
+
"""Arguments for searching SharePoint files."""
|
|
208
|
+
site: str = Field(
|
|
209
|
+
description="SharePoint site name"
|
|
210
|
+
)
|
|
211
|
+
query: str = Field(
|
|
212
|
+
description="Search query (filename or content search)"
|
|
213
|
+
)
|
|
214
|
+
library: Optional[str] = Field(
|
|
215
|
+
default="Documents",
|
|
216
|
+
description="Document library to search in"
|
|
217
|
+
)
|
|
218
|
+
folder_path: Optional[str] = Field(
|
|
219
|
+
default="",
|
|
220
|
+
description="Limit search to specific folder path"
|
|
221
|
+
)
|
|
222
|
+
file_extension: Optional[str] = Field(
|
|
223
|
+
default=None,
|
|
224
|
+
description="Filter by file extension (e.g., 'pdf', 'docx')"
|
|
225
|
+
)
|
|
226
|
+
max_results: int = Field(
|
|
227
|
+
default=20,
|
|
228
|
+
description="Maximum number of results to return (1-100)"
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
class SearchSharePointFilesTool(O365Tool):
|
|
233
|
+
"""
|
|
234
|
+
Tool for searching files in SharePoint.
|
|
235
|
+
|
|
236
|
+
This tool searches for files in SharePoint by name, content, or metadata.
|
|
237
|
+
Supports filtering by file type and location.
|
|
238
|
+
|
|
239
|
+
Examples:
|
|
240
|
+
# Search by filename
|
|
241
|
+
result = await tool.run(
|
|
242
|
+
site="TeamSite",
|
|
243
|
+
query="quarterly report"
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
# Search for PDFs only
|
|
247
|
+
result = await tool.run(
|
|
248
|
+
site="ProjectSite",
|
|
249
|
+
query="invoice",
|
|
250
|
+
file_extension="pdf"
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
# Search in specific folder
|
|
254
|
+
result = await tool.run(
|
|
255
|
+
site="TeamSite",
|
|
256
|
+
query="meeting notes",
|
|
257
|
+
folder_path="Project/Meetings"
|
|
258
|
+
)
|
|
259
|
+
"""
|
|
260
|
+
|
|
261
|
+
name: str = "search_sharepoint_files"
|
|
262
|
+
description: str = (
|
|
263
|
+
"Search for files in SharePoint by name or content. "
|
|
264
|
+
"Supports filtering by file type and location."
|
|
265
|
+
)
|
|
266
|
+
args_schema: Type[BaseModel] = SearchSharePointFilesArgs
|
|
267
|
+
|
|
268
|
+
async def _execute_graph_operation(
|
|
269
|
+
self,
|
|
270
|
+
client: SharepointClient,
|
|
271
|
+
**kwargs
|
|
272
|
+
) -> Dict[str, Any]:
|
|
273
|
+
"""
|
|
274
|
+
Search SharePoint files using the SharepointClient.
|
|
275
|
+
|
|
276
|
+
Args:
|
|
277
|
+
client: Authenticated SharepointClient instance
|
|
278
|
+
**kwargs: Tool parameters
|
|
279
|
+
|
|
280
|
+
Returns:
|
|
281
|
+
Dict with search results
|
|
282
|
+
"""
|
|
283
|
+
site = kwargs.get('site')
|
|
284
|
+
query = kwargs.get('query')
|
|
285
|
+
library = kwargs.get('library', 'Documents')
|
|
286
|
+
folder_path = kwargs.get('folder_path', '')
|
|
287
|
+
file_extension = kwargs.get('file_extension')
|
|
288
|
+
max_results = min(kwargs.get('max_results', 20), 100)
|
|
289
|
+
|
|
290
|
+
try:
|
|
291
|
+
# Configure client
|
|
292
|
+
client.site = site
|
|
293
|
+
client.credentials['tenant'] = site
|
|
294
|
+
|
|
295
|
+
self.logger.info(f"Searching SharePoint for: {query}")
|
|
296
|
+
|
|
297
|
+
# Configure search spec
|
|
298
|
+
client._srcfiles = [{
|
|
299
|
+
'directory': f"{library}/{folder_path}".strip('/'),
|
|
300
|
+
'pattern': query,
|
|
301
|
+
'extension': file_extension
|
|
302
|
+
}]
|
|
303
|
+
|
|
304
|
+
# Verify access and perform search
|
|
305
|
+
await client.verify_sharepoint_access()
|
|
306
|
+
search_results = await client.file_search()
|
|
307
|
+
|
|
308
|
+
# Limit results
|
|
309
|
+
if len(search_results) > max_results:
|
|
310
|
+
search_results = search_results[:max_results]
|
|
311
|
+
|
|
312
|
+
# Format results
|
|
313
|
+
files = []
|
|
314
|
+
for result in search_results:
|
|
315
|
+
if item := result.get('item'):
|
|
316
|
+
file_info = {
|
|
317
|
+
"name": item.name,
|
|
318
|
+
"path": result.get('path', ''),
|
|
319
|
+
"size": item.size or 0,
|
|
320
|
+
"modified": item.last_modified_date_time.isoformat() if item.last_modified_date_time else None,
|
|
321
|
+
"web_url": item.web_url,
|
|
322
|
+
"id": item.id
|
|
323
|
+
}
|
|
324
|
+
files.append(file_info)
|
|
325
|
+
|
|
326
|
+
self.logger.info(f"Found {len(files)} matching files")
|
|
327
|
+
|
|
328
|
+
return {
|
|
329
|
+
"site": site,
|
|
330
|
+
"query": query,
|
|
331
|
+
"library": library,
|
|
332
|
+
"folder_path": folder_path,
|
|
333
|
+
"file_extension": file_extension,
|
|
334
|
+
"total_results": len(files),
|
|
335
|
+
"files": files
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
except Exception as e:
|
|
339
|
+
self.logger.error(f"Failed to search SharePoint: {e}")
|
|
340
|
+
raise
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
# ============================================================================
|
|
344
|
+
# DOWNLOAD SHAREPOINT FILE TOOL
|
|
345
|
+
# ============================================================================
|
|
346
|
+
|
|
347
|
+
class DownloadSharePointFileArgs(O365ToolArgsSchema):
|
|
348
|
+
"""Arguments for downloading SharePoint files."""
|
|
349
|
+
site: str = Field(
|
|
350
|
+
description="SharePoint site name"
|
|
351
|
+
)
|
|
352
|
+
library: str = Field(
|
|
353
|
+
default="Documents",
|
|
354
|
+
description="Document library name"
|
|
355
|
+
)
|
|
356
|
+
file_path: str = Field(
|
|
357
|
+
description="Path to file within library (e.g., 'Reports/Q4_Report.pdf')"
|
|
358
|
+
)
|
|
359
|
+
local_destination: Optional[str] = Field(
|
|
360
|
+
default=None,
|
|
361
|
+
description="Local path to save file. If not provided, saves to current directory."
|
|
362
|
+
)
|
|
363
|
+
rename_as: Optional[str] = Field(
|
|
364
|
+
default=None,
|
|
365
|
+
description="Rename file when downloading"
|
|
366
|
+
)
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
class DownloadSharePointFileTool(O365Tool):
|
|
370
|
+
"""
|
|
371
|
+
Tool for downloading files from SharePoint.
|
|
372
|
+
|
|
373
|
+
This tool downloads a specific file from SharePoint to the local filesystem.
|
|
374
|
+
|
|
375
|
+
Examples:
|
|
376
|
+
# Download to current directory
|
|
377
|
+
result = await tool.run(
|
|
378
|
+
site="TeamSite",
|
|
379
|
+
library="Documents",
|
|
380
|
+
file_path="Reports/Q4_Report.pdf"
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
# Download and rename
|
|
384
|
+
result = await tool.run(
|
|
385
|
+
site="ProjectSite",
|
|
386
|
+
file_path="Contracts/Agreement.docx",
|
|
387
|
+
rename_as="Client_Agreement.docx"
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
# Download to specific location
|
|
391
|
+
result = await tool.run(
|
|
392
|
+
site="TeamSite",
|
|
393
|
+
file_path="Data/export.xlsx",
|
|
394
|
+
local_destination="/tmp/downloads"
|
|
395
|
+
)
|
|
396
|
+
"""
|
|
397
|
+
|
|
398
|
+
name: str = "download_sharepoint_file"
|
|
399
|
+
description: str = (
|
|
400
|
+
"Download a file from SharePoint to local storage. "
|
|
401
|
+
"Supports renaming and custom destination paths."
|
|
402
|
+
)
|
|
403
|
+
args_schema: Type[BaseModel] = DownloadSharePointFileArgs
|
|
404
|
+
|
|
405
|
+
async def _execute_graph_operation(
|
|
406
|
+
self,
|
|
407
|
+
client: SharepointClient,
|
|
408
|
+
**kwargs
|
|
409
|
+
) -> Dict[str, Any]:
|
|
410
|
+
"""
|
|
411
|
+
Download SharePoint file using the SharepointClient.
|
|
412
|
+
|
|
413
|
+
Args:
|
|
414
|
+
client: Authenticated SharepointClient instance
|
|
415
|
+
**kwargs: Tool parameters
|
|
416
|
+
|
|
417
|
+
Returns:
|
|
418
|
+
Dict with download details
|
|
419
|
+
"""
|
|
420
|
+
site = kwargs.get('site')
|
|
421
|
+
library = kwargs.get('library', 'Documents')
|
|
422
|
+
file_path = kwargs.get('file_path')
|
|
423
|
+
local_destination = kwargs.get('local_destination')
|
|
424
|
+
rename_as = kwargs.get('rename_as')
|
|
425
|
+
|
|
426
|
+
try:
|
|
427
|
+
# Configure client
|
|
428
|
+
client.site = site
|
|
429
|
+
client.credentials['tenant'] = site
|
|
430
|
+
|
|
431
|
+
# Parse file path
|
|
432
|
+
path_parts = file_path.rsplit('/', 1)
|
|
433
|
+
if len(path_parts) == 2:
|
|
434
|
+
folder_path, filename = path_parts
|
|
435
|
+
else:
|
|
436
|
+
folder_path = ""
|
|
437
|
+
filename = file_path
|
|
438
|
+
|
|
439
|
+
full_directory = f"{library}/{folder_path}".strip('/')
|
|
440
|
+
|
|
441
|
+
self.logger.info(f"Downloading: {site}/{full_directory}/{filename}")
|
|
442
|
+
|
|
443
|
+
# Set up download destination
|
|
444
|
+
dest_dir = Path(local_destination) if local_destination else Path.cwd()
|
|
445
|
+
|
|
446
|
+
dest_dir.mkdir(parents=True, exist_ok=True)
|
|
447
|
+
client.directory = str(dest_dir)
|
|
448
|
+
|
|
449
|
+
# Configure file lookup
|
|
450
|
+
client._srcfiles = [{
|
|
451
|
+
'directory': full_directory,
|
|
452
|
+
'filename': filename
|
|
453
|
+
}]
|
|
454
|
+
|
|
455
|
+
# Set rename if requested
|
|
456
|
+
if rename_as:
|
|
457
|
+
client._filenames = [rename_as]
|
|
458
|
+
|
|
459
|
+
# Verify access
|
|
460
|
+
await client.verify_sharepoint_access()
|
|
461
|
+
|
|
462
|
+
# Find file
|
|
463
|
+
found_files = await client.file_lookup()
|
|
464
|
+
|
|
465
|
+
if not found_files:
|
|
466
|
+
raise FileNotFoundError(f"File not found: {file_path}")
|
|
467
|
+
|
|
468
|
+
# Download files
|
|
469
|
+
downloaded = await client.download_found_files(found_files)
|
|
470
|
+
|
|
471
|
+
if not downloaded:
|
|
472
|
+
raise RuntimeError("Download failed")
|
|
473
|
+
|
|
474
|
+
download_info = downloaded[0]
|
|
475
|
+
local_path = download_info['filename']
|
|
476
|
+
|
|
477
|
+
self.logger.info(f"Downloaded to: {local_path}")
|
|
478
|
+
|
|
479
|
+
return {
|
|
480
|
+
"site": site,
|
|
481
|
+
"library": library,
|
|
482
|
+
"file_path": file_path,
|
|
483
|
+
"local_path": local_path,
|
|
484
|
+
"download_url": download_info.get('download_url', ''),
|
|
485
|
+
"size": Path(local_path).stat().st_size if Path(local_path).exists() else 0
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
except Exception as e:
|
|
489
|
+
self.logger.error(f"Failed to download SharePoint file: {e}")
|
|
490
|
+
raise
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
# ============================================================================
|
|
494
|
+
# UPLOAD SHAREPOINT FILE TOOL
|
|
495
|
+
# ============================================================================
|
|
496
|
+
|
|
497
|
+
class UploadSharePointFileArgs(O365ToolArgsSchema):
|
|
498
|
+
"""Arguments for uploading files to SharePoint."""
|
|
499
|
+
site: str = Field(
|
|
500
|
+
description="SharePoint site name"
|
|
501
|
+
)
|
|
502
|
+
local_file_path: str = Field(
|
|
503
|
+
description="Local file path to upload"
|
|
504
|
+
)
|
|
505
|
+
library: str = Field(
|
|
506
|
+
default="Documents",
|
|
507
|
+
description="Target document library"
|
|
508
|
+
)
|
|
509
|
+
folder_path: Optional[str] = Field(
|
|
510
|
+
default="",
|
|
511
|
+
description="Target folder path within library (e.g., 'Reports/2025')"
|
|
512
|
+
)
|
|
513
|
+
rename_as: Optional[str] = Field(
|
|
514
|
+
default=None,
|
|
515
|
+
description="Rename file when uploading"
|
|
516
|
+
)
|
|
517
|
+
overwrite: bool = Field(
|
|
518
|
+
default=True,
|
|
519
|
+
description="Whether to overwrite existing files"
|
|
520
|
+
)
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
class UploadSharePointFileTool(O365Tool):
|
|
524
|
+
"""
|
|
525
|
+
Tool for uploading files to SharePoint.
|
|
526
|
+
|
|
527
|
+
This tool uploads a local file to a SharePoint document library.
|
|
528
|
+
Supports folder creation and file renaming.
|
|
529
|
+
|
|
530
|
+
Examples:
|
|
531
|
+
# Upload to library root
|
|
532
|
+
result = await tool.run(
|
|
533
|
+
site="TeamSite",
|
|
534
|
+
local_file_path="/tmp/report.pdf"
|
|
535
|
+
)
|
|
536
|
+
|
|
537
|
+
# Upload to specific folder
|
|
538
|
+
result = await tool.run(
|
|
539
|
+
site="ProjectSite",
|
|
540
|
+
local_file_path="/data/export.xlsx",
|
|
541
|
+
folder_path="Reports/2025"
|
|
542
|
+
)
|
|
543
|
+
|
|
544
|
+
# Upload and rename
|
|
545
|
+
result = await tool.run(
|
|
546
|
+
site="TeamSite",
|
|
547
|
+
local_file_path="/tmp/draft.docx",
|
|
548
|
+
folder_path="Contracts",
|
|
549
|
+
rename_as="Final_Agreement.docx"
|
|
550
|
+
)
|
|
551
|
+
"""
|
|
552
|
+
|
|
553
|
+
name: str = "upload_sharepoint_file"
|
|
554
|
+
description: str = (
|
|
555
|
+
"Upload a file to SharePoint document library. "
|
|
556
|
+
"Creates folders as needed and supports file renaming."
|
|
557
|
+
)
|
|
558
|
+
args_schema: Type[BaseModel] = UploadSharePointFileArgs
|
|
559
|
+
|
|
560
|
+
async def _execute_graph_operation(
|
|
561
|
+
self,
|
|
562
|
+
client: SharepointClient,
|
|
563
|
+
**kwargs
|
|
564
|
+
) -> Dict[str, Any]:
|
|
565
|
+
"""
|
|
566
|
+
Upload file to SharePoint using the SharepointClient.
|
|
567
|
+
|
|
568
|
+
Args:
|
|
569
|
+
client: Authenticated SharepointClient instance
|
|
570
|
+
**kwargs: Tool parameters
|
|
571
|
+
|
|
572
|
+
Returns:
|
|
573
|
+
Dict with upload details
|
|
574
|
+
"""
|
|
575
|
+
site = kwargs.get('site')
|
|
576
|
+
local_file_path = kwargs.get('local_file_path')
|
|
577
|
+
library = kwargs.get('library', 'Documents')
|
|
578
|
+
folder_path = kwargs.get('folder_path', '')
|
|
579
|
+
rename_as = kwargs.get('rename_as')
|
|
580
|
+
overwrite = kwargs.get('overwrite', True)
|
|
581
|
+
|
|
582
|
+
try:
|
|
583
|
+
# Validate local file
|
|
584
|
+
local_path = Path(local_file_path)
|
|
585
|
+
if not local_path.exists():
|
|
586
|
+
raise FileNotFoundError(f"Local file not found: {local_file_path}")
|
|
587
|
+
|
|
588
|
+
# Configure client
|
|
589
|
+
client.site = site
|
|
590
|
+
client.credentials['tenant'] = site
|
|
591
|
+
|
|
592
|
+
# Build destination path
|
|
593
|
+
destination = f"{library}/{folder_path}".strip('/')
|
|
594
|
+
|
|
595
|
+
self.logger.info(f"Uploading {local_path.name} to {site}/{destination}")
|
|
596
|
+
|
|
597
|
+
# Verify access
|
|
598
|
+
await client.verify_sharepoint_access()
|
|
599
|
+
|
|
600
|
+
# Upload file
|
|
601
|
+
filenames = [local_path]
|
|
602
|
+
destination_filenames = [rename_as] if rename_as else None
|
|
603
|
+
|
|
604
|
+
upload_results = await client.upload_files(
|
|
605
|
+
filenames=filenames,
|
|
606
|
+
destination=destination,
|
|
607
|
+
destination_filenames=destination_filenames
|
|
608
|
+
)
|
|
609
|
+
|
|
610
|
+
if not upload_results:
|
|
611
|
+
raise RuntimeError("Upload failed")
|
|
612
|
+
|
|
613
|
+
result = upload_results[0]['filename']
|
|
614
|
+
|
|
615
|
+
self.logger.info(f"Uploaded successfully: {result['name']}")
|
|
616
|
+
|
|
617
|
+
return {
|
|
618
|
+
"site": site,
|
|
619
|
+
"library": library,
|
|
620
|
+
"folder_path": folder_path,
|
|
621
|
+
"uploaded_file": result['name'],
|
|
622
|
+
"size": result['size'],
|
|
623
|
+
"web_url": result.get('web_url', ''),
|
|
624
|
+
"server_relative_url": result.get('serverRelativeUrl', '')
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
except Exception as e:
|
|
628
|
+
self.logger.error(f"Failed to upload to SharePoint: {e}")
|
|
629
|
+
raise
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
# ============================================================================
|
|
633
|
+
# EXPORT ALL SHAREPOINT TOOLS
|
|
634
|
+
# ============================================================================
|
|
635
|
+
|
|
636
|
+
__all__ = [
|
|
637
|
+
'ListSharePointFilesTool',
|
|
638
|
+
'SearchSharePointFilesTool',
|
|
639
|
+
'DownloadSharePointFileTool',
|
|
640
|
+
'UploadSharePointFileTool'
|
|
641
|
+
]
|