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,303 @@
|
|
|
1
|
+
# AgentsCrew Redis Persistence - Integrated into BotManager
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Redis persistence for AgentsCrew has been **fully integrated into BotManager**. Crews are automatically saved to and loaded from Redis, making persistence completely transparent to users of the API.
|
|
6
|
+
|
|
7
|
+
## How It Works
|
|
8
|
+
|
|
9
|
+
### Automatic Persistence
|
|
10
|
+
|
|
11
|
+
The BotManager now handles all Redis persistence automatically:
|
|
12
|
+
|
|
13
|
+
1. **On Startup** (`on_startup`):
|
|
14
|
+
- All crews are loaded from Redis into memory
|
|
15
|
+
- Similar to how bots are loaded from the database
|
|
16
|
+
|
|
17
|
+
2. **When Creating/Updating a Crew** (`add_crew`):
|
|
18
|
+
- Crew is added to in-memory cache
|
|
19
|
+
- Automatically saved to Redis (key: `crew:{name}`)
|
|
20
|
+
- If Redis fails, crew remains in memory with a warning
|
|
21
|
+
|
|
22
|
+
3. **When Getting a Crew** (`get_crew`):
|
|
23
|
+
- First checks in-memory cache
|
|
24
|
+
- If not found, loads from Redis
|
|
25
|
+
- Reconstructs the crew and caches it in memory
|
|
26
|
+
|
|
27
|
+
4. **When Deleting a Crew** (`remove_crew`):
|
|
28
|
+
- Removes from in-memory cache
|
|
29
|
+
- Automatically deletes from Redis
|
|
30
|
+
- If Redis fails, crew is still removed from memory
|
|
31
|
+
|
|
32
|
+
## Key Format
|
|
33
|
+
|
|
34
|
+
Crews are stored in Redis with the following key structure:
|
|
35
|
+
|
|
36
|
+
- **Crew Definition**: `crew:{name}` - Full CrewDefinition as JSON
|
|
37
|
+
- **Crew List**: `crew:list` - Set of all crew names
|
|
38
|
+
- **ID Mapping**: `crew:id:{crew_id}` - Maps crew_id to crew name
|
|
39
|
+
- **Redis Database**: DB 2 (separate from conversation history on DB 3)
|
|
40
|
+
|
|
41
|
+
## Usage
|
|
42
|
+
|
|
43
|
+
### Via REST API
|
|
44
|
+
|
|
45
|
+
The persistence is **completely transparent**. Just use the crew endpoints normally:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# Create a crew (automatically saved to Redis)
|
|
49
|
+
curl -X PUT http://localhost:5000/api/v1/crew \
|
|
50
|
+
-H "Content-Type: application/json" \
|
|
51
|
+
-d '{
|
|
52
|
+
"name": "research_team",
|
|
53
|
+
"execution_mode": "sequential",
|
|
54
|
+
"agents": [...]
|
|
55
|
+
}'
|
|
56
|
+
|
|
57
|
+
# Get a crew (loads from Redis if not in memory)
|
|
58
|
+
curl http://localhost:5000/api/v1/crew?name=research_team
|
|
59
|
+
|
|
60
|
+
# Execute a crew
|
|
61
|
+
curl -X POST http://localhost:5000/api/v1/crew \
|
|
62
|
+
-H "Content-Type: application/json" \
|
|
63
|
+
-d '{
|
|
64
|
+
"crew_id": "research_team",
|
|
65
|
+
"query": "Research AI trends"
|
|
66
|
+
}'
|
|
67
|
+
|
|
68
|
+
# Delete a crew (removes from both memory and Redis)
|
|
69
|
+
curl -X DELETE http://localhost:5000/api/v1/crew?name=research_team
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Programmatically
|
|
73
|
+
|
|
74
|
+
If you're using BotManager directly in code:
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from parrot.manager.manager import BotManager
|
|
78
|
+
from parrot.handlers.crew.models import CrewDefinition, AgentDefinition, ExecutionMode
|
|
79
|
+
|
|
80
|
+
# Initialize manager
|
|
81
|
+
bot_manager = BotManager()
|
|
82
|
+
|
|
83
|
+
# Create crew definition
|
|
84
|
+
crew_def = CrewDefinition(
|
|
85
|
+
name="my_crew",
|
|
86
|
+
execution_mode=ExecutionMode.SEQUENTIAL,
|
|
87
|
+
agents=[
|
|
88
|
+
AgentDefinition(
|
|
89
|
+
agent_id="agent1",
|
|
90
|
+
agent_class="BasicAgent",
|
|
91
|
+
name="Agent 1",
|
|
92
|
+
config={"model": "gpt-4"}
|
|
93
|
+
)
|
|
94
|
+
]
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
# Create and add crew (automatically saved to Redis)
|
|
98
|
+
crew = await bot_manager._create_crew_from_definition(crew_def)
|
|
99
|
+
await bot_manager.add_crew(crew_def.name, crew, crew_def)
|
|
100
|
+
|
|
101
|
+
# Get crew (loads from Redis if not in memory)
|
|
102
|
+
crew_data = await bot_manager.get_crew("my_crew")
|
|
103
|
+
if crew_data:
|
|
104
|
+
crew, crew_def = crew_data
|
|
105
|
+
print(f"Loaded: {crew_def.name}")
|
|
106
|
+
|
|
107
|
+
# Remove crew (deletes from both memory and Redis)
|
|
108
|
+
await bot_manager.remove_crew("my_crew")
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Configuration
|
|
112
|
+
|
|
113
|
+
Redis configuration is in `parrot/conf.py`:
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
REDIS_HOST = 'localhost' # Default
|
|
117
|
+
REDIS_PORT = 6379 # Default
|
|
118
|
+
REDIS_DB = 2 # CrewRedis uses DB 2
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Startup Behavior
|
|
122
|
+
|
|
123
|
+
When the application starts:
|
|
124
|
+
|
|
125
|
+
1. **Loads Bots** from database (existing behavior)
|
|
126
|
+
2. **Loads Crews** from Redis (new behavior)
|
|
127
|
+
3. Both are ready for use immediately
|
|
128
|
+
|
|
129
|
+
Example startup log:
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
INFO :: Bots loaded successfully. Total active bots: 5
|
|
133
|
+
INFO Loading 3 crews from Redis...
|
|
134
|
+
INFO Loaded crew 'research_team' with 3 agents in sequential mode
|
|
135
|
+
INFO Loaded crew 'writing_team' with 2 agents in parallel mode
|
|
136
|
+
INFO Loaded crew 'analysis_crew' with 4 agents in flow mode
|
|
137
|
+
INFO :: Crews loaded successfully. Total active crews: 3
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Benefits
|
|
141
|
+
|
|
142
|
+
### 1. **Zero Configuration**
|
|
143
|
+
- No manual Redis calls needed
|
|
144
|
+
- Works out of the box
|
|
145
|
+
|
|
146
|
+
### 2. **Persistence Across Restarts**
|
|
147
|
+
- Crews survive server restarts
|
|
148
|
+
- Automatically restored on startup
|
|
149
|
+
|
|
150
|
+
### 3. **Graceful Degradation**
|
|
151
|
+
- If Redis is unavailable, crews still work in-memory
|
|
152
|
+
- Warnings logged for Redis failures
|
|
153
|
+
|
|
154
|
+
### 4. **Performance**
|
|
155
|
+
- In-memory cache for fast access
|
|
156
|
+
- Redis only accessed on cache miss
|
|
157
|
+
|
|
158
|
+
## Architecture
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
┌─────────────────┐
|
|
162
|
+
│ REST API │
|
|
163
|
+
│ CrewHandler │
|
|
164
|
+
└────────┬────────┘
|
|
165
|
+
│
|
|
166
|
+
▼
|
|
167
|
+
┌─────────────────┐
|
|
168
|
+
│ BotManager │
|
|
169
|
+
│ │
|
|
170
|
+
│ ┌───────────┐ │
|
|
171
|
+
│ │ Memory │ │ ← Fast in-memory cache
|
|
172
|
+
│ │ Cache │ │
|
|
173
|
+
│ └───────────┘ │
|
|
174
|
+
│ │ │
|
|
175
|
+
│ ▼ │
|
|
176
|
+
│ ┌───────────┐ │
|
|
177
|
+
│ │CrewRedis │ │ ← Persistent storage
|
|
178
|
+
│ └───────────┘ │
|
|
179
|
+
└────────┬────────┘
|
|
180
|
+
│
|
|
181
|
+
▼
|
|
182
|
+
┌─────────────────┐
|
|
183
|
+
│ Redis DB 2 │
|
|
184
|
+
└─────────────────┘
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Error Handling
|
|
188
|
+
|
|
189
|
+
The system handles Redis failures gracefully:
|
|
190
|
+
|
|
191
|
+
```python
|
|
192
|
+
# If Redis is down during startup
|
|
193
|
+
WARNING Redis connection failed, skipping crew loading
|
|
194
|
+
# → Application starts with empty crew cache
|
|
195
|
+
|
|
196
|
+
# If Redis fails during save
|
|
197
|
+
ERROR Failed to save crew 'my_crew' to Redis: Connection refused
|
|
198
|
+
INFO Crew 'my_crew' registered in memory only (Redis persistence failed)
|
|
199
|
+
# → Crew works normally but won't survive restart
|
|
200
|
+
|
|
201
|
+
# If Redis fails during delete
|
|
202
|
+
ERROR Failed to delete crew 'my_crew' from Redis: Connection refused
|
|
203
|
+
INFO Crew 'my_crew' removed from memory only
|
|
204
|
+
# → Crew removed from memory but remains in Redis (manual cleanup needed)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Monitoring
|
|
208
|
+
|
|
209
|
+
Check crew statistics:
|
|
210
|
+
|
|
211
|
+
```python
|
|
212
|
+
stats = bot_manager.get_crew_stats()
|
|
213
|
+
print(stats)
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Returns:
|
|
217
|
+
|
|
218
|
+
```python
|
|
219
|
+
{
|
|
220
|
+
'total_crews': 3,
|
|
221
|
+
'crews_by_mode': {
|
|
222
|
+
'sequential': 1,
|
|
223
|
+
'parallel': 1,
|
|
224
|
+
'flow': 1
|
|
225
|
+
},
|
|
226
|
+
'total_agents': 9,
|
|
227
|
+
'crews': [
|
|
228
|
+
{'name': 'research_team', 'crew_id': 'uuid...', 'mode': 'sequential', 'agent_count': 3},
|
|
229
|
+
{'name': 'writing_team', 'crew_id': 'uuid...', 'mode': 'parallel', 'agent_count': 2},
|
|
230
|
+
{'name': 'analysis_crew', 'crew_id': 'uuid...', 'mode': 'flow', 'agent_count': 4}
|
|
231
|
+
]
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Direct Redis Access (Optional)
|
|
236
|
+
|
|
237
|
+
If you need to access Redis directly for debugging:
|
|
238
|
+
|
|
239
|
+
```python
|
|
240
|
+
# Access the Redis client from BotManager
|
|
241
|
+
crew_redis = bot_manager.crew_redis
|
|
242
|
+
|
|
243
|
+
# Check connection
|
|
244
|
+
is_connected = await crew_redis.ping()
|
|
245
|
+
|
|
246
|
+
# List all crews in Redis
|
|
247
|
+
crew_names = await crew_redis.list_crews()
|
|
248
|
+
|
|
249
|
+
# Get crew metadata
|
|
250
|
+
metadata = await crew_redis.get_crew_metadata("my_crew")
|
|
251
|
+
|
|
252
|
+
# Clear all crews (caution!)
|
|
253
|
+
deleted_count = await crew_redis.clear_all_crews()
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Migration
|
|
257
|
+
|
|
258
|
+
If you have crews in the old standalone CrewRedis system, they're automatically accessible via BotManager's `get_crew()` method, which will load them from Redis on first access.
|
|
259
|
+
|
|
260
|
+
## Troubleshooting
|
|
261
|
+
|
|
262
|
+
### Crew not found after restart
|
|
263
|
+
|
|
264
|
+
Check if Redis is running:
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
redis-cli ping
|
|
268
|
+
# Should return: PONG
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Check if crew is in Redis:
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
redis-cli -n 2 KEYS "crew:*"
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Redis connection errors
|
|
278
|
+
|
|
279
|
+
Verify Redis configuration in `parrot/conf.py`:
|
|
280
|
+
|
|
281
|
+
```python
|
|
282
|
+
REDIS_HOST = 'localhost'
|
|
283
|
+
REDIS_PORT = 6379
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Test connection:
|
|
287
|
+
|
|
288
|
+
```python
|
|
289
|
+
await bot_manager.crew_redis.ping()
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## Summary
|
|
293
|
+
|
|
294
|
+
Redis persistence for crews is now **fully automatic**:
|
|
295
|
+
|
|
296
|
+
✅ Crews are saved to Redis when created
|
|
297
|
+
✅ Crews are loaded from Redis on startup
|
|
298
|
+
✅ Crews are loaded from Redis on first access
|
|
299
|
+
✅ Crews are deleted from Redis when removed
|
|
300
|
+
✅ All transparent to API users
|
|
301
|
+
✅ Graceful fallback if Redis is unavailable
|
|
302
|
+
|
|
303
|
+
No manual Redis operations needed - just use the CrewHandler API!
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
# Redis Persistence for AgentsCrew
|
|
2
|
+
|
|
3
|
+
This module provides async-based Redis persistence for AgentsCrew definitions, allowing crews to be stored, retrieved, and managed across sessions.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `CrewRedis` class enables you to:
|
|
8
|
+
- Save crew definitions to Redis with key format `crew:{name}`
|
|
9
|
+
- Load crew definitions by name or crew_id
|
|
10
|
+
- List all available crews
|
|
11
|
+
- Update crew metadata
|
|
12
|
+
- Delete crews
|
|
13
|
+
- Manage multiple crews efficiently
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
The Redis persistence layer requires the `redis` package with async support:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install redis
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Configuration
|
|
24
|
+
|
|
25
|
+
Redis configuration is managed through `parrot/conf.py`:
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
REDIS_HOST = 'localhost' # Default
|
|
29
|
+
REDIS_PORT = 6379 # Default
|
|
30
|
+
REDIS_DB = 2 # CrewRedis uses DB 2 by default
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Basic Usage
|
|
34
|
+
|
|
35
|
+
### Initialize CrewRedis
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from parrot.handlers.crew.redis_persistence import CrewRedis
|
|
39
|
+
|
|
40
|
+
# Use default configuration
|
|
41
|
+
crew_redis = CrewRedis()
|
|
42
|
+
|
|
43
|
+
# Or specify custom Redis URL
|
|
44
|
+
crew_redis = CrewRedis(redis_url="redis://localhost:6379/2")
|
|
45
|
+
|
|
46
|
+
# Check connection
|
|
47
|
+
is_connected = await crew_redis.ping()
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Save a Crew Definition
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from parrot.handlers.crew.models import CrewDefinition, AgentDefinition, ExecutionMode
|
|
54
|
+
|
|
55
|
+
# Create a crew definition
|
|
56
|
+
crew_def = CrewDefinition(
|
|
57
|
+
name="blog_writing_team",
|
|
58
|
+
description="A crew for researching and writing blog posts",
|
|
59
|
+
execution_mode=ExecutionMode.SEQUENTIAL,
|
|
60
|
+
agents=[
|
|
61
|
+
AgentDefinition(
|
|
62
|
+
agent_id="researcher",
|
|
63
|
+
agent_class="BasicAgent",
|
|
64
|
+
name="Content Researcher",
|
|
65
|
+
config={"model": "gpt-4", "temperature": 0.7},
|
|
66
|
+
tools=["web_search", "summarize"],
|
|
67
|
+
system_prompt="You are an expert researcher."
|
|
68
|
+
),
|
|
69
|
+
AgentDefinition(
|
|
70
|
+
agent_id="writer",
|
|
71
|
+
agent_class="BasicAgent",
|
|
72
|
+
name="Blog Writer",
|
|
73
|
+
config={"model": "gpt-4", "temperature": 0.9},
|
|
74
|
+
tools=["write", "format_markdown"],
|
|
75
|
+
system_prompt="You are a creative blog writer."
|
|
76
|
+
)
|
|
77
|
+
],
|
|
78
|
+
shared_tools=["calculator"],
|
|
79
|
+
metadata={"version": "1.0", "author": "content_team"}
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# Save to Redis (key: crew:blog_writing_team)
|
|
83
|
+
success = await crew_redis.save_crew(crew_def)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Load a Crew Definition
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
# Load by name (key: crew:blog_writing_team)
|
|
90
|
+
crew = await crew_redis.load_crew("blog_writing_team")
|
|
91
|
+
|
|
92
|
+
if crew:
|
|
93
|
+
print(f"Loaded crew: {crew.name}")
|
|
94
|
+
print(f"Agents: {len(crew.agents)}")
|
|
95
|
+
print(f"Execution mode: {crew.execution_mode}")
|
|
96
|
+
|
|
97
|
+
# Load by crew_id
|
|
98
|
+
crew = await crew_redis.load_crew_by_id("some-uuid-here")
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### List All Crews
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
# Get list of crew names
|
|
105
|
+
crew_names = await crew_redis.list_crews()
|
|
106
|
+
print(f"Available crews: {crew_names}")
|
|
107
|
+
|
|
108
|
+
# Get all crew definitions
|
|
109
|
+
all_crews = await crew_redis.get_all_crews()
|
|
110
|
+
for crew in all_crews:
|
|
111
|
+
print(f"{crew.name}: {crew.description}")
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Check Crew Existence
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
exists = await crew_redis.crew_exists("blog_writing_team")
|
|
118
|
+
if exists:
|
|
119
|
+
print("Crew exists in Redis")
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Update Crew Metadata
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
# Update metadata without loading full definition
|
|
126
|
+
success = await crew_redis.update_crew_metadata(
|
|
127
|
+
"blog_writing_team",
|
|
128
|
+
{
|
|
129
|
+
"status": "active",
|
|
130
|
+
"runs": 10,
|
|
131
|
+
"last_run": "2025-12-12T10:00:00"
|
|
132
|
+
}
|
|
133
|
+
)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Get Crew Metadata
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
# Get metadata without loading full crew definition
|
|
140
|
+
metadata = await crew_redis.get_crew_metadata("blog_writing_team")
|
|
141
|
+
if metadata:
|
|
142
|
+
print(f"Crew ID: {metadata['crew_id']}")
|
|
143
|
+
print(f"Agent count: {metadata['agent_count']}")
|
|
144
|
+
print(f"Created at: {metadata['created_at']}")
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Delete a Crew
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
# Delete crew from Redis
|
|
151
|
+
success = await crew_redis.delete_crew("blog_writing_team")
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Clean Up
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
# Close Redis connection when done
|
|
158
|
+
await crew_redis.close()
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Key Format
|
|
162
|
+
|
|
163
|
+
The CrewRedis class uses the following key formats in Redis:
|
|
164
|
+
|
|
165
|
+
- **Crew Definition**: `crew:{name}` - Stores the full CrewDefinition as JSON
|
|
166
|
+
- **Crew List**: `crew:list` - Set of all crew names
|
|
167
|
+
- **ID Mapping**: `crew:id:{crew_id}` - Maps crew_id to crew name for lookup by ID
|
|
168
|
+
|
|
169
|
+
## Advanced Usage
|
|
170
|
+
|
|
171
|
+
### Flow-Based Crews
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
from parrot.handlers.crew.models import FlowRelation
|
|
175
|
+
|
|
176
|
+
crew_def = CrewDefinition(
|
|
177
|
+
name="research_synthesis_team",
|
|
178
|
+
description="Parallel research with synthesis",
|
|
179
|
+
execution_mode=ExecutionMode.FLOW,
|
|
180
|
+
agents=[
|
|
181
|
+
AgentDefinition(
|
|
182
|
+
agent_id="coordinator",
|
|
183
|
+
name="Research Coordinator",
|
|
184
|
+
# ... config
|
|
185
|
+
),
|
|
186
|
+
AgentDefinition(
|
|
187
|
+
agent_id="tech_researcher",
|
|
188
|
+
name="Tech Researcher",
|
|
189
|
+
# ... config
|
|
190
|
+
),
|
|
191
|
+
AgentDefinition(
|
|
192
|
+
agent_id="synthesizer",
|
|
193
|
+
name="Synthesizer",
|
|
194
|
+
# ... config
|
|
195
|
+
)
|
|
196
|
+
],
|
|
197
|
+
flow_relations=[
|
|
198
|
+
# Coordinator runs first, then researchers in parallel
|
|
199
|
+
FlowRelation(
|
|
200
|
+
source="coordinator",
|
|
201
|
+
target=["tech_researcher", "market_researcher"]
|
|
202
|
+
),
|
|
203
|
+
# Synthesizer runs after both researchers complete
|
|
204
|
+
FlowRelation(
|
|
205
|
+
source=["tech_researcher", "market_researcher"],
|
|
206
|
+
target="synthesizer"
|
|
207
|
+
)
|
|
208
|
+
]
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
await crew_redis.save_crew(crew_def)
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Bulk Operations
|
|
215
|
+
|
|
216
|
+
```python
|
|
217
|
+
# Get all crews
|
|
218
|
+
all_crews = await crew_redis.get_all_crews()
|
|
219
|
+
|
|
220
|
+
# Filter by execution mode
|
|
221
|
+
sequential_crews = [
|
|
222
|
+
crew for crew in all_crews
|
|
223
|
+
if crew.execution_mode == ExecutionMode.SEQUENTIAL
|
|
224
|
+
]
|
|
225
|
+
|
|
226
|
+
# Clear all crews (use with caution!)
|
|
227
|
+
deleted_count = await crew_redis.clear_all_crews()
|
|
228
|
+
print(f"Deleted {deleted_count} crews")
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Integration with BotManager
|
|
232
|
+
|
|
233
|
+
The CrewRedis class can be integrated with the existing BotManager for persistent storage:
|
|
234
|
+
|
|
235
|
+
```python
|
|
236
|
+
class BotManager:
|
|
237
|
+
def __init__(self):
|
|
238
|
+
self._crews = {} # In-memory cache
|
|
239
|
+
self.crew_redis = CrewRedis() # Persistent storage
|
|
240
|
+
|
|
241
|
+
async def create_crew(self, crew_def: CrewDefinition):
|
|
242
|
+
# Create crew instance
|
|
243
|
+
crew = AgentCrew(name=crew_def.name, agents=agents)
|
|
244
|
+
|
|
245
|
+
# Cache in memory
|
|
246
|
+
self._crews[crew_def.crew_id] = (crew, crew_def)
|
|
247
|
+
|
|
248
|
+
# Persist to Redis
|
|
249
|
+
await self.crew_redis.save_crew(crew_def)
|
|
250
|
+
|
|
251
|
+
async def get_crew(self, crew_id: str):
|
|
252
|
+
# Check memory cache first
|
|
253
|
+
if crew_id in self._crews:
|
|
254
|
+
return self._crews[crew_id]
|
|
255
|
+
|
|
256
|
+
# Load from Redis
|
|
257
|
+
crew_def = await self.crew_redis.load_crew_by_id(crew_id)
|
|
258
|
+
if crew_def:
|
|
259
|
+
# Reconstruct crew from definition
|
|
260
|
+
crew = self._create_crew_from_definition(crew_def)
|
|
261
|
+
self._crews[crew_id] = (crew, crew_def)
|
|
262
|
+
return (crew, crew_def)
|
|
263
|
+
|
|
264
|
+
return None
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Error Handling
|
|
268
|
+
|
|
269
|
+
The CrewRedis class includes comprehensive error handling and logging:
|
|
270
|
+
|
|
271
|
+
```python
|
|
272
|
+
try:
|
|
273
|
+
crew = await crew_redis.load_crew("nonexistent_crew")
|
|
274
|
+
if crew is None:
|
|
275
|
+
print("Crew not found")
|
|
276
|
+
except Exception as e:
|
|
277
|
+
print(f"Error loading crew: {e}")
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
All methods return appropriate values:
|
|
281
|
+
- `save_crew()`: Returns `True` on success, `False` on failure
|
|
282
|
+
- `load_crew()`: Returns `CrewDefinition` if found, `None` otherwise
|
|
283
|
+
- `delete_crew()`: Returns `True` if deleted, `False` if not found
|
|
284
|
+
- `list_crews()`: Returns empty list on error
|
|
285
|
+
|
|
286
|
+
## Performance Considerations
|
|
287
|
+
|
|
288
|
+
1. **Connection Pooling**: The Redis client automatically manages connection pooling
|
|
289
|
+
2. **Serialization**: Uses JSON for efficient serialization/deserialization
|
|
290
|
+
3. **Caching**: Consider implementing an in-memory cache layer for frequently accessed crews
|
|
291
|
+
4. **Batch Operations**: Use `get_all_crews()` for bulk loading instead of multiple individual loads
|
|
292
|
+
|
|
293
|
+
## Testing
|
|
294
|
+
|
|
295
|
+
Run the built-in test suite:
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
# Test the persistence layer
|
|
299
|
+
python parrot/handlers/crew/redis_persistence.py
|
|
300
|
+
|
|
301
|
+
# Run the comprehensive examples
|
|
302
|
+
python examples/crew/redis_persistence_example.py
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## Database Selection
|
|
306
|
+
|
|
307
|
+
By default, CrewRedis uses Redis database 2 to avoid conflicts with other Redis-based storage:
|
|
308
|
+
|
|
309
|
+
- **DB 0**: General purpose (default)
|
|
310
|
+
- **DB 1**: Configuration cache
|
|
311
|
+
- **DB 2**: Crew persistence (CrewRedis)
|
|
312
|
+
- **DB 3**: Conversation history
|
|
313
|
+
- **DB 4**: Services
|
|
314
|
+
|
|
315
|
+
## Troubleshooting
|
|
316
|
+
|
|
317
|
+
### Redis Connection Failed
|
|
318
|
+
|
|
319
|
+
```python
|
|
320
|
+
if not await crew_redis.ping():
|
|
321
|
+
print("Check Redis server is running: redis-cli ping")
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Serialization Errors
|
|
325
|
+
|
|
326
|
+
Ensure all crew data types are JSON-serializable. The module automatically handles datetime serialization.
|
|
327
|
+
|
|
328
|
+
### Key Conflicts
|
|
329
|
+
|
|
330
|
+
If using custom key prefixes, ensure they don't conflict with existing Redis keys:
|
|
331
|
+
|
|
332
|
+
```python
|
|
333
|
+
crew_redis = CrewRedis(key_prefix="myapp_crew")
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## Example Scripts
|
|
337
|
+
|
|
338
|
+
See `/examples/crew/redis_persistence_example.py` for comprehensive examples including:
|
|
339
|
+
- Basic persistence
|
|
340
|
+
- Flow-based crews
|
|
341
|
+
- Metadata updates
|
|
342
|
+
- Bulk operations
|
|
343
|
+
|
|
344
|
+
## API Reference
|
|
345
|
+
|
|
346
|
+
### CrewRedis Class
|
|
347
|
+
|
|
348
|
+
#### Methods
|
|
349
|
+
|
|
350
|
+
- `__init__(redis_url=None, key_prefix="crew", db=2)`
|
|
351
|
+
- `save_crew(crew: CrewDefinition) -> bool`
|
|
352
|
+
- `load_crew(name: str) -> Optional[CrewDefinition]`
|
|
353
|
+
- `load_crew_by_id(crew_id: str) -> Optional[CrewDefinition]`
|
|
354
|
+
- `delete_crew(name: str) -> bool`
|
|
355
|
+
- `list_crews() -> List[str]`
|
|
356
|
+
- `crew_exists(name: str) -> bool`
|
|
357
|
+
- `get_all_crews() -> List[CrewDefinition]`
|
|
358
|
+
- `get_crew_metadata(name: str) -> Optional[Dict[str, Any]]`
|
|
359
|
+
- `update_crew_metadata(name: str, metadata: Dict[str, Any]) -> bool`
|
|
360
|
+
- `ping() -> bool`
|
|
361
|
+
- `close() -> None`
|
|
362
|
+
- `clear_all_crews() -> int`
|
|
363
|
+
|
|
364
|
+
## License
|
|
365
|
+
|
|
366
|
+
This module is part of the ai-parrot project and follows the same MIT license.
|
|
File without changes
|