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,664 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CodeInterpreterTool - Parrot Tool for comprehensive code analysis.
|
|
3
|
+
|
|
4
|
+
Agent-as-Tool that wraps an LLM agent with specialized capabilities for:
|
|
5
|
+
- Code analysis with complexity metrics
|
|
6
|
+
- Documentation generation
|
|
7
|
+
- Test generation
|
|
8
|
+
- Bug detection
|
|
9
|
+
- Code explanation
|
|
10
|
+
"""
|
|
11
|
+
import time
|
|
12
|
+
from typing import Optional, Dict, Any, Literal
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from pydantic import BaseModel, Field
|
|
15
|
+
import hashlib
|
|
16
|
+
from parrot.tools.abstract import AbstractTool
|
|
17
|
+
|
|
18
|
+
# Import response models
|
|
19
|
+
from .models import (
|
|
20
|
+
CodeAnalysisResponse,
|
|
21
|
+
DocumentationResponse,
|
|
22
|
+
TestGenerationResponse,
|
|
23
|
+
DebugResponse,
|
|
24
|
+
ExplanationResponse,
|
|
25
|
+
OperationType,
|
|
26
|
+
ExecutionStatus,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# Import system prompt
|
|
30
|
+
from .prompts import CODE_INTERPRETER_SYSTEM_PROMPT
|
|
31
|
+
|
|
32
|
+
# Import internal tools
|
|
33
|
+
from .internals import (
|
|
34
|
+
StaticAnalysisTool,
|
|
35
|
+
PythonExecutionTool,
|
|
36
|
+
FileOperationsTool,
|
|
37
|
+
calculate_code_hash,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# Import isolated executor
|
|
41
|
+
from .executor import create_executor
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class CodeInterpreterArgs(BaseModel):
|
|
45
|
+
"""Input schema for CodeInterpreterTool."""
|
|
46
|
+
code: str = Field(
|
|
47
|
+
...,
|
|
48
|
+
description="Python source code to analyze"
|
|
49
|
+
)
|
|
50
|
+
operation: Literal["analyze", "document", "test", "debug", "explain"] = Field(
|
|
51
|
+
default="analyze",
|
|
52
|
+
description="Type of operation to perform on the code"
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# Operation-specific parameters
|
|
56
|
+
focus_areas: Optional[str] = Field(
|
|
57
|
+
None,
|
|
58
|
+
description="Comma-separated list of areas to focus on for analysis (e.g., 'complexity,error handling')"
|
|
59
|
+
)
|
|
60
|
+
docstring_format: str = Field(
|
|
61
|
+
default="google",
|
|
62
|
+
description="Format for docstrings: 'google', 'numpy', or 'sphinx'"
|
|
63
|
+
)
|
|
64
|
+
include_module_docs: bool = Field(
|
|
65
|
+
default=True,
|
|
66
|
+
description="Whether to generate module-level documentation"
|
|
67
|
+
)
|
|
68
|
+
test_framework: str = Field(
|
|
69
|
+
default="pytest",
|
|
70
|
+
description="Testing framework to use for test generation"
|
|
71
|
+
)
|
|
72
|
+
coverage_target: float = Field(
|
|
73
|
+
default=80.0,
|
|
74
|
+
description="Target code coverage percentage for tests"
|
|
75
|
+
)
|
|
76
|
+
include_edge_cases: bool = Field(
|
|
77
|
+
default=True,
|
|
78
|
+
description="Whether to include edge case tests"
|
|
79
|
+
)
|
|
80
|
+
severity_threshold: str = Field(
|
|
81
|
+
default="low",
|
|
82
|
+
description="Minimum severity for bug detection: 'critical', 'high', 'medium', or 'low'"
|
|
83
|
+
)
|
|
84
|
+
include_style_issues: bool = Field(
|
|
85
|
+
default=False,
|
|
86
|
+
description="Whether to include style/formatting issues in bug detection"
|
|
87
|
+
)
|
|
88
|
+
expertise_level: str = Field(
|
|
89
|
+
default="intermediate",
|
|
90
|
+
description="User expertise level for explanations: 'beginner', 'intermediate', or 'advanced'"
|
|
91
|
+
)
|
|
92
|
+
include_visualization: bool = Field(
|
|
93
|
+
default=True,
|
|
94
|
+
description="Whether to include ASCII visualizations in explanations"
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class CodeInterpreterTool(AbstractTool):
|
|
99
|
+
"""
|
|
100
|
+
Agent-as-Tool for comprehensive Python code analysis.
|
|
101
|
+
|
|
102
|
+
Features:
|
|
103
|
+
- Code analysis with complexity metrics
|
|
104
|
+
- Automatic documentation generation
|
|
105
|
+
- Test generation with pytest
|
|
106
|
+
- Bug detection with severity classification
|
|
107
|
+
- Code explanation at various expertise levels
|
|
108
|
+
- Isolated code execution for verification
|
|
109
|
+
|
|
110
|
+
This tool wraps an LLM agent with specialized capabilities and internal tools
|
|
111
|
+
for static analysis, code execution, and file operations.
|
|
112
|
+
"""
|
|
113
|
+
|
|
114
|
+
name = "code_interpreter"
|
|
115
|
+
description = (
|
|
116
|
+
"Analyze, document, test, debug, and explain Python code. "
|
|
117
|
+
"Provides comprehensive code analysis with complexity metrics, "
|
|
118
|
+
"generates documentation and tests, detects bugs, and explains code functionality."
|
|
119
|
+
)
|
|
120
|
+
args_schema = CodeInterpreterArgs
|
|
121
|
+
|
|
122
|
+
def __init__(
|
|
123
|
+
self,
|
|
124
|
+
llm,
|
|
125
|
+
use_docker: bool = True,
|
|
126
|
+
docker_config: Optional[Dict[str, Any]] = None,
|
|
127
|
+
**kwargs
|
|
128
|
+
):
|
|
129
|
+
"""
|
|
130
|
+
Initialize the CodeInterpreterTool.
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
llm: LLM client instance (must support structured outputs via ask() method)
|
|
134
|
+
use_docker: Whether to use Docker for code execution
|
|
135
|
+
docker_config: Optional Docker configuration parameters
|
|
136
|
+
**kwargs: Additional arguments for AbstractTool
|
|
137
|
+
"""
|
|
138
|
+
super().__init__(**kwargs)
|
|
139
|
+
|
|
140
|
+
# Store LLM client with Parrot convention
|
|
141
|
+
self._llm = llm
|
|
142
|
+
|
|
143
|
+
# Initialize internal tools
|
|
144
|
+
docker_config = docker_config or {}
|
|
145
|
+
self.executor = create_executor(use_docker=use_docker, **docker_config)
|
|
146
|
+
self.static_analyzer = StaticAnalysisTool()
|
|
147
|
+
self.python_tool = PythonExecutionTool(self.executor)
|
|
148
|
+
self.file_ops = FileOperationsTool(self.output_dir)
|
|
149
|
+
|
|
150
|
+
# System prompt for the agent
|
|
151
|
+
self.system_prompt = CODE_INTERPRETER_SYSTEM_PROMPT
|
|
152
|
+
|
|
153
|
+
self.logger.info(f"CodeInterpreterTool initialized. Output dir: {self.output_dir}")
|
|
154
|
+
|
|
155
|
+
def _default_output_dir(self) -> Path:
|
|
156
|
+
"""Get the default output directory for code interpreter outputs."""
|
|
157
|
+
return self.static_dir / "reports" / "code_interpreter"
|
|
158
|
+
|
|
159
|
+
def _build_tool_context(self, code: str) -> str:
|
|
160
|
+
"""
|
|
161
|
+
Build context with static analysis results for the agent.
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
code: Source code to analyze
|
|
165
|
+
|
|
166
|
+
Returns:
|
|
167
|
+
Formatted context string
|
|
168
|
+
"""
|
|
169
|
+
# Perform static analysis
|
|
170
|
+
structure = self.static_analyzer.analyze_code_structure(code)
|
|
171
|
+
complexity = self.static_analyzer.calculate_complexity(code)
|
|
172
|
+
|
|
173
|
+
context = "## Static Analysis Results\n\n"
|
|
174
|
+
|
|
175
|
+
if structure.get("success"):
|
|
176
|
+
context += "### Code Structure\n"
|
|
177
|
+
context += f"- Functions: {len(structure.get('functions', []))}\n"
|
|
178
|
+
context += f"- Classes: {len(structure.get('classes', []))}\n"
|
|
179
|
+
context += f"- Imports: {len(structure.get('imports', []))}\n"
|
|
180
|
+
|
|
181
|
+
metrics = structure.get('metrics', {})
|
|
182
|
+
context += f"\n### Basic Metrics\n"
|
|
183
|
+
context += f"- Total lines: {metrics.get('total_lines', 0)}\n"
|
|
184
|
+
context += f"- Code lines: {metrics.get('code_lines', 0)}\n"
|
|
185
|
+
context += f"- Comment lines: {metrics.get('comment_lines', 0)}\n"
|
|
186
|
+
|
|
187
|
+
if complexity.get("success"):
|
|
188
|
+
cc = complexity.get("cyclomatic_complexity", {})
|
|
189
|
+
context += f"\n### Complexity Metrics\n"
|
|
190
|
+
context += f"- Average cyclomatic complexity: {cc.get('average', 0)}\n"
|
|
191
|
+
context += f"- Total cyclomatic complexity: {cc.get('total', 0)}\n"
|
|
192
|
+
|
|
193
|
+
if complexity.get("maintainability_index"):
|
|
194
|
+
context += f"- Maintainability index: {complexity['maintainability_index']}\n"
|
|
195
|
+
|
|
196
|
+
context += f"\n## Source Code\n```python\n{code}\n```\n"
|
|
197
|
+
|
|
198
|
+
return context
|
|
199
|
+
|
|
200
|
+
async def _make_agent_request(
|
|
201
|
+
self,
|
|
202
|
+
operation_type: OperationType,
|
|
203
|
+
code: str,
|
|
204
|
+
user_request: str,
|
|
205
|
+
response_model: type,
|
|
206
|
+
additional_context: Optional[str] = None,
|
|
207
|
+
) -> Any:
|
|
208
|
+
"""
|
|
209
|
+
Make a request to the LLM agent with structured output.
|
|
210
|
+
|
|
211
|
+
Args:
|
|
212
|
+
operation_type: Type of operation to perform
|
|
213
|
+
code: Source code to analyze
|
|
214
|
+
user_request: User's specific request
|
|
215
|
+
response_model: Pydantic model for structured response
|
|
216
|
+
additional_context: Optional additional context
|
|
217
|
+
|
|
218
|
+
Returns:
|
|
219
|
+
Structured response from the agent
|
|
220
|
+
"""
|
|
221
|
+
start_time = time.time()
|
|
222
|
+
|
|
223
|
+
# Build the context
|
|
224
|
+
tool_context = self._build_tool_context(code)
|
|
225
|
+
|
|
226
|
+
# Build the full prompt
|
|
227
|
+
prompt = f"{tool_context}\n\n## User Request\n{user_request}"
|
|
228
|
+
|
|
229
|
+
if additional_context:
|
|
230
|
+
prompt += f"\n\n## Additional Context\n{additional_context}"
|
|
231
|
+
|
|
232
|
+
try:
|
|
233
|
+
# Make the request with structured output
|
|
234
|
+
# Assuming the LLM client has an ask() method that accepts response_format
|
|
235
|
+
response = await self._llm.ask(
|
|
236
|
+
prompt=prompt,
|
|
237
|
+
system_prompt=self.system_prompt,
|
|
238
|
+
response_format=response_model,
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
# Calculate execution time
|
|
242
|
+
execution_time = int((time.time() - start_time) * 1000)
|
|
243
|
+
|
|
244
|
+
# Update execution time in response
|
|
245
|
+
if hasattr(response, 'execution_time_ms'):
|
|
246
|
+
response.execution_time_ms = execution_time
|
|
247
|
+
|
|
248
|
+
# Update code hash
|
|
249
|
+
if hasattr(response, 'code_hash'):
|
|
250
|
+
response.code_hash = calculate_code_hash(code)
|
|
251
|
+
|
|
252
|
+
return response
|
|
253
|
+
|
|
254
|
+
except Exception as e:
|
|
255
|
+
# Return error response
|
|
256
|
+
execution_time = int((time.time() - start_time) * 1000)
|
|
257
|
+
|
|
258
|
+
self.logger.error(f"Agent request failed: {e}")
|
|
259
|
+
|
|
260
|
+
# Create minimal error response
|
|
261
|
+
return response_model(
|
|
262
|
+
operation_type=operation_type,
|
|
263
|
+
status=ExecutionStatus.FAILED,
|
|
264
|
+
execution_time_ms=execution_time,
|
|
265
|
+
code_hash=calculate_code_hash(code),
|
|
266
|
+
error_message=f"Agent request failed: {str(e)}",
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
async def _execute_analyze(
|
|
270
|
+
self,
|
|
271
|
+
code: str,
|
|
272
|
+
focus_areas: Optional[str] = None,
|
|
273
|
+
) -> CodeAnalysisResponse:
|
|
274
|
+
"""Perform code analysis operation."""
|
|
275
|
+
user_request = "Perform a comprehensive analysis of this code."
|
|
276
|
+
|
|
277
|
+
if focus_areas:
|
|
278
|
+
areas = [area.strip() for area in focus_areas.split(',')]
|
|
279
|
+
user_request += f"\n\nFocus particularly on: {', '.join(areas)}"
|
|
280
|
+
|
|
281
|
+
user_request += """
|
|
282
|
+
|
|
283
|
+
Provide:
|
|
284
|
+
1. Executive summary of the code's purpose
|
|
285
|
+
2. Detailed analysis of all functions and classes
|
|
286
|
+
3. Dependencies and their usage
|
|
287
|
+
4. Complexity metrics interpretation
|
|
288
|
+
5. Quality observations (strengths and improvements)
|
|
289
|
+
"""
|
|
290
|
+
|
|
291
|
+
return await self._make_agent_request(
|
|
292
|
+
operation_type=OperationType.ANALYZE,
|
|
293
|
+
code=code,
|
|
294
|
+
user_request=user_request,
|
|
295
|
+
response_model=CodeAnalysisResponse,
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
async def _execute_document(
|
|
299
|
+
self,
|
|
300
|
+
code: str,
|
|
301
|
+
docstring_format: str = "google",
|
|
302
|
+
include_module_docs: bool = True,
|
|
303
|
+
) -> DocumentationResponse:
|
|
304
|
+
"""Generate documentation operation."""
|
|
305
|
+
user_request = f"""Generate comprehensive documentation for this code.
|
|
306
|
+
|
|
307
|
+
Requirements:
|
|
308
|
+
- Use {docstring_format}-style docstrings
|
|
309
|
+
- Document all functions, classes, and methods
|
|
310
|
+
- Include parameter types and descriptions
|
|
311
|
+
- Include return value descriptions
|
|
312
|
+
- Include exception documentation
|
|
313
|
+
- Add usage examples where helpful
|
|
314
|
+
"""
|
|
315
|
+
|
|
316
|
+
if include_module_docs:
|
|
317
|
+
user_request += "- Generate module-level documentation in markdown format\n"
|
|
318
|
+
|
|
319
|
+
response = await self._make_agent_request(
|
|
320
|
+
operation_type=OperationType.DOCUMENT,
|
|
321
|
+
code=code,
|
|
322
|
+
user_request=user_request,
|
|
323
|
+
response_model=DocumentationResponse,
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
# Save generated documentation to files
|
|
327
|
+
if response.status == ExecutionStatus.SUCCESS:
|
|
328
|
+
files_to_save = {}
|
|
329
|
+
|
|
330
|
+
# Save modified code with docstrings
|
|
331
|
+
filename = self.generate_filename("documented_code", ".py")
|
|
332
|
+
files_to_save[filename] = response.modified_code
|
|
333
|
+
|
|
334
|
+
# Save module documentation if available
|
|
335
|
+
if response.module_documentation:
|
|
336
|
+
doc_filename = self.generate_filename("module_documentation", ".md")
|
|
337
|
+
files_to_save[doc_filename] = response.module_documentation
|
|
338
|
+
|
|
339
|
+
# Save files using file_ops
|
|
340
|
+
for filename, content in files_to_save.items():
|
|
341
|
+
result = self.file_ops.save_file(
|
|
342
|
+
content=content,
|
|
343
|
+
filename=filename,
|
|
344
|
+
subdirectory=f"documentation_{response.operation_id}"
|
|
345
|
+
)
|
|
346
|
+
|
|
347
|
+
if result.get("success"):
|
|
348
|
+
response.saved_files.append(result["absolute_path"])
|
|
349
|
+
|
|
350
|
+
return response
|
|
351
|
+
|
|
352
|
+
async def _execute_test(
|
|
353
|
+
self,
|
|
354
|
+
code: str,
|
|
355
|
+
test_framework: str = "pytest",
|
|
356
|
+
coverage_target: float = 80.0,
|
|
357
|
+
include_edge_cases: bool = True,
|
|
358
|
+
) -> TestGenerationResponse:
|
|
359
|
+
"""Generate tests operation."""
|
|
360
|
+
user_request = f"""Generate comprehensive tests for this code.
|
|
361
|
+
|
|
362
|
+
Requirements:
|
|
363
|
+
- Use {test_framework} as the testing framework
|
|
364
|
+
- Target {coverage_target}% code coverage
|
|
365
|
+
- Include both happy path and error cases
|
|
366
|
+
"""
|
|
367
|
+
|
|
368
|
+
if include_edge_cases:
|
|
369
|
+
user_request += "- Generate specific tests for edge cases\n"
|
|
370
|
+
|
|
371
|
+
user_request += """
|
|
372
|
+
- Use descriptive test names
|
|
373
|
+
- Include fixtures where appropriate
|
|
374
|
+
- Add docstrings to explain what each test validates
|
|
375
|
+
- Organize tests logically
|
|
376
|
+
"""
|
|
377
|
+
|
|
378
|
+
response = await self._make_agent_request(
|
|
379
|
+
operation_type=OperationType.TEST,
|
|
380
|
+
code=code,
|
|
381
|
+
user_request=user_request,
|
|
382
|
+
response_model=TestGenerationResponse,
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
# Save generated tests to file
|
|
386
|
+
if response.status == ExecutionStatus.SUCCESS and response.generated_tests:
|
|
387
|
+
# Combine all test code
|
|
388
|
+
all_tests = [
|
|
389
|
+
"import pytest",
|
|
390
|
+
"import sys",
|
|
391
|
+
"from pathlib import Path",
|
|
392
|
+
"",
|
|
393
|
+
"# Add source code directory to path if needed",
|
|
394
|
+
"# sys.path.insert(0, str(Path(__file__).parent))",
|
|
395
|
+
"",
|
|
396
|
+
]
|
|
397
|
+
|
|
398
|
+
for test in response.generated_tests:
|
|
399
|
+
all_tests.extend(
|
|
400
|
+
(
|
|
401
|
+
f"# Test: {test.name}",
|
|
402
|
+
f"# Type: {test.test_type.value}",
|
|
403
|
+
test.test_code,
|
|
404
|
+
"",
|
|
405
|
+
)
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
test_content = "\n".join(all_tests)
|
|
409
|
+
|
|
410
|
+
# Also save the original source code
|
|
411
|
+
test_filename = self.generate_filename("test_generated", ".py")
|
|
412
|
+
source_filename = self.generate_filename("source_code", ".py")
|
|
413
|
+
|
|
414
|
+
subdirectory = f"tests_{response.operation_id}"
|
|
415
|
+
|
|
416
|
+
# Save test file
|
|
417
|
+
test_result = self.file_ops.save_file(
|
|
418
|
+
content=test_content,
|
|
419
|
+
filename=test_filename,
|
|
420
|
+
subdirectory=subdirectory
|
|
421
|
+
)
|
|
422
|
+
|
|
423
|
+
# Save source file
|
|
424
|
+
source_result = self.file_ops.save_file(
|
|
425
|
+
content=code,
|
|
426
|
+
filename=source_filename,
|
|
427
|
+
subdirectory=subdirectory
|
|
428
|
+
)
|
|
429
|
+
|
|
430
|
+
if test_result.get("success"):
|
|
431
|
+
response.saved_files.append(test_result["absolute_path"])
|
|
432
|
+
response.test_file_path = test_result["absolute_path"]
|
|
433
|
+
|
|
434
|
+
if source_result.get("success"):
|
|
435
|
+
response.saved_files.append(source_result["absolute_path"])
|
|
436
|
+
|
|
437
|
+
# Save setup instructions if provided
|
|
438
|
+
if response.setup_instructions:
|
|
439
|
+
readme_filename = self.generate_filename("README", ".md")
|
|
440
|
+
readme_content = f"# Test Setup Instructions\n\n{response.setup_instructions}"
|
|
441
|
+
readme_result = self.file_ops.save_file(
|
|
442
|
+
content=readme_content,
|
|
443
|
+
filename=readme_filename,
|
|
444
|
+
subdirectory=subdirectory
|
|
445
|
+
)
|
|
446
|
+
if readme_result.get("success"):
|
|
447
|
+
response.saved_files.append(readme_result["absolute_path"])
|
|
448
|
+
|
|
449
|
+
return response
|
|
450
|
+
|
|
451
|
+
async def _execute_debug(
|
|
452
|
+
self,
|
|
453
|
+
code: str,
|
|
454
|
+
severity_threshold: str = "low",
|
|
455
|
+
include_style_issues: bool = False,
|
|
456
|
+
) -> DebugResponse:
|
|
457
|
+
"""Detect bugs operation."""
|
|
458
|
+
user_request = f"""Analyze this code for potential bugs and issues.
|
|
459
|
+
|
|
460
|
+
Requirements:
|
|
461
|
+
- Report issues with severity {severity_threshold} and above
|
|
462
|
+
- Check for logic errors, exception handling, resource management
|
|
463
|
+
- Look for security vulnerabilities
|
|
464
|
+
- Identify potential performance issues
|
|
465
|
+
- Check for type inconsistencies
|
|
466
|
+
"""
|
|
467
|
+
|
|
468
|
+
if not include_style_issues:
|
|
469
|
+
user_request += "- Focus on functional issues, not style/formatting\n"
|
|
470
|
+
|
|
471
|
+
user_request += """
|
|
472
|
+
For each issue found:
|
|
473
|
+
- Provide specific location in code
|
|
474
|
+
- Explain the problem clearly
|
|
475
|
+
- Describe the trigger scenario
|
|
476
|
+
- Suggest a specific fix with code diff if possible
|
|
477
|
+
- Provide impact analysis
|
|
478
|
+
"""
|
|
479
|
+
|
|
480
|
+
return await self._make_agent_request(
|
|
481
|
+
operation_type=OperationType.DEBUG,
|
|
482
|
+
code=code,
|
|
483
|
+
user_request=user_request,
|
|
484
|
+
response_model=DebugResponse,
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
async def _execute_explain(
|
|
488
|
+
self,
|
|
489
|
+
code: str,
|
|
490
|
+
expertise_level: str = "intermediate",
|
|
491
|
+
include_visualization: bool = True,
|
|
492
|
+
) -> ExplanationResponse:
|
|
493
|
+
"""Explain code operation."""
|
|
494
|
+
user_request = f"""Explain how this code works.
|
|
495
|
+
|
|
496
|
+
Target audience expertise level: {expertise_level}
|
|
497
|
+
|
|
498
|
+
Requirements:
|
|
499
|
+
- Start with a high-level summary
|
|
500
|
+
- Explain the execution flow step by step
|
|
501
|
+
- Define any technical concepts that may not be familiar
|
|
502
|
+
- Describe data structures used
|
|
503
|
+
"""
|
|
504
|
+
|
|
505
|
+
if include_visualization:
|
|
506
|
+
user_request += "- Include ASCII diagrams or visualizations where helpful\n"
|
|
507
|
+
|
|
508
|
+
if expertise_level == "beginner":
|
|
509
|
+
user_request += "- Use simple analogies and avoid jargon\n"
|
|
510
|
+
user_request += "- Explain basic programming concepts as needed\n"
|
|
511
|
+
elif expertise_level == "advanced":
|
|
512
|
+
user_request += "- Include complexity analysis\n"
|
|
513
|
+
user_request += "- Discuss algorithmic trade-offs\n"
|
|
514
|
+
|
|
515
|
+
return await self._make_agent_request(
|
|
516
|
+
operation_type=OperationType.EXPLAIN,
|
|
517
|
+
code=code,
|
|
518
|
+
user_request=user_request,
|
|
519
|
+
response_model=ExplanationResponse,
|
|
520
|
+
additional_context=f"User expertise level: {expertise_level}",
|
|
521
|
+
)
|
|
522
|
+
|
|
523
|
+
async def _execute(
|
|
524
|
+
self,
|
|
525
|
+
code: str,
|
|
526
|
+
operation: str = "analyze",
|
|
527
|
+
focus_areas: Optional[str] = None,
|
|
528
|
+
docstring_format: str = "google",
|
|
529
|
+
include_module_docs: bool = True,
|
|
530
|
+
test_framework: str = "pytest",
|
|
531
|
+
coverage_target: float = 80.0,
|
|
532
|
+
include_edge_cases: bool = True,
|
|
533
|
+
severity_threshold: str = "low",
|
|
534
|
+
include_style_issues: bool = False,
|
|
535
|
+
expertise_level: str = "intermediate",
|
|
536
|
+
include_visualization: bool = True,
|
|
537
|
+
**kwargs
|
|
538
|
+
) -> Dict[str, Any]:
|
|
539
|
+
"""
|
|
540
|
+
Execute the code interpreter tool (AbstractTool interface).
|
|
541
|
+
|
|
542
|
+
Args:
|
|
543
|
+
code: Python source code to analyze
|
|
544
|
+
operation: Type of operation ('analyze', 'document', 'test', 'debug', 'explain')
|
|
545
|
+
focus_areas: Areas to focus on for analysis
|
|
546
|
+
docstring_format: Format for docstrings
|
|
547
|
+
include_module_docs: Whether to generate module docs
|
|
548
|
+
test_framework: Testing framework to use
|
|
549
|
+
coverage_target: Target coverage percentage
|
|
550
|
+
include_edge_cases: Whether to include edge case tests
|
|
551
|
+
severity_threshold: Minimum severity for bug detection
|
|
552
|
+
include_style_issues: Whether to include style issues
|
|
553
|
+
expertise_level: User expertise level for explanations
|
|
554
|
+
include_visualization: Whether to include visualizations
|
|
555
|
+
**kwargs: Additional arguments
|
|
556
|
+
|
|
557
|
+
Returns:
|
|
558
|
+
Dictionary with operation results
|
|
559
|
+
"""
|
|
560
|
+
self.logger.info(f"Executing CodeInterpreterTool operation: {operation}")
|
|
561
|
+
|
|
562
|
+
try:
|
|
563
|
+
# Route to appropriate operation
|
|
564
|
+
if operation == "analyze":
|
|
565
|
+
response = await self._execute_analyze(code, focus_areas)
|
|
566
|
+
elif operation == "document":
|
|
567
|
+
response = await self._execute_document(
|
|
568
|
+
code, docstring_format, include_module_docs
|
|
569
|
+
)
|
|
570
|
+
elif operation == "test":
|
|
571
|
+
response = await self._execute_test(
|
|
572
|
+
code, test_framework, coverage_target, include_edge_cases
|
|
573
|
+
)
|
|
574
|
+
elif operation == "debug":
|
|
575
|
+
response = await self._execute_debug(
|
|
576
|
+
code, severity_threshold, include_style_issues
|
|
577
|
+
)
|
|
578
|
+
elif operation == "explain":
|
|
579
|
+
response = await self._execute_explain(
|
|
580
|
+
code, expertise_level, include_visualization
|
|
581
|
+
)
|
|
582
|
+
else:
|
|
583
|
+
return {
|
|
584
|
+
"error": f"Unknown operation: {operation}",
|
|
585
|
+
"valid_operations": ["analyze", "document", "test", "debug", "explain"]
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
# Convert Pydantic model to dict for return
|
|
589
|
+
return response.model_dump()
|
|
590
|
+
|
|
591
|
+
except Exception as e:
|
|
592
|
+
self.logger.error(f"Error in CodeInterpreterTool: {e}", exc_info=True)
|
|
593
|
+
return {
|
|
594
|
+
"error": str(e),
|
|
595
|
+
"operation": operation,
|
|
596
|
+
"code_preview": f"{code[:100]}..." if len(code) > 100 else code,
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
# Convenience methods for direct access (optional, for backward compatibility)
|
|
600
|
+
|
|
601
|
+
async def analyze_code(
|
|
602
|
+
self,
|
|
603
|
+
code: str,
|
|
604
|
+
focus_areas: Optional[list[str]] = None,
|
|
605
|
+
) -> CodeAnalysisResponse:
|
|
606
|
+
"""Convenience method for code analysis."""
|
|
607
|
+
focus_str = ','.join(focus_areas) if focus_areas else None
|
|
608
|
+
return await self._execute_analyze(code, focus_str)
|
|
609
|
+
|
|
610
|
+
async def generate_documentation(
|
|
611
|
+
self,
|
|
612
|
+
code: str,
|
|
613
|
+
docstring_format: str = "google",
|
|
614
|
+
include_module_docs: bool = True,
|
|
615
|
+
) -> DocumentationResponse:
|
|
616
|
+
"""Convenience method for documentation generation."""
|
|
617
|
+
return await self._execute_document(code, docstring_format, include_module_docs)
|
|
618
|
+
|
|
619
|
+
async def generate_tests(
|
|
620
|
+
self,
|
|
621
|
+
code: str,
|
|
622
|
+
test_framework: str = "pytest",
|
|
623
|
+
coverage_target: float = 80.0,
|
|
624
|
+
include_edge_cases: bool = True,
|
|
625
|
+
) -> TestGenerationResponse:
|
|
626
|
+
"""Convenience method for test generation."""
|
|
627
|
+
return await self._execute_test(
|
|
628
|
+
code, test_framework, coverage_target, include_edge_cases
|
|
629
|
+
)
|
|
630
|
+
|
|
631
|
+
async def detect_bugs(
|
|
632
|
+
self,
|
|
633
|
+
code: str,
|
|
634
|
+
severity_threshold: str = "low",
|
|
635
|
+
include_style_issues: bool = False,
|
|
636
|
+
) -> DebugResponse:
|
|
637
|
+
"""Convenience method for bug detection."""
|
|
638
|
+
return await self._execute_debug(code, severity_threshold, include_style_issues)
|
|
639
|
+
|
|
640
|
+
async def explain_code(
|
|
641
|
+
self,
|
|
642
|
+
code: str,
|
|
643
|
+
expertise_level: str = "intermediate",
|
|
644
|
+
include_visualization: bool = True,
|
|
645
|
+
) -> ExplanationResponse:
|
|
646
|
+
"""Convenience method for code explanation."""
|
|
647
|
+
return await self._execute_explain(code, expertise_level, include_visualization)
|
|
648
|
+
|
|
649
|
+
def execute_code_safely(self, code: str) -> Dict[str, Any]:
|
|
650
|
+
"""
|
|
651
|
+
Execute code in isolated environment (direct tool access).
|
|
652
|
+
|
|
653
|
+
Args:
|
|
654
|
+
code: Python code to execute
|
|
655
|
+
|
|
656
|
+
Returns:
|
|
657
|
+
Execution results dictionary
|
|
658
|
+
"""
|
|
659
|
+
return self.python_tool.execute(code, "Direct code execution")
|
|
660
|
+
|
|
661
|
+
def cleanup(self):
|
|
662
|
+
"""Clean up resources (Docker containers, temp files, etc.)"""
|
|
663
|
+
if hasattr(self.executor, 'cleanup'):
|
|
664
|
+
self.executor.cleanup()
|