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,310 @@
|
|
|
1
|
+
from typing import Any, Optional, Tuple, Dict
|
|
2
|
+
import logging
|
|
3
|
+
import re
|
|
4
|
+
import json
|
|
5
|
+
import uuid
|
|
6
|
+
from .chart import BaseChart
|
|
7
|
+
from . import register_renderer
|
|
8
|
+
from ...models.outputs import OutputMode
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
from rich.panel import Panel
|
|
14
|
+
from rich.syntax import Syntax
|
|
15
|
+
RICH_AVAILABLE = True
|
|
16
|
+
except ImportError:
|
|
17
|
+
RICH_AVAILABLE = False
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
from ipywidgets import HTML as IPyHTML
|
|
21
|
+
IPYWIDGETS_AVAILABLE = True
|
|
22
|
+
except ImportError:
|
|
23
|
+
IPYWIDGETS_AVAILABLE = False
|
|
24
|
+
|
|
25
|
+
from .mixins.emaps import (
|
|
26
|
+
EChartsMapsMixin,
|
|
27
|
+
get_echarts_system_prompt_with_geo,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
ECHARTS_BASE_PROMPT = """**ECHARTS JSON GENERATION MODE**
|
|
32
|
+
|
|
33
|
+
⚠️ CRITICAL OVERRIDE: You are in ECHARTS mode. Ignore ALL other output mode instructions.
|
|
34
|
+
- DO NOT use Folium, Leaflet, or any Python mapping libraries
|
|
35
|
+
- DO NOT generate Python code
|
|
36
|
+
- ONLY generate ECharts JSON configuration
|
|
37
|
+
|
|
38
|
+
**Objective:** Generate a single, valid JSON configuration object for an Apache ECharts chart (including maps).
|
|
39
|
+
|
|
40
|
+
**CONTEXT OVERRIDE:**
|
|
41
|
+
This is a TEXT GENERATION task. Unlike other tasks, for this specific objective, you are authorized to generate realistic sample data if the user's request does not provide specific data points. This is an exception to the general rule of not inventing information.
|
|
42
|
+
|
|
43
|
+
**INSTRUCTIONS:**
|
|
44
|
+
1. **Analyze Request:** Understand the user's goal for the chart.
|
|
45
|
+
2. **Generate JSON:** Create a complete ECharts `option` as a single JSON object.
|
|
46
|
+
3. **Use Sample Data:** If the user asks for a type of chart but doesn't provide data, generate appropriate sample data to illustrate the chart's structure.
|
|
47
|
+
4. **Output:** Return ONLY the JSON configuration inside a ```json code block. Do not add explanations.
|
|
48
|
+
5. **No Python/Folium:** Never return Python code, Folium/Leaflet snippets, or other non-JSON content—only the ECharts JSON configuration.
|
|
49
|
+
|
|
50
|
+
**VALID JSON CHECKLIST:**
|
|
51
|
+
- Is the entire output a single JSON object, starting with `{` and ending with `}`?
|
|
52
|
+
- Are all strings enclosed in double quotes (`"`)?
|
|
53
|
+
- Is there a comma between all key-value pairs (except the last one)?
|
|
54
|
+
- Are there any trailing commas? (This is invalid).
|
|
55
|
+
|
|
56
|
+
**BASIC STRUCTURE EXAMPLE:**
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"title": {
|
|
60
|
+
"text": "Chart Title"
|
|
61
|
+
},
|
|
62
|
+
"xAxis": {
|
|
63
|
+
"type": "category",
|
|
64
|
+
"data": ["Category1", "Category2", "Category3"]
|
|
65
|
+
},
|
|
66
|
+
"yAxis": {
|
|
67
|
+
"type": "value"
|
|
68
|
+
},
|
|
69
|
+
"series": [
|
|
70
|
+
{
|
|
71
|
+
"name": "Series Name",
|
|
72
|
+
"type": "bar",
|
|
73
|
+
"data": [120, 200, 150]
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**EXAMPLE 1: User requests a pie chart without data.**
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"title": {
|
|
83
|
+
"text": "Sample Pie Chart"
|
|
84
|
+
},
|
|
85
|
+
"series": [
|
|
86
|
+
{
|
|
87
|
+
"type": "pie",
|
|
88
|
+
"data": [
|
|
89
|
+
{"value": 335, "name": "Category A"},
|
|
90
|
+
{"value": 234, "name": "Category B"},
|
|
91
|
+
{"value": 154, "name": "Category C"}
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**GEO/MAP SUPPORT:**
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
ECHARTS_SYSTEM_PROMPT = get_echarts_system_prompt_with_geo(ECHARTS_BASE_PROMPT)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@register_renderer(OutputMode.ECHARTS, system_prompt=ECHARTS_SYSTEM_PROMPT)
|
|
106
|
+
class EChartsRenderer(EChartsMapsMixin, BaseChart):
|
|
107
|
+
"""Renderer for Apache ECharts (JSON Configuration)"""
|
|
108
|
+
|
|
109
|
+
def execute_code(
|
|
110
|
+
self,
|
|
111
|
+
code: str,
|
|
112
|
+
pandas_tool: Any = None,
|
|
113
|
+
**kwargs,
|
|
114
|
+
) -> Tuple[Any, Optional[str]]:
|
|
115
|
+
"""Parse and validate ECharts JSON configuration."""
|
|
116
|
+
try:
|
|
117
|
+
# Clean up code string if needed (remove markdown blocks if still present)
|
|
118
|
+
cleaned_code = self._extract_json_code(code) or code
|
|
119
|
+
|
|
120
|
+
# Parse JSON
|
|
121
|
+
config = json.loads(cleaned_code)
|
|
122
|
+
|
|
123
|
+
# Unwrap common nested structure `{ "option": { ... } }`
|
|
124
|
+
if (
|
|
125
|
+
isinstance(config, dict)
|
|
126
|
+
and 'option' in config
|
|
127
|
+
and isinstance(config['option'], dict)
|
|
128
|
+
):
|
|
129
|
+
# If the response wraps the actual chart config under an
|
|
130
|
+
# "option" key, use the inner configuration for validation and
|
|
131
|
+
# rendering. This aligns with typical ECharts code snippets and
|
|
132
|
+
# prevents false validation errors.
|
|
133
|
+
config = config['option']
|
|
134
|
+
|
|
135
|
+
# Basic validation - check for required structure
|
|
136
|
+
if not isinstance(config, dict):
|
|
137
|
+
return None, "ECharts config must be a JSON object"
|
|
138
|
+
|
|
139
|
+
# 'series' is usually required, but 'dataset' or 'options' (for timeline) are also valid
|
|
140
|
+
if all(
|
|
141
|
+
k not in config
|
|
142
|
+
for k in ['series', 'dataset', 'options', 'baseOption']
|
|
143
|
+
):
|
|
144
|
+
return None, "ECharts config must include 'series', 'dataset', or timeline 'options'"
|
|
145
|
+
|
|
146
|
+
return config, None
|
|
147
|
+
|
|
148
|
+
except json.JSONDecodeError as e:
|
|
149
|
+
return None, f"Invalid JSON: {str(e)}"
|
|
150
|
+
except Exception as e:
|
|
151
|
+
return None, f"Validation error: {str(e)}"
|
|
152
|
+
|
|
153
|
+
def _render_chart_content(self, chart_obj: Any, **kwargs) -> str:
|
|
154
|
+
"""Render ECharts visualization content (HTML/JS)."""
|
|
155
|
+
# chart_obj is the configuration dict
|
|
156
|
+
config = chart_obj
|
|
157
|
+
chart_id = f"echarts-{uuid.uuid4().hex[:8]}"
|
|
158
|
+
|
|
159
|
+
# Convert to JSON
|
|
160
|
+
# config_json = json.dumps(config, indent=2)
|
|
161
|
+
# Get dimensions
|
|
162
|
+
width = kwargs.get('width', '100%')
|
|
163
|
+
height = kwargs.get('height', '500px')
|
|
164
|
+
# return f'''
|
|
165
|
+
# <div id="{chart_id}" style="width: {width}; height: {height};"></div>
|
|
166
|
+
# <script type="text/javascript">
|
|
167
|
+
# (function() {{
|
|
168
|
+
# var chartDom = document.getElementById('{chart_id}');
|
|
169
|
+
# if (!chartDom) return;
|
|
170
|
+
|
|
171
|
+
# var myChart = echarts.init(chartDom);
|
|
172
|
+
# var option = {config_json};
|
|
173
|
+
|
|
174
|
+
# option && myChart.setOption(option);
|
|
175
|
+
|
|
176
|
+
# // Resize handler
|
|
177
|
+
# window.addEventListener('resize', function() {{
|
|
178
|
+
# myChart.resize();
|
|
179
|
+
# }});
|
|
180
|
+
|
|
181
|
+
# console.log('ECharts {chart_id} rendered successfully');
|
|
182
|
+
# }})();
|
|
183
|
+
# </script>
|
|
184
|
+
# '''
|
|
185
|
+
# Use mixin method for enhanced geo rendering
|
|
186
|
+
return self._render_chart_content_geo(config, chart_id, width, height)
|
|
187
|
+
|
|
188
|
+
def to_html(
|
|
189
|
+
self,
|
|
190
|
+
chart_obj: Any,
|
|
191
|
+
mode: str = 'partial',
|
|
192
|
+
**kwargs
|
|
193
|
+
) -> str:
|
|
194
|
+
"""Convert ECharts to HTML."""
|
|
195
|
+
# ECharts library for <head>
|
|
196
|
+
echarts_version = kwargs.get('echarts_version', '5.4.3')
|
|
197
|
+
|
|
198
|
+
# Proper CDN URL (no markdown syntax)
|
|
199
|
+
extra_head = kwargs.get('extra_head', '') + f"""
|
|
200
|
+
<!-- Apache ECharts -->
|
|
201
|
+
<script src="https://cdn.jsdelivr.net/npm/echarts@{echarts_version}/dist/echarts.min.js"></script>
|
|
202
|
+
"""
|
|
203
|
+
|
|
204
|
+
kwargs['extra_head'] = extra_head
|
|
205
|
+
|
|
206
|
+
# Call parent to_html
|
|
207
|
+
return super().to_html(chart_obj, mode=mode, **kwargs)
|
|
208
|
+
|
|
209
|
+
async def render(
|
|
210
|
+
self,
|
|
211
|
+
response: Any,
|
|
212
|
+
theme: str = 'monokai',
|
|
213
|
+
environment: str = 'html',
|
|
214
|
+
include_code: bool = False,
|
|
215
|
+
html_mode: str = 'partial',
|
|
216
|
+
**kwargs
|
|
217
|
+
) -> Tuple[Any, Optional[Any]]:
|
|
218
|
+
"""Render ECharts visualization."""
|
|
219
|
+
|
|
220
|
+
# 1. Extract Code
|
|
221
|
+
code = getattr(response, 'code', None)
|
|
222
|
+
output_format = kwargs.get('output_format', environment)
|
|
223
|
+
|
|
224
|
+
# Fallback: Extract from text if not in structured output
|
|
225
|
+
if not code:
|
|
226
|
+
content = self._get_content(response)
|
|
227
|
+
code = self._extract_json_code(content)
|
|
228
|
+
|
|
229
|
+
if not code:
|
|
230
|
+
error_msg = "No ECharts configuration found in response"
|
|
231
|
+
if output_format == 'terminal':
|
|
232
|
+
return error_msg, None
|
|
233
|
+
error_html = self._wrap_for_environment(
|
|
234
|
+
f"<div class='error'>{error_msg}</div>",
|
|
235
|
+
output_format
|
|
236
|
+
)
|
|
237
|
+
if output_format == 'html':
|
|
238
|
+
return None, error_html
|
|
239
|
+
return error_html, None
|
|
240
|
+
|
|
241
|
+
# 2. Parse/Execute (Validation)
|
|
242
|
+
config, error = self.execute_code(code)
|
|
243
|
+
|
|
244
|
+
if error:
|
|
245
|
+
logger.error("Failed to parse ECharts JSON: %s", error)
|
|
246
|
+
if output_format == 'terminal':
|
|
247
|
+
return f"Error parsing JSON: {error}\n\n{code}", None
|
|
248
|
+
error_html = self._wrap_for_environment(
|
|
249
|
+
self._render_error(error, code, theme),
|
|
250
|
+
output_format
|
|
251
|
+
)
|
|
252
|
+
if output_format == 'html':
|
|
253
|
+
return code, error_html
|
|
254
|
+
return code, error_html
|
|
255
|
+
|
|
256
|
+
# 3. Handle Terminal Environment (Show JSON)
|
|
257
|
+
if output_format == 'terminal':
|
|
258
|
+
if RICH_AVAILABLE:
|
|
259
|
+
json_syntax = Syntax(
|
|
260
|
+
json.dumps(config, indent=2), "json", theme=theme, line_numbers=True
|
|
261
|
+
)
|
|
262
|
+
return Panel(json_syntax, title="📊 ECharts Configuration (JSON)", border_style="blue"), None
|
|
263
|
+
return json.dumps(config, indent=2), None
|
|
264
|
+
|
|
265
|
+
# 4. Generate HTML for Web/Jupyter
|
|
266
|
+
html_output = self.to_html(
|
|
267
|
+
config,
|
|
268
|
+
mode=html_mode,
|
|
269
|
+
include_code=include_code,
|
|
270
|
+
code=code,
|
|
271
|
+
theme=theme,
|
|
272
|
+
title=kwargs.pop('title', 'ECharts Visualization'),
|
|
273
|
+
icon='📊',
|
|
274
|
+
**kwargs
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
# 5. Wrap for Environment
|
|
278
|
+
if output_format in {'jupyter', 'notebook', 'ipython', 'colab'}:
|
|
279
|
+
wrapped_html = self._wrap_for_environment(html_output, output_format)
|
|
280
|
+
else:
|
|
281
|
+
wrapped_html = html_output
|
|
282
|
+
|
|
283
|
+
# 6. Return based on output format
|
|
284
|
+
if output_format == 'html':
|
|
285
|
+
# Return the generated code along with the wrapped HTML
|
|
286
|
+
return code, wrapped_html
|
|
287
|
+
|
|
288
|
+
# Default: Return Code + Wrapped Output
|
|
289
|
+
return code, wrapped_html
|
|
290
|
+
|
|
291
|
+
@staticmethod
|
|
292
|
+
def _extract_json_code(content: str) -> Optional[str]:
|
|
293
|
+
"""Extract JSON code from markdown blocks."""
|
|
294
|
+
# Try json code block
|
|
295
|
+
pattern = r'```json\n(.*?)```'
|
|
296
|
+
if matches := re.findall(pattern, content, re.DOTALL):
|
|
297
|
+
return matches[0].strip()
|
|
298
|
+
|
|
299
|
+
# Try generic code block
|
|
300
|
+
pattern = r'```\n(.*?)```'
|
|
301
|
+
if matches := re.findall(pattern, content, re.DOTALL):
|
|
302
|
+
# Check if it looks like JSON
|
|
303
|
+
potential_json = matches[0].strip()
|
|
304
|
+
if potential_json.startswith('{') or potential_json.startswith('['):
|
|
305
|
+
return potential_json
|
|
306
|
+
|
|
307
|
+
# Maybe the content IS just the JSON string?
|
|
308
|
+
content = content.strip()
|
|
309
|
+
return content if content.startswith('{') and content.endswith('}') else None
|
|
310
|
+
|
|
File without changes
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import Any, Dict, Optional
|
|
3
|
+
import pandas as pd
|
|
4
|
+
|
|
5
|
+
class AbstractAppGenerator(ABC):
|
|
6
|
+
"""
|
|
7
|
+
Abstract base class for Application Generators.
|
|
8
|
+
Handles payload extraction and defines the interface for generation.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
def __init__(self, response: Any):
|
|
12
|
+
self.response = response
|
|
13
|
+
self.payload = self._extract_payload(response)
|
|
14
|
+
|
|
15
|
+
def _extract_payload(self, response: Any) -> Dict[str, Any]:
|
|
16
|
+
"""
|
|
17
|
+
Extract and normalize the payload from the Agent Response.
|
|
18
|
+
Can be overridden by subclasses for specific needs.
|
|
19
|
+
"""
|
|
20
|
+
payload = {
|
|
21
|
+
"input": getattr(response, "input", "No query provided"),
|
|
22
|
+
"explanation": "",
|
|
23
|
+
"data": pd.DataFrame(),
|
|
24
|
+
"code": None
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
# 1. Extract Explanation
|
|
28
|
+
output = getattr(response, "output", "")
|
|
29
|
+
if hasattr(output, "explanation"):
|
|
30
|
+
payload["explanation"] = output.explanation
|
|
31
|
+
elif hasattr(output, "response"):
|
|
32
|
+
payload["explanation"] = output.response
|
|
33
|
+
elif isinstance(output, str):
|
|
34
|
+
payload["explanation"] = output
|
|
35
|
+
|
|
36
|
+
# 2. Extract Data
|
|
37
|
+
if hasattr(output, "to_dataframe"):
|
|
38
|
+
payload["data"] = output.to_dataframe()
|
|
39
|
+
elif hasattr(output, "data") and output.data is not None:
|
|
40
|
+
payload["data"] = pd.DataFrame(output.data)
|
|
41
|
+
elif hasattr(response, "data") and response.data is not None:
|
|
42
|
+
if isinstance(response.data, pd.DataFrame):
|
|
43
|
+
payload["data"] = response.data
|
|
44
|
+
else:
|
|
45
|
+
payload["data"] = pd.DataFrame(response.data)
|
|
46
|
+
|
|
47
|
+
# 3. Extract Code
|
|
48
|
+
if hasattr(output, "code") and output.code:
|
|
49
|
+
payload["code"] = output.code
|
|
50
|
+
elif hasattr(response, "code") and response.code:
|
|
51
|
+
payload["code"] = response.code
|
|
52
|
+
|
|
53
|
+
return payload
|
|
54
|
+
|
|
55
|
+
@abstractmethod
|
|
56
|
+
def generate(self) -> Any:
|
|
57
|
+
"""
|
|
58
|
+
Generate the application output.
|
|
59
|
+
Returns source code string (for web apps) or Renderable (for terminal).
|
|
60
|
+
"""
|
|
61
|
+
pass
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
from typing import Any, Dict
|
|
2
|
+
import json
|
|
3
|
+
import pandas as pd
|
|
4
|
+
from .abstract import AbstractAppGenerator
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class PanelGenerator(AbstractAppGenerator):
|
|
8
|
+
"""Generates a single-file Panel application."""
|
|
9
|
+
|
|
10
|
+
def generate(self) -> str:
|
|
11
|
+
# 1. Serialize Data for Embedding
|
|
12
|
+
data_str = "[]"
|
|
13
|
+
if not self.payload["data"].empty:
|
|
14
|
+
data_str = self.payload["data"].to_json(orient="records")
|
|
15
|
+
|
|
16
|
+
# 2. Sanitize Strings
|
|
17
|
+
explanation = self.payload["explanation"].replace('"""', "\\\"\\\"\\\"")
|
|
18
|
+
query = self.payload["input"].replace('"', '\\"')
|
|
19
|
+
# 3. Construct Visualization Logic
|
|
20
|
+
viz_code = ""
|
|
21
|
+
imports = ["import panel as pn", "import pandas as pd", "import json"]
|
|
22
|
+
|
|
23
|
+
if code_snippet := self.payload["code"]:
|
|
24
|
+
if isinstance(code_snippet, (dict, list)):
|
|
25
|
+
# JSON Specification (Altair/Vega-Lite)
|
|
26
|
+
imports.append("import altair as alt")
|
|
27
|
+
viz_code = f"""
|
|
28
|
+
# --- Visualization (Vega-Lite JSON) ---
|
|
29
|
+
spec = {json.dumps(code_snippet)}
|
|
30
|
+
viz_pane = pn.pane.Vega(spec, sizing_mode='stretch_width', height=400)
|
|
31
|
+
"""
|
|
32
|
+
elif isinstance(code_snippet, str):
|
|
33
|
+
# Python Code Execution
|
|
34
|
+
# We wrap the execution to capture the figure
|
|
35
|
+
viz_code = f"""
|
|
36
|
+
# --- Visualization (Dynamic Code) ---
|
|
37
|
+
def get_visualization(df):
|
|
38
|
+
try:
|
|
39
|
+
# Inject dataframe into local scope
|
|
40
|
+
local_vars = {{'df': df, 'pd': pd, 'pn': pn}}
|
|
41
|
+
|
|
42
|
+
# Execute the generated code
|
|
43
|
+
exec('''{code_snippet}''', globals(), local_vars)
|
|
44
|
+
|
|
45
|
+
# Attempt to find a renderable object in locals
|
|
46
|
+
# Priority: 'fig', 'chart', 'map', or the last expression
|
|
47
|
+
for var_name in ['fig', 'chart', 'map', 'm']:
|
|
48
|
+
if var_name in local_vars:
|
|
49
|
+
return local_vars[var_name]
|
|
50
|
+
return None
|
|
51
|
+
except Exception as e:
|
|
52
|
+
return pn.pane.Alert(f"Error rendering chart: {{e}}", alert_type="danger")
|
|
53
|
+
|
|
54
|
+
viz_obj = get_visualization(df)
|
|
55
|
+
|
|
56
|
+
# Determine appropriate pane type based on object
|
|
57
|
+
if viz_obj:
|
|
58
|
+
if hasattr(viz_obj, 'to_dict') and 'data' in viz_obj.to_dict(): # Plotly
|
|
59
|
+
viz_pane = pn.pane.Plotly(viz_obj, sizing_mode='stretch_width', height=400)
|
|
60
|
+
elif hasattr(viz_obj, 'savefig'): # Matplotlib
|
|
61
|
+
viz_pane = pn.pane.Matplotlib(viz_obj, sizing_mode='stretch_width', height=400, tight=True)
|
|
62
|
+
elif hasattr(viz_obj, 'save') and hasattr(viz_obj, '_repr_html_'): # Folium/Altair
|
|
63
|
+
viz_pane = pn.pane.plot.Folium(viz_obj, sizing_mode='stretch_width', height=400)
|
|
64
|
+
else:
|
|
65
|
+
# Fallback/Generic (HoloViews, Bokeh, etc.)
|
|
66
|
+
viz_pane = pn.panel(viz_obj, sizing_mode='stretch_width')
|
|
67
|
+
else:
|
|
68
|
+
viz_pane = pn.pane.Markdown("No visualization generated.")
|
|
69
|
+
"""
|
|
70
|
+
# Add common imports just in case the generated code needs them
|
|
71
|
+
imports.extend([
|
|
72
|
+
"import matplotlib.pyplot as plt",
|
|
73
|
+
"import plotly.express as px",
|
|
74
|
+
"import plotly.graph_objects as go",
|
|
75
|
+
"import altair as alt"
|
|
76
|
+
])
|
|
77
|
+
else:
|
|
78
|
+
viz_pane = "viz_pane = pn.pane.Markdown('No visualization requested.')"
|
|
79
|
+
viz_code = viz_pane
|
|
80
|
+
|
|
81
|
+
imports = "\n".join(sorted(list(set(imports))))
|
|
82
|
+
|
|
83
|
+
# 4. Generate Full Script
|
|
84
|
+
return f"""
|
|
85
|
+
{imports}
|
|
86
|
+
pn.extension('tabulator', 'vega', 'plotly', 'katex', design='bootstrap')
|
|
87
|
+
|
|
88
|
+
# --- Data Loading ---
|
|
89
|
+
@pn.cache
|
|
90
|
+
def load_data():
|
|
91
|
+
raw_json = '{data_str}'
|
|
92
|
+
try:
|
|
93
|
+
data = json.loads(raw_json)
|
|
94
|
+
return pd.DataFrame(data)
|
|
95
|
+
except Exception:
|
|
96
|
+
return pd.DataFrame()
|
|
97
|
+
|
|
98
|
+
df = load_data()
|
|
99
|
+
|
|
100
|
+
# --- Visualizations ---
|
|
101
|
+
{viz_code}
|
|
102
|
+
|
|
103
|
+
# --- Layout Components ---
|
|
104
|
+
title = pn.pane.Markdown(f"# 🤖 AI Analysis Report\\n**Query:** `{query}`", sizing_mode='stretch_width')
|
|
105
|
+
|
|
106
|
+
explanation_pane = pn.pane.Markdown(
|
|
107
|
+
f\"\"\"{explanation}\"\"\",
|
|
108
|
+
sizing_mode='stretch_width',
|
|
109
|
+
styles={{'padding': '10px', 'background': '#f8f9fa', 'border-radius': '5px'}}
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
data_view = pn.widgets.Tabulator(
|
|
113
|
+
df,
|
|
114
|
+
pagination='remote',
|
|
115
|
+
page_size=10,
|
|
116
|
+
sizing_mode='stretch_width',
|
|
117
|
+
theme='bootstrap',
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
# --- Dashboard Template ---
|
|
121
|
+
template = pn.template.FastListTemplate(
|
|
122
|
+
title='AI-Parrot Dashboard',
|
|
123
|
+
sidebar=[
|
|
124
|
+
pn.pane.Markdown("## 📊 Data Summary"),
|
|
125
|
+
pn.indicators.Number(name='Total Rows', value=df.shape[0] if not df.empty else 0, format='{{value}}'),
|
|
126
|
+
pn.indicators.Number(name='Total Columns', value=df.shape[1] if not df.empty else 0, format='{{value}}'),
|
|
127
|
+
pn.layout.Divider(),
|
|
128
|
+
pn.pane.Markdown("### Columns"),
|
|
129
|
+
pn.pane.DataFrame(pd.DataFrame(df.columns, columns=['Name']), height=300, sizing_mode='stretch_width') if not df.empty else ""
|
|
130
|
+
],
|
|
131
|
+
main=[
|
|
132
|
+
pn.Row(title),
|
|
133
|
+
pn.Row(
|
|
134
|
+
pn.Column("### 📝 Analysis", explanation_pane, sizing_mode='stretch_width'),
|
|
135
|
+
pn.Column("### 📈 Visualization", viz_pane, sizing_mode='stretch_width')
|
|
136
|
+
),
|
|
137
|
+
pn.Row("### 🗃️ Source Data", data_view)
|
|
138
|
+
],
|
|
139
|
+
accent_base_color="#2E86C1",
|
|
140
|
+
header_background="#2E86C1",
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
if __name__.startswith("bokeh"):
|
|
144
|
+
template.servable()
|
|
145
|
+
"""
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from .abstract import AbstractAppGenerator
|
|
3
|
+
|
|
4
|
+
class StreamlitGenerator(AbstractAppGenerator):
|
|
5
|
+
"""Generates a single-file Streamlit application."""
|
|
6
|
+
|
|
7
|
+
def generate(self) -> str:
|
|
8
|
+
# Serialize data for embedding
|
|
9
|
+
data_str = "[]"
|
|
10
|
+
if not self.payload["data"].empty:
|
|
11
|
+
data_str = self.payload["data"].to_json(orient="records")
|
|
12
|
+
|
|
13
|
+
# Sanitize strings
|
|
14
|
+
explanation = self.payload["explanation"].replace('"""', "\\\"\\\"\\\"")
|
|
15
|
+
query = self.payload["input"].replace('"', '\\"')
|
|
16
|
+
# Dynamic Code Injection
|
|
17
|
+
code_section = ""
|
|
18
|
+
if code_snippet := self.payload["code"]:
|
|
19
|
+
if isinstance(code_snippet, (dict, list)):
|
|
20
|
+
# JSON Chart (Vega/Altair)
|
|
21
|
+
code_section = f"""
|
|
22
|
+
st.subheader("📊 Generated Visualization")
|
|
23
|
+
spec = {json.dumps(code_snippet)}
|
|
24
|
+
st.vega_lite_chart(data=df, spec=spec, use_container_width=True)
|
|
25
|
+
"""
|
|
26
|
+
elif isinstance(code_snippet, str):
|
|
27
|
+
# Python Code
|
|
28
|
+
# We wrap it to ensure it uses the local 'df' and 'st' context
|
|
29
|
+
code_section = f"""
|
|
30
|
+
st.subheader("📊 Analysis Visualization")
|
|
31
|
+
with st.container():
|
|
32
|
+
# Injected Code Execution
|
|
33
|
+
try:
|
|
34
|
+
{self._indent_code(code_snippet)}
|
|
35
|
+
except Exception as e:
|
|
36
|
+
st.error(f"Error rendering visualization: {{e}}")
|
|
37
|
+
st.code('''{code_snippet}''', language='python')
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
return f"""
|
|
41
|
+
import streamlit as st
|
|
42
|
+
import pandas as pd
|
|
43
|
+
import json
|
|
44
|
+
import altair as alt
|
|
45
|
+
import plotly.express as px
|
|
46
|
+
import matplotlib.pyplot as plt
|
|
47
|
+
|
|
48
|
+
st.set_page_config(page_title="Agent Analysis", layout="wide")
|
|
49
|
+
|
|
50
|
+
@st.cache_data
|
|
51
|
+
def load_data():
|
|
52
|
+
try:
|
|
53
|
+
return pd.DataFrame(json.loads('{data_str}'))
|
|
54
|
+
except:
|
|
55
|
+
return pd.DataFrame()
|
|
56
|
+
|
|
57
|
+
df = load_data()
|
|
58
|
+
|
|
59
|
+
st.title("🤖 Analysis Report")
|
|
60
|
+
st.markdown(f"**Query:** {query}")
|
|
61
|
+
st.divider()
|
|
62
|
+
|
|
63
|
+
col1, col2 = st.columns([2, 1])
|
|
64
|
+
with col1:
|
|
65
|
+
st.subheader("📝 Findings")
|
|
66
|
+
st.markdown(\"\"\"{explanation}\"\"\")
|
|
67
|
+
|
|
68
|
+
with col2:
|
|
69
|
+
st.subheader("🔢 Data Stats")
|
|
70
|
+
if not df.empty:
|
|
71
|
+
st.dataframe(df.describe().T, height=300)
|
|
72
|
+
else:
|
|
73
|
+
st.info("No data available")
|
|
74
|
+
|
|
75
|
+
st.divider()
|
|
76
|
+
if not df.empty:
|
|
77
|
+
with st.expander("🗃️ Source Data", expanded=True):
|
|
78
|
+
st.dataframe(df, use_container_width=True)
|
|
79
|
+
|
|
80
|
+
{code_section}
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
def _indent_code(self, code: str, spaces: int = 8) -> str:
|
|
84
|
+
"""Helper to indent injected code correctly."""
|
|
85
|
+
indentation = " " * spaces
|
|
86
|
+
return "\n".join(f"{indentation}{line}" for line in code.splitlines())
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
import json
|
|
3
|
+
try:
|
|
4
|
+
from rich.console import Console, Group
|
|
5
|
+
from rich.panel import Panel
|
|
6
|
+
from rich.markdown import Markdown
|
|
7
|
+
from rich.table import Table
|
|
8
|
+
from rich.layout import Layout
|
|
9
|
+
from rich.syntax import Syntax
|
|
10
|
+
RICH_AVAILABLE = True
|
|
11
|
+
except ImportError:
|
|
12
|
+
RICH_AVAILABLE = False
|
|
13
|
+
from .abstract import AbstractAppGenerator
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TerminalGenerator(AbstractAppGenerator):
|
|
17
|
+
"""Generates a Rich Console Dashboard."""
|
|
18
|
+
|
|
19
|
+
def generate(self) -> Any:
|
|
20
|
+
if not RICH_AVAILABLE:
|
|
21
|
+
return f"Query: {self.payload['input']}\n\n{self.payload['explanation']}"
|
|
22
|
+
|
|
23
|
+
# 1. Header
|
|
24
|
+
header = Panel(
|
|
25
|
+
f"[bold blue]Query:[/bold blue] {self.payload['input']}",
|
|
26
|
+
title="🤖 AI Agent Analysis",
|
|
27
|
+
border_style="green"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# 2. Explanation (Markdown)
|
|
31
|
+
explanation = Panel(
|
|
32
|
+
Markdown(self.payload["explanation"]),
|
|
33
|
+
title="📝 Analysis",
|
|
34
|
+
border_style="blue"
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# 3. Data Table
|
|
38
|
+
df = self.payload["data"]
|
|
39
|
+
if not df.empty:
|
|
40
|
+
table = Table(show_header=True, header_style="bold magenta")
|
|
41
|
+
# Limit to first 5 columns and 10 rows for terminal readability
|
|
42
|
+
show_cols = df.columns[:5]
|
|
43
|
+
for col in show_cols:
|
|
44
|
+
table.add_column(str(col))
|
|
45
|
+
|
|
46
|
+
for _, row in df.head(10).iterrows():
|
|
47
|
+
table.add_row(*[str(item) for item in row])
|
|
48
|
+
|
|
49
|
+
data_panel = Panel(table, title=f"🔢 Data Preview ({len(df)} rows)", border_style="yellow")
|
|
50
|
+
else:
|
|
51
|
+
data_panel = Panel("No structured data returned.", title="🔢 Data", border_style="yellow")
|
|
52
|
+
|
|
53
|
+
# 4. Code View
|
|
54
|
+
if code_content := self.payload["code"]:
|
|
55
|
+
if isinstance(code_content, (dict, list)):
|
|
56
|
+
syntax = Syntax(json.dumps(code_content, indent=2), "json", theme="monokai")
|
|
57
|
+
else:
|
|
58
|
+
syntax = Syntax(code_content, "python", theme="monokai", line_numbers=True)
|
|
59
|
+
|
|
60
|
+
code_panel = Panel(syntax, title="📊 Generated Code", border_style="cyan")
|
|
61
|
+
return Group(header, explanation, data_panel, code_panel)
|
|
62
|
+
|
|
63
|
+
return Group(header, explanation, data_panel)
|