machinaos 0.0.78 → 0.0.80
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.
- package/.env.template +74 -5
- package/{workflows/AI Assistant_workflow-1778504793388-ou1m1tz2x.json → .machina/workflows/AI Assistant_example_workflow-1779017037684-e2e5da7a.json } +164 -105
- package/{workflows/AI Employee_example_workflow-1777720598005-u4cm858dv.json → .machina/workflows/AI Employee_example_workflow-1779102911870-cbc76c82.json } +582 -328
- package/{workflows/Claude Assistant_workflow-1778380124051-mdibn807c.json → .machina/workflows/Claude Assistant_example_workflow-1779095939967-2369cff4.json } +152 -83
- package/README.md +5 -2
- package/bin/cli.js +2 -2
- package/{machina → cli}/__main__.py +11 -7
- package/cli/_common.py +122 -0
- package/cli/buildenv.py +40 -0
- package/cli/cli.py +204 -0
- package/{machina → cli}/colors.py +10 -2
- package/cli/commands/__init__.py +1 -0
- package/cli/commands/_temporal_specs.py +59 -0
- package/{machina → cli}/commands/build.py +35 -45
- package/cli/commands/clean.py +141 -0
- package/cli/commands/daemon/__init__.py +47 -0
- package/cli/commands/daemon/_state.py +97 -0
- package/cli/commands/daemon/restart.py +14 -0
- package/cli/commands/daemon/start.py +49 -0
- package/cli/commands/daemon/status.py +20 -0
- package/cli/commands/daemon/stop.py +22 -0
- package/{machina → cli}/commands/dev.py +32 -42
- package/{machina → cli}/commands/docs.py +13 -11
- package/{machina → cli}/commands/start.py +69 -62
- package/{machina → cli}/commands/stop.py +7 -10
- package/{machina → cli}/commands/version.py +12 -6
- package/cli/config.py +170 -0
- package/cli/platform_.py +169 -0
- package/{machina → cli}/ports.py +42 -3
- package/{machina → cli}/run.py +29 -2
- package/{machina → cli}/supervisor.py +29 -12
- package/{machina → cli}/tcp.py +6 -2
- package/{machina → cli}/tree.py +38 -11
- package/client/dist/assets/{ActionBar-Du2MSFSz.js → ActionBar-Cjr3TF7g.js} +1 -1
- package/client/dist/assets/{ApiKeyInput-k2LBmBjb.js → ApiKeyInput-DIJE2PVA.js} +1 -1
- package/client/dist/assets/{ApiKeyPanel-C_bV9U0X.js → ApiKeyPanel-CPmye7uh.js} +1 -1
- package/client/dist/assets/{ApiUsageSection-CmVfwZzL.js → ApiUsageSection-TF_7gH2D.js} +1 -1
- package/client/dist/assets/{EmailPanel-CeKIMGu-.js → EmailPanel-Bs-xvbKR.js} +1 -1
- package/client/dist/assets/{OAuthPanel-KA3t3Q2K.js → OAuthPanel-BDtVJhAV.js} +1 -1
- package/client/dist/assets/{QrPairingPanel-NgNpJNuk.js → QrPairingPanel-BwJehTuZ.js} +1 -1
- package/client/dist/assets/{RateLimitSection-Du5YNVIA.js → RateLimitSection-CfNOoPIS.js} +1 -1
- package/client/dist/assets/{StatusCard-DNLyayXc.js → StatusCard-DkwIrgdP.js} +1 -1
- package/client/dist/assets/index-P2FzntoL.js +165 -0
- package/client/dist/index.html +1 -1
- package/client/package.json +1 -1
- package/client/src/Dashboard.tsx +128 -76
- package/client/src/adapters/nodeSpecToDescription.ts +7 -0
- package/client/src/assets/icons/index.test.ts +10 -0
- package/client/src/assets/icons/index.ts +16 -3
- package/client/src/components/AIAgentNode.tsx +8 -8
- package/client/src/components/ParameterRenderer.tsx +6 -3
- package/client/src/components/SkillEditorModal.tsx +1 -0
- package/client/src/components/credentials/panels/EmailPanel.tsx +2 -0
- package/client/src/components/credentials/sections/ProviderDefaultsSection.tsx +2 -0
- package/client/src/components/credentials/sections/RateLimitSection.tsx +1 -0
- package/client/src/components/icons/AIProviderIcons.tsx +1 -0
- package/client/src/components/maps/GoogleMapsPicker.tsx +1 -0
- package/client/src/components/parameterPanel/InputSection.tsx +1 -0
- package/client/src/components/parameterPanel/MasterSkillEditor.tsx +1 -0
- package/client/src/components/parameterPanel/OutputSection.tsx +1 -0
- package/client/src/components/ui/ComponentPalette.tsx +1 -0
- package/client/src/components/ui/MapSelector.tsx +1 -0
- package/client/src/components/ui/NodeContextMenu.tsx +3 -3
- package/client/src/components/ui/SettingsPanel.tsx +1 -0
- package/client/src/components/ui/action-button.tsx +1 -0
- package/client/src/components/ui/badge.tsx +1 -0
- package/client/src/components/ui/button.tsx +1 -0
- package/client/src/components/ui/form.tsx +1 -0
- package/client/src/components/ui/tabs.tsx +1 -0
- package/client/src/contexts/AuthContext.tsx +1 -0
- package/client/src/contexts/ThemeContext.tsx +1 -0
- package/client/src/contexts/WebSocketContext.tsx +104 -34
- package/client/src/hooks/__tests__/useApiKeys.test.ts +2 -2
- package/client/src/hooks/useReactFlowNodes.ts +1 -0
- package/client/src/hooks/useWorkflowValidation.ts +142 -0
- package/client/src/lib/nodeSpec.ts +1 -0
- package/client/src/test/providers.tsx +1 -0
- package/client/src/types/__tests__/cloudEvents.test.ts +5 -2
- package/client/src/types/cloudEvents.ts +19 -7
- package/client/src/utils/nodeUtils.ts +1 -1
- package/client/src/utils/workflow.ts +8 -2
- package/client/src/utils/workflowExport.ts +60 -3
- package/package.json +24 -23
- package/scripts/install.js +16 -27
- package/scripts/migrate_icons.py +3 -1
- package/scripts/migrate_skill_icons.py +6 -7
- package/scripts/postinstall.js +11 -9
- package/server/config/ai_cli_providers.json +2 -3
- package/server/config/credential_providers.json +15 -15
- package/server/config/llm_defaults.json +1 -1
- package/server/config/model_registry.json +416 -611
- package/server/constants.py +285 -223
- package/server/core/__init__.py +1 -1
- package/server/core/cache.py +9 -29
- package/server/core/cleanup.py +12 -24
- package/server/core/config.py +148 -24
- package/server/core/container.py +68 -59
- package/server/core/credential_backends.py +5 -13
- package/server/core/credentials_database.py +13 -43
- package/server/core/database.py +292 -353
- package/server/core/health.py +4 -5
- package/server/core/logging.py +241 -87
- package/server/core/paths.py +285 -0
- package/server/core/tracing.py +2 -8
- package/server/gunicorn.conf.py +1 -0
- package/server/main.py +150 -74
- package/server/middleware/auth.py +18 -24
- package/server/models/__init__.py +1 -1
- package/server/models/auth.py +5 -12
- package/server/models/database.py +36 -68
- package/server/models/node_metadata.py +25 -18
- package/server/nodejs/dist/index.js +107 -0
- package/server/nodes/README.md +11 -5
- package/server/nodes/__init__.py +1 -1
- package/server/nodes/_visuals.py +146 -14
- package/server/nodes/agent/_events.py +124 -0
- package/server/nodes/agent/_handles.py +15 -29
- package/server/nodes/agent/_inline.py +28 -25
- package/server/nodes/agent/_specialized.py +30 -15
- package/server/nodes/agent/{ai_agent.py → ai_agent/__init__.py} +33 -17
- package/server/nodes/agent/ai_agent/meta.json +3 -0
- package/server/nodes/agent/{ai_employee.py → ai_employee/__init__.py} +5 -2
- package/server/nodes/agent/ai_employee/meta.json +3 -0
- package/server/nodes/agent/{android_agent.py → android_agent/__init__.py} +1 -1
- package/server/nodes/agent/android_agent/meta.json +3 -0
- package/server/nodes/agent/{autonomous_agent.py → autonomous_agent/__init__.py} +2 -1
- package/server/nodes/agent/autonomous_agent/meta.json +3 -0
- package/server/nodes/agent/{chat_agent.py → chat_agent/__init__.py} +29 -12
- package/server/nodes/agent/chat_agent/meta.json +3 -0
- package/server/nodes/agent/{claude_code_agent.py → claude_code_agent/__init__.py} +192 -95
- package/server/nodes/agent/claude_code_agent/_handlers.py +169 -0
- package/server/{services/claude_oauth.py → nodes/agent/claude_code_agent/_oauth.py} +26 -13
- package/server/nodes/agent/claude_code_agent/_pool.py +1020 -0
- package/server/nodes/agent/claude_code_agent/_provider.py +513 -0
- package/server/nodes/agent/claude_code_agent/_skills.py +245 -0
- package/server/nodes/agent/claude_code_agent/meta.json +3 -0
- package/server/nodes/agent/{codex_agent.py → codex_agent/__init__.py} +26 -35
- package/server/nodes/agent/codex_agent/meta.json +3 -0
- package/server/nodes/agent/{coding_agent.py → coding_agent/__init__.py} +1 -1
- package/server/nodes/agent/coding_agent/meta.json +3 -0
- package/server/nodes/agent/{consumer_agent.py → consumer_agent/__init__.py} +1 -1
- package/server/nodes/agent/consumer_agent/meta.json +3 -0
- package/server/nodes/agent/{orchestrator_agent.py → orchestrator_agent/__init__.py} +5 -2
- package/server/nodes/agent/orchestrator_agent/meta.json +3 -0
- package/server/nodes/agent/{payments_agent.py → payments_agent/__init__.py} +1 -1
- package/server/nodes/agent/payments_agent/meta.json +3 -0
- package/server/nodes/agent/{productivity_agent.py → productivity_agent/__init__.py} +1 -1
- package/server/nodes/agent/productivity_agent/meta.json +3 -0
- package/server/nodes/agent/{rlm_agent.py → rlm_agent/__init__.py} +18 -17
- package/server/nodes/agent/rlm_agent/meta.json +3 -0
- package/server/nodes/agent/{social_agent.py → social_agent/__init__.py} +1 -1
- package/server/nodes/agent/social_agent/meta.json +3 -0
- package/server/nodes/agent/{task_agent.py → task_agent/__init__.py} +1 -1
- package/server/nodes/agent/task_agent/meta.json +3 -0
- package/server/nodes/agent/{tool_agent.py → tool_agent/__init__.py} +1 -1
- package/server/nodes/agent/tool_agent/meta.json +3 -0
- package/server/nodes/agent/{travel_agent.py → travel_agent/__init__.py} +1 -1
- package/server/nodes/agent/travel_agent/meta.json +3 -0
- package/server/nodes/agent/{web_agent.py → web_agent/__init__.py} +1 -1
- package/server/nodes/agent/web_agent/meta.json +3 -0
- package/server/nodes/android/__init__.py +24 -0
- package/server/nodes/android/_base.py +93 -76
- package/server/nodes/android/_dispatcher.py +140 -223
- package/server/nodes/android/_events.py +154 -0
- package/server/nodes/android/_handlers.py +13 -7
- package/server/nodes/android/_option_loaders.py +1 -4
- package/server/nodes/android/_refresh.py +27 -37
- package/server/nodes/android/_relay/broadcaster.py +25 -41
- package/server/nodes/android/_relay/client.py +23 -42
- package/server/nodes/android/_relay/manager.py +1 -0
- package/server/nodes/android/_relay/protocol.py +6 -0
- package/server/nodes/android/_router.py +48 -133
- package/server/nodes/android/{airplane_mode_control.py → airplane_mode_control/__init__.py} +2 -1
- package/server/nodes/android/airplane_mode_control/meta.json +3 -0
- package/server/nodes/android/{app_launcher.py → app_launcher/__init__.py} +2 -1
- package/server/nodes/android/app_launcher/meta.json +3 -0
- package/server/nodes/android/{app_list.py → app_list/__init__.py} +2 -1
- package/server/nodes/android/app_list/meta.json +3 -0
- package/server/nodes/android/{audio_automation.py → audio_automation/__init__.py} +2 -1
- package/server/nodes/android/audio_automation/meta.json +3 -0
- package/server/nodes/android/{battery_monitor.py → battery_monitor/__init__.py} +2 -1
- package/server/nodes/android/battery_monitor/meta.json +3 -0
- package/server/nodes/android/{bluetooth_automation.py → bluetooth_automation/__init__.py} +2 -1
- package/server/nodes/android/bluetooth_automation/meta.json +3 -0
- package/server/nodes/android/{camera_control.py → camera_control/__init__.py} +2 -1
- package/server/nodes/android/camera_control/meta.json +3 -0
- package/server/nodes/android/{device_state_automation.py → device_state_automation/__init__.py} +2 -1
- package/server/nodes/android/device_state_automation/meta.json +3 -0
- package/server/nodes/android/{environmental_sensors.py → environmental_sensors/__init__.py} +2 -1
- package/server/nodes/android/environmental_sensors/meta.json +3 -0
- package/server/nodes/android/{location.py → location/__init__.py} +2 -1
- package/server/nodes/android/location/meta.json +3 -0
- package/server/nodes/android/{media_control.py → media_control/__init__.py} +2 -1
- package/server/nodes/android/media_control/meta.json +3 -0
- package/server/nodes/android/{motion_detection.py → motion_detection/__init__.py} +2 -1
- package/server/nodes/android/motion_detection/meta.json +3 -0
- package/server/nodes/android/{network_monitor.py → network_monitor/__init__.py} +2 -1
- package/server/nodes/android/network_monitor/meta.json +3 -0
- package/server/nodes/android/{screen_control_automation.py → screen_control_automation/__init__.py} +2 -1
- package/server/nodes/android/screen_control_automation/meta.json +3 -0
- package/server/nodes/android/{system_info.py → system_info/__init__.py} +2 -1
- package/server/nodes/android/system_info/meta.json +3 -0
- package/server/nodes/android/{wifi_automation.py → wifi_automation/__init__.py} +2 -1
- package/server/nodes/android/wifi_automation/meta.json +3 -0
- package/server/nodes/browser/__init__.py +22 -1
- package/server/nodes/browser/_install.py +63 -0
- package/server/nodes/browser/_service.py +21 -25
- package/server/nodes/browser/{browser.py → browser/__init__.py} +58 -25
- package/server/nodes/browser/browser/meta.json +3 -0
- package/server/nodes/chat/{chat_history.py → chat_history/__init__.py} +2 -4
- package/server/nodes/chat/chat_history/meta.json +3 -0
- package/server/nodes/chat/{chat_send.py → chat_send/__init__.py} +2 -4
- package/server/nodes/chat/chat_send/icon.svg +1 -0
- package/server/nodes/chat/chat_send/meta.json +3 -0
- package/server/nodes/code/_base.py +1 -1
- package/server/nodes/code/{javascript_executor.py → javascript_executor/__init__.py} +5 -5
- package/server/nodes/code/javascript_executor/meta.json +3 -0
- package/server/nodes/code/{python_executor.py → python_executor/__init__.py} +32 -14
- package/server/nodes/code/python_executor/meta.json +3 -0
- package/server/nodes/code/{typescript_executor.py → typescript_executor/__init__.py} +5 -5
- package/server/nodes/code/typescript_executor/meta.json +3 -0
- package/server/nodes/document/{document_parser.py → document_parser/__init__.py} +26 -15
- package/server/nodes/document/document_parser/meta.json +3 -0
- package/server/nodes/document/{embedding_generator.py → embedding_generator/__init__.py} +16 -9
- package/server/nodes/document/embedding_generator/meta.json +3 -0
- package/server/nodes/document/{file_downloader.py → file_downloader/__init__.py} +30 -20
- package/server/nodes/document/file_downloader/meta.json +3 -0
- package/server/nodes/document/{http_scraper.py → http_scraper/__init__.py} +31 -21
- package/server/nodes/document/http_scraper/meta.json +3 -0
- package/server/nodes/document/{text_chunker.py → text_chunker/__init__.py} +17 -12
- package/server/nodes/document/text_chunker/meta.json +3 -0
- package/server/nodes/document/{vector_store.py → vector_store/__init__.py} +88 -72
- package/server/nodes/document/vector_store/meta.json +3 -0
- package/server/nodes/email/__init__.py +9 -2
- package/server/nodes/email/_events.py +54 -0
- package/server/nodes/email/_filters.py +3 -3
- package/server/nodes/email/_himalaya.py +95 -50
- package/server/nodes/email/_service.py +23 -13
- package/server/nodes/email/{email_read.py → email_read/__init__.py} +23 -11
- package/server/nodes/email/email_read/icon.svg +6 -0
- package/server/nodes/email/email_read/meta.json +3 -0
- package/server/nodes/email/{email_receive.py → email_receive/__init__.py} +45 -23
- package/server/nodes/email/email_receive/meta.json +3 -0
- package/server/nodes/email/{email_send.py → email_send/__init__.py} +13 -7
- package/server/nodes/email/email_send/meta.json +3 -0
- package/server/nodes/filesystem/_backend.py +1 -5
- package/server/nodes/filesystem/{file_modify.py → file_modify/__init__.py} +10 -5
- package/server/nodes/filesystem/file_modify/meta.json +3 -0
- package/server/nodes/filesystem/{file_read.py → file_read/__init__.py} +7 -3
- package/server/nodes/filesystem/file_read/meta.json +3 -0
- package/server/nodes/filesystem/{fs_search.py → fs_search/__init__.py} +11 -3
- package/server/nodes/filesystem/fs_search/meta.json +3 -0
- package/server/nodes/filesystem/{shell.py → shell/__init__.py} +12 -5
- package/server/nodes/filesystem/shell/meta.json +3 -0
- package/server/nodes/google/__init__.py +12 -0
- package/server/nodes/google/_auth_helper.py +7 -13
- package/server/nodes/google/_base.py +14 -11
- package/server/nodes/google/_credentials.py +2 -1
- package/server/nodes/google/_events.py +47 -0
- package/server/nodes/google/_filters.py +3 -3
- package/server/nodes/google/_gmail.py +70 -47
- package/server/nodes/google/_handlers.py +3 -1
- package/server/nodes/google/_oauth.py +25 -11
- package/server/nodes/google/_option_loaders.py +9 -30
- package/server/nodes/google/_refresh.py +8 -12
- package/server/nodes/google/_router.py +4 -5
- package/server/nodes/google/{calendar.py → calendar/__init__.py} +87 -64
- package/server/nodes/google/calendar/meta.json +3 -0
- package/server/nodes/google/{contacts.py → contacts/__init__.py} +84 -72
- package/server/nodes/google/contacts/meta.json +3 -0
- package/server/nodes/google/{drive.py → drive/__init__.py} +87 -72
- package/server/nodes/google/drive/meta.json +3 -0
- package/server/nodes/google/{gmail.py → gmail/__init__.py} +73 -39
- package/server/nodes/google/gmail/meta.json +3 -0
- package/server/nodes/google/{gmail_receive.py → gmail_receive/__init__.py} +31 -24
- package/server/nodes/google/gmail_receive/icon.svg +7 -0
- package/server/nodes/google/gmail_receive/meta.json +3 -0
- package/server/nodes/google/google.svg +7 -0
- package/server/nodes/google/{sheets.py → sheets/__init__.py} +54 -42
- package/server/nodes/google/sheets/meta.json +3 -0
- package/server/nodes/google/{tasks.py → tasks/__init__.py} +56 -43
- package/server/nodes/google/tasks/meta.json +3 -0
- package/server/nodes/groups.py +28 -28
- package/server/nodes/location/__init__.py +31 -1
- package/server/nodes/location/_credentials.py +1 -6
- package/server/nodes/location/_service.py +88 -107
- package/server/nodes/location/{gmaps_create.py → gmaps_create/__init__.py} +6 -6
- package/server/nodes/location/gmaps_create/meta.json +3 -0
- package/server/nodes/location/{gmaps_locations.py → gmaps_locations/__init__.py} +8 -6
- package/server/nodes/location/gmaps_locations/meta.json +3 -0
- package/server/nodes/location/{gmaps_nearby_places.py → gmaps_nearby_places/__init__.py} +8 -6
- package/server/nodes/location/gmaps_nearby_places/meta.json +3 -0
- package/server/nodes/model/_base.py +10 -7
- package/server/nodes/model/_credentials.py +10 -10
- package/server/nodes/model/_local_validator.py +28 -24
- package/server/nodes/model/{anthropic_chat_model.py → anthropic_chat_model/__init__.py} +5 -3
- package/server/nodes/model/anthropic_chat_model/meta.json +3 -0
- package/server/nodes/model/{cerebras_chat_model.py → cerebras_chat_model/__init__.py} +5 -3
- package/server/nodes/model/cerebras_chat_model/meta.json +3 -0
- package/server/nodes/model/{deepseek_chat_model.py → deepseek_chat_model/__init__.py} +8 -4
- package/server/nodes/model/deepseek_chat_model/meta.json +3 -0
- package/server/nodes/model/{gemini_chat_model.py → gemini_chat_model/__init__.py} +5 -3
- package/server/nodes/model/gemini_chat_model/meta.json +3 -0
- package/server/nodes/model/{groq_chat_model.py → groq_chat_model/__init__.py} +2 -2
- package/server/nodes/model/groq_chat_model/meta.json +3 -0
- package/server/nodes/model/{kimi_chat_model.py → kimi_chat_model/__init__.py} +2 -2
- package/server/nodes/model/kimi_chat_model/meta.json +3 -0
- package/server/nodes/model/{lmstudio_chat_model.py → lmstudio_chat_model/__init__.py} +2 -2
- package/server/nodes/model/lmstudio_chat_model/meta.json +3 -0
- package/server/nodes/model/{mistral_chat_model.py → mistral_chat_model/__init__.py} +2 -2
- package/server/nodes/model/mistral_chat_model/meta.json +3 -0
- package/server/nodes/model/{ollama_chat_model.py → ollama_chat_model/__init__.py} +2 -2
- package/server/nodes/model/ollama_chat_model/meta.json +3 -0
- package/server/nodes/model/{openai_chat_model.py → openai_chat_model/__init__.py} +8 -4
- package/server/nodes/model/openai_chat_model/meta.json +3 -0
- package/server/nodes/model/{openrouter_chat_model.py → openrouter_chat_model/__init__.py} +8 -4
- package/server/nodes/model/openrouter_chat_model/meta.json +3 -0
- package/server/nodes/proxy/_usage.py +14 -15
- package/server/nodes/proxy/{proxy_config.py → proxy_config/__init__.py} +39 -30
- package/server/nodes/proxy/proxy_config/meta.json +3 -0
- package/server/nodes/proxy/{proxy_request.py → proxy_request/__init__.py} +30 -16
- package/server/nodes/proxy/proxy_request/meta.json +3 -0
- package/server/nodes/proxy/{proxy_status.py → proxy_status/__init__.py} +2 -0
- package/server/nodes/proxy/proxy_status/meta.json +3 -0
- package/server/nodes/scheduler/{cron_scheduler.py → cron_scheduler/__init__.py} +96 -23
- package/server/nodes/scheduler/cron_scheduler/_workflow.py +155 -0
- package/server/nodes/scheduler/cron_scheduler/meta.json +3 -0
- package/server/nodes/scheduler/{timer.py → timer/__init__.py} +6 -5
- package/server/nodes/scheduler/timer/meta.json +3 -0
- package/server/nodes/scraper/_credentials.py +0 -1
- package/server/nodes/scraper/{apify_actor.py → apify_actor/__init__.py} +44 -35
- package/server/nodes/scraper/apify_actor/icon.svg +5 -0
- package/server/nodes/scraper/apify_actor/meta.json +3 -0
- package/server/nodes/scraper/{crawlee_scraper.py → crawlee_scraper/__init__.py} +96 -57
- package/server/nodes/scraper/crawlee_scraper/meta.json +3 -0
- package/server/nodes/search/{brave_search.py → brave_search/__init__.py} +6 -5
- package/server/nodes/search/brave_search/icon.svg +3 -0
- package/server/nodes/search/brave_search/meta.json +3 -0
- package/server/nodes/search/{duckduckgo_search.py → duckduckgo_search/__init__.py} +17 -6
- package/server/nodes/search/duckduckgo_search/meta.json +3 -0
- package/server/nodes/search/{perplexity_search.py → perplexity_search/__init__.py} +4 -5
- package/server/nodes/search/perplexity_search/icon.svg +3 -0
- package/server/nodes/search/perplexity_search/meta.json +3 -0
- package/server/nodes/search/{serper_search.py → serper_search/__init__.py} +32 -25
- package/server/nodes/search/serper_search/icon.svg +3 -0
- package/server/nodes/search/serper_search/meta.json +3 -0
- package/server/nodes/skill/__init__.py +21 -1
- package/server/nodes/skill/_expander.py +75 -0
- package/server/nodes/skill/{master_skill.py → master_skill/__init__.py} +2 -8
- package/server/nodes/skill/master_skill/_events.py +84 -0
- package/server/nodes/skill/master_skill/meta.json +3 -0
- package/server/nodes/skill/{simple_memory.py → simple_memory/__init__.py} +8 -16
- package/server/nodes/skill/simple_memory/meta.json +3 -0
- package/server/nodes/social/_base.py +223 -231
- package/server/nodes/social/{social_receive.py → social_receive/__init__.py} +38 -13
- package/server/nodes/social/social_receive/meta.json +3 -0
- package/server/nodes/social/{social_send.py → social_send/__init__.py} +71 -29
- package/server/nodes/social/social_send/icon.svg +1 -0
- package/server/nodes/social/social_send/meta.json +3 -0
- package/server/nodes/stripe/__init__.py +7 -3
- package/server/nodes/stripe/_credentials.py +0 -1
- package/server/nodes/stripe/_handlers.py +18 -7
- package/server/nodes/stripe/_install.py +14 -15
- package/server/nodes/stripe/_source.py +5 -5
- package/server/nodes/stripe/icon.svg +1 -0
- package/server/nodes/stripe/meta.json +3 -0
- package/server/nodes/stripe/stripe_action.py +4 -4
- package/server/nodes/stripe/stripe_receive.py +6 -9
- package/server/nodes/telegram/__init__.py +13 -0
- package/server/nodes/telegram/_credentials.py +2 -7
- package/server/nodes/telegram/_events.py +167 -0
- package/server/nodes/telegram/_filters.py +3 -11
- package/server/nodes/telegram/_handlers.py +17 -7
- package/server/nodes/telegram/_refresh.py +24 -34
- package/server/nodes/telegram/_service.py +29 -45
- package/server/nodes/telegram/meta.json +3 -0
- package/server/nodes/telegram/telegram.svg +3 -0
- package/server/nodes/telegram/telegram_receive.py +38 -18
- package/server/nodes/telegram/telegram_send.py +21 -19
- package/server/nodes/text/{file_handler.py → file_handler/__init__.py} +7 -1
- package/server/nodes/text/file_handler/meta.json +3 -0
- package/server/nodes/text/{text_generator.py → text_generator/__init__.py} +2 -1
- package/server/nodes/text/text_generator/meta.json +3 -0
- package/server/nodes/tool/{agent_builder.py → agent_builder/__init__.py} +105 -100
- package/server/nodes/tool/agent_builder/_events.py +91 -0
- package/server/nodes/tool/agent_builder/meta.json +3 -0
- package/server/nodes/tool/{calculator_tool.py → calculator_tool/__init__.py} +19 -7
- package/server/nodes/tool/calculator_tool/meta.json +3 -0
- package/server/nodes/tool/{current_time_tool.py → current_time_tool/__init__.py} +6 -4
- package/server/nodes/tool/current_time_tool/meta.json +3 -0
- package/server/nodes/tool/{task_manager.py → task_manager/__init__.py} +17 -18
- package/server/nodes/tool/task_manager/meta.json +3 -0
- package/server/nodes/tool/{write_todos.py → write_todos/__init__.py} +20 -6
- package/server/nodes/tool/write_todos/meta.json +3 -0
- package/server/nodes/trigger/{chat_trigger.py → chat_trigger/__init__.py} +11 -7
- package/server/nodes/trigger/chat_trigger/_events.py +53 -0
- package/server/nodes/trigger/chat_trigger/meta.json +3 -0
- package/server/nodes/trigger/{task_trigger.py → task_trigger/__init__.py} +10 -7
- package/server/nodes/trigger/task_trigger/meta.json +3 -0
- package/server/nodes/trigger/{webhook_trigger.py → webhook_trigger/__init__.py} +10 -7
- package/server/nodes/trigger/webhook_trigger/_events.py +54 -0
- package/server/nodes/trigger/webhook_trigger/meta.json +3 -0
- package/server/nodes/twitter/__init__.py +7 -1
- package/server/nodes/twitter/_base.py +86 -61
- package/server/nodes/twitter/_credentials.py +7 -5
- package/server/nodes/twitter/_events.py +101 -0
- package/server/nodes/twitter/_filters.py +9 -9
- package/server/nodes/twitter/_handlers.py +3 -1
- package/server/nodes/twitter/_oauth.py +1 -2
- package/server/nodes/twitter/_refresh.py +8 -12
- package/server/nodes/twitter/{twitter_receive.py → twitter_receive/__init__.py} +7 -7
- package/server/nodes/twitter/twitter_receive/icon.svg +1 -0
- package/server/nodes/twitter/twitter_receive/meta.json +3 -0
- package/server/nodes/twitter/{twitter_search.py → twitter_search/__init__.py} +16 -11
- package/server/nodes/twitter/twitter_search/icon.svg +1 -0
- package/server/nodes/twitter/twitter_search/meta.json +3 -0
- package/server/nodes/twitter/{twitter_send.py → twitter_send/__init__.py} +60 -27
- package/server/nodes/twitter/twitter_send/icon.svg +1 -0
- package/server/nodes/twitter/twitter_send/meta.json +3 -0
- package/server/nodes/twitter/{twitter_user.py → twitter_user/__init__.py} +34 -19
- package/server/nodes/twitter/twitter_user/icon.svg +1 -0
- package/server/nodes/twitter/twitter_user/meta.json +3 -0
- package/server/nodes/utility/{console.py → console/__init__.py} +17 -22
- package/server/nodes/utility/console/meta.json +3 -0
- package/server/nodes/utility/{http_request.py → http_request/__init__.py} +9 -6
- package/server/nodes/utility/http_request/meta.json +3 -0
- package/server/nodes/utility/{process_manager.py → process_manager/__init__.py} +10 -6
- package/server/nodes/utility/process_manager/meta.json +3 -0
- package/server/nodes/utility/team_monitor/meta.json +3 -0
- package/server/nodes/utility/{webhook_response.py → webhook_response/__init__.py} +12 -7
- package/server/nodes/utility/webhook_response/meta.json +3 -0
- package/server/nodes/visuals.json +69 -251
- package/server/nodes/whatsapp/__init__.py +24 -0
- package/server/nodes/whatsapp/_base.py +283 -338
- package/server/nodes/whatsapp/_credentials.py +44 -0
- package/server/nodes/whatsapp/_events.py +277 -0
- package/server/nodes/whatsapp/_filters.py +36 -37
- package/server/nodes/whatsapp/_handlers.py +2 -0
- package/server/nodes/whatsapp/_option_loaders.py +1 -3
- package/server/nodes/whatsapp/_refresh.py +13 -18
- package/server/nodes/whatsapp/_runtime.py +9 -6
- package/server/nodes/whatsapp/_service.py +89 -152
- package/server/nodes/whatsapp/meta.json +3 -0
- package/server/nodes/whatsapp/whatsapp_db.py +116 -54
- package/server/nodes/whatsapp/whatsapp_receive.py +30 -13
- package/server/nodes/whatsapp/whatsapp_send.py +60 -37
- package/server/nodes/workflow/{start.py → start/__init__.py} +1 -4
- package/server/nodes/workflow/start/meta.json +3 -0
- package/server/package-lock.json +3 -3
- package/server/package.json +3 -0
- package/server/pyproject.toml +39 -10
- package/server/requirements.txt +3 -5
- package/server/routers/__init__.py +1 -1
- package/server/routers/auth.py +16 -56
- package/server/routers/database.py +27 -50
- package/server/routers/nodejs_compat.py +25 -87
- package/server/routers/schemas.py +66 -2
- package/server/routers/webhook.py +12 -12
- package/server/routers/websocket.py +312 -1716
- package/server/routers/workflow.py +28 -53
- package/server/scripts/smoke_test_skills.py +178 -0
- package/server/services/__init__.py +1 -1
- package/server/services/_supervisor/process.py +9 -3
- package/server/services/_supervisor/registry.py +3 -3
- package/server/services/_supervisor/util.py +1 -1
- package/server/services/agent_team.py +15 -43
- package/server/services/agent_teams/__init__.py +17 -0
- package/server/services/agent_teams/handlers.py +195 -0
- package/server/services/ai.py +853 -1108
- package/server/services/auth.py +10 -34
- package/server/services/chat_client.py +5 -34
- package/server/services/circuit_breaker.py +2 -6
- package/server/services/cli_agent/__init__.py +28 -4
- package/server/services/cli_agent/_cli_auth.py +61 -0
- package/server/services/cli_agent/_handlers.py +24 -183
- package/server/services/cli_agent/config.py +5 -8
- package/server/services/cli_agent/factory.py +168 -22
- package/server/services/cli_agent/jsonl_watcher.py +380 -0
- package/server/services/cli_agent/lockfile.py +9 -2
- package/server/services/cli_agent/mcp_server.py +110 -34
- package/server/services/cli_agent/protocol.py +37 -19
- package/server/services/cli_agent/providers/__init__.py +8 -4
- package/server/services/cli_agent/providers/google_gemini.py +11 -5
- package/server/services/cli_agent/providers/openai_codex.py +34 -34
- package/server/services/cli_agent/service.py +245 -83
- package/server/services/cli_agent/session.py +409 -229
- package/server/services/cli_agent/transports/__init__.py +47 -0
- package/server/services/cli_agent/transports/base.py +111 -0
- package/server/services/cli_agent/transports/posix.py +196 -0
- package/server/services/cli_agent/transports/windows.py +189 -0
- package/server/services/cli_agent/types.py +45 -18
- package/server/services/cli_agent/workflow_tools.py +28 -15
- package/server/services/compaction.py +68 -52
- package/server/services/credential_registry.py +6 -20
- package/server/services/credentials/__init__.py +18 -0
- package/server/services/credentials/handlers.py +196 -0
- package/server/services/deployment/__init__.py +12 -1
- package/server/services/deployment/canary_registry.py +137 -0
- package/server/services/deployment/handlers.py +382 -0
- package/server/services/deployment/manager.py +653 -163
- package/server/services/deployment/poll_registry.py +2 -6
- package/server/services/deployment/state.py +2 -0
- package/server/services/deployment/triggers.py +87 -93
- package/server/services/event_waiter.py +47 -54
- package/server/services/events/__init__.py +11 -0
- package/server/services/events/admin_handlers.py +368 -0
- package/server/services/events/daemon.py +3 -1
- package/server/services/events/dispatch.py +188 -0
- package/server/services/events/envelope.py +264 -45
- package/server/services/events/oauth_lifecycle.py +98 -42
- package/server/services/events/triggers.py +3 -13
- package/server/services/events/verifiers/hmac_basic.py +1 -1
- package/server/services/events/verifiers/standard_webhooks.py +2 -4
- package/server/services/events/webhook.py +2 -3
- package/server/services/example_loader.py +73 -15
- package/server/services/execution/cache.py +36 -76
- package/server/services/execution/conditions.py +7 -20
- package/server/services/execution/dlq.py +20 -24
- package/server/services/execution/executor.py +234 -265
- package/server/services/execution/models.py +40 -46
- package/server/services/execution/recovery.py +23 -46
- package/server/services/handlers/__init__.py +12 -16
- package/server/services/handlers/todo.py +3 -6
- package/server/services/handlers/tools.py +143 -194
- package/server/services/handlers/triggers.py +24 -23
- package/server/services/llm/config.py +10 -1
- package/server/services/llm/factory.py +16 -4
- package/server/services/llm/messages.py +1 -5
- package/server/services/llm/protocol.py +9 -1
- package/server/services/llm/providers/anthropic.py +23 -12
- package/server/services/llm/providers/gemini.py +43 -22
- package/server/services/llm/providers/openai.py +14 -6
- package/server/services/llm/providers/openrouter.py +6 -1
- package/server/services/markdown_formatter.py +1 -2
- package/server/services/memory/__init__.py +2 -2
- package/server/services/memory/jsonl.py +6 -2
- package/server/services/memory/markdown.py +6 -6
- package/server/services/memory/state.py +6 -5
- package/server/services/memory_store.py +8 -12
- package/server/services/model_registry.py +22 -20
- package/server/services/node_executor.py +85 -80
- package/server/services/node_output_schemas.py +4 -7
- package/server/services/node_registry.py +40 -4
- package/server/services/node_spec.py +3 -7
- package/server/services/nodejs_client.py +4 -14
- package/server/services/oauth_utils.py +11 -7
- package/server/services/parameter_resolver.py +30 -36
- package/server/services/plugin/base.py +321 -38
- package/server/services/plugin/connection.py +12 -7
- package/server/services/plugin/credential.py +80 -22
- package/server/services/plugin/edge_walker.py +128 -105
- package/server/services/plugin/identifiers.py +48 -0
- package/server/services/plugin/interceptor.py +1 -1
- package/server/services/plugin/oauth.py +25 -21
- package/server/services/plugin/operation.py +1 -1
- package/server/services/plugin/polling.py +151 -26
- package/server/services/plugin/registry.py +52 -4
- package/server/services/plugin/routing.py +6 -9
- package/server/services/plugin/scaling.py +36 -18
- package/server/services/plugin/service_factories.py +95 -0
- package/server/services/plugin/shutdown_hooks.py +103 -0
- package/server/services/plugin/social_provider_registry.py +80 -0
- package/server/services/plugin/ws.py +2 -1
- package/server/services/pricing.py +26 -40
- package/server/services/pricing_handlers.py +90 -0
- package/server/services/process_service.py +33 -32
- package/server/services/proxy/models.py +15 -9
- package/server/services/proxy/service.py +26 -40
- package/server/services/rlm/adapters.py +43 -40
- package/server/services/rlm/constants.py +9 -9
- package/server/services/rlm/service.py +57 -45
- package/server/services/scheduler.py +8 -39
- package/server/services/settings/__init__.py +16 -0
- package/server/services/settings/handlers.py +275 -0
- package/server/services/skill_loader.py +53 -45
- package/server/services/skill_prompt.py +8 -6
- package/server/services/skills/__init__.py +23 -0
- package/server/services/skills/handlers.py +479 -0
- package/server/services/status_broadcaster.py +314 -291
- package/server/services/temporal/__init__.py +22 -1
- package/server/services/temporal/_handlers.py +65 -0
- package/server/services/temporal/_install.py +158 -0
- package/server/services/temporal/_refresh.py +57 -0
- package/server/services/temporal/_retry_policies.py +85 -0
- package/server/services/temporal/_runtime.py +181 -0
- package/server/services/temporal/_supervised_runtime.py +102 -0
- package/server/services/temporal/activities.py +168 -11
- package/server/services/temporal/agent_activities.py +683 -0
- package/server/services/temporal/agent_workflow.py +601 -0
- package/server/services/temporal/client.py +58 -13
- package/server/services/temporal/executor.py +2 -3
- package/server/services/temporal/plugin_activities.py +37 -2
- package/server/services/temporal/plugin_registry.py +82 -0
- package/server/services/temporal/polling_trigger_workflow.py +267 -0
- package/server/services/temporal/schedules.py +220 -0
- package/server/services/temporal/search_attributes.py +177 -0
- package/server/services/temporal/trigger_listener_workflow.py +378 -0
- package/server/services/temporal/worker.py +111 -18
- package/server/services/temporal/workflow.py +259 -40
- package/server/services/temporal/ws_client.py +22 -11
- package/server/services/text.py +14 -28
- package/server/services/tracked_http.py +29 -49
- package/server/services/user_auth.py +7 -21
- package/server/services/workflow.py +28 -20
- package/server/services/workflow_import.py +351 -0
- package/server/services/workflow_ops.py +4 -0
- package/server/services/workflow_storage/__init__.py +18 -0
- package/server/services/workflow_storage/handlers.py +132 -0
- package/server/services/workflow_validator.py +209 -0
- package/server/services/ws_handler_registry.py +80 -9
- package/server/skills/assistant/agent-builder-skill/SKILL.md +6 -6
- package/server/tests/conftest.py +54 -3
- package/server/tests/credentials/test_auth_service.py +9 -21
- package/server/tests/credentials/test_credential_broadcasts.py +116 -22
- package/server/tests/credentials/test_credentials_database.py +12 -38
- package/server/tests/credentials/test_encryption.py +3 -9
- package/server/tests/credentials/test_google_oauth.py +1 -3
- package/server/tests/credentials/test_oauth_utils.py +31 -38
- package/server/tests/credentials/test_twitter_oauth.py +1 -3
- package/server/tests/credentials/test_websocket_handlers.py +37 -72
- package/server/tests/fixtures/tool_names_snapshot.json +78 -0
- package/server/tests/llm/test_factory.py +12 -4
- package/server/tests/llm/test_providers.py +25 -32
- package/server/tests/llm/test_wiring.py +27 -22
- package/server/tests/nodes/_compat.py +4 -5
- package/server/tests/nodes/_harness.py +31 -24
- package/server/tests/nodes/_mocks.py +2 -6
- package/server/tests/nodes/test_agent_builder.py +43 -35
- package/server/tests/nodes/test_ai_agents.py +29 -24
- package/server/tests/nodes/test_ai_chat_models.py +3 -9
- package/server/tests/nodes/test_ai_tools.py +29 -24
- package/server/tests/nodes/test_android.py +34 -64
- package/server/tests/nodes/test_chat_utility.py +2 -2
- package/server/tests/nodes/test_code_fs_process.py +26 -84
- package/server/tests/nodes/test_document.py +23 -47
- package/server/tests/nodes/test_email.py +88 -51
- package/server/tests/nodes/test_google_workspace.py +26 -20
- package/server/tests/nodes/test_http_proxy.py +43 -89
- package/server/tests/nodes/test_search.py +3 -9
- package/server/tests/nodes/test_specialized_agents.py +58 -162
- package/server/tests/nodes/test_stripe_plugin.py +25 -5
- package/server/tests/nodes/test_telegram_social.py +33 -37
- package/server/tests/nodes/test_twitter.py +59 -150
- package/server/tests/nodes/test_web_automation.py +21 -51
- package/server/tests/nodes/test_whatsapp.py +13 -19
- package/server/tests/nodes/test_workflow_triggers.py +16 -45
- package/server/tests/services/cli_agent/test_claude_session_events.py +201 -0
- package/server/tests/services/cli_agent/test_jsonl_watcher.py +190 -0
- package/server/tests/services/cli_agent/test_mcp_server.py +67 -29
- package/server/tests/services/cli_agent/test_providers.py +236 -47
- package/server/tests/services/cli_agent/test_service.py +9 -7
- package/server/tests/services/memory/test_jsonl.py +30 -25
- package/server/tests/services/test_events.py +26 -7
- package/server/tests/services/test_identifiers.py +122 -0
- package/server/tests/services/test_process_lifecycle.py +129 -0
- package/server/tests/services/test_supervisor.py +0 -1
- package/server/tests/temporal/__init__.py +0 -0
- package/server/tests/temporal/test_agent_workflow.py +215 -0
- package/server/tests/temporal/test_dispatch.py +231 -0
- package/server/tests/test_admin_handlers.py +394 -0
- package/server/tests/test_auto_skill.py +4 -2
- package/server/tests/test_canary_registry.py +310 -0
- package/server/tests/test_chat_trigger_canary_producer.py +101 -0
- package/server/tests/test_cloudevents_node_parameters.py +129 -0
- package/server/tests/test_credential_icon.py +115 -0
- package/server/tests/test_cron_canary.py +511 -0
- package/server/tests/test_deployment_canary_listener.py +692 -0
- package/server/tests/test_event_framework_phase_a.py +537 -0
- package/server/tests/test_no_raw_prints.py +131 -0
- package/server/tests/test_node_spec.py +196 -103
- package/server/tests/test_parameter_resolver.py +20 -20
- package/server/tests/test_plugin_contract.py +76 -49
- package/server/tests/test_plugin_helpers.py +0 -1
- package/server/tests/test_plugin_self_containment.py +40 -47
- package/server/tests/test_polling_trigger_workflow.py +572 -0
- package/server/tests/test_retry_policies.py +146 -0
- package/server/tests/test_service_factories.py +168 -0
- package/server/tests/test_shutdown_hooks.py +199 -0
- package/server/tests/test_social_provider_registry.py +177 -0
- package/server/tests/test_status_broadcasts.py +214 -63
- package/server/tests/test_task_trigger_canary_producer.py +131 -0
- package/server/tests/test_telegram_trigger_canary_producer.py +113 -0
- package/server/tests/test_tool_registry.py +110 -0
- package/server/tests/test_trigger_listener_workflow.py +365 -0
- package/server/tests/test_whatsapp_trigger_canary_producer.py +164 -0
- package/server/tests/test_workflow_ops.py +1 -3
- package/server/tests/test_workflow_validator.py +791 -0
- package/server/uv.lock +3539 -0
- package/client/dist/assets/index-DQ0nwhec.js +0 -257
- package/client/src/assets/icons/apify/index.ts +0 -19
- package/client/src/assets/icons/browser/index.ts +0 -17
- package/client/src/assets/icons/email/index.ts +0 -22
- package/client/src/assets/icons/google/index.ts +0 -34
- package/client/src/assets/icons/llm/deepseek.svg +0 -1
- package/client/src/assets/icons/llm/index.ts +0 -18
- package/client/src/assets/icons/llm/kimi.svg +0 -1
- package/client/src/assets/icons/llm/mistral.svg +0 -1
- package/client/src/assets/icons/search/index.ts +0 -28
- package/client/src/assets/icons/telegram/index.ts +0 -19
- package/machina/buildenv.py +0 -44
- package/machina/cli.py +0 -55
- package/machina/commands/__init__.py +0 -1
- package/machina/commands/clean.py +0 -80
- package/machina/commands/daemon.py +0 -150
- package/machina/config.py +0 -93
- package/machina/platform_.py +0 -37
- package/machina/pyproject.toml +0 -33
- package/server/nodes/agent/deep_agent.py +0 -103
- package/server/services/agents/__init__.py +0 -9
- package/server/services/agents/adapters.py +0 -199
- package/server/services/agents/constants.py +0 -10
- package/server/services/agents/service.py +0 -297
- package/server/services/cli_agent/providers/anthropic_claude.py +0 -419
- /package/{machina → cli}/README.md +0 -0
- /package/{machina → cli}/__init__.py +0 -0
- /package/{client/src/assets/icons/apify → server/credentials/icons}/apify.svg +0 -0
- /package/{client/src/assets/icons/search/brave.svg → server/credentials/icons/brave_search.svg} +0 -0
- /package/{client/src/assets/icons/email/read.svg → server/credentials/icons/email_himalaya.svg} +0 -0
- /package/{client/src/assets/icons/search → server/credentials/icons}/perplexity.svg +0 -0
- /package/{client/src/assets/icons/search/google.svg → server/credentials/icons/serper.svg} +0 -0
- /package/{client/src/assets → server/credentials}/icons/stripe.svg +0 -0
- /package/{client/src/assets/icons/twitter/x.svg → server/credentials/icons/twitter.svg} +0 -0
- /package/{client/src/assets/icons/browser/chrome.svg → server/nodes/browser/browser/icon.svg} +0 -0
- /package/{client/src/assets/icons/chat/chat.svg → server/nodes/chat/chat_history/icon.svg} +0 -0
- /package/{client/src/assets/icons/code/javascript.svg → server/nodes/code/javascript_executor/icon.svg} +0 -0
- /package/{client/src/assets/icons/code/python.svg → server/nodes/code/python_executor/icon.svg} +0 -0
- /package/{client/src/assets/icons/code/typescript.svg → server/nodes/code/typescript_executor/icon.svg} +0 -0
- /package/{client/src/assets/icons/email/receive.svg → server/nodes/email/email_receive/icon.svg} +0 -0
- /package/{client/src/assets/icons/email/send.svg → server/nodes/email/email_send/icon.svg} +0 -0
- /package/{client/src/assets/icons/google/calendar.svg → server/nodes/google/calendar/icon.svg} +0 -0
- /package/{client/src/assets/icons/google/contacts.svg → server/nodes/google/contacts/icon.svg} +0 -0
- /package/{client/src/assets/icons/google/drive.svg → server/nodes/google/drive/icon.svg} +0 -0
- /package/{client/src/assets/icons/google/gmail.svg → server/nodes/google/gmail/icon.svg} +0 -0
- /package/{client/src/assets/icons/google/sheets.svg → server/nodes/google/sheets/icon.svg} +0 -0
- /package/{client/src/assets/icons/google/tasks.svg → server/nodes/google/tasks/icon.svg} +0 -0
- /package/{client/src/assets/icons/search/duckduckgo.svg → server/nodes/search/duckduckgo_search/icon.svg} +0 -0
- /package/{client/src/assets/icons/social/social.svg → server/nodes/social/social_receive/icon.svg} +0 -0
- /package/{client/src/assets/icons/telegram/telegram.svg → server/nodes/telegram/icon.svg} +0 -0
- /package/server/nodes/utility/{team_monitor.py → team_monitor/__init__.py} +0 -0
- /package/{client/src/assets/icons/whatsapp/whatsapp-db.svg → server/nodes/whatsapp/icon_whatsappDb.svg} +0 -0
- /package/{client/src/assets/icons/whatsapp/whatsapp-receive.svg → server/nodes/whatsapp/icon_whatsappReceive.svg} +0 -0
- /package/{client/src/assets/icons/whatsapp/whatsapp-send.svg → server/nodes/whatsapp/icon_whatsappSend.svg} +0 -0
- /package/{client/src/assets/icons → server/nodes}/whatsapp/whatsapp.svg +0 -0
|
@@ -5,8 +5,6 @@ Each tool type has its own handler function that processes the tool call
|
|
|
5
5
|
and returns results.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
import math
|
|
9
|
-
import json
|
|
10
8
|
import asyncio
|
|
11
9
|
import uuid
|
|
12
10
|
import hashlib
|
|
@@ -20,6 +18,7 @@ if TYPE_CHECKING:
|
|
|
20
18
|
|
|
21
19
|
logger = get_logger(__name__)
|
|
22
20
|
|
|
21
|
+
|
|
23
22
|
def _plugin_connection_factory(plugin_cls, context):
|
|
24
23
|
"""Build a per-call :class:`Connection` factory bound to a plugin
|
|
25
24
|
class's declared credentials. Mirrors
|
|
@@ -35,10 +34,7 @@ def _plugin_connection_factory(plugin_cls, context):
|
|
|
35
34
|
def factory(credential_id: str):
|
|
36
35
|
cred_cls = creds_by_id.get(credential_id)
|
|
37
36
|
if cred_cls is None:
|
|
38
|
-
raise RuntimeError(
|
|
39
|
-
f"Plugin {plugin_cls.type} did not declare credential "
|
|
40
|
-
f"'{credential_id}' but tried to use it."
|
|
41
|
-
)
|
|
37
|
+
raise RuntimeError(f"Plugin {plugin_cls.type} did not declare credential " f"'{credential_id}' but tried to use it.")
|
|
42
38
|
return Connection(cred_cls, user_id=user_id, session_id=session_id)
|
|
43
39
|
|
|
44
40
|
return factory
|
|
@@ -70,8 +66,7 @@ def is_node_in_active_delegation(node_id: str) -> bool:
|
|
|
70
66
|
return _active_delegated_nodes.get(node_id, 0) > 0
|
|
71
67
|
|
|
72
68
|
|
|
73
|
-
async def execute_tool(tool_name: str, tool_args: Dict[str, Any],
|
|
74
|
-
config: Dict[str, Any]) -> Dict[str, Any]:
|
|
69
|
+
async def execute_tool(tool_name: str, tool_args: Dict[str, Any], config: Dict[str, Any]) -> Dict[str, Any]:
|
|
75
70
|
"""Execute a tool by name and own the tool node's status lifecycle.
|
|
76
71
|
|
|
77
72
|
This is the single source of truth for the tool node's
|
|
@@ -100,12 +95,13 @@ async def execute_tool(tool_name: str, tool_args: Dict[str, Any],
|
|
|
100
95
|
from services.status_broadcaster import get_status_broadcaster
|
|
101
96
|
|
|
102
97
|
broadcaster = get_status_broadcaster()
|
|
103
|
-
node_id = config.get(
|
|
104
|
-
workflow_id = config.get(
|
|
98
|
+
node_id = config.get("node_id")
|
|
99
|
+
workflow_id = config.get("workflow_id")
|
|
105
100
|
|
|
106
101
|
if node_id and broadcaster:
|
|
107
102
|
await broadcaster.update_node_status(
|
|
108
|
-
node_id,
|
|
103
|
+
node_id,
|
|
104
|
+
"executing",
|
|
109
105
|
{"message": f"Executing {tool_name}"},
|
|
110
106
|
workflow_id=workflow_id,
|
|
111
107
|
)
|
|
@@ -116,50 +112,48 @@ async def execute_tool(tool_name: str, tool_args: Dict[str, Any],
|
|
|
116
112
|
logger.error("[Tool] Execution failed: %s", tool_name, exc_info=True)
|
|
117
113
|
if node_id and broadcaster:
|
|
118
114
|
await broadcaster.update_node_status(
|
|
119
|
-
node_id,
|
|
115
|
+
node_id,
|
|
116
|
+
"error",
|
|
120
117
|
{"message": f"{tool_name} failed", "error": str(e)},
|
|
121
118
|
workflow_id=workflow_id,
|
|
122
119
|
)
|
|
123
120
|
raise
|
|
124
121
|
|
|
125
|
-
handler_owns_lifecycle = (
|
|
126
|
-
isinstance(result, dict)
|
|
127
|
-
and result.get("status") in ("delegated", "ALREADY_DELEGATED")
|
|
128
|
-
)
|
|
122
|
+
handler_owns_lifecycle = isinstance(result, dict) and result.get("status") in ("delegated", "ALREADY_DELEGATED")
|
|
129
123
|
if node_id and broadcaster and not handler_owns_lifecycle:
|
|
130
124
|
await broadcaster.update_node_status(
|
|
131
|
-
node_id,
|
|
125
|
+
node_id,
|
|
126
|
+
"success",
|
|
132
127
|
{"message": f"{tool_name} completed", "result": result},
|
|
133
128
|
workflow_id=workflow_id,
|
|
134
129
|
)
|
|
135
130
|
return result
|
|
136
131
|
|
|
137
132
|
|
|
138
|
-
async def _dispatch_tool(tool_name: str, tool_args: Dict[str, Any],
|
|
139
|
-
config: Dict[str, Any]) -> Dict[str, Any]:
|
|
133
|
+
async def _dispatch_tool(tool_name: str, tool_args: Dict[str, Any], config: Dict[str, Any]) -> Dict[str, Any]:
|
|
140
134
|
"""Route a tool call to the right handler based on ``node_type``.
|
|
141
135
|
|
|
142
136
|
Pure dispatch — no broadcasting. Lifecycle is owned by
|
|
143
137
|
:func:`execute_tool`.
|
|
144
138
|
"""
|
|
145
|
-
node_type = config.get(
|
|
146
|
-
node_params = config.get(
|
|
139
|
+
node_type = config.get("node_type", "")
|
|
140
|
+
node_params = config.get("parameters", {})
|
|
147
141
|
|
|
148
142
|
# Execution context for tool handlers. Includes canvas state
|
|
149
143
|
# (nodes/edges/workflow_id) that callers (chat_tool_executor in
|
|
150
|
-
# ai.py / rlm adapter
|
|
144
|
+
# ai.py / rlm adapter) plumb in via `config`.
|
|
151
145
|
# Tools that need canvas awareness (e.g. agentBuilder.inspect_canvas)
|
|
152
146
|
# read these via NodeContext.nodes / .edges / .workflow_id; tools
|
|
153
147
|
# that don't simply ignore them.
|
|
154
148
|
context = {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
149
|
+
"workspace_dir": config.get("workspace_dir", ""),
|
|
150
|
+
"nodes": config.get("nodes", []),
|
|
151
|
+
"edges": config.get("edges", []),
|
|
152
|
+
"workflow_id": config.get("workflow_id"),
|
|
153
|
+
"parent_node_id": config.get("parent_node_id"),
|
|
160
154
|
}
|
|
161
155
|
|
|
162
|
-
logger.info("[Tool] Executing '%s' (node_type=%s, workspace=%s)", tool_name, node_type, context[
|
|
156
|
+
logger.info("[Tool] Executing '%s' (node_type=%s, workspace=%s)", tool_name, node_type, context["workspace_dir"])
|
|
163
157
|
|
|
164
158
|
# ----------------------------------------------------------------
|
|
165
159
|
# Plugin fast-path (Wave 11.B.1): if this node_type is a
|
|
@@ -177,17 +171,16 @@ async def _dispatch_tool(tool_name: str, tool_args: Dict[str, Any],
|
|
|
177
171
|
# prompt) expect for delegation tools.
|
|
178
172
|
# ----------------------------------------------------------------
|
|
179
173
|
from services.node_registry import get_node_class
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
else get_node_class(node_type)
|
|
183
|
-
)
|
|
174
|
+
|
|
175
|
+
plugin_cls = None if node_type in AI_AGENT_TYPES else get_node_class(node_type)
|
|
184
176
|
if plugin_cls is not None:
|
|
185
177
|
from services.plugin import NodeContext
|
|
178
|
+
|
|
186
179
|
instance = plugin_cls()
|
|
187
180
|
ctx = NodeContext.from_legacy(
|
|
188
|
-
node_id=config.get(
|
|
181
|
+
node_id=config.get("node_id", f"tool_{node_type}"),
|
|
189
182
|
node_type=node_type,
|
|
190
|
-
context={**context,
|
|
183
|
+
context={**context, "parameters": node_params},
|
|
191
184
|
connection_factory=_plugin_connection_factory(plugin_cls, context),
|
|
192
185
|
)
|
|
193
186
|
return await instance.execute_as_tool(tool_args, node_params, ctx)
|
|
@@ -205,36 +198,42 @@ async def _dispatch_tool(tool_name: str, tool_args: Dict[str, Any],
|
|
|
205
198
|
# also need LLM-arg translation that doesn't fit the plugin Params
|
|
206
199
|
# shape. Both dispatchers live with their domain on
|
|
207
200
|
# nodes/android/_base.py (Wave 11.E.3 move).
|
|
208
|
-
if node_type ==
|
|
201
|
+
if node_type == "androidTool":
|
|
209
202
|
from nodes.android._base import execute_android_toolkit
|
|
203
|
+
|
|
210
204
|
return await execute_android_toolkit(tool_args, config)
|
|
211
205
|
if node_type in ANDROID_SERVICE_NODE_TYPES:
|
|
212
206
|
from nodes.android._base import execute_android_service_tool
|
|
207
|
+
|
|
213
208
|
return await execute_android_service_tool(tool_args, config)
|
|
214
209
|
|
|
215
210
|
# taskManager: dispatcher reads through to the agent-delegation
|
|
216
211
|
# tracking dicts (_delegated_tasks / _delegation_results) defined
|
|
217
212
|
# below in this module. The operation matrix moved to the plugin
|
|
218
213
|
# (Wave 11.I, milestone O).
|
|
219
|
-
if node_type ==
|
|
214
|
+
if node_type == "taskManager":
|
|
220
215
|
from nodes.tool.task_manager import _execute_task_manager
|
|
216
|
+
|
|
221
217
|
return await _execute_task_manager(tool_args, config)
|
|
222
218
|
|
|
223
219
|
# proxyConfig: 10-operation matrix lives on the plugin
|
|
224
220
|
# (nodes/proxy/proxy_config.execute_proxy_config). Plugin params win.
|
|
225
|
-
if node_type ==
|
|
221
|
+
if node_type == "proxyConfig":
|
|
226
222
|
from nodes.proxy.proxy_config import execute_proxy_config
|
|
227
|
-
|
|
223
|
+
|
|
224
|
+
merged = {**config.get("parameters", {}), **tool_args}
|
|
228
225
|
return await execute_proxy_config(merged)
|
|
229
226
|
|
|
230
227
|
# Built-in: Check delegated task results
|
|
231
228
|
# Auto-injected when parent has delegation tools
|
|
232
|
-
if node_type ==
|
|
229
|
+
if node_type == "_builtin_check_delegated_tasks":
|
|
233
230
|
return await _execute_check_delegated_tasks(tool_args, config)
|
|
234
231
|
|
|
235
|
-
# AI Agent delegation (fire-and-forget async delegation)
|
|
236
|
-
#
|
|
237
|
-
|
|
232
|
+
# AI Agent delegation (fire-and-forget async delegation).
|
|
233
|
+
# ``AI_AGENT_TYPES`` (imported above from ``constants``) is the
|
|
234
|
+
# canonical 18-entry frozenset; a new agent type added there picks
|
|
235
|
+
# up delegation support without touching this dispatcher.
|
|
236
|
+
if node_type in AI_AGENT_TYPES:
|
|
238
237
|
return await _execute_delegated_agent(tool_args, config)
|
|
239
238
|
|
|
240
239
|
# Generic fallback for unknown node types
|
|
@@ -246,14 +245,6 @@ async def _dispatch_tool(tool_name: str, tool_args: Dict[str, Any],
|
|
|
246
245
|
# nodes/tool/calculator_tool.py CalculatorToolNode.calculate().
|
|
247
246
|
|
|
248
247
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
248
|
# _execute_duckduckgo_search: Wave 11.C moved logic to
|
|
258
249
|
# nodes/search/duckduckgo_search.py DuckDuckGoSearchNode.search(). Wave
|
|
259
250
|
# 11.I milestone O moved the flat (args, config) -> dict shim used by
|
|
@@ -264,10 +255,6 @@ async def _dispatch_tool(tool_name: str, tool_args: Dict[str, Any],
|
|
|
264
255
|
# now routes through the plugin fast-path (nodes/whatsapp/*.py).
|
|
265
256
|
|
|
266
257
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
258
|
# Wave 11.D.10: _execute_geocoding / _execute_nearby_places deleted.
|
|
272
259
|
# gmaps_locations + gmaps_nearby_places now route through the plugin
|
|
273
260
|
# fast-path (nodes/location/*.py).
|
|
@@ -282,16 +269,7 @@ async def _dispatch_tool(tool_name: str, tool_args: Dict[str, Any],
|
|
|
282
269
|
# (nodes/google/*.py). These functions were defined but unreferenced.
|
|
283
270
|
|
|
284
271
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
async def _execute_generic(args: Dict[str, Any],
|
|
294
|
-
config: Dict[str, Any]) -> Dict[str, Any]:
|
|
272
|
+
async def _execute_generic(args: Dict[str, Any], config: Dict[str, Any]) -> Dict[str, Any]:
|
|
295
273
|
"""Execute a generic tool (fallback handler).
|
|
296
274
|
|
|
297
275
|
For node types without specific handlers, this returns the input
|
|
@@ -305,15 +283,14 @@ async def _execute_generic(args: Dict[str, Any],
|
|
|
305
283
|
Dict with input echoed and node info
|
|
306
284
|
"""
|
|
307
285
|
return {
|
|
308
|
-
"input": args.get(
|
|
309
|
-
"node_type": config.get(
|
|
310
|
-
"node_id": config.get(
|
|
311
|
-
"message": "Generic tool executed - no specific handler for this node type"
|
|
286
|
+
"input": args.get("input", ""),
|
|
287
|
+
"node_type": config.get("node_type"),
|
|
288
|
+
"node_id": config.get("node_id"),
|
|
289
|
+
"message": "Generic tool executed - no specific handler for this node type",
|
|
312
290
|
}
|
|
313
291
|
|
|
314
292
|
|
|
315
|
-
async def _execute_delegated_agent(args: Dict[str, Any],
|
|
316
|
-
config: Dict[str, Any]) -> Dict[str, Any]:
|
|
293
|
+
async def _execute_delegated_agent(args: Dict[str, Any], config: Dict[str, Any]) -> Dict[str, Any]:
|
|
317
294
|
"""Delegate a task to a child AI Agent (fire-and-forget pattern).
|
|
318
295
|
|
|
319
296
|
This spawns the child agent as an asyncio background task and returns
|
|
@@ -329,26 +306,26 @@ async def _execute_delegated_agent(args: Dict[str, Any],
|
|
|
329
306
|
"""
|
|
330
307
|
from services.status_broadcaster import get_status_broadcaster
|
|
331
308
|
|
|
332
|
-
node_id = config.get(
|
|
333
|
-
node_type = config.get(
|
|
334
|
-
workflow_id = config.get(
|
|
335
|
-
task_description = args.get(
|
|
336
|
-
task_context = args.get(
|
|
309
|
+
node_id = config.get("node_id")
|
|
310
|
+
node_type = config.get("node_type")
|
|
311
|
+
workflow_id = config.get("workflow_id")
|
|
312
|
+
task_description = args.get("task", "")
|
|
313
|
+
task_context = args.get("context", "")
|
|
337
314
|
|
|
338
315
|
# Get injected services
|
|
339
|
-
ai_service = config.get(
|
|
340
|
-
database = config.get(
|
|
341
|
-
nodes = config.get(
|
|
342
|
-
edges = config.get(
|
|
316
|
+
ai_service = config.get("ai_service")
|
|
317
|
+
database = config.get("database")
|
|
318
|
+
nodes = config.get("nodes", [])
|
|
319
|
+
edges = config.get("edges", [])
|
|
343
320
|
|
|
344
321
|
if not ai_service or not database:
|
|
345
322
|
return {
|
|
346
323
|
"error": "Agent delegation requires ai_service and database in config",
|
|
347
|
-
"hint": "Ensure nodes/edges are passed to tool config"
|
|
324
|
+
"hint": "Ensure nodes/edges are passed to tool config",
|
|
348
325
|
}
|
|
349
326
|
|
|
350
327
|
# Get parent node ID for duplicate tracking
|
|
351
|
-
parent_node_id = config.get(
|
|
328
|
+
parent_node_id = config.get("parent_node_id", "")
|
|
352
329
|
|
|
353
330
|
# Generate hash of task to detect duplicate delegation attempts
|
|
354
331
|
task_hash = hashlib.md5(f"{task_description}:{task_context}".encode()).hexdigest()[:16]
|
|
@@ -362,7 +339,7 @@ async def _execute_delegated_agent(args: Dict[str, Any],
|
|
|
362
339
|
"success": True,
|
|
363
340
|
"status": "ALREADY_DELEGATED",
|
|
364
341
|
"task_id": existing_task_id,
|
|
365
|
-
"agent_name": config.get(
|
|
342
|
+
"agent_name": config.get("parameters", {}).get("label", node_type),
|
|
366
343
|
"result": (
|
|
367
344
|
f"This task was ALREADY delegated (task_id: {existing_task_id}). "
|
|
368
345
|
f"Do NOT call this tool again. Use 'check_delegated_tasks' to check status."
|
|
@@ -388,44 +365,41 @@ async def _execute_delegated_agent(args: Dict[str, Any],
|
|
|
388
365
|
|
|
389
366
|
# Inject API key - delegated agents bypass NodeExecutor._inject_api_keys,
|
|
390
367
|
# so we must resolve the key here from the credential store
|
|
391
|
-
if not child_params.get(
|
|
368
|
+
if not child_params.get("api_key"):
|
|
392
369
|
from constants import detect_ai_provider
|
|
370
|
+
|
|
393
371
|
provider = detect_ai_provider(node_type, child_params)
|
|
394
372
|
key = await ai_service.auth.get_api_key(provider, "default")
|
|
395
373
|
if key:
|
|
396
|
-
child_params[
|
|
374
|
+
child_params["api_key"] = key
|
|
397
375
|
logger.debug(f"[Delegated Agent] Injected API key for provider={provider}")
|
|
398
376
|
|
|
399
377
|
# Inject default model if not set
|
|
400
|
-
if not child_params.get(
|
|
378
|
+
if not child_params.get("model"):
|
|
401
379
|
from constants import detect_ai_provider
|
|
380
|
+
|
|
402
381
|
provider = detect_ai_provider(node_type, child_params)
|
|
403
382
|
models = await ai_service.auth.get_stored_models(provider, "default")
|
|
404
383
|
if models:
|
|
405
|
-
child_params[
|
|
384
|
+
child_params["model"] = models[0]
|
|
406
385
|
|
|
407
386
|
# Task goes into system_message (directive), context data goes into prompt.
|
|
408
387
|
# Schema-canonical key is snake_case; drop any pre-migration camelCase
|
|
409
388
|
# mirror so the saved-params dict downstream uses the canonical key.
|
|
410
|
-
child_params[
|
|
411
|
-
child_params.pop(
|
|
412
|
-
child_params[
|
|
389
|
+
child_params["system_message"] = task_description
|
|
390
|
+
child_params.pop("systemMessage", None)
|
|
391
|
+
child_params["prompt"] = task_context if task_context else task_description
|
|
413
392
|
|
|
414
393
|
# Create execution context for child agent
|
|
415
|
-
child_context = {
|
|
416
|
-
'nodes': nodes,
|
|
417
|
-
'edges': edges,
|
|
418
|
-
'workflow_id': workflow_id,
|
|
419
|
-
'outputs': {},
|
|
420
|
-
'parent_task_id': task_id
|
|
421
|
-
}
|
|
394
|
+
child_context = {"nodes": nodes, "edges": edges, "workflow_id": workflow_id, "outputs": {}, "parent_task_id": task_id}
|
|
422
395
|
|
|
423
396
|
broadcaster = get_status_broadcaster()
|
|
424
|
-
agent_label = child_params.get(
|
|
397
|
+
agent_label = child_params.get("label", node_type)
|
|
425
398
|
|
|
426
399
|
logger.info(f"[Delegated Agent] Starting task {task_id} for '{agent_label}' (node: {node_id})")
|
|
427
|
-
logger.debug(
|
|
428
|
-
|
|
400
|
+
logger.debug(
|
|
401
|
+
f"[Delegated Agent] Context: {len(nodes)} nodes, {len(edges)} edges, " f"edge_targets={set(e.get('target') for e in edges)}"
|
|
402
|
+
)
|
|
429
403
|
|
|
430
404
|
# Define the background coroutine
|
|
431
405
|
async def run_child_agent():
|
|
@@ -434,12 +408,8 @@ async def _execute_delegated_agent(args: Dict[str, Any],
|
|
|
434
408
|
await broadcaster.update_node_status(
|
|
435
409
|
node_id,
|
|
436
410
|
"executing",
|
|
437
|
-
{
|
|
438
|
-
|
|
439
|
-
"task_id": task_id,
|
|
440
|
-
"message": f"Working on: {task_description[:100]}..."
|
|
441
|
-
},
|
|
442
|
-
workflow_id=workflow_id
|
|
411
|
+
{"phase": "delegated_task", "task_id": task_id, "message": f"Working on: {task_description[:100]}..."},
|
|
412
|
+
workflow_id=workflow_id,
|
|
443
413
|
)
|
|
444
414
|
|
|
445
415
|
# Execute the child agent via its own plugin class.
|
|
@@ -455,27 +425,22 @@ async def _execute_delegated_agent(args: Dict[str, Any],
|
|
|
455
425
|
raise RuntimeError(f"Unknown delegated agent type: {node_type}")
|
|
456
426
|
instance = plugin_cls()
|
|
457
427
|
child_ctx = NodeContext.from_legacy(
|
|
458
|
-
node_id=node_id,
|
|
428
|
+
node_id=node_id,
|
|
429
|
+
node_type=node_type,
|
|
430
|
+
context=child_context,
|
|
459
431
|
)
|
|
460
432
|
result = await instance.execute(node_id, child_params, child_ctx)
|
|
461
433
|
|
|
462
434
|
logger.info(f"[Delegated Agent] Task {task_id} completed: success={result.get('success')}")
|
|
463
435
|
|
|
464
436
|
# Check if child agent actually succeeded
|
|
465
|
-
if not result.get(
|
|
437
|
+
if not result.get("success"):
|
|
466
438
|
# Child agent returned failure - treat as error
|
|
467
|
-
error_msg = result.get(
|
|
439
|
+
error_msg = result.get("error", "Child agent returned failure")
|
|
468
440
|
logger.warning(f"[Delegated Agent] Task {task_id} returned success=False: {error_msg}")
|
|
469
441
|
|
|
470
442
|
await broadcaster.update_node_status(
|
|
471
|
-
node_id,
|
|
472
|
-
"error",
|
|
473
|
-
{
|
|
474
|
-
"phase": "delegated_error",
|
|
475
|
-
"task_id": task_id,
|
|
476
|
-
"error": error_msg
|
|
477
|
-
},
|
|
478
|
-
workflow_id=workflow_id
|
|
443
|
+
node_id, "error", {"phase": "delegated_error", "task_id": task_id, "error": error_msg}, workflow_id=workflow_id
|
|
479
444
|
)
|
|
480
445
|
|
|
481
446
|
# Cache error for parent retrieval
|
|
@@ -496,43 +461,40 @@ async def _execute_delegated_agent(args: Dict[str, Any],
|
|
|
496
461
|
output_name="delegation_result",
|
|
497
462
|
data={
|
|
498
463
|
"task_id": task_id,
|
|
499
|
-
"parent_node_id": config.get(
|
|
464
|
+
"parent_node_id": config.get("parent_node_id", ""),
|
|
500
465
|
"agent_name": agent_label,
|
|
501
466
|
"status": "error",
|
|
502
467
|
"error": error_msg,
|
|
503
|
-
}
|
|
468
|
+
},
|
|
504
469
|
)
|
|
505
470
|
|
|
506
|
-
# Dispatch error event for trigger nodes
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
471
|
+
# Dispatch error event for trigger nodes — Wave 12 B8.
|
|
472
|
+
from nodes.agent._events import broadcast_agent_task_failed
|
|
473
|
+
|
|
474
|
+
await broadcast_agent_task_failed(
|
|
475
|
+
task_id=task_id,
|
|
476
|
+
agent_name=agent_label,
|
|
477
|
+
agent_node_id=node_id,
|
|
478
|
+
parent_node_id=config.get("parent_node_id", ""),
|
|
479
|
+
workflow_id=workflow_id,
|
|
480
|
+
error=error_msg,
|
|
481
|
+
)
|
|
516
482
|
|
|
517
483
|
return result
|
|
518
484
|
|
|
519
485
|
# Success case - extract response properly
|
|
520
|
-
response_text = result.get(
|
|
486
|
+
response_text = result.get("result", {}).get("response", "")
|
|
521
487
|
if not response_text:
|
|
522
488
|
# Fallback: try to stringify the result dict
|
|
523
|
-
response_text = str(result.get(
|
|
489
|
+
response_text = str(result.get("result", "")) if result.get("result") else "No response generated"
|
|
524
490
|
|
|
525
491
|
# Broadcast completion
|
|
526
|
-
response_preview = response_text[:200] if response_text else
|
|
492
|
+
response_preview = response_text[:200] if response_text else ""
|
|
527
493
|
await broadcaster.update_node_status(
|
|
528
494
|
node_id,
|
|
529
495
|
"success",
|
|
530
|
-
{
|
|
531
|
-
|
|
532
|
-
"task_id": task_id,
|
|
533
|
-
"result_summary": response_preview
|
|
534
|
-
},
|
|
535
|
-
workflow_id=workflow_id
|
|
496
|
+
{"phase": "delegated_complete", "task_id": task_id, "result_summary": response_preview},
|
|
497
|
+
workflow_id=workflow_id,
|
|
536
498
|
)
|
|
537
499
|
|
|
538
500
|
# Cache result for parent retrieval (Layer 2: in-memory)
|
|
@@ -553,37 +515,31 @@ async def _execute_delegated_agent(args: Dict[str, Any],
|
|
|
553
515
|
output_name="delegation_result",
|
|
554
516
|
data={
|
|
555
517
|
"task_id": task_id,
|
|
556
|
-
"parent_node_id": config.get(
|
|
518
|
+
"parent_node_id": config.get("parent_node_id", ""),
|
|
557
519
|
"agent_name": agent_label,
|
|
558
520
|
"status": "completed",
|
|
559
521
|
"result": response_text,
|
|
560
|
-
}
|
|
522
|
+
},
|
|
561
523
|
)
|
|
562
524
|
|
|
563
|
-
# Dispatch task_completed event for trigger nodes
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
525
|
+
# Dispatch task_completed event for trigger nodes — Wave 12 B8.
|
|
526
|
+
from nodes.agent._events import broadcast_agent_task_completed
|
|
527
|
+
|
|
528
|
+
await broadcast_agent_task_completed(
|
|
529
|
+
task_id=task_id,
|
|
530
|
+
agent_name=agent_label,
|
|
531
|
+
agent_node_id=node_id,
|
|
532
|
+
parent_node_id=config.get("parent_node_id", ""),
|
|
533
|
+
workflow_id=workflow_id,
|
|
534
|
+
result=response_text,
|
|
535
|
+
)
|
|
573
536
|
|
|
574
537
|
return result
|
|
575
538
|
|
|
576
539
|
except Exception as e:
|
|
577
540
|
logger.error(f"[Delegated Agent] Task {task_id} failed: {e}")
|
|
578
541
|
await broadcaster.update_node_status(
|
|
579
|
-
node_id,
|
|
580
|
-
"error",
|
|
581
|
-
{
|
|
582
|
-
"phase": "delegated_error",
|
|
583
|
-
"task_id": task_id,
|
|
584
|
-
"error": str(e)
|
|
585
|
-
},
|
|
586
|
-
workflow_id=workflow_id
|
|
542
|
+
node_id, "error", {"phase": "delegated_error", "task_id": task_id, "error": str(e)}, workflow_id=workflow_id
|
|
587
543
|
)
|
|
588
544
|
|
|
589
545
|
# Cache error for parent retrieval (Layer 2: in-memory)
|
|
@@ -604,23 +560,24 @@ async def _execute_delegated_agent(args: Dict[str, Any],
|
|
|
604
560
|
output_name="delegation_result",
|
|
605
561
|
data={
|
|
606
562
|
"task_id": task_id,
|
|
607
|
-
"parent_node_id": config.get(
|
|
563
|
+
"parent_node_id": config.get("parent_node_id", ""),
|
|
608
564
|
"agent_name": agent_label,
|
|
609
565
|
"status": "error",
|
|
610
566
|
"error": str(e),
|
|
611
|
-
}
|
|
567
|
+
},
|
|
612
568
|
)
|
|
613
569
|
|
|
614
|
-
# Dispatch task_completed event for trigger nodes (error case)
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
570
|
+
# Dispatch task_completed event for trigger nodes (error case) — Wave 12 B8.
|
|
571
|
+
from nodes.agent._events import broadcast_agent_task_failed
|
|
572
|
+
|
|
573
|
+
await broadcast_agent_task_failed(
|
|
574
|
+
task_id=task_id,
|
|
575
|
+
agent_name=agent_label,
|
|
576
|
+
agent_node_id=node_id,
|
|
577
|
+
parent_node_id=config.get("parent_node_id", ""),
|
|
578
|
+
workflow_id=workflow_id,
|
|
579
|
+
error=str(e),
|
|
580
|
+
)
|
|
624
581
|
|
|
625
582
|
return {"success": False, "error": str(e)}
|
|
626
583
|
|
|
@@ -658,8 +615,7 @@ async def _execute_delegated_agent(args: Dict[str, Any],
|
|
|
658
615
|
}
|
|
659
616
|
|
|
660
617
|
|
|
661
|
-
async def get_delegated_task_status(task_ids: Optional[List[str]] = None,
|
|
662
|
-
database=None) -> Dict[str, Any]:
|
|
618
|
+
async def get_delegated_task_status(task_ids: Optional[List[str]] = None, database=None) -> Dict[str, Any]:
|
|
663
619
|
"""Check status and retrieve results of delegated tasks.
|
|
664
620
|
|
|
665
621
|
3-layer lookup: live tasks -> memory cache -> DB (NodeOutput).
|
|
@@ -674,9 +630,7 @@ async def get_delegated_task_status(task_ids: Optional[List[str]] = None,
|
|
|
674
630
|
"""
|
|
675
631
|
if not task_ids:
|
|
676
632
|
# Return all known from memory
|
|
677
|
-
task_ids = list(set(
|
|
678
|
-
list(_delegated_tasks.keys()) + list(_delegation_results.keys())
|
|
679
|
-
))
|
|
633
|
+
task_ids = list(set(list(_delegated_tasks.keys()) + list(_delegation_results.keys())))
|
|
680
634
|
|
|
681
635
|
tasks = []
|
|
682
636
|
db_lookup_ids = []
|
|
@@ -691,7 +645,7 @@ async def get_delegated_task_status(task_ids: Optional[List[str]] = None,
|
|
|
691
645
|
# Task finished -- extract result via task.result()
|
|
692
646
|
try:
|
|
693
647
|
result = live_task.result()
|
|
694
|
-
response = result.get(
|
|
648
|
+
response = result.get("result", {}).get("response", str(result.get("result", "")))
|
|
695
649
|
tasks.append({"task_id": tid, "status": "completed", "result": response})
|
|
696
650
|
except Exception as e:
|
|
697
651
|
tasks.append({"task_id": tid, "status": "error", "error": str(e)})
|
|
@@ -709,21 +663,20 @@ async def get_delegated_task_status(task_ids: Optional[List[str]] = None,
|
|
|
709
663
|
# DB fallback for results not in memory (cross-restart)
|
|
710
664
|
if db_lookup_ids and database:
|
|
711
665
|
for tid in list(db_lookup_ids):
|
|
712
|
-
db_result = await database.get_node_output_by_session(
|
|
713
|
-
session_id=f"delegation_{tid}",
|
|
714
|
-
output_name="delegation_result"
|
|
715
|
-
)
|
|
666
|
+
db_result = await database.get_node_output_by_session(session_id=f"delegation_{tid}", output_name="delegation_result")
|
|
716
667
|
if db_result:
|
|
717
|
-
data = db_result.get(
|
|
668
|
+
data = db_result.get("data", {})
|
|
718
669
|
result_data = data.get("result", {})
|
|
719
670
|
response_text = result_data.get("response", str(result_data)) if isinstance(result_data, dict) else str(result_data)
|
|
720
|
-
tasks.append(
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
671
|
+
tasks.append(
|
|
672
|
+
{
|
|
673
|
+
"task_id": tid,
|
|
674
|
+
"status": data.get("status", "completed"),
|
|
675
|
+
"agent_name": data.get("agent_name", ""),
|
|
676
|
+
"result": response_text,
|
|
677
|
+
"error": data.get("error"),
|
|
678
|
+
}
|
|
679
|
+
)
|
|
727
680
|
db_lookup_ids.remove(tid)
|
|
728
681
|
|
|
729
682
|
# Remaining IDs not found anywhere
|
|
@@ -733,15 +686,14 @@ async def get_delegated_task_status(task_ids: Optional[List[str]] = None,
|
|
|
733
686
|
return {"tasks": tasks}
|
|
734
687
|
|
|
735
688
|
|
|
736
|
-
async def _execute_check_delegated_tasks(args: Dict[str, Any],
|
|
737
|
-
config: Dict[str, Any]) -> Dict[str, Any]:
|
|
689
|
+
async def _execute_check_delegated_tasks(args: Dict[str, Any], config: Dict[str, Any]) -> Dict[str, Any]:
|
|
738
690
|
"""LLM-callable tool: check on delegated child agents.
|
|
739
691
|
|
|
740
692
|
Returns status and results for previously delegated tasks.
|
|
741
693
|
Follows Celery AsyncResult / Ray ObjectRef patterns.
|
|
742
694
|
"""
|
|
743
|
-
task_ids = args.get(
|
|
744
|
-
database = config.get(
|
|
695
|
+
task_ids = args.get("task_ids")
|
|
696
|
+
database = config.get("database")
|
|
745
697
|
result = await get_delegated_task_status(task_ids=task_ids, database=database)
|
|
746
698
|
|
|
747
699
|
formatted = []
|
|
@@ -785,6 +737,3 @@ async def _execute_check_delegated_tasks(args: Dict[str, Any],
|
|
|
785
737
|
# now route through the plugin fast-path in execute_tool which calls
|
|
786
738
|
# the BaseNode.execute_as_tool method on the plugin class.
|
|
787
739
|
# _execute_serper_search_tool stays until serperSearch is migrated.
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|