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,1052 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onMount } from 'svelte';
|
|
3
|
+
import { get } from 'svelte/store';
|
|
4
|
+
import { page } from '$app/stores';
|
|
5
|
+
import { crew as crewApi } from '$lib/api';
|
|
6
|
+
import type { CrewExecutionMode } from '$lib/api/crew/crew';
|
|
7
|
+
import MarkdownEditor from '$lib/components/MarkdownEditor.svelte';
|
|
8
|
+
import JsonViewer from '$lib/components/JsonViewer.svelte';
|
|
9
|
+
import { markdownToHtml } from '$lib/utils/markdown';
|
|
10
|
+
import { LoadingSpinner } from '$lib/components';
|
|
11
|
+
|
|
12
|
+
type CrewExecutionMode = 'sequential' | 'parallel' | 'loop' | 'flow';
|
|
13
|
+
|
|
14
|
+
interface CrewSummary {
|
|
15
|
+
crew_id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
execution_mode?: CrewExecutionMode;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface CrewAgentSummary {
|
|
22
|
+
agent_id: string;
|
|
23
|
+
name?: string | null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface CrewDetails extends CrewSummary {
|
|
27
|
+
agents?: CrewAgentSummary[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface CrewJobStatus {
|
|
31
|
+
job_id: string;
|
|
32
|
+
crew_id: string;
|
|
33
|
+
status: string;
|
|
34
|
+
message?: string;
|
|
35
|
+
result?: {
|
|
36
|
+
output?: unknown;
|
|
37
|
+
response?: Record<string, { input?: string; output?: string }>;
|
|
38
|
+
};
|
|
39
|
+
execution_mode?: string;
|
|
40
|
+
[key: string]: unknown;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface AgentResponse {
|
|
44
|
+
input?: string;
|
|
45
|
+
output?: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
interface AgentResponseView {
|
|
49
|
+
name: string;
|
|
50
|
+
input?: string;
|
|
51
|
+
outputHtml: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
let crews: CrewSummary[] = [];
|
|
55
|
+
let crewsLoading = false;
|
|
56
|
+
let crewsError = '';
|
|
57
|
+
let selectedCrewId = '';
|
|
58
|
+
|
|
59
|
+
let crewDetails: CrewDetails | null = null;
|
|
60
|
+
let crewDetailsLoading = false;
|
|
61
|
+
let crewDetailsError = '';
|
|
62
|
+
let lastLoadedCrewId: string | null = null;
|
|
63
|
+
let pendingCrewId: string | null = null;
|
|
64
|
+
let detailsRequestId = 0;
|
|
65
|
+
|
|
66
|
+
let question = '';
|
|
67
|
+
let parallelInputMode: 'shared' | 'custom' = 'shared';
|
|
68
|
+
let parallelSharedTask = '';
|
|
69
|
+
let parallelAgentTasks: Record<string, string> = {};
|
|
70
|
+
let parallelSynthesisPrompt = '';
|
|
71
|
+
let parallelAllResults = false;
|
|
72
|
+
let loopInitialTask = '';
|
|
73
|
+
let loopCondition = '';
|
|
74
|
+
let loopMaxIterations = 4;
|
|
75
|
+
let loopAgentSequence: string[] = [];
|
|
76
|
+
let loopSynthesisPrompt = '';
|
|
77
|
+
let flowInitialTask = '';
|
|
78
|
+
let flowSynthesisPrompt = '';
|
|
79
|
+
|
|
80
|
+
let jobStatus: CrewJobStatus | null = null;
|
|
81
|
+
let statusMessage = '';
|
|
82
|
+
let jobError = '';
|
|
83
|
+
let isSubmitting = false;
|
|
84
|
+
|
|
85
|
+
let rawAgentResponses: [string, AgentResponse][] = [];
|
|
86
|
+
let agentResponses: AgentResponseView[] = [];
|
|
87
|
+
const crewSelectId = 'crew-select';
|
|
88
|
+
|
|
89
|
+
let selectedCrew: CrewSummary | null = null;
|
|
90
|
+
const executionModeMeta = {
|
|
91
|
+
sequential: {
|
|
92
|
+
label: 'Sequential',
|
|
93
|
+
description: 'Run agents one after another using the crew\'s defined order.'
|
|
94
|
+
},
|
|
95
|
+
parallel: {
|
|
96
|
+
label: 'Parallel',
|
|
97
|
+
description: 'Execute agents simultaneously with shared or per-agent prompts.'
|
|
98
|
+
},
|
|
99
|
+
loop: {
|
|
100
|
+
label: 'Loop',
|
|
101
|
+
description: 'Iterate through agents until the stop condition is met.'
|
|
102
|
+
},
|
|
103
|
+
flow: {
|
|
104
|
+
label: 'Flow',
|
|
105
|
+
description: 'Follow the crew\'s flow configuration to determine execution order.'
|
|
106
|
+
}
|
|
107
|
+
} satisfies Record<CrewExecutionMode, { label: string; description: string }>;
|
|
108
|
+
|
|
109
|
+
const executionModeOptions = (
|
|
110
|
+
Object.entries(executionModeMeta) as [CrewExecutionMode, { label: string; description: string }][]
|
|
111
|
+
).map(([value, meta]) => ({ value, ...meta }));
|
|
112
|
+
|
|
113
|
+
let currentMode: CrewExecutionMode = 'sequential';
|
|
114
|
+
let modeLocked = false;
|
|
115
|
+
let lastModeCrewId: string | null = null;
|
|
116
|
+
let finalOutputRaw: unknown = null;
|
|
117
|
+
let finalOutputHtml = '';
|
|
118
|
+
let finalOutputList: unknown[] = [];
|
|
119
|
+
let finalOutputListHtml: string[] = [];
|
|
120
|
+
let draggingIndex: number | null = null;
|
|
121
|
+
|
|
122
|
+
$: selectedCrew = crews.find((crewItem) => crewItem.crew_id === selectedCrewId) ?? null;
|
|
123
|
+
$: if (selectedCrewId !== lastModeCrewId) {
|
|
124
|
+
modeLocked = false;
|
|
125
|
+
lastModeCrewId = selectedCrewId || null;
|
|
126
|
+
}
|
|
127
|
+
$: if (!selectedCrewId) {
|
|
128
|
+
if (currentMode !== 'sequential') {
|
|
129
|
+
currentMode = 'sequential';
|
|
130
|
+
}
|
|
131
|
+
} else if (!modeLocked) {
|
|
132
|
+
const defaultMode = (crewDetails?.execution_mode ?? selectedCrew?.execution_mode ?? 'sequential') as CrewExecutionMode;
|
|
133
|
+
if (currentMode !== defaultMode) {
|
|
134
|
+
currentMode = defaultMode;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
$: rawAgentResponses =
|
|
138
|
+
jobStatus?.result?.response && typeof jobStatus.result.response === 'object'
|
|
139
|
+
? (Object.entries(jobStatus.result.response) as [string, AgentResponse][])
|
|
140
|
+
: [];
|
|
141
|
+
$: agentResponses = rawAgentResponses.map(([name, details]) => ({
|
|
142
|
+
name,
|
|
143
|
+
input: typeof details?.input === 'string' ? details.input : undefined,
|
|
144
|
+
outputHtml:
|
|
145
|
+
typeof details?.output === 'string' && details.output.trim()
|
|
146
|
+
? markdownToHtml(details.output)
|
|
147
|
+
: ''
|
|
148
|
+
}));
|
|
149
|
+
$: finalOutputRaw = jobStatus?.result?.output ?? null;
|
|
150
|
+
$: finalOutputHtml =
|
|
151
|
+
typeof finalOutputRaw === 'string' && finalOutputRaw.trim()
|
|
152
|
+
? markdownToHtml(finalOutputRaw)
|
|
153
|
+
: '';
|
|
154
|
+
$: finalOutputList = Array.isArray(finalOutputRaw) ? (finalOutputRaw as unknown[]) : [];
|
|
155
|
+
$: finalOutputListHtml = finalOutputList.map((item) => {
|
|
156
|
+
if (typeof item === 'string') {
|
|
157
|
+
return item.trim() ? markdownToHtml(item) : '';
|
|
158
|
+
}
|
|
159
|
+
try {
|
|
160
|
+
return markdownToHtml('```json\n' + JSON.stringify(item, null, 2) + '\n```');
|
|
161
|
+
} catch (error) {
|
|
162
|
+
return markdownToHtml(String(item));
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
$: if (selectedCrewId) {
|
|
166
|
+
if (selectedCrewId !== pendingCrewId && selectedCrewId !== lastLoadedCrewId) {
|
|
167
|
+
pendingCrewId = selectedCrewId;
|
|
168
|
+
void loadCrewDetails(selectedCrewId);
|
|
169
|
+
}
|
|
170
|
+
} else if (lastLoadedCrewId || pendingCrewId) {
|
|
171
|
+
crewDetails = null;
|
|
172
|
+
crewDetailsError = '';
|
|
173
|
+
lastLoadedCrewId = null;
|
|
174
|
+
pendingCrewId = null;
|
|
175
|
+
loopAgentSequence = [];
|
|
176
|
+
initializeAgentPrompts([]);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function extractErrorMessage(error: unknown, fallback: string) {
|
|
180
|
+
let responseMessage: string | undefined;
|
|
181
|
+
|
|
182
|
+
if (
|
|
183
|
+
typeof error === 'object' &&
|
|
184
|
+
error !== null &&
|
|
185
|
+
'response' in error &&
|
|
186
|
+
(error as Record<string, unknown>).response &&
|
|
187
|
+
typeof (error as Record<string, unknown>).response === 'object'
|
|
188
|
+
) {
|
|
189
|
+
const response = (error as { response?: Record<string, unknown> }).response;
|
|
190
|
+
const data = response?.data;
|
|
191
|
+
if (
|
|
192
|
+
data &&
|
|
193
|
+
typeof data === 'object' &&
|
|
194
|
+
'message' in data &&
|
|
195
|
+
typeof (data as Record<string, unknown>).message === 'string'
|
|
196
|
+
) {
|
|
197
|
+
responseMessage = (data as { message?: string }).message;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (responseMessage) {
|
|
202
|
+
return responseMessage;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (error instanceof Error && typeof error.message === 'string') {
|
|
206
|
+
return error.message;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return fallback;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function initializeAgentPrompts(agentIds: string[]) {
|
|
213
|
+
const prompts: Record<string, string> = {};
|
|
214
|
+
for (const id of agentIds) {
|
|
215
|
+
if (typeof id === 'string' && id) {
|
|
216
|
+
prompts[id] = '';
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
parallelAgentTasks = prompts;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function setParallelAgentTask(agentId: string, value: string) {
|
|
223
|
+
parallelAgentTasks = { ...parallelAgentTasks, [agentId]: value };
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function getAgentDisplayName(agentId: string) {
|
|
227
|
+
const agent = crewDetails?.agents?.find((item) => item.agent_id === agentId);
|
|
228
|
+
return agent?.name?.trim() || agentId;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function getExecutionModeLabel(mode?: string | null) {
|
|
232
|
+
if (!mode) {
|
|
233
|
+
return '';
|
|
234
|
+
}
|
|
235
|
+
const meta = executionModeMeta[mode as CrewExecutionMode];
|
|
236
|
+
return meta?.label ?? mode;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function moveAgentInSequence(fromIndex: number, toIndex: number) {
|
|
240
|
+
if (fromIndex === toIndex || fromIndex < 0 || toIndex < 0) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const updated = [...loopAgentSequence];
|
|
244
|
+
if (fromIndex >= updated.length) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const [moved] = updated.splice(fromIndex, 1);
|
|
248
|
+
const clampedIndex = Math.min(Math.max(toIndex, 0), updated.length);
|
|
249
|
+
updated.splice(clampedIndex, 0, moved);
|
|
250
|
+
loopAgentSequence = updated;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function moveAgentUp(index: number) {
|
|
254
|
+
if (index <= 0) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
moveAgentInSequence(index, index - 1);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function moveAgentDown(index: number) {
|
|
261
|
+
if (index >= loopAgentSequence.length - 1) {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
moveAgentInSequence(index, index + 1);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function handleDragStart(event: DragEvent, index: number) {
|
|
268
|
+
draggingIndex = index;
|
|
269
|
+
if (event.dataTransfer) {
|
|
270
|
+
event.dataTransfer.effectAllowed = 'move';
|
|
271
|
+
event.dataTransfer.setData('text/plain', index.toString());
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function handleDragOver(event: DragEvent) {
|
|
276
|
+
event.preventDefault();
|
|
277
|
+
if (event.dataTransfer) {
|
|
278
|
+
event.dataTransfer.dropEffect = 'move';
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function handleDrop(event: DragEvent, index: number) {
|
|
283
|
+
event.preventDefault();
|
|
284
|
+
const data = event.dataTransfer?.getData('text/plain');
|
|
285
|
+
const fromIndex = draggingIndex ?? (data ? parseInt(data, 10) : -1);
|
|
286
|
+
if (Number.isNaN(fromIndex) || fromIndex < 0) {
|
|
287
|
+
draggingIndex = null;
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
moveAgentInSequence(fromIndex, index);
|
|
291
|
+
draggingIndex = null;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function handleDropAtEnd(event: DragEvent) {
|
|
295
|
+
event.preventDefault();
|
|
296
|
+
const data = event.dataTransfer?.getData('text/plain');
|
|
297
|
+
const fromIndex = draggingIndex ?? (data ? parseInt(data, 10) : -1);
|
|
298
|
+
if (Number.isNaN(fromIndex) || fromIndex < 0) {
|
|
299
|
+
draggingIndex = null;
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
const updated = [...loopAgentSequence];
|
|
303
|
+
if (fromIndex >= updated.length) {
|
|
304
|
+
draggingIndex = null;
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
const [moved] = updated.splice(fromIndex, 1);
|
|
308
|
+
updated.push(moved);
|
|
309
|
+
loopAgentSequence = updated;
|
|
310
|
+
draggingIndex = null;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function handleDragEnd() {
|
|
314
|
+
draggingIndex = null;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
async function fetchCrews(initialCrewId?: string | null) {
|
|
318
|
+
crewsLoading = true;
|
|
319
|
+
crewsError = '';
|
|
320
|
+
|
|
321
|
+
try {
|
|
322
|
+
const response = await crewApi.listCrews();
|
|
323
|
+
const list = Array.isArray(response?.crews) ? (response.crews as CrewSummary[]) : [];
|
|
324
|
+
crews = list.map((item) => ({
|
|
325
|
+
...item,
|
|
326
|
+
execution_mode:
|
|
327
|
+
typeof item.execution_mode === 'string'
|
|
328
|
+
? (item.execution_mode as CrewExecutionMode)
|
|
329
|
+
: undefined
|
|
330
|
+
}));
|
|
331
|
+
|
|
332
|
+
if (initialCrewId) {
|
|
333
|
+
const exists = list.some((item) => item.crew_id === initialCrewId);
|
|
334
|
+
if (exists) {
|
|
335
|
+
selectedCrewId = initialCrewId;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
} catch (error) {
|
|
339
|
+
console.error('Failed to load crews', error);
|
|
340
|
+
crewsError = extractErrorMessage(error, 'Unable to load crews at this time.');
|
|
341
|
+
crews = [];
|
|
342
|
+
} finally {
|
|
343
|
+
crewsLoading = false;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
async function loadCrewDetails(crewId: string) {
|
|
348
|
+
pendingCrewId = crewId;
|
|
349
|
+
const currentRequest = ++detailsRequestId;
|
|
350
|
+
crewDetailsLoading = true;
|
|
351
|
+
crewDetailsError = '';
|
|
352
|
+
|
|
353
|
+
try {
|
|
354
|
+
const response = await crewApi.getCrewById(crewId);
|
|
355
|
+
if (currentRequest !== detailsRequestId) {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
const details = (response ?? {}) as CrewDetails;
|
|
360
|
+
const agents = Array.isArray(details?.agents)
|
|
361
|
+
? details.agents.filter((agent): agent is CrewAgentSummary => typeof agent?.agent_id === 'string')
|
|
362
|
+
: [];
|
|
363
|
+
|
|
364
|
+
crewDetails = {
|
|
365
|
+
...details,
|
|
366
|
+
agents
|
|
367
|
+
};
|
|
368
|
+
lastLoadedCrewId = crewId;
|
|
369
|
+
loopAgentSequence = agents.map((agent) => agent.agent_id);
|
|
370
|
+
initializeAgentPrompts(loopAgentSequence);
|
|
371
|
+
resetQuestion();
|
|
372
|
+
} catch (error) {
|
|
373
|
+
if (currentRequest !== detailsRequestId) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
console.error('Failed to load crew details', error);
|
|
377
|
+
crewDetails = null;
|
|
378
|
+
loopAgentSequence = [];
|
|
379
|
+
initializeAgentPrompts([]);
|
|
380
|
+
crewDetailsError = extractErrorMessage(
|
|
381
|
+
error,
|
|
382
|
+
'Unable to load crew details. Please try again.'
|
|
383
|
+
);
|
|
384
|
+
lastLoadedCrewId = crewId;
|
|
385
|
+
resetQuestion();
|
|
386
|
+
} finally {
|
|
387
|
+
if (currentRequest === detailsRequestId) {
|
|
388
|
+
crewDetailsLoading = false;
|
|
389
|
+
pendingCrewId = null;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
async function handleSubmit(event: Event) {
|
|
395
|
+
event.preventDefault();
|
|
396
|
+
jobError = '';
|
|
397
|
+
|
|
398
|
+
if (!selectedCrewId) {
|
|
399
|
+
jobError = 'Please choose a crew to ask your question.';
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
const executionOptions: crewApi.ExecuteCrewOptions = {
|
|
404
|
+
execution_mode: currentMode
|
|
405
|
+
};
|
|
406
|
+
let queryPayload: string | Record<string, string>;
|
|
407
|
+
|
|
408
|
+
if (currentMode === 'parallel') {
|
|
409
|
+
if (parallelInputMode === 'shared') {
|
|
410
|
+
if (!parallelSharedTask.trim()) {
|
|
411
|
+
jobError = 'Please provide a shared task for the crew.';
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
queryPayload = parallelSharedTask.trim();
|
|
415
|
+
} else {
|
|
416
|
+
const entries = Object.entries(parallelAgentTasks ?? {});
|
|
417
|
+
if (!entries.length) {
|
|
418
|
+
jobError = 'No agents available to run in parallel.';
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
const missingPrompts = entries.filter(([, prompt]) => !prompt?.trim());
|
|
422
|
+
if (missingPrompts.length) {
|
|
423
|
+
jobError = 'Please provide a prompt for each agent.';
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
const customTasks: Record<string, string> = {};
|
|
427
|
+
for (const [agentId, prompt] of entries) {
|
|
428
|
+
customTasks[agentId] = prompt.trim();
|
|
429
|
+
}
|
|
430
|
+
queryPayload = customTasks;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (parallelSynthesisPrompt.trim()) {
|
|
434
|
+
executionOptions.synthesis_prompt = parallelSynthesisPrompt.trim();
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
const kwargs: Record<string, unknown> = {};
|
|
438
|
+
if (parallelAllResults) {
|
|
439
|
+
kwargs.all_results = true;
|
|
440
|
+
}
|
|
441
|
+
executionOptions.kwargs = kwargs;
|
|
442
|
+
} else if (currentMode === 'loop') {
|
|
443
|
+
if (!loopInitialTask.trim()) {
|
|
444
|
+
jobError = 'Please provide an initial task to start the loop.';
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
if (!loopCondition.trim()) {
|
|
448
|
+
jobError = 'Please provide a condition to stop the loop.';
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
const iterations = Math.max(1, Number(loopMaxIterations) || 1);
|
|
453
|
+
|
|
454
|
+
queryPayload = loopInitialTask.trim();
|
|
455
|
+
const kwargs: Record<string, unknown> = {
|
|
456
|
+
condition: loopCondition.trim(),
|
|
457
|
+
max_iterations: iterations
|
|
458
|
+
};
|
|
459
|
+
if (loopAgentSequence.length) {
|
|
460
|
+
kwargs.agent_sequence = [...loopAgentSequence];
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
if (loopSynthesisPrompt.trim()) {
|
|
464
|
+
executionOptions.synthesis_prompt = loopSynthesisPrompt.trim();
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
executionOptions.kwargs = kwargs;
|
|
468
|
+
} else if (currentMode === 'flow') {
|
|
469
|
+
if (!flowInitialTask.trim()) {
|
|
470
|
+
jobError = 'Please provide an initial task for the flow execution.';
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
queryPayload = flowInitialTask.trim();
|
|
475
|
+
|
|
476
|
+
if (flowSynthesisPrompt.trim()) {
|
|
477
|
+
executionOptions.synthesis_prompt = flowSynthesisPrompt.trim();
|
|
478
|
+
}
|
|
479
|
+
} else {
|
|
480
|
+
if (!question.trim()) {
|
|
481
|
+
jobError = 'Please provide a question or task for the crew.';
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
queryPayload = question.trim();
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
isSubmitting = true;
|
|
489
|
+
statusMessage = '';
|
|
490
|
+
jobStatus = null;
|
|
491
|
+
|
|
492
|
+
try {
|
|
493
|
+
const execution = await crewApi.executeCrew(selectedCrewId, queryPayload, executionOptions);
|
|
494
|
+
jobStatus = execution;
|
|
495
|
+
statusMessage = execution?.message ?? 'Crew execution started.';
|
|
496
|
+
|
|
497
|
+
if (!execution?.job_id) {
|
|
498
|
+
throw new Error('The crew execution did not return a job identifier.');
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
const finalStatus = await crewApi.pollJobUntilComplete(execution.job_id, 2000, 120);
|
|
502
|
+
jobStatus = finalStatus as CrewJobStatus;
|
|
503
|
+
statusMessage = finalStatus?.message ?? `Crew status: ${finalStatus?.status ?? 'unknown'}`;
|
|
504
|
+
} catch (error) {
|
|
505
|
+
console.error('Failed to execute crew', error);
|
|
506
|
+
jobError = extractErrorMessage(error, 'Unable to execute the crew. Please try again.');
|
|
507
|
+
} finally {
|
|
508
|
+
isSubmitting = false;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
function resetQuestion() {
|
|
513
|
+
question = '';
|
|
514
|
+
parallelSharedTask = '';
|
|
515
|
+
parallelSynthesisPrompt = '';
|
|
516
|
+
parallelAllResults = false;
|
|
517
|
+
parallelInputMode = 'shared';
|
|
518
|
+
loopInitialTask = '';
|
|
519
|
+
loopCondition = '';
|
|
520
|
+
loopMaxIterations = 4;
|
|
521
|
+
loopSynthesisPrompt = '';
|
|
522
|
+
flowInitialTask = '';
|
|
523
|
+
flowSynthesisPrompt = '';
|
|
524
|
+
if (loopAgentSequence.length) {
|
|
525
|
+
initializeAgentPrompts(loopAgentSequence);
|
|
526
|
+
} else {
|
|
527
|
+
parallelAgentTasks = {};
|
|
528
|
+
}
|
|
529
|
+
jobStatus = null;
|
|
530
|
+
jobError = '';
|
|
531
|
+
statusMessage = '';
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
function handleModeChange(mode: CrewExecutionMode) {
|
|
535
|
+
if (currentMode !== mode) {
|
|
536
|
+
currentMode = mode;
|
|
537
|
+
}
|
|
538
|
+
modeLocked = true;
|
|
539
|
+
jobStatus = null;
|
|
540
|
+
jobError = '';
|
|
541
|
+
statusMessage = '';
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
function retryLoadCrewDetails() {
|
|
545
|
+
if (!selectedCrewId) {
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
lastLoadedCrewId = null;
|
|
549
|
+
pendingCrewId = null;
|
|
550
|
+
void loadCrewDetails(selectedCrewId);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
onMount(() => {
|
|
554
|
+
const initialCrewId = get(page).url.searchParams.get('crew_id');
|
|
555
|
+
fetchCrews(initialCrewId);
|
|
556
|
+
});
|
|
557
|
+
</script>
|
|
558
|
+
|
|
559
|
+
<svelte:head>
|
|
560
|
+
<title>Ask a Crew</title>
|
|
561
|
+
</svelte:head>
|
|
562
|
+
|
|
563
|
+
<div class="min-h-screen bg-base-200/60 py-10">
|
|
564
|
+
<div class="mx-auto max-w-5xl space-y-8 px-4">
|
|
565
|
+
<div class="flex flex-wrap items-start justify-between gap-3">
|
|
566
|
+
<div>
|
|
567
|
+
<h1 class="text-3xl font-bold text-base-content">Ask a Crew</h1>
|
|
568
|
+
<p class="mt-2 text-base text-base-content/70">
|
|
569
|
+
Select one of your existing crews and configure how it should run. Provide prompts, loop conditions, or
|
|
570
|
+
synthesis instructions and review both the final outcome and each agent's contribution.
|
|
571
|
+
</p>
|
|
572
|
+
</div>
|
|
573
|
+
<a class="btn btn-ghost" href="/">
|
|
574
|
+
← Back to dashboard
|
|
575
|
+
</a>
|
|
576
|
+
</div>
|
|
577
|
+
|
|
578
|
+
<section class="rounded-xl bg-base-100 p-6 shadow">
|
|
579
|
+
<form class="space-y-6" on:submit={handleSubmit}>
|
|
580
|
+
<div class="space-y-2">
|
|
581
|
+
<label class="block text-sm font-semibold text-base-content/80" for={crewSelectId}>Select crew</label>
|
|
582
|
+
{#if crewsLoading}
|
|
583
|
+
<div class="flex items-center gap-3 rounded-lg border border-dashed border-base-300 p-4 text-sm text-base-content/70">
|
|
584
|
+
<LoadingSpinner size="sm" center={false} />
|
|
585
|
+
<span>Loading crews…</span>
|
|
586
|
+
</div>
|
|
587
|
+
{:else if crewsError}
|
|
588
|
+
<div class="alert alert-error">
|
|
589
|
+
<span>{crewsError}</span>
|
|
590
|
+
<button type="button" class="btn btn-sm" on:click={() => fetchCrews(selectedCrewId)}>
|
|
591
|
+
Retry
|
|
592
|
+
</button>
|
|
593
|
+
</div>
|
|
594
|
+
{:else}
|
|
595
|
+
<select
|
|
596
|
+
class="select select-bordered w-full"
|
|
597
|
+
id={crewSelectId}
|
|
598
|
+
bind:value={selectedCrewId}
|
|
599
|
+
>
|
|
600
|
+
<option value="" disabled selected={!selectedCrewId}>
|
|
601
|
+
Choose a crew to query
|
|
602
|
+
</option>
|
|
603
|
+
{#each crews as crewItem (crewItem.crew_id)}
|
|
604
|
+
<option value={crewItem.crew_id}>
|
|
605
|
+
{crewItem.name} — {crewItem.crew_id}
|
|
606
|
+
</option>
|
|
607
|
+
{/each}
|
|
608
|
+
</select>
|
|
609
|
+
{#if selectedCrew}
|
|
610
|
+
<div class="space-y-2 text-sm text-base-content/70">
|
|
611
|
+
<p>
|
|
612
|
+
<span class="font-semibold">Crew ID:</span> {selectedCrew.crew_id}
|
|
613
|
+
<span class="mx-2">·</span>
|
|
614
|
+
<span class="font-semibold">Default mode:</span> {selectedCrew.execution_mode || 'sequential'}
|
|
615
|
+
</p>
|
|
616
|
+
<p class="text-xs text-base-content/60">
|
|
617
|
+
{selectedCrew.description || 'No description provided'}
|
|
618
|
+
</p>
|
|
619
|
+
{#if crewDetails?.agents}
|
|
620
|
+
<p class="text-xs text-base-content/60">
|
|
621
|
+
<span class="font-semibold text-base-content">Agents:</span> {crewDetails.agents.length}
|
|
622
|
+
</p>
|
|
623
|
+
{/if}
|
|
624
|
+
</div>
|
|
625
|
+
{/if}
|
|
626
|
+
{#if crewDetailsLoading}
|
|
627
|
+
<div class="mt-3 flex items-center gap-3 rounded-lg border border-dashed border-base-300 p-3 text-sm text-base-content/70">
|
|
628
|
+
<LoadingSpinner size="sm" center={false} />
|
|
629
|
+
<span>Loading crew details…</span>
|
|
630
|
+
</div>
|
|
631
|
+
{:else if crewDetailsError}
|
|
632
|
+
<div class="alert alert-warning mt-3">
|
|
633
|
+
<span>{crewDetailsError}</span>
|
|
634
|
+
<button type="button" class="btn btn-sm" on:click={retryLoadCrewDetails}>
|
|
635
|
+
Retry
|
|
636
|
+
</button>
|
|
637
|
+
</div>
|
|
638
|
+
{/if}
|
|
639
|
+
{/if}
|
|
640
|
+
</div>
|
|
641
|
+
|
|
642
|
+
{#if selectedCrew}
|
|
643
|
+
<div class="rounded-lg border border-base-300 bg-base-200/60 px-4 py-4 text-sm text-base-content/70">
|
|
644
|
+
<div class="flex flex-col gap-4 md:flex-row md:items-start md:justify-between">
|
|
645
|
+
<div class="space-y-1">
|
|
646
|
+
<span class="block text-sm font-semibold uppercase tracking-wide text-base-content/80">
|
|
647
|
+
Execution mode
|
|
648
|
+
</span>
|
|
649
|
+
<p class="text-xs text-base-content/60">
|
|
650
|
+
{executionModeMeta[currentMode].description}
|
|
651
|
+
</p>
|
|
652
|
+
</div>
|
|
653
|
+
<div class="w-full max-w-xs">
|
|
654
|
+
<label class="form-control w-full">
|
|
655
|
+
<span class="label-text text-xs font-semibold text-base-content/60">Mode</span>
|
|
656
|
+
<select
|
|
657
|
+
class="select select-bordered mt-1 w-full capitalize"
|
|
658
|
+
bind:value={currentMode}
|
|
659
|
+
on:change={(event) =>
|
|
660
|
+
handleModeChange((event.target as HTMLSelectElement).value as CrewExecutionMode)
|
|
661
|
+
}
|
|
662
|
+
disabled={isSubmitting || crewsLoading || crewDetailsLoading}
|
|
663
|
+
>
|
|
664
|
+
{#each executionModeOptions as option (option.value)}
|
|
665
|
+
<option value={option.value} class="capitalize">{option.label}</option>
|
|
666
|
+
{/each}
|
|
667
|
+
</select>
|
|
668
|
+
</label>
|
|
669
|
+
</div>
|
|
670
|
+
</div>
|
|
671
|
+
{#if crewDetails?.agents}
|
|
672
|
+
<p class="mt-4 text-xs text-base-content/60">
|
|
673
|
+
<span class="font-semibold text-base-content">Agents:</span> {crewDetails.agents.length}
|
|
674
|
+
</p>
|
|
675
|
+
{/if}
|
|
676
|
+
</div>
|
|
677
|
+
{/if}
|
|
678
|
+
|
|
679
|
+
{#if currentMode === 'parallel'}
|
|
680
|
+
<div class="space-y-6">
|
|
681
|
+
<div class="rounded-lg border border-base-300 bg-base-100 p-4">
|
|
682
|
+
<div class="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
|
|
683
|
+
<div>
|
|
684
|
+
<h3 class="text-lg font-semibold text-base-content">Parallel tasks</h3>
|
|
685
|
+
<p class="text-sm text-base-content/70">Choose how prompts are distributed across agents.</p>
|
|
686
|
+
</div>
|
|
687
|
+
</div>
|
|
688
|
+
<div class="mt-4 flex flex-col gap-2 md:flex-row md:items-center">
|
|
689
|
+
<label class="flex cursor-pointer items-center gap-2 rounded-lg border border-base-300 bg-base-200/60 px-3 py-2 text-sm">
|
|
690
|
+
<input
|
|
691
|
+
type="radio"
|
|
692
|
+
class="radio radio-sm"
|
|
693
|
+
value="shared"
|
|
694
|
+
bind:group={parallelInputMode}
|
|
695
|
+
disabled={isSubmitting || crewDetailsLoading}
|
|
696
|
+
/>
|
|
697
|
+
<span>Single prompt for all agents</span>
|
|
698
|
+
</label>
|
|
699
|
+
<label class="flex cursor-pointer items-center gap-2 rounded-lg border border-base-300 bg-base-200/60 px-3 py-2 text-sm">
|
|
700
|
+
<input
|
|
701
|
+
type="radio"
|
|
702
|
+
class="radio radio-sm"
|
|
703
|
+
value="custom"
|
|
704
|
+
bind:group={parallelInputMode}
|
|
705
|
+
disabled={isSubmitting || crewDetailsLoading || !(crewDetails?.agents?.length)}
|
|
706
|
+
/>
|
|
707
|
+
<span>Custom prompt per agent</span>
|
|
708
|
+
</label>
|
|
709
|
+
</div>
|
|
710
|
+
{#if parallelInputMode === 'shared'}
|
|
711
|
+
<div class="mt-4">
|
|
712
|
+
<MarkdownEditor
|
|
713
|
+
bind:value={parallelSharedTask}
|
|
714
|
+
helperText="This prompt will be sent to every agent."
|
|
715
|
+
disabled={isSubmitting || crewsLoading || crewDetailsLoading}
|
|
716
|
+
/>
|
|
717
|
+
</div>
|
|
718
|
+
{:else}
|
|
719
|
+
<div class="mt-4 space-y-4">
|
|
720
|
+
{#if crewDetailsLoading}
|
|
721
|
+
<div class="flex items-center gap-3 text-sm text-base-content/70">
|
|
722
|
+
<LoadingSpinner size="sm" center={false} />
|
|
723
|
+
<span>Loading agent details…</span>
|
|
724
|
+
</div>
|
|
725
|
+
{:else if crewDetailsError}
|
|
726
|
+
<p class="text-sm text-error">Crew details are unavailable. Retry loading above.</p>
|
|
727
|
+
{:else if !crewDetails?.agents?.length}
|
|
728
|
+
<p class="text-sm text-base-content/60">This crew does not have any agents configured.</p>
|
|
729
|
+
{:else}
|
|
730
|
+
{#each crewDetails.agents as agent (agent.agent_id)}
|
|
731
|
+
<div class="space-y-2 rounded-lg border border-base-300 bg-base-200/60 p-3">
|
|
732
|
+
<div class="flex flex-wrap items-center justify-between gap-2">
|
|
733
|
+
<span class="font-semibold text-base-content">{agent.name?.trim() || agent.agent_id}</span>
|
|
734
|
+
<span class="badge badge-outline text-xs">{agent.agent_id}</span>
|
|
735
|
+
</div>
|
|
736
|
+
<textarea
|
|
737
|
+
class="textarea textarea-bordered w-full text-sm"
|
|
738
|
+
rows="3"
|
|
739
|
+
value={parallelAgentTasks[agent.agent_id] ?? ''}
|
|
740
|
+
on:input={(event) =>
|
|
741
|
+
setParallelAgentTask(agent.agent_id, (event.currentTarget as HTMLTextAreaElement).value)
|
|
742
|
+
}
|
|
743
|
+
placeholder="Enter a prompt for this agent"
|
|
744
|
+
disabled={isSubmitting}
|
|
745
|
+
></textarea>
|
|
746
|
+
</div>
|
|
747
|
+
{/each}
|
|
748
|
+
{/if}
|
|
749
|
+
</div>
|
|
750
|
+
{/if}
|
|
751
|
+
</div>
|
|
752
|
+
|
|
753
|
+
<div class="rounded-lg border border-base-300 bg-base-100 p-4">
|
|
754
|
+
<h3 class="text-lg font-semibold text-base-content">Synthesis</h3>
|
|
755
|
+
<p class="text-sm text-base-content/70">
|
|
756
|
+
Provide an optional synthesis prompt to summarize the combined results.
|
|
757
|
+
</p>
|
|
758
|
+
<textarea
|
|
759
|
+
class="textarea textarea-bordered mt-3 w-full text-sm"
|
|
760
|
+
rows="3"
|
|
761
|
+
bind:value={parallelSynthesisPrompt}
|
|
762
|
+
placeholder="Ask the crew to synthesize the parallel outputs (optional)"
|
|
763
|
+
disabled={isSubmitting}
|
|
764
|
+
></textarea>
|
|
765
|
+
<label class="mt-4 flex items-center justify-between gap-3 rounded-lg border border-base-300 bg-base-200/60 px-4 py-3 text-sm text-base-content">
|
|
766
|
+
<span>Return each agent result separately</span>
|
|
767
|
+
<input type="checkbox" class="toggle" bind:checked={parallelAllResults} disabled={isSubmitting} />
|
|
768
|
+
</label>
|
|
769
|
+
<p class="mt-2 text-xs text-base-content/60">
|
|
770
|
+
When enabled, the final output will be a list of each agent's response.
|
|
771
|
+
</p>
|
|
772
|
+
</div>
|
|
773
|
+
</div>
|
|
774
|
+
{:else if currentMode === 'loop'}
|
|
775
|
+
<div class="space-y-6">
|
|
776
|
+
<div class="space-y-4 rounded-lg border border-base-300 bg-base-100 p-4">
|
|
777
|
+
<div>
|
|
778
|
+
<h3 class="text-lg font-semibold text-base-content">Loop configuration</h3>
|
|
779
|
+
<p class="text-sm text-base-content/70">
|
|
780
|
+
Provide the initial task and stopping criteria for the loop.
|
|
781
|
+
</p>
|
|
782
|
+
</div>
|
|
783
|
+
<MarkdownEditor
|
|
784
|
+
bind:value={loopInitialTask}
|
|
785
|
+
helperText="Initial task for the first iteration."
|
|
786
|
+
disabled={isSubmitting || crewsLoading || crewDetailsLoading}
|
|
787
|
+
/>
|
|
788
|
+
<div class="grid gap-4 md:grid-cols-2">
|
|
789
|
+
<label class="form-control w-full">
|
|
790
|
+
<span class="label-text text-sm font-semibold text-base-content">Stopping condition</span>
|
|
791
|
+
<input
|
|
792
|
+
type="text"
|
|
793
|
+
class="input input-bordered mt-2"
|
|
794
|
+
bind:value={loopCondition}
|
|
795
|
+
placeholder="Stop when..."
|
|
796
|
+
disabled={isSubmitting}
|
|
797
|
+
/>
|
|
798
|
+
<span class="mt-1 text-xs text-base-content/60">
|
|
799
|
+
Example: “Stop when the reviewer marks the report as FINAL”.
|
|
800
|
+
</span>
|
|
801
|
+
</label>
|
|
802
|
+
<label class="form-control w-full">
|
|
803
|
+
<span class="label-text text-sm font-semibold text-base-content">Max iterations</span>
|
|
804
|
+
<input
|
|
805
|
+
type="number"
|
|
806
|
+
class="input input-bordered mt-2"
|
|
807
|
+
min="1"
|
|
808
|
+
bind:value={loopMaxIterations}
|
|
809
|
+
disabled={isSubmitting}
|
|
810
|
+
/>
|
|
811
|
+
<span class="mt-1 text-xs text-base-content/60">
|
|
812
|
+
Safety limit for how many times the loop can run.
|
|
813
|
+
</span>
|
|
814
|
+
</label>
|
|
815
|
+
</div>
|
|
816
|
+
</div>
|
|
817
|
+
|
|
818
|
+
<div class="space-y-3 rounded-lg border border-base-300 bg-base-100 p-4">
|
|
819
|
+
<div class="flex flex-wrap items-center justify-between gap-2">
|
|
820
|
+
<h3 class="text-lg font-semibold text-base-content">Agent sequence</h3>
|
|
821
|
+
<span class="text-xs text-base-content/60">Drag and drop to reorder</span>
|
|
822
|
+
</div>
|
|
823
|
+
{#if crewDetailsLoading}
|
|
824
|
+
<div class="flex items-center gap-3 text-sm text-base-content/70">
|
|
825
|
+
<LoadingSpinner size="sm" center={false} />
|
|
826
|
+
<span>Loading agents…</span>
|
|
827
|
+
</div>
|
|
828
|
+
{:else if !loopAgentSequence.length}
|
|
829
|
+
<p class="text-sm text-base-content/60">No agents available for loop execution.</p>
|
|
830
|
+
{:else}
|
|
831
|
+
<ul class="space-y-2">
|
|
832
|
+
{#each loopAgentSequence as agentId, index (agentId)}
|
|
833
|
+
<li
|
|
834
|
+
class:opacity-60={draggingIndex === index}
|
|
835
|
+
class="flex items-center justify-between gap-3 rounded-lg border border-base-300 bg-base-100 p-3"
|
|
836
|
+
draggable={!isSubmitting}
|
|
837
|
+
on:dragstart={(event) => handleDragStart(event, index)}
|
|
838
|
+
on:dragover={handleDragOver}
|
|
839
|
+
on:drop={(event) => handleDrop(event, index)}
|
|
840
|
+
on:dragend={handleDragEnd}
|
|
841
|
+
>
|
|
842
|
+
<div>
|
|
843
|
+
<p class="font-semibold text-base-content">{getAgentDisplayName(agentId)}</p>
|
|
844
|
+
<p class="text-xs text-base-content/60">{agentId}</p>
|
|
845
|
+
</div>
|
|
846
|
+
<div class="flex items-center gap-2">
|
|
847
|
+
<button
|
|
848
|
+
type="button"
|
|
849
|
+
class="btn btn-ghost btn-xs"
|
|
850
|
+
on:click={() => moveAgentUp(index)}
|
|
851
|
+
disabled={index === 0 || isSubmitting}
|
|
852
|
+
aria-label={`Move ${getAgentDisplayName(agentId)} up`}
|
|
853
|
+
title="Move up"
|
|
854
|
+
>
|
|
855
|
+
↑
|
|
856
|
+
</button>
|
|
857
|
+
<button
|
|
858
|
+
type="button"
|
|
859
|
+
class="btn btn-ghost btn-xs"
|
|
860
|
+
on:click={() => moveAgentDown(index)}
|
|
861
|
+
disabled={index === loopAgentSequence.length - 1 || isSubmitting}
|
|
862
|
+
aria-label={`Move ${getAgentDisplayName(agentId)} down`}
|
|
863
|
+
title="Move down"
|
|
864
|
+
>
|
|
865
|
+
↓
|
|
866
|
+
</button>
|
|
867
|
+
</div>
|
|
868
|
+
</li>
|
|
869
|
+
{/each}
|
|
870
|
+
</ul>
|
|
871
|
+
<div
|
|
872
|
+
class="rounded-lg border border-dashed border-base-300 bg-base-200/60 p-3 text-center text-xs text-base-content/60"
|
|
873
|
+
on:dragover={handleDragOver}
|
|
874
|
+
on:drop={handleDropAtEnd}
|
|
875
|
+
>
|
|
876
|
+
Drop here to move an agent to the end of the sequence
|
|
877
|
+
</div>
|
|
878
|
+
{/if}
|
|
879
|
+
</div>
|
|
880
|
+
|
|
881
|
+
<div class="rounded-lg border border-base-300 bg-base-100 p-4">
|
|
882
|
+
<h3 class="text-lg font-semibold text-base-content">Synthesis</h3>
|
|
883
|
+
<p class="text-sm text-base-content/70">
|
|
884
|
+
Optionally summarize the loop results after the stopping condition is met.
|
|
885
|
+
</p>
|
|
886
|
+
<textarea
|
|
887
|
+
class="textarea textarea-bordered mt-3 w-full text-sm"
|
|
888
|
+
rows="3"
|
|
889
|
+
bind:value={loopSynthesisPrompt}
|
|
890
|
+
placeholder="Ask the crew to synthesize the loop outputs (optional)"
|
|
891
|
+
disabled={isSubmitting}
|
|
892
|
+
></textarea>
|
|
893
|
+
</div>
|
|
894
|
+
</div>
|
|
895
|
+
{:else if currentMode === 'flow'}
|
|
896
|
+
<div class="space-y-6">
|
|
897
|
+
<div class="space-y-4 rounded-lg border border-base-300 bg-base-100 p-4">
|
|
898
|
+
<div>
|
|
899
|
+
<h3 class="text-lg font-semibold text-base-content">Flow execution</h3>
|
|
900
|
+
<p class="text-sm text-base-content/70">
|
|
901
|
+
Provide the starting task for the workflow defined in the crew builder.
|
|
902
|
+
</p>
|
|
903
|
+
</div>
|
|
904
|
+
<MarkdownEditor
|
|
905
|
+
bind:value={flowInitialTask}
|
|
906
|
+
helperText="Initial task for the flow execution."
|
|
907
|
+
disabled={isSubmitting || crewsLoading || crewDetailsLoading}
|
|
908
|
+
/>
|
|
909
|
+
<p class="text-xs text-base-content/60">
|
|
910
|
+
The execution order follows the flow configuration from the crew builder.
|
|
911
|
+
</p>
|
|
912
|
+
</div>
|
|
913
|
+
|
|
914
|
+
<div class="rounded-lg border border-base-300 bg-base-100 p-4">
|
|
915
|
+
<h3 class="text-lg font-semibold text-base-content">Synthesis</h3>
|
|
916
|
+
<p class="text-sm text-base-content/70">
|
|
917
|
+
Optionally summarize results from the completed flow.
|
|
918
|
+
</p>
|
|
919
|
+
<textarea
|
|
920
|
+
class="textarea textarea-bordered mt-3 w-full text-sm"
|
|
921
|
+
rows="3"
|
|
922
|
+
bind:value={flowSynthesisPrompt}
|
|
923
|
+
placeholder="Ask the crew to synthesize the flow outputs (optional)"
|
|
924
|
+
disabled={isSubmitting}
|
|
925
|
+
></textarea>
|
|
926
|
+
</div>
|
|
927
|
+
</div>
|
|
928
|
+
{:else}
|
|
929
|
+
<MarkdownEditor
|
|
930
|
+
bind:value={question}
|
|
931
|
+
helperText="Supports headings, lists, inline code, and more."
|
|
932
|
+
disabled={isSubmitting || crewsLoading}
|
|
933
|
+
/>
|
|
934
|
+
{/if}
|
|
935
|
+
|
|
936
|
+
{#if jobError}
|
|
937
|
+
<div class="alert alert-error">
|
|
938
|
+
<span>{jobError}</span>
|
|
939
|
+
</div>
|
|
940
|
+
{/if}
|
|
941
|
+
|
|
942
|
+
<div class="flex flex-wrap gap-3">
|
|
943
|
+
<button type="submit" class="btn btn-primary" disabled={isSubmitting || !selectedCrewId}>
|
|
944
|
+
{#if isSubmitting}
|
|
945
|
+
<span class="loading loading-spinner"></span>
|
|
946
|
+
Running…
|
|
947
|
+
{:else}
|
|
948
|
+
Ask Crew
|
|
949
|
+
{/if}
|
|
950
|
+
</button>
|
|
951
|
+
<button type="button" class="btn btn-ghost" on:click={resetQuestion} disabled={isSubmitting}>
|
|
952
|
+
Clear
|
|
953
|
+
</button>
|
|
954
|
+
</div>
|
|
955
|
+
</form>
|
|
956
|
+
</section>
|
|
957
|
+
|
|
958
|
+
{#if isSubmitting}
|
|
959
|
+
<div class="flex items-center justify-center gap-3 rounded-xl border border-dashed border-base-300 bg-base-100 p-6 text-base-content/70">
|
|
960
|
+
<LoadingSpinner text="Waiting for the crew to finish…" />
|
|
961
|
+
</div>
|
|
962
|
+
{/if}
|
|
963
|
+
|
|
964
|
+
{#if statusMessage}
|
|
965
|
+
<div class="alert alert-info">
|
|
966
|
+
<div>
|
|
967
|
+
<span class="font-semibold">Status:</span>
|
|
968
|
+
<span class="ml-2">{statusMessage}</span>
|
|
969
|
+
</div>
|
|
970
|
+
{#if jobStatus}
|
|
971
|
+
<span class="badge badge-outline">{jobStatus.status}</span>
|
|
972
|
+
{/if}
|
|
973
|
+
</div>
|
|
974
|
+
{/if}
|
|
975
|
+
|
|
976
|
+
{#if jobStatus}
|
|
977
|
+
<section class="space-y-6">
|
|
978
|
+
<div class="rounded-xl bg-base-100 p-6 shadow">
|
|
979
|
+
<div class="flex flex-wrap items-center justify-between gap-4">
|
|
980
|
+
<div>
|
|
981
|
+
<h2 class="text-2xl font-semibold text-base-content">Crew response</h2>
|
|
982
|
+
<p class="text-sm text-base-content/70">Job ID: {jobStatus.job_id}</p>
|
|
983
|
+
{#if jobStatus.execution_mode}
|
|
984
|
+
<p class="text-sm text-base-content/60">
|
|
985
|
+
Execution mode: {getExecutionModeLabel(jobStatus.execution_mode)}
|
|
986
|
+
</p>
|
|
987
|
+
{/if}
|
|
988
|
+
</div>
|
|
989
|
+
<div class="badge badge-primary badge-outline text-base-content">
|
|
990
|
+
{jobStatus.status}
|
|
991
|
+
</div>
|
|
992
|
+
</div>
|
|
993
|
+
|
|
994
|
+
<div class="mt-6 space-y-4">
|
|
995
|
+
<div class="rounded-lg border border-base-300 bg-base-200 p-4">
|
|
996
|
+
<h3 class="text-lg font-semibold text-base-content">Final output</h3>
|
|
997
|
+
{#if finalOutputHtml}
|
|
998
|
+
<div class="mt-3 space-y-2 text-base leading-relaxed text-base-content">
|
|
999
|
+
{@html finalOutputHtml}
|
|
1000
|
+
</div>
|
|
1001
|
+
{:else if finalOutputList.length}
|
|
1002
|
+
<div class="mt-3 space-y-3">
|
|
1003
|
+
{#each finalOutputList as item, index (index)}
|
|
1004
|
+
<div class="rounded-lg border border-base-300 bg-base-100 p-3">
|
|
1005
|
+
<div class="text-sm font-semibold text-base-content">Result {index + 1}</div>
|
|
1006
|
+
{#if finalOutputListHtml[index]}
|
|
1007
|
+
<div class="mt-2 space-y-2 text-sm leading-relaxed text-base-content">
|
|
1008
|
+
{@html finalOutputListHtml[index]}
|
|
1009
|
+
</div>
|
|
1010
|
+
{:else}
|
|
1011
|
+
<p class="mt-2 text-sm text-base-content/70">{String(item ?? '')}</p>
|
|
1012
|
+
{/if}
|
|
1013
|
+
</div>
|
|
1014
|
+
{/each}
|
|
1015
|
+
</div>
|
|
1016
|
+
{:else}
|
|
1017
|
+
<p class="mt-3 text-base-content/70">No final output was returned.</p>
|
|
1018
|
+
{/if}
|
|
1019
|
+
</div>
|
|
1020
|
+
|
|
1021
|
+
{#if agentResponses.length}
|
|
1022
|
+
<div class="rounded-lg border border-base-300 bg-base-200 p-4">
|
|
1023
|
+
<h3 class="text-lg font-semibold text-base-content">Agents responses</h3>
|
|
1024
|
+
<div class="mt-4 space-y-4">
|
|
1025
|
+
{#each agentResponses as agent (agent.name)}
|
|
1026
|
+
<div class="rounded-lg border border-base-300 bg-base-100 p-4">
|
|
1027
|
+
<h4 class="text-base font-semibold text-base-content">{agent.name}</h4>
|
|
1028
|
+
{#if agent.input}
|
|
1029
|
+
<p class="mt-2 text-sm text-base-content/70">
|
|
1030
|
+
<span class="font-semibold">Input:</span> {agent.input}
|
|
1031
|
+
</p>
|
|
1032
|
+
{/if}
|
|
1033
|
+
{#if agent.outputHtml}
|
|
1034
|
+
<div class="mt-3 space-y-2 text-sm leading-relaxed text-base-content">
|
|
1035
|
+
{@html agent.outputHtml}
|
|
1036
|
+
</div>
|
|
1037
|
+
{:else}
|
|
1038
|
+
<p class="mt-3 text-sm text-base-content/60">No output recorded for this agent.</p>
|
|
1039
|
+
{/if}
|
|
1040
|
+
</div>
|
|
1041
|
+
{/each}
|
|
1042
|
+
</div>
|
|
1043
|
+
</div>
|
|
1044
|
+
{/if}
|
|
1045
|
+
</div>
|
|
1046
|
+
</div>
|
|
1047
|
+
|
|
1048
|
+
<JsonViewer data={jobStatus} title="Advanced results" />
|
|
1049
|
+
</section>
|
|
1050
|
+
{/if}
|
|
1051
|
+
</div>
|
|
1052
|
+
</div>
|