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,188 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ArxivTool - Search and retrieve papers from arXiv.org
|
|
3
|
+
"""
|
|
4
|
+
from typing import List, Dict, Any, Type
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
from parrot.tools.abstract import AbstractTool, AbstractToolArgsSchema
|
|
7
|
+
try:
|
|
8
|
+
import arxiv
|
|
9
|
+
except ImportError:
|
|
10
|
+
arxiv = None
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ArxivSearchArgsSchema(AbstractToolArgsSchema):
|
|
14
|
+
"""Schema for arXiv search arguments."""
|
|
15
|
+
query: str = Field(
|
|
16
|
+
description="Search query for arXiv papers. Can include keywords, author names, or arXiv categories."
|
|
17
|
+
)
|
|
18
|
+
max_results: int = Field(
|
|
19
|
+
default=5,
|
|
20
|
+
description="Maximum number of results to return (default: 5, max: 100)",
|
|
21
|
+
ge=1,
|
|
22
|
+
le=100
|
|
23
|
+
)
|
|
24
|
+
sort_by: str = Field(
|
|
25
|
+
default="relevance",
|
|
26
|
+
description="Sort order: 'relevance', 'lastUpdatedDate', or 'submittedDate'",
|
|
27
|
+
pattern="^(relevance|lastUpdatedDate|submittedDate)$"
|
|
28
|
+
)
|
|
29
|
+
sort_order: str = Field(
|
|
30
|
+
default="descending",
|
|
31
|
+
description="Sort direction: 'ascending' or 'descending'",
|
|
32
|
+
pattern="^(ascending|descending)$"
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ArxivTool(AbstractTool):
|
|
37
|
+
"""
|
|
38
|
+
Tool for searching academic papers on arXiv.org.
|
|
39
|
+
|
|
40
|
+
This tool allows searching for papers by keywords, authors, categories, or any combination.
|
|
41
|
+
Returns comprehensive paper information including:
|
|
42
|
+
- Title
|
|
43
|
+
- Authors
|
|
44
|
+
- Publication date
|
|
45
|
+
- Abstract/Summary
|
|
46
|
+
- ArXiv ID
|
|
47
|
+
- PDF URL
|
|
48
|
+
- Categories
|
|
49
|
+
|
|
50
|
+
Example queries:
|
|
51
|
+
- "machine learning transformers"
|
|
52
|
+
- "quantum computing"
|
|
53
|
+
- "au:LeCun" (search by author)
|
|
54
|
+
- "cat:cs.AI" (search by category)
|
|
55
|
+
|
|
56
|
+
See https://info.arxiv.org/help/api/user-manual.html for advanced query syntax.
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
name: str = "arxiv_search"
|
|
60
|
+
description: str = (
|
|
61
|
+
"Search for academic papers on arXiv.org. "
|
|
62
|
+
"Supports keyword search, author search, and category filtering. "
|
|
63
|
+
"Returns paper title, authors, publication date, summary, and links."
|
|
64
|
+
)
|
|
65
|
+
args_schema: Type[BaseModel] = ArxivSearchArgsSchema
|
|
66
|
+
return_direct: bool = False
|
|
67
|
+
|
|
68
|
+
def __init__(self, **kwargs):
|
|
69
|
+
"""Initialize the arXiv tool."""
|
|
70
|
+
super().__init__(**kwargs)
|
|
71
|
+
|
|
72
|
+
if arxiv is None:
|
|
73
|
+
raise ImportError(
|
|
74
|
+
"The 'arxiv' package is required for ArxivTool. "
|
|
75
|
+
"Install it with: pip install arxiv"
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
def _format_authors(self, authors: List[arxiv.Result.Author]) -> List[str]:
|
|
79
|
+
"""Format author list from arXiv result."""
|
|
80
|
+
return [author.name for author in authors]
|
|
81
|
+
|
|
82
|
+
def _format_paper(self, paper: arxiv.Result) -> Dict[str, Any]:
|
|
83
|
+
"""
|
|
84
|
+
Format a single arXiv paper result into a structured dictionary.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
paper: arXiv Result object
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
Dictionary with paper information
|
|
91
|
+
"""
|
|
92
|
+
return {
|
|
93
|
+
"title": paper.title,
|
|
94
|
+
"authors": self._format_authors(paper.authors),
|
|
95
|
+
"published": paper.published.strftime("%Y-%m-%d") if paper.published else None,
|
|
96
|
+
"updated": paper.updated.strftime("%Y-%m-%d") if paper.updated else None,
|
|
97
|
+
"summary": paper.summary.replace("\n", " ").strip(),
|
|
98
|
+
"arxiv_id": paper.entry_id.split("/")[-1],
|
|
99
|
+
"pdf_url": paper.pdf_url,
|
|
100
|
+
"categories": paper.categories,
|
|
101
|
+
"primary_category": paper.primary_category,
|
|
102
|
+
"comment": paper.comment if hasattr(paper, "comment") else None,
|
|
103
|
+
"journal_ref": paper.journal_ref if hasattr(paper, "journal_ref") else None,
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async def _execute(
|
|
107
|
+
self,
|
|
108
|
+
query: str,
|
|
109
|
+
max_results: int = 5,
|
|
110
|
+
sort_by: str = "relevance",
|
|
111
|
+
sort_order: str = "descending",
|
|
112
|
+
**kwargs
|
|
113
|
+
) -> Any:
|
|
114
|
+
"""
|
|
115
|
+
Execute arXiv search with given parameters.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
query: Search query string
|
|
119
|
+
max_results: Maximum number of results to return
|
|
120
|
+
sort_by: Sort criterion (relevance, lastUpdatedDate, submittedDate)
|
|
121
|
+
sort_order: Sort direction (ascending, descending)
|
|
122
|
+
**kwargs: Additional arguments (ignored)
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
List of paper dictionaries with metadata
|
|
126
|
+
"""
|
|
127
|
+
try:
|
|
128
|
+
# Map string sort criteria to arxiv.SortCriterion enum
|
|
129
|
+
sort_criterion_map = {
|
|
130
|
+
"relevance": arxiv.SortCriterion.Relevance,
|
|
131
|
+
"lastUpdatedDate": arxiv.SortCriterion.LastUpdatedDate,
|
|
132
|
+
"submittedDate": arxiv.SortCriterion.SubmittedDate,
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
# Map string sort order to arxiv.SortOrder enum
|
|
136
|
+
sort_order_map = {
|
|
137
|
+
"ascending": arxiv.SortOrder.Ascending,
|
|
138
|
+
"descending": arxiv.SortOrder.Descending,
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
sort_criterion = sort_criterion_map.get(
|
|
142
|
+
sort_by, arxiv.SortCriterion.Relevance
|
|
143
|
+
)
|
|
144
|
+
sort_direction = sort_order_map.get(
|
|
145
|
+
sort_order, arxiv.SortOrder.Descending
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# Create search client
|
|
149
|
+
client = arxiv.Client()
|
|
150
|
+
|
|
151
|
+
# Create search query
|
|
152
|
+
search = arxiv.Search(
|
|
153
|
+
query=query,
|
|
154
|
+
max_results=max_results,
|
|
155
|
+
sort_by=sort_criterion,
|
|
156
|
+
sort_order=sort_direction
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
# Execute search and collect results
|
|
160
|
+
papers = []
|
|
161
|
+
papers.extend(
|
|
162
|
+
self._format_paper(paper) for paper in client.results(search)
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
if not papers:
|
|
166
|
+
self.logger.warning(f"No results found for query: {query}")
|
|
167
|
+
return {
|
|
168
|
+
"query": query,
|
|
169
|
+
"count": 0,
|
|
170
|
+
"papers": [],
|
|
171
|
+
"message": "No papers found matching your query."
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
self.logger.info(
|
|
175
|
+
f"Found {len(papers)} papers for query: '{query}'"
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
"query": query,
|
|
180
|
+
"count": len(papers),
|
|
181
|
+
"papers": papers,
|
|
182
|
+
"message": f"Found {len(papers)} paper(s)"
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
except Exception as e:
|
|
186
|
+
error_msg = f"Error searching arXiv: {str(e)}"
|
|
187
|
+
self.logger.error(error_msg)
|
|
188
|
+
raise ValueError(error_msg) from e
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# calculator/operations/__init__.py
|
|
2
|
+
"""
|
|
3
|
+
Calculator operations module.
|
|
4
|
+
|
|
5
|
+
Each operation should be a function that:
|
|
6
|
+
1. Has clear type hints
|
|
7
|
+
2. Includes a docstring
|
|
8
|
+
3. Is decorated with @operation (optional, for metadata)
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from functools import wraps
|
|
12
|
+
from typing import Callable
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def operation(name: str = None, description: str = None):
|
|
16
|
+
"""
|
|
17
|
+
Decorator to mark a function as a calculator operation.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
name: Operation name (defaults to function name)
|
|
21
|
+
description: Operation description (defaults to docstring)
|
|
22
|
+
"""
|
|
23
|
+
def decorator(func: Callable) -> Callable:
|
|
24
|
+
func._is_operation = True
|
|
25
|
+
func._operation_name = name or func.__name__
|
|
26
|
+
func._operation_description = description or func.__doc__
|
|
27
|
+
|
|
28
|
+
@wraps(func)
|
|
29
|
+
def wrapper(*args, **kwargs):
|
|
30
|
+
return func(*args, **kwargs)
|
|
31
|
+
|
|
32
|
+
# Preserve operation metadata
|
|
33
|
+
wrapper._is_operation = True
|
|
34
|
+
wrapper._operation_name = func._operation_name
|
|
35
|
+
wrapper._operation_description = func._operation_description
|
|
36
|
+
|
|
37
|
+
return wrapper
|
|
38
|
+
return decorator
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# calculator/operations/calculus.py
|
|
2
|
+
"""Calculus operations."""
|
|
3
|
+
from typing import Callable, List
|
|
4
|
+
from . import operation
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@operation(name="derivative")
|
|
8
|
+
def numerical_derivative(
|
|
9
|
+
expression: str = None,
|
|
10
|
+
x: float = None,
|
|
11
|
+
h: float = 1e-5,
|
|
12
|
+
**kwargs
|
|
13
|
+
) -> float:
|
|
14
|
+
"""
|
|
15
|
+
Calculate numerical derivative using central difference.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
expression: Python expression as string (e.g., "x**2 + 3*x")
|
|
19
|
+
x: Point at which to evaluate derivative
|
|
20
|
+
h: Step size for numerical differentiation
|
|
21
|
+
"""
|
|
22
|
+
if expression is None or x is None:
|
|
23
|
+
raise ValueError("Need both expression and x value")
|
|
24
|
+
|
|
25
|
+
# Compile expression for evaluation
|
|
26
|
+
# This uses Python's eval - in production, consider safer alternatives
|
|
27
|
+
import numpy as np
|
|
28
|
+
|
|
29
|
+
def f(val):
|
|
30
|
+
# Make common functions available
|
|
31
|
+
from math import sin, cos, tan, exp, log, sqrt, pi, e
|
|
32
|
+
return eval(expression, {"x": val, "np": np, "__builtins__": {}},
|
|
33
|
+
{"sin": sin, "cos": cos, "tan": tan, "exp": exp,
|
|
34
|
+
"log": log, "sqrt": sqrt, "pi": pi, "e": e})
|
|
35
|
+
|
|
36
|
+
# Central difference: f'(x) ≈ (f(x+h) - f(x-h)) / (2h)
|
|
37
|
+
return (f(x + h) - f(x - h)) / (2 * h)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@operation(name="integrate")
|
|
41
|
+
def numerical_integral(
|
|
42
|
+
expression: str = None,
|
|
43
|
+
a: float = None,
|
|
44
|
+
b: float = None,
|
|
45
|
+
n: int = 1000,
|
|
46
|
+
**kwargs
|
|
47
|
+
) -> float:
|
|
48
|
+
"""
|
|
49
|
+
Calculate numerical integral using Simpson's rule.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
expression: Python expression as string
|
|
53
|
+
a: Lower bound
|
|
54
|
+
b: Upper bound
|
|
55
|
+
n: Number of intervals (must be even)
|
|
56
|
+
"""
|
|
57
|
+
if any(v is None for v in [expression, a, b]):
|
|
58
|
+
raise ValueError("Need expression, a, and b")
|
|
59
|
+
|
|
60
|
+
if n % 2 != 0:
|
|
61
|
+
n += 1
|
|
62
|
+
|
|
63
|
+
from math import sin, cos, tan, exp, log, sqrt, pi, e
|
|
64
|
+
|
|
65
|
+
def f(val):
|
|
66
|
+
return eval(expression, {"x": val, "__builtins__": {}},
|
|
67
|
+
{"sin": sin, "cos": cos, "tan": tan, "exp": exp,
|
|
68
|
+
"log": log, "sqrt": sqrt, "pi": pi, "e": e})
|
|
69
|
+
|
|
70
|
+
h = (b - a) / n
|
|
71
|
+
result = f(a) + f(b)
|
|
72
|
+
|
|
73
|
+
for i in range(1, n):
|
|
74
|
+
x = a + i * h
|
|
75
|
+
if i % 2 == 0:
|
|
76
|
+
result += 2 * f(x)
|
|
77
|
+
else:
|
|
78
|
+
result += 4 * f(x)
|
|
79
|
+
|
|
80
|
+
return result * h / 3
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# calculator/operations/statistics.py
|
|
2
|
+
"""Statistical operations."""
|
|
3
|
+
import math
|
|
4
|
+
from typing import List
|
|
5
|
+
from . import operation
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@operation(name="mean", description="Calculate arithmetic mean")
|
|
9
|
+
def calculate_mean(values: List[float], **kwargs) -> float:
|
|
10
|
+
"""Calculate the arithmetic mean of a list of values."""
|
|
11
|
+
if not values:
|
|
12
|
+
raise ValueError("Cannot calculate mean of empty list")
|
|
13
|
+
return sum(values) / len(values)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@operation(name="std", description="Calculate standard deviation")
|
|
17
|
+
def calculate_std(values: List[float], sample: bool = True, **kwargs) -> float:
|
|
18
|
+
"""
|
|
19
|
+
Calculate standard deviation.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
values: List of numerical values
|
|
23
|
+
sample: If True, use sample std (n-1), else population std (n)
|
|
24
|
+
"""
|
|
25
|
+
if not values:
|
|
26
|
+
raise ValueError("Cannot calculate std of empty list")
|
|
27
|
+
|
|
28
|
+
mean = sum(values) / len(values)
|
|
29
|
+
variance = sum((x - mean) ** 2 for x in values)
|
|
30
|
+
|
|
31
|
+
divisor = len(values) - 1 if sample else len(values)
|
|
32
|
+
if divisor == 0:
|
|
33
|
+
raise ValueError("Need at least 2 values for sample standard deviation")
|
|
34
|
+
|
|
35
|
+
return math.sqrt(variance / divisor)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@operation(name="median")
|
|
39
|
+
def calculate_median(values: List[float], **kwargs) -> float:
|
|
40
|
+
"""Calculate median value."""
|
|
41
|
+
if not values:
|
|
42
|
+
raise ValueError("Cannot calculate median of empty list")
|
|
43
|
+
|
|
44
|
+
sorted_values = sorted(values)
|
|
45
|
+
n = len(sorted_values)
|
|
46
|
+
|
|
47
|
+
if n % 2 == 0:
|
|
48
|
+
return (sorted_values[n//2 - 1] + sorted_values[n//2]) / 2
|
|
49
|
+
else:
|
|
50
|
+
return sorted_values[n//2]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@operation(name="correlation")
|
|
54
|
+
def calculate_correlation(values: List[float], **kwargs) -> float:
|
|
55
|
+
"""
|
|
56
|
+
Calculate Pearson correlation coefficient.
|
|
57
|
+
Expects values to be alternating [x1, y1, x2, y2, ...]
|
|
58
|
+
"""
|
|
59
|
+
if len(values) < 4 or len(values) % 2 != 0:
|
|
60
|
+
raise ValueError("Need at least 2 pairs of values for correlation")
|
|
61
|
+
|
|
62
|
+
x_values = values[::2]
|
|
63
|
+
y_values = values[1::2]
|
|
64
|
+
|
|
65
|
+
n = len(x_values)
|
|
66
|
+
mean_x = sum(x_values) / n
|
|
67
|
+
mean_y = sum(y_values) / n
|
|
68
|
+
|
|
69
|
+
numerator = sum((x - mean_x) * (y - mean_y) for x, y in zip(x_values, y_values))
|
|
70
|
+
denominator_x = math.sqrt(sum((x - mean_x) ** 2 for x in x_values))
|
|
71
|
+
denominator_y = math.sqrt(sum((y - mean_y) ** 2 for y in y_values))
|
|
72
|
+
|
|
73
|
+
if denominator_x == 0 or denominator_y == 0:
|
|
74
|
+
raise ValueError("Standard deviation is zero, cannot calculate correlation")
|
|
75
|
+
|
|
76
|
+
return numerator / (denominator_x * denominator_y)
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# calculator/tool.py
|
|
2
|
+
from typing import Dict, Any, Optional, List, Callable
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
5
|
+
from parrot.tools.abstract import AbstractTool, ToolResult
|
|
6
|
+
import importlib
|
|
7
|
+
import inspect
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CalculatorArgs(BaseModel):
|
|
11
|
+
"""Arguments for calculator operations."""
|
|
12
|
+
operation: str = Field(
|
|
13
|
+
description="Operation to perform (e.g., 'mean', 'std', 'correlation', 'derivative')"
|
|
14
|
+
)
|
|
15
|
+
values: Optional[List[float]] = Field(
|
|
16
|
+
default=None,
|
|
17
|
+
description="List of numerical values for statistical operations"
|
|
18
|
+
)
|
|
19
|
+
x: Optional[float] = Field(default=None, description="First operand or x value")
|
|
20
|
+
y: Optional[float] = Field(default=None, description="Second operand or y value")
|
|
21
|
+
expression: Optional[str] = Field(
|
|
22
|
+
default=None,
|
|
23
|
+
description="Mathematical expression for evaluation"
|
|
24
|
+
)
|
|
25
|
+
params: Optional[Dict[str, Any]] = Field(
|
|
26
|
+
default_factory=dict,
|
|
27
|
+
description="Additional parameters for specific operations"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class CalculatorTool(AbstractTool):
|
|
32
|
+
"""
|
|
33
|
+
Advanced calculator tool with dynamically loaded operations.
|
|
34
|
+
|
|
35
|
+
Supports mathematical, statistical, and scientific computations
|
|
36
|
+
by loading operation functions from the operations/ folder.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
name = "CalculatorTool"
|
|
40
|
+
description = (
|
|
41
|
+
"Advanced calculator supporting mathematical, statistical, and scientific operations. "
|
|
42
|
+
"Available operations are dynamically loaded from operation modules."
|
|
43
|
+
)
|
|
44
|
+
args_schema = CalculatorArgs
|
|
45
|
+
|
|
46
|
+
def __init__(self, **kwargs):
|
|
47
|
+
super().__init__(**kwargs)
|
|
48
|
+
self.operations: Dict[str, Callable] = {}
|
|
49
|
+
self._load_operations()
|
|
50
|
+
|
|
51
|
+
def _load_operations(self):
|
|
52
|
+
"""Dynamically load all operations from the operations/ folder."""
|
|
53
|
+
operations_dir = Path(__file__).parent / "operations"
|
|
54
|
+
|
|
55
|
+
if not operations_dir.exists():
|
|
56
|
+
self.logger.warning(f"Operations directory not found: {operations_dir}")
|
|
57
|
+
return
|
|
58
|
+
|
|
59
|
+
# Discover all Python files in operations/
|
|
60
|
+
for py_file in operations_dir.glob("*.py"):
|
|
61
|
+
if py_file.name.startswith("_"):
|
|
62
|
+
continue
|
|
63
|
+
|
|
64
|
+
module_name = f"parrot.tools.calculator.operations.{py_file.stem}"
|
|
65
|
+
|
|
66
|
+
try:
|
|
67
|
+
module = importlib.import_module(module_name)
|
|
68
|
+
|
|
69
|
+
# Load all functions marked with @operation decorator
|
|
70
|
+
# or all public functions
|
|
71
|
+
for name, obj in inspect.getmembers(module, inspect.isfunction):
|
|
72
|
+
if not name.startswith("_"):
|
|
73
|
+
# Check if function has operation metadata
|
|
74
|
+
if hasattr(obj, "_is_operation"):
|
|
75
|
+
operation_name = obj._operation_name or name
|
|
76
|
+
self.operations[operation_name] = obj
|
|
77
|
+
self.logger.debug(
|
|
78
|
+
f"Loaded operation: {operation_name} from {py_file.name}"
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
except Exception as e:
|
|
82
|
+
self.logger.error(f"Failed to load operations from {py_file}: {e}")
|
|
83
|
+
|
|
84
|
+
async def _execute(
|
|
85
|
+
self,
|
|
86
|
+
operation: str,
|
|
87
|
+
values: Optional[List[float]] = None,
|
|
88
|
+
x: Optional[float] = None,
|
|
89
|
+
y: Optional[float] = None,
|
|
90
|
+
expression: Optional[str] = None,
|
|
91
|
+
params: Optional[Dict[str, Any]] = None,
|
|
92
|
+
**kwargs
|
|
93
|
+
) -> Dict[str, Any]:
|
|
94
|
+
"""Execute the requested operation."""
|
|
95
|
+
|
|
96
|
+
if operation not in self.operations:
|
|
97
|
+
available = ", ".join(sorted(self.operations.keys()))
|
|
98
|
+
return {
|
|
99
|
+
"status": "error",
|
|
100
|
+
"error": f"Unknown operation '{operation}'. Available: {available}",
|
|
101
|
+
"result": None
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
try:
|
|
105
|
+
func = self.operations[operation]
|
|
106
|
+
|
|
107
|
+
# Build kwargs for the operation function
|
|
108
|
+
op_kwargs = {
|
|
109
|
+
"values": values,
|
|
110
|
+
"x": x,
|
|
111
|
+
"y": y,
|
|
112
|
+
"expression": expression,
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if params:
|
|
116
|
+
op_kwargs.update(params)
|
|
117
|
+
|
|
118
|
+
# Filter None values
|
|
119
|
+
op_kwargs = {k: v for k, v in op_kwargs.items() if v is not None}
|
|
120
|
+
|
|
121
|
+
# Execute operation
|
|
122
|
+
result = await self._call_operation(func, op_kwargs)
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
"status": "success",
|
|
126
|
+
"result": result,
|
|
127
|
+
"operation": operation,
|
|
128
|
+
"metadata": {
|
|
129
|
+
"available_operations": list(self.operations.keys())
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
except Exception as e:
|
|
134
|
+
self.logger.error(f"Error executing operation '{operation}': {e}")
|
|
135
|
+
return {
|
|
136
|
+
"status": "error",
|
|
137
|
+
"error": str(e),
|
|
138
|
+
"result": None
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async def _call_operation(self, func: Callable, kwargs: Dict[str, Any]) -> Any:
|
|
142
|
+
"""Call operation function (sync or async)."""
|
|
143
|
+
if inspect.iscoroutinefunction(func):
|
|
144
|
+
return await func(**kwargs)
|
|
145
|
+
else:
|
|
146
|
+
return func(**kwargs)
|
|
147
|
+
|
|
148
|
+
def list_operations(self) -> List[str]:
|
|
149
|
+
"""List all available operations."""
|
|
150
|
+
return sorted(self.operations.keys())
|