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,523 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Redis Persistence for AgentsCrew Definitions.
|
|
3
|
+
|
|
4
|
+
Provides async-based persistence layer for storing and retrieving
|
|
5
|
+
Crew definitions from Redis using JSON serialization.
|
|
6
|
+
"""
|
|
7
|
+
from typing import List, Optional, Dict, Any
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
import json
|
|
10
|
+
from redis.asyncio import Redis
|
|
11
|
+
from navconfig.logging import logging
|
|
12
|
+
|
|
13
|
+
from .models import CrewDefinition
|
|
14
|
+
from ...conf import REDIS_URL
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class CrewRedis:
|
|
18
|
+
"""Redis-based persistence for AgentsCrew definitions."""
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
redis_url: str = None,
|
|
23
|
+
key_prefix: str = "crew",
|
|
24
|
+
db: int = 2 # Use DB 2 for crew persistence
|
|
25
|
+
):
|
|
26
|
+
"""
|
|
27
|
+
Initialize Redis persistence for crews.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
redis_url: Redis connection URL (default from config)
|
|
31
|
+
key_prefix: Prefix for Redis keys (default: 'crew')
|
|
32
|
+
db: Redis database number (default: 2)
|
|
33
|
+
"""
|
|
34
|
+
self.logger = logging.getLogger('CrewRedis')
|
|
35
|
+
self.key_prefix = key_prefix
|
|
36
|
+
|
|
37
|
+
# Build Redis URL with specific DB if not provided
|
|
38
|
+
if redis_url is None:
|
|
39
|
+
from ...conf import REDIS_HOST, REDIS_PORT
|
|
40
|
+
redis_url = f"redis://{REDIS_HOST}:{REDIS_PORT}/{db}"
|
|
41
|
+
|
|
42
|
+
self.redis_url = redis_url
|
|
43
|
+
self.redis = Redis.from_url(
|
|
44
|
+
self.redis_url,
|
|
45
|
+
decode_responses=True,
|
|
46
|
+
encoding="utf-8",
|
|
47
|
+
socket_connect_timeout=5,
|
|
48
|
+
socket_timeout=5,
|
|
49
|
+
retry_on_timeout=True
|
|
50
|
+
)
|
|
51
|
+
self.logger.info(f"CrewRedis initialized with URL: {self.redis_url}")
|
|
52
|
+
|
|
53
|
+
def _get_key(self, name: str) -> str:
|
|
54
|
+
"""
|
|
55
|
+
Generate Redis key for crew definition.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
name: Name of the crew
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
Redis key in format 'crew:{name}'
|
|
62
|
+
"""
|
|
63
|
+
return f"{self.key_prefix}:{name}"
|
|
64
|
+
|
|
65
|
+
def _get_list_key(self) -> str:
|
|
66
|
+
"""Get the key for the set of all crew names."""
|
|
67
|
+
return f"{self.key_prefix}:list"
|
|
68
|
+
|
|
69
|
+
def _get_id_mapping_key(self, crew_id: str) -> str:
|
|
70
|
+
"""
|
|
71
|
+
Generate Redis key for crew_id to name mapping.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
crew_id: UUID of the crew
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
Redis key in format 'crew:id:{crew_id}'
|
|
78
|
+
"""
|
|
79
|
+
return f"{self.key_prefix}:id:{crew_id}"
|
|
80
|
+
|
|
81
|
+
def _serialize_crew(self, crew: CrewDefinition) -> str:
|
|
82
|
+
"""
|
|
83
|
+
Serialize CrewDefinition to JSON string.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
crew: CrewDefinition instance
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
JSON string representation
|
|
90
|
+
"""
|
|
91
|
+
try:
|
|
92
|
+
# Use Pydantic's model_dump to get dictionary
|
|
93
|
+
crew_dict = crew.model_dump(mode='json')
|
|
94
|
+
|
|
95
|
+
# Convert datetime objects to ISO format
|
|
96
|
+
if isinstance(crew_dict.get('created_at'), datetime):
|
|
97
|
+
crew_dict['created_at'] = crew_dict['created_at'].isoformat()
|
|
98
|
+
if isinstance(crew_dict.get('updated_at'), datetime):
|
|
99
|
+
crew_dict['updated_at'] = crew_dict['updated_at'].isoformat()
|
|
100
|
+
|
|
101
|
+
return json.dumps(crew_dict, ensure_ascii=False, separators=(',', ':'))
|
|
102
|
+
except Exception as e:
|
|
103
|
+
self.logger.error(f"Serialization error: {e}")
|
|
104
|
+
raise
|
|
105
|
+
|
|
106
|
+
def _deserialize_crew(self, data: str) -> CrewDefinition:
|
|
107
|
+
"""
|
|
108
|
+
Deserialize JSON string to CrewDefinition.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
data: JSON string
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
CrewDefinition instance
|
|
115
|
+
"""
|
|
116
|
+
try:
|
|
117
|
+
crew_dict = json.loads(data)
|
|
118
|
+
|
|
119
|
+
# Convert ISO format strings back to datetime
|
|
120
|
+
if 'created_at' in crew_dict and isinstance(crew_dict['created_at'], str):
|
|
121
|
+
crew_dict['created_at'] = datetime.fromisoformat(crew_dict['created_at'])
|
|
122
|
+
if 'updated_at' in crew_dict and isinstance(crew_dict['updated_at'], str):
|
|
123
|
+
crew_dict['updated_at'] = datetime.fromisoformat(crew_dict['updated_at'])
|
|
124
|
+
|
|
125
|
+
return CrewDefinition(**crew_dict)
|
|
126
|
+
except Exception as e:
|
|
127
|
+
self.logger.error(f"Deserialization error: {e}")
|
|
128
|
+
self.logger.error(f"Problematic data: {data[:200]}")
|
|
129
|
+
raise
|
|
130
|
+
|
|
131
|
+
async def save_crew(self, crew: CrewDefinition) -> bool:
|
|
132
|
+
"""
|
|
133
|
+
Save crew definition to Redis.
|
|
134
|
+
|
|
135
|
+
Stores the crew definition with key format 'crew:{name}'.
|
|
136
|
+
Also maintains a set of all crew names and a crew_id to name mapping.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
crew: CrewDefinition instance to save
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
True if saved successfully, False otherwise
|
|
143
|
+
"""
|
|
144
|
+
try:
|
|
145
|
+
# Update the updated_at timestamp
|
|
146
|
+
crew.updated_at = datetime.utcnow()
|
|
147
|
+
|
|
148
|
+
key = self._get_key(crew.name)
|
|
149
|
+
serialized = self._serialize_crew(crew)
|
|
150
|
+
|
|
151
|
+
# Save crew definition
|
|
152
|
+
await self.redis.set(key, serialized)
|
|
153
|
+
|
|
154
|
+
# Add to crew list (set of all crew names)
|
|
155
|
+
await self.redis.sadd(self._get_list_key(), crew.name)
|
|
156
|
+
|
|
157
|
+
# Create crew_id to name mapping for lookup by ID
|
|
158
|
+
id_key = self._get_id_mapping_key(crew.crew_id)
|
|
159
|
+
await self.redis.set(id_key, crew.name)
|
|
160
|
+
|
|
161
|
+
self.logger.info(f"Crew '{crew.name}' (ID: {crew.crew_id}) saved successfully")
|
|
162
|
+
return True
|
|
163
|
+
except Exception as e:
|
|
164
|
+
self.logger.error(f"Error saving crew '{crew.name}': {e}")
|
|
165
|
+
return False
|
|
166
|
+
|
|
167
|
+
async def load_crew(self, name: str) -> Optional[CrewDefinition]:
|
|
168
|
+
"""
|
|
169
|
+
Load crew definition from Redis by name.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
name: Name of the crew to load
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
CrewDefinition instance if found, None otherwise
|
|
176
|
+
"""
|
|
177
|
+
try:
|
|
178
|
+
key = self._get_key(name)
|
|
179
|
+
data = await self.redis.get(key)
|
|
180
|
+
|
|
181
|
+
if data is None:
|
|
182
|
+
self.logger.warning(f"Crew '{name}' not found in Redis")
|
|
183
|
+
return None
|
|
184
|
+
|
|
185
|
+
crew = self._deserialize_crew(data)
|
|
186
|
+
self.logger.info(f"Crew '{name}' loaded successfully")
|
|
187
|
+
return crew
|
|
188
|
+
except Exception as e:
|
|
189
|
+
self.logger.error(f"Error loading crew '{name}': {e}")
|
|
190
|
+
return None
|
|
191
|
+
|
|
192
|
+
async def load_crew_by_id(self, crew_id: str) -> Optional[CrewDefinition]:
|
|
193
|
+
"""
|
|
194
|
+
Load crew definition from Redis by crew_id.
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
crew_id: UUID of the crew to load
|
|
198
|
+
|
|
199
|
+
Returns:
|
|
200
|
+
CrewDefinition instance if found, None otherwise
|
|
201
|
+
"""
|
|
202
|
+
try:
|
|
203
|
+
# First, look up the crew name from the ID
|
|
204
|
+
id_key = self._get_id_mapping_key(crew_id)
|
|
205
|
+
name = await self.redis.get(id_key)
|
|
206
|
+
|
|
207
|
+
if name is None:
|
|
208
|
+
self.logger.warning(f"Crew with ID '{crew_id}' not found in Redis")
|
|
209
|
+
return None
|
|
210
|
+
|
|
211
|
+
# Then load the crew by name
|
|
212
|
+
return await self.load_crew(name)
|
|
213
|
+
except Exception as e:
|
|
214
|
+
self.logger.error(f"Error loading crew by ID '{crew_id}': {e}")
|
|
215
|
+
return None
|
|
216
|
+
|
|
217
|
+
async def delete_crew(self, name: str) -> bool:
|
|
218
|
+
"""
|
|
219
|
+
Delete crew definition from Redis.
|
|
220
|
+
|
|
221
|
+
Args:
|
|
222
|
+
name: Name of the crew to delete
|
|
223
|
+
|
|
224
|
+
Returns:
|
|
225
|
+
True if deleted successfully, False otherwise
|
|
226
|
+
"""
|
|
227
|
+
try:
|
|
228
|
+
# First, get the crew to extract the ID
|
|
229
|
+
crew = await self.load_crew(name)
|
|
230
|
+
|
|
231
|
+
key = self._get_key(name)
|
|
232
|
+
result = await self.redis.delete(key)
|
|
233
|
+
|
|
234
|
+
# Remove from crew list
|
|
235
|
+
await self.redis.srem(self._get_list_key(), name)
|
|
236
|
+
|
|
237
|
+
# Remove ID mapping if crew was found
|
|
238
|
+
if crew:
|
|
239
|
+
id_key = self._get_id_mapping_key(crew.crew_id)
|
|
240
|
+
await self.redis.delete(id_key)
|
|
241
|
+
|
|
242
|
+
if result > 0:
|
|
243
|
+
self.logger.info(f"Crew '{name}' deleted successfully")
|
|
244
|
+
return True
|
|
245
|
+
else:
|
|
246
|
+
self.logger.warning(f"Crew '{name}' not found for deletion")
|
|
247
|
+
return False
|
|
248
|
+
except Exception as e:
|
|
249
|
+
self.logger.error(f"Error deleting crew '{name}': {e}")
|
|
250
|
+
return False
|
|
251
|
+
|
|
252
|
+
async def list_crews(self) -> List[str]:
|
|
253
|
+
"""
|
|
254
|
+
List all crew names in Redis.
|
|
255
|
+
|
|
256
|
+
Returns:
|
|
257
|
+
List of crew names
|
|
258
|
+
"""
|
|
259
|
+
try:
|
|
260
|
+
crews = await self.redis.smembers(self._get_list_key())
|
|
261
|
+
return sorted(list(crews))
|
|
262
|
+
except Exception as e:
|
|
263
|
+
self.logger.error(f"Error listing crews: {e}")
|
|
264
|
+
return []
|
|
265
|
+
|
|
266
|
+
async def crew_exists(self, name: str) -> bool:
|
|
267
|
+
"""
|
|
268
|
+
Check if a crew exists in Redis.
|
|
269
|
+
|
|
270
|
+
Args:
|
|
271
|
+
name: Name of the crew
|
|
272
|
+
|
|
273
|
+
Returns:
|
|
274
|
+
True if crew exists, False otherwise
|
|
275
|
+
"""
|
|
276
|
+
try:
|
|
277
|
+
key = self._get_key(name)
|
|
278
|
+
exists = await self.redis.exists(key)
|
|
279
|
+
return exists > 0
|
|
280
|
+
except Exception as e:
|
|
281
|
+
self.logger.error(f"Error checking crew existence '{name}': {e}")
|
|
282
|
+
return False
|
|
283
|
+
|
|
284
|
+
async def get_all_crews(self) -> List[CrewDefinition]:
|
|
285
|
+
"""
|
|
286
|
+
Get all crew definitions from Redis.
|
|
287
|
+
|
|
288
|
+
Returns:
|
|
289
|
+
List of CrewDefinition instances
|
|
290
|
+
"""
|
|
291
|
+
try:
|
|
292
|
+
crew_names = await self.list_crews()
|
|
293
|
+
crews = []
|
|
294
|
+
|
|
295
|
+
for name in crew_names:
|
|
296
|
+
crew = await self.load_crew(name)
|
|
297
|
+
if crew:
|
|
298
|
+
crews.append(crew)
|
|
299
|
+
|
|
300
|
+
self.logger.info(f"Retrieved {len(crews)} crews from Redis")
|
|
301
|
+
return crews
|
|
302
|
+
except Exception as e:
|
|
303
|
+
self.logger.error(f"Error getting all crews: {e}")
|
|
304
|
+
return []
|
|
305
|
+
|
|
306
|
+
async def get_crew_metadata(self, name: str) -> Optional[Dict[str, Any]]:
|
|
307
|
+
"""
|
|
308
|
+
Get crew metadata without loading the full definition.
|
|
309
|
+
|
|
310
|
+
Args:
|
|
311
|
+
name: Name of the crew
|
|
312
|
+
|
|
313
|
+
Returns:
|
|
314
|
+
Dictionary with crew metadata (name, crew_id, description, etc.)
|
|
315
|
+
"""
|
|
316
|
+
try:
|
|
317
|
+
crew = await self.load_crew(name)
|
|
318
|
+
if crew:
|
|
319
|
+
return {
|
|
320
|
+
'crew_id': crew.crew_id,
|
|
321
|
+
'name': crew.name,
|
|
322
|
+
'description': crew.description,
|
|
323
|
+
'execution_mode': crew.execution_mode.value,
|
|
324
|
+
'agent_count': len(crew.agents),
|
|
325
|
+
'created_at': crew.created_at.isoformat(),
|
|
326
|
+
'updated_at': crew.updated_at.isoformat(),
|
|
327
|
+
'metadata': crew.metadata
|
|
328
|
+
}
|
|
329
|
+
return None
|
|
330
|
+
except Exception as e:
|
|
331
|
+
self.logger.error(f"Error getting crew metadata '{name}': {e}")
|
|
332
|
+
return None
|
|
333
|
+
|
|
334
|
+
async def update_crew_metadata(
|
|
335
|
+
self,
|
|
336
|
+
name: str,
|
|
337
|
+
metadata: Dict[str, Any]
|
|
338
|
+
) -> bool:
|
|
339
|
+
"""
|
|
340
|
+
Update crew metadata without modifying agents or configuration.
|
|
341
|
+
|
|
342
|
+
Args:
|
|
343
|
+
name: Name of the crew
|
|
344
|
+
metadata: Metadata dictionary to update
|
|
345
|
+
|
|
346
|
+
Returns:
|
|
347
|
+
True if updated successfully, False otherwise
|
|
348
|
+
"""
|
|
349
|
+
try:
|
|
350
|
+
crew = await self.load_crew(name)
|
|
351
|
+
if crew is None:
|
|
352
|
+
self.logger.warning(f"Cannot update metadata: crew '{name}' not found")
|
|
353
|
+
return False
|
|
354
|
+
|
|
355
|
+
# Update metadata
|
|
356
|
+
crew.metadata.update(metadata)
|
|
357
|
+
crew.updated_at = datetime.utcnow()
|
|
358
|
+
|
|
359
|
+
# Save back to Redis
|
|
360
|
+
return await self.save_crew(crew)
|
|
361
|
+
except Exception as e:
|
|
362
|
+
self.logger.error(f"Error updating crew metadata '{name}': {e}")
|
|
363
|
+
return False
|
|
364
|
+
|
|
365
|
+
async def ping(self) -> bool:
|
|
366
|
+
"""
|
|
367
|
+
Test Redis connection.
|
|
368
|
+
|
|
369
|
+
Returns:
|
|
370
|
+
True if connection is healthy, False otherwise
|
|
371
|
+
"""
|
|
372
|
+
try:
|
|
373
|
+
await self.redis.ping()
|
|
374
|
+
return True
|
|
375
|
+
except Exception as e:
|
|
376
|
+
self.logger.error(f"Error pinging Redis: {e}")
|
|
377
|
+
return False
|
|
378
|
+
|
|
379
|
+
async def close(self):
|
|
380
|
+
"""Close the Redis connection."""
|
|
381
|
+
try:
|
|
382
|
+
await self.redis.close()
|
|
383
|
+
self.logger.info("Redis connection closed")
|
|
384
|
+
except Exception as e:
|
|
385
|
+
self.logger.error(f"Error closing Redis connection: {e}")
|
|
386
|
+
|
|
387
|
+
async def clear_all_crews(self) -> int:
|
|
388
|
+
"""
|
|
389
|
+
Delete all crews from Redis (use with caution).
|
|
390
|
+
|
|
391
|
+
Returns:
|
|
392
|
+
Number of crews deleted
|
|
393
|
+
"""
|
|
394
|
+
try:
|
|
395
|
+
crew_names = await self.list_crews()
|
|
396
|
+
deleted_count = 0
|
|
397
|
+
|
|
398
|
+
for name in crew_names:
|
|
399
|
+
if await self.delete_crew(name):
|
|
400
|
+
deleted_count += 1
|
|
401
|
+
|
|
402
|
+
self.logger.warning(f"Cleared {deleted_count} crews from Redis")
|
|
403
|
+
return deleted_count
|
|
404
|
+
except Exception as e:
|
|
405
|
+
self.logger.error(f"Error clearing all crews: {e}")
|
|
406
|
+
return 0
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
# Example usage and testing
|
|
410
|
+
async def test_crew_redis():
|
|
411
|
+
"""Test the CrewRedis persistence layer."""
|
|
412
|
+
from .models import AgentDefinition, ExecutionMode
|
|
413
|
+
|
|
414
|
+
crew_redis = CrewRedis()
|
|
415
|
+
|
|
416
|
+
if not await crew_redis.ping():
|
|
417
|
+
print("❌ Redis connection failed!")
|
|
418
|
+
return
|
|
419
|
+
|
|
420
|
+
print("✓ Redis connection successful")
|
|
421
|
+
|
|
422
|
+
try:
|
|
423
|
+
# Test 1: Create and save a crew
|
|
424
|
+
print("\n=== Test 1: Save Crew ===")
|
|
425
|
+
crew_def = CrewDefinition(
|
|
426
|
+
name="test_crew",
|
|
427
|
+
description="A test crew for Redis persistence",
|
|
428
|
+
execution_mode=ExecutionMode.SEQUENTIAL,
|
|
429
|
+
agents=[
|
|
430
|
+
AgentDefinition(
|
|
431
|
+
agent_id="agent_1",
|
|
432
|
+
agent_class="BasicAgent",
|
|
433
|
+
name="Researcher",
|
|
434
|
+
config={"model": "gpt-4", "temperature": 0.7},
|
|
435
|
+
tools=["search", "summarize"],
|
|
436
|
+
system_prompt="You are a research agent."
|
|
437
|
+
),
|
|
438
|
+
AgentDefinition(
|
|
439
|
+
agent_id="agent_2",
|
|
440
|
+
agent_class="BasicAgent",
|
|
441
|
+
name="Writer",
|
|
442
|
+
config={"model": "gpt-4", "temperature": 0.9},
|
|
443
|
+
tools=["write", "edit"],
|
|
444
|
+
system_prompt="You are a writing agent."
|
|
445
|
+
)
|
|
446
|
+
],
|
|
447
|
+
shared_tools=["calculator"],
|
|
448
|
+
metadata={"version": "1.0", "author": "test"}
|
|
449
|
+
)
|
|
450
|
+
|
|
451
|
+
saved = await crew_redis.save_crew(crew_def)
|
|
452
|
+
print(f"Crew saved: {saved}")
|
|
453
|
+
print(f"Crew ID: {crew_def.crew_id}")
|
|
454
|
+
|
|
455
|
+
# Test 2: Load crew by name
|
|
456
|
+
print("\n=== Test 2: Load Crew by Name ===")
|
|
457
|
+
loaded_crew = await crew_redis.load_crew("test_crew")
|
|
458
|
+
if loaded_crew:
|
|
459
|
+
print(f"✓ Loaded crew: {loaded_crew.name}")
|
|
460
|
+
print(f" - Description: {loaded_crew.description}")
|
|
461
|
+
print(f" - Execution mode: {loaded_crew.execution_mode}")
|
|
462
|
+
print(f" - Agents: {len(loaded_crew.agents)}")
|
|
463
|
+
print(f" - Agent 1: {loaded_crew.agents[0].name}")
|
|
464
|
+
print(f" - Agent 2: {loaded_crew.agents[1].name}")
|
|
465
|
+
else:
|
|
466
|
+
print("❌ Failed to load crew")
|
|
467
|
+
|
|
468
|
+
# Test 3: Load crew by ID
|
|
469
|
+
print("\n=== Test 3: Load Crew by ID ===")
|
|
470
|
+
loaded_by_id = await crew_redis.load_crew_by_id(crew_def.crew_id)
|
|
471
|
+
if loaded_by_id:
|
|
472
|
+
print(f"✓ Loaded crew by ID: {loaded_by_id.name}")
|
|
473
|
+
else:
|
|
474
|
+
print("❌ Failed to load crew by ID")
|
|
475
|
+
|
|
476
|
+
# Test 4: List crews
|
|
477
|
+
print("\n=== Test 4: List Crews ===")
|
|
478
|
+
crews = await crew_redis.list_crews()
|
|
479
|
+
print(f"All crews: {crews}")
|
|
480
|
+
|
|
481
|
+
# Test 5: Check crew existence
|
|
482
|
+
print("\n=== Test 5: Check Existence ===")
|
|
483
|
+
exists = await crew_redis.crew_exists("test_crew")
|
|
484
|
+
print(f"Crew exists: {exists}")
|
|
485
|
+
|
|
486
|
+
not_exists = await crew_redis.crew_exists("nonexistent_crew")
|
|
487
|
+
print(f"Nonexistent crew exists: {not_exists}")
|
|
488
|
+
|
|
489
|
+
# Test 6: Get crew metadata
|
|
490
|
+
print("\n=== Test 6: Get Crew Metadata ===")
|
|
491
|
+
metadata = await crew_redis.get_crew_metadata("test_crew")
|
|
492
|
+
if metadata:
|
|
493
|
+
print(f"Crew metadata:")
|
|
494
|
+
for key, value in metadata.items():
|
|
495
|
+
print(f" - {key}: {value}")
|
|
496
|
+
|
|
497
|
+
# Test 7: Update metadata
|
|
498
|
+
print("\n=== Test 7: Update Metadata ===")
|
|
499
|
+
updated = await crew_redis.update_crew_metadata(
|
|
500
|
+
"test_crew",
|
|
501
|
+
{"version": "1.1", "last_test": datetime.utcnow().isoformat()}
|
|
502
|
+
)
|
|
503
|
+
print(f"Metadata updated: {updated}")
|
|
504
|
+
|
|
505
|
+
# Test 8: Get all crews
|
|
506
|
+
print("\n=== Test 8: Get All Crews ===")
|
|
507
|
+
all_crews = await crew_redis.get_all_crews()
|
|
508
|
+
print(f"Total crews: {len(all_crews)}")
|
|
509
|
+
|
|
510
|
+
# Cleanup
|
|
511
|
+
print("\n=== Cleanup ===")
|
|
512
|
+
deleted = await crew_redis.delete_crew("test_crew")
|
|
513
|
+
print(f"Crew deleted: {deleted}")
|
|
514
|
+
|
|
515
|
+
print("\n✓ All tests passed!")
|
|
516
|
+
|
|
517
|
+
finally:
|
|
518
|
+
await crew_redis.close()
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
if __name__ == "__main__":
|
|
522
|
+
import asyncio
|
|
523
|
+
asyncio.run(test_crew_redis())
|