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
package/cli/_common.py
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"""Cross-verb helpers shared by ``machina`` commands.
|
|
2
|
+
|
|
3
|
+
Centralises the four patterns that previously appeared inlined in
|
|
4
|
+
``start.py`` / ``dev.py`` / ``stop.py`` / ``clean.py`` / ``build.py``:
|
|
5
|
+
|
|
6
|
+
- :func:`preflight` -- ``load_config()`` + ``project_root()``
|
|
7
|
+
preamble every verb opens with.
|
|
8
|
+
- :func:`free_all_ports` -- ``for port in cfg.all_ports: kill_port``
|
|
9
|
+
loop; lazy-imports ``cli.ports`` so a
|
|
10
|
+
broken ``psutil`` install doesn't take
|
|
11
|
+
down the recovery verb.
|
|
12
|
+
- :func:`build_backend_spec` -- the shared ``uv_run("uvicorn", ...)``
|
|
13
|
+
ServiceSpec used by both ``start``
|
|
14
|
+
and ``dev``.
|
|
15
|
+
- :func:`error_block` -- multi-line ``[red]Error: ...[/]``
|
|
16
|
+
formatter; lazy-imports ``cli.colors``.
|
|
17
|
+
|
|
18
|
+
No third-party packages are imported at module load time. Importing
|
|
19
|
+
this module from ``cli/commands/clean.py`` is safe even when
|
|
20
|
+
``rich`` / ``psutil`` / ``platformdirs`` are missing -- only the
|
|
21
|
+
helper that actually needs the dep pulls it in.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
from pathlib import Path
|
|
27
|
+
from typing import TYPE_CHECKING
|
|
28
|
+
|
|
29
|
+
from cli.config import Config, load_config
|
|
30
|
+
from cli.platform_ import project_root, server_dir
|
|
31
|
+
|
|
32
|
+
if TYPE_CHECKING:
|
|
33
|
+
from cli.ports import KillResult
|
|
34
|
+
from cli.supervisor import ServiceSpec
|
|
35
|
+
|
|
36
|
+
# ``cli.run`` (and ``cli.supervisor`` via ``cli.colors``) transitively
|
|
37
|
+
# pull in ``rich``. They're only needed by ``build_backend_spec`` /
|
|
38
|
+
# ``error_block`` which themselves lazy-import. Keeping them out of the
|
|
39
|
+
# top-level import list means ``machina clean`` (which calls only
|
|
40
|
+
# ``preflight`` and ``free_all_ports``) loads even when ``rich`` /
|
|
41
|
+
# ``psutil`` / ``platformdirs`` are unavailable.
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def preflight(cfg: Config | None = None) -> tuple[Config, Path]:
|
|
45
|
+
"""Standard verb preamble: ``(load_config(), project_root())``.
|
|
46
|
+
|
|
47
|
+
Pass an explicit ``cfg`` to avoid the lookup (e.g. when the caller
|
|
48
|
+
already has one). ``load_config`` is ``@lru_cache``d, so repeated
|
|
49
|
+
calls inside the same process are free regardless.
|
|
50
|
+
"""
|
|
51
|
+
return cfg or load_config(), project_root()
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def free_all_ports(cfg: Config) -> list[KillResult]:
|
|
55
|
+
"""Kill anything listening on ``cfg.all_ports``; return per-port
|
|
56
|
+
results.
|
|
57
|
+
|
|
58
|
+
Returns a list (not a count) so callers can render per-port status
|
|
59
|
+
-- ``machina stop`` shows ``[OK]`` / ``[!!]`` markers and the killed
|
|
60
|
+
PIDs, ``machina start`` and ``clean`` just want them gone. The
|
|
61
|
+
helper centralises the iteration, callers pick the rendering.
|
|
62
|
+
|
|
63
|
+
``cli.ports`` is imported lazily so this module loads even when
|
|
64
|
+
``psutil`` (a transitive dep) is missing -- important for the
|
|
65
|
+
recovery verb ``machina clean``.
|
|
66
|
+
"""
|
|
67
|
+
from cli.ports import kill_port
|
|
68
|
+
|
|
69
|
+
return [kill_port(port) for port in cfg.all_ports]
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def build_backend_spec(
|
|
73
|
+
cfg: Config,
|
|
74
|
+
*,
|
|
75
|
+
host: str,
|
|
76
|
+
root: Path | None = None,
|
|
77
|
+
) -> "ServiceSpec":
|
|
78
|
+
"""The Python backend ``ServiceSpec`` shared by ``start`` and ``dev``.
|
|
79
|
+
|
|
80
|
+
Routes through :func:`cli.run.uv_run` so the standardised
|
|
81
|
+
``uv run --no-sync`` flags stay in one place. ``host`` is the only
|
|
82
|
+
differentiator (``start`` picks ``127.0.0.1`` on Windows/WSL vs
|
|
83
|
+
``0.0.0.0`` elsewhere; ``dev`` honours its ``--daemon`` flag).
|
|
84
|
+
|
|
85
|
+
``cli.run`` and ``cli.supervisor`` are lazy-imported so this module
|
|
86
|
+
stays importable when their transitive ``rich`` dep is missing --
|
|
87
|
+
``machina clean`` doesn't call this and shouldn't pay for it.
|
|
88
|
+
"""
|
|
89
|
+
from cli.run import uv_run
|
|
90
|
+
from cli.supervisor import ServiceSpec
|
|
91
|
+
|
|
92
|
+
return ServiceSpec(
|
|
93
|
+
name="server",
|
|
94
|
+
argv=uv_run(
|
|
95
|
+
"uvicorn",
|
|
96
|
+
"main:app",
|
|
97
|
+
"--host",
|
|
98
|
+
host,
|
|
99
|
+
"--port",
|
|
100
|
+
str(cfg.backend_port),
|
|
101
|
+
"--log-level",
|
|
102
|
+
"warning",
|
|
103
|
+
),
|
|
104
|
+
cwd=server_dir(root),
|
|
105
|
+
ready_port=cfg.backend_port,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def error_block(title: str, lines: list[str]) -> None:
|
|
110
|
+
"""Print a multi-line ``[red]Error: ...[/]`` block, indented body.
|
|
111
|
+
|
|
112
|
+
``cli.colors`` is imported lazily so this module remains
|
|
113
|
+
importable without ``rich``. Anything heavier (e.g., remediation
|
|
114
|
+
URLs, code snippets) goes in ``lines`` -- it's rendered as plain
|
|
115
|
+
``console.print`` calls so rich BBCode in callers' strings still
|
|
116
|
+
interprets.
|
|
117
|
+
"""
|
|
118
|
+
from cli.colors import console
|
|
119
|
+
|
|
120
|
+
console.print(f"[red]Error: {title}[/]")
|
|
121
|
+
for line in lines:
|
|
122
|
+
console.print(f" {line}")
|
package/cli/buildenv.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""Build-environment helpers shared by ``start`` / ``dev`` / ``daemon``.
|
|
2
|
+
|
|
3
|
+
``validate_build`` refuses to launch when ``machina build`` hasn't been
|
|
4
|
+
run. Layout knowledge lives in :mod:`cli.platform_` -- this file only
|
|
5
|
+
composes the documented prefixes (workspace venv, node_modules, client
|
|
6
|
+
dist) into a boolean check.
|
|
7
|
+
|
|
8
|
+
Subprocess callers (start / dev / daemon / temporal specs) build their
|
|
9
|
+
argv via :func:`cli.run.uv_run`, which runs the command inside the uv
|
|
10
|
+
workspace ``.venv`` per https://docs.astral.sh/uv/reference/cli/#uv-run.
|
|
11
|
+
There is no path-to-interpreter logic on the CLI side -- uv owns that.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
import typer
|
|
19
|
+
|
|
20
|
+
from cli.colors import console
|
|
21
|
+
from cli.platform_ import (
|
|
22
|
+
client_dist_entry,
|
|
23
|
+
node_modules_dir,
|
|
24
|
+
server_venv,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def validate_build(root: Path, *, require_client_dist: bool = False) -> None:
|
|
29
|
+
"""Refuse to launch if ``machina build`` hasn't been run.
|
|
30
|
+
|
|
31
|
+
Raises ``typer.Exit(1)`` with a remediation hint. ``dev`` allows a
|
|
32
|
+
missing ``client/dist`` (Vite serves the source); ``start`` opts in
|
|
33
|
+
via ``require_client_dist=True``.
|
|
34
|
+
"""
|
|
35
|
+
if not node_modules_dir(root).exists() or not server_venv(root).exists():
|
|
36
|
+
console.print('[red]Error: Project not built. Run "machina build" first.[/]')
|
|
37
|
+
raise typer.Exit(code=1)
|
|
38
|
+
if require_client_dist and not client_dist_entry(root).exists():
|
|
39
|
+
console.print('[red]Error: Client not built. Run "machina build" first.[/]')
|
|
40
|
+
raise typer.Exit(code=1)
|
package/cli/cli.py
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"""Typer CLI for ``machina``.
|
|
2
|
+
|
|
3
|
+
Every verb is registered here as a thin stub that lazy-imports its
|
|
4
|
+
implementation on dispatch. Running ``machina clean`` (the recovery
|
|
5
|
+
verb) only triggers the import of ``cli.commands.clean`` -- not
|
|
6
|
+
``dev`` / ``start`` / temporal specs / daemon verbs / docs / version.
|
|
7
|
+
|
|
8
|
+
Pattern lifted from gemini-cli's ``gemini.tsx`` + vercel's ``vc.js``
|
|
9
|
+
(fast-path ``--version`` and ``--help`` before any heavy import) and
|
|
10
|
+
next.js's ``bin/next.ts`` (per-verb ``import('../cli/<verb>.js')``).
|
|
11
|
+
Typer's ``add_typer`` requires a concrete sub-app at registration
|
|
12
|
+
time, so for grouped verbs (``daemon`` / ``docs`` / ``version``) we
|
|
13
|
+
build fresh Typer instances HERE and lazy-wrap each leaf -- avoids
|
|
14
|
+
importing ``cli.commands.daemon`` etc. at boot.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import typer
|
|
20
|
+
|
|
21
|
+
app = typer.Typer(
|
|
22
|
+
name="machina",
|
|
23
|
+
help="MachinaOS project supervisor CLI.",
|
|
24
|
+
no_args_is_help=True,
|
|
25
|
+
add_completion=False,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@app.callback()
|
|
30
|
+
def _root() -> None:
|
|
31
|
+
"""Marks the Typer app as a multi-command group."""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# ----------------------------------------------------------- top-level verbs
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@app.command(
|
|
38
|
+
"start",
|
|
39
|
+
help="Start all services in production mode (static client + uvicorn + temporal).",
|
|
40
|
+
)
|
|
41
|
+
def _start() -> None:
|
|
42
|
+
from cli.commands.start import start_command
|
|
43
|
+
|
|
44
|
+
start_command()
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@app.command(
|
|
48
|
+
"dev",
|
|
49
|
+
help="Start all services in dev mode (Vite HMR + uvicorn + temporal).",
|
|
50
|
+
)
|
|
51
|
+
def _dev(
|
|
52
|
+
daemon: bool = typer.Option(
|
|
53
|
+
False,
|
|
54
|
+
"--daemon",
|
|
55
|
+
help="Bind backend to 0.0.0.0 instead of 127.0.0.1.",
|
|
56
|
+
),
|
|
57
|
+
) -> None:
|
|
58
|
+
from cli.commands.dev import dev_command
|
|
59
|
+
|
|
60
|
+
dev_command(daemon=daemon)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@app.command(
|
|
64
|
+
"stop",
|
|
65
|
+
help="Stop all MachinaOS services and free configured ports.",
|
|
66
|
+
)
|
|
67
|
+
def _stop() -> None:
|
|
68
|
+
from cli.commands.stop import stop_command
|
|
69
|
+
|
|
70
|
+
stop_command()
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@app.command(
|
|
74
|
+
"clean",
|
|
75
|
+
help="Stop services then remove build artefacts and venvs.",
|
|
76
|
+
)
|
|
77
|
+
def _clean() -> None:
|
|
78
|
+
from cli.commands.clean import clean_command
|
|
79
|
+
|
|
80
|
+
clean_command()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@app.command(
|
|
84
|
+
"build",
|
|
85
|
+
help="Install toolchain + build client + sync Python + verify deps.",
|
|
86
|
+
)
|
|
87
|
+
def _build() -> None:
|
|
88
|
+
from cli.commands.build import build_command
|
|
89
|
+
|
|
90
|
+
build_command()
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
# --------------------------------------------------------------- daemon group
|
|
94
|
+
|
|
95
|
+
daemon_app = typer.Typer(
|
|
96
|
+
name="daemon",
|
|
97
|
+
help="Run the MachinaOs backend as a detached process.",
|
|
98
|
+
no_args_is_help=True,
|
|
99
|
+
add_completion=False,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
@daemon_app.command(
|
|
104
|
+
"start",
|
|
105
|
+
help="Start the backend in the background; write PID file to user-data dir.",
|
|
106
|
+
)
|
|
107
|
+
def _daemon_start() -> None:
|
|
108
|
+
from cli.commands.daemon.start import start_command
|
|
109
|
+
|
|
110
|
+
start_command()
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@daemon_app.command(
|
|
114
|
+
"stop",
|
|
115
|
+
help="Stop the backend if running; clear PID file either way.",
|
|
116
|
+
)
|
|
117
|
+
def _daemon_stop() -> None:
|
|
118
|
+
from cli.commands.daemon.stop import stop_command
|
|
119
|
+
|
|
120
|
+
stop_command()
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@daemon_app.command(
|
|
124
|
+
"status",
|
|
125
|
+
help="Exit 0 if running (and print PID); exit 1 otherwise.",
|
|
126
|
+
)
|
|
127
|
+
def _daemon_status() -> None:
|
|
128
|
+
from cli.commands.daemon.status import status_command
|
|
129
|
+
|
|
130
|
+
status_command()
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@daemon_app.command(
|
|
134
|
+
"restart",
|
|
135
|
+
help="Stop the backend then start it again; convenience wrapper.",
|
|
136
|
+
)
|
|
137
|
+
def _daemon_restart() -> None:
|
|
138
|
+
from cli.commands.daemon.restart import restart_command
|
|
139
|
+
|
|
140
|
+
restart_command()
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
app.add_typer(daemon_app, name="daemon")
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
# ----------------------------------------------------------------- docs group
|
|
147
|
+
|
|
148
|
+
docs_app = typer.Typer(
|
|
149
|
+
name="docs",
|
|
150
|
+
help="Documentation tooling (rebuild indices, completeness checks).",
|
|
151
|
+
no_args_is_help=True,
|
|
152
|
+
add_completion=False,
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@docs_app.command(
|
|
157
|
+
"nodes",
|
|
158
|
+
help="Rebuild (or --check) the per-node documentation index.",
|
|
159
|
+
)
|
|
160
|
+
def _docs_nodes(
|
|
161
|
+
check: bool = typer.Option(
|
|
162
|
+
False,
|
|
163
|
+
"--check",
|
|
164
|
+
help="Instead of rewriting, exit 1 if any registered node lacks a doc.",
|
|
165
|
+
),
|
|
166
|
+
) -> None:
|
|
167
|
+
from cli.commands.docs import nodes
|
|
168
|
+
|
|
169
|
+
nodes(check=check)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
app.add_typer(docs_app, name="docs")
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
# -------------------------------------------------------------- version group
|
|
176
|
+
|
|
177
|
+
version_app = typer.Typer(
|
|
178
|
+
name="version",
|
|
179
|
+
help="Version-sync tooling.",
|
|
180
|
+
no_args_is_help=True,
|
|
181
|
+
add_completion=False,
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
@version_app.command(
|
|
186
|
+
"sync",
|
|
187
|
+
help="Sync package.json versions from latest git tag.",
|
|
188
|
+
)
|
|
189
|
+
def _version_sync(
|
|
190
|
+
tag: str | None = typer.Argument(
|
|
191
|
+
None,
|
|
192
|
+
help="Git tag to use (defaults to latest).",
|
|
193
|
+
),
|
|
194
|
+
) -> None:
|
|
195
|
+
from cli.commands.version import sync
|
|
196
|
+
|
|
197
|
+
sync(tag=tag)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
app.add_typer(version_app, name="version")
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
if __name__ == "__main__":
|
|
204
|
+
app()
|
|
@@ -23,8 +23,16 @@ console = Console(log_time_format="[%H:%M:%S.%f]", log_path=False)
|
|
|
23
23
|
# Honcho's rotation, lifted: skip very-dark (black) and very-bright (white)
|
|
24
24
|
# so prefixes remain readable on both light and dark terminals.
|
|
25
25
|
_PALETTE = [
|
|
26
|
-
"cyan",
|
|
27
|
-
"
|
|
26
|
+
"cyan",
|
|
27
|
+
"green",
|
|
28
|
+
"yellow",
|
|
29
|
+
"blue",
|
|
30
|
+
"magenta",
|
|
31
|
+
"bright_cyan",
|
|
32
|
+
"bright_green",
|
|
33
|
+
"bright_yellow",
|
|
34
|
+
"bright_blue",
|
|
35
|
+
"bright_magenta",
|
|
28
36
|
]
|
|
29
37
|
_color_cycle = cycle(_PALETTE)
|
|
30
38
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""``machina`` subcommand modules. Imported by ``cli.cli``."""
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""ServiceSpec for the Temporal stack — shared by ``start`` and ``dev``.
|
|
2
|
+
|
|
3
|
+
One ServiceSpec running the supervised :class:`TemporalServerRuntime`
|
|
4
|
+
singleton via :mod:`services.temporal._supervised_runtime` (a thin
|
|
5
|
+
shim that lives next to the runtime factory it imports). The runtime
|
|
6
|
+
spawns the official ``temporal`` CLI (downloaded by pooch from
|
|
7
|
+
https://temporal.download/cli/archive/latest) with the ``server
|
|
8
|
+
start-dev`` subcommand against a SQLite db at
|
|
9
|
+
``settings.temporal_sqlite_path``.
|
|
10
|
+
|
|
11
|
+
Matches the local-dev install method documented at
|
|
12
|
+
https://docs.temporal.io/develop/python/set-up-your-local-python.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import os
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
|
|
20
|
+
from cli.config import Config
|
|
21
|
+
from cli.platform_ import server_dir
|
|
22
|
+
from cli.run import uv_run
|
|
23
|
+
from cli.supervisor import RestartPolicy, ServiceSpec
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def temporal_specs(root: Path, cfg: Config) -> list[ServiceSpec]:
|
|
27
|
+
"""Return the Temporal ServiceSpec list.
|
|
28
|
+
|
|
29
|
+
``cfg`` is :class:`cli.config.Config`; ``cfg.temporal_port`` drives
|
|
30
|
+
the gRPC readiness probe.
|
|
31
|
+
|
|
32
|
+
Readiness-probe + graceful-shutdown windows are read at call time
|
|
33
|
+
from ``os.environ`` (pushed there by :func:`cli.config.load_config`
|
|
34
|
+
from ``.env.template``); ``KeyError`` if missing — broken install.
|
|
35
|
+
Doing the reads here, not at module import, keeps the module safe
|
|
36
|
+
to import before ``load_config()`` runs (tests, REPL, reverse
|
|
37
|
+
import order).
|
|
38
|
+
"""
|
|
39
|
+
return [
|
|
40
|
+
ServiceSpec(
|
|
41
|
+
name="temporal",
|
|
42
|
+
argv=uv_run(
|
|
43
|
+
"python",
|
|
44
|
+
"-m",
|
|
45
|
+
"services.temporal._supervised_runtime",
|
|
46
|
+
"services.temporal._runtime:get_temporal_server_runtime",
|
|
47
|
+
),
|
|
48
|
+
cwd=server_dir(root),
|
|
49
|
+
ready_port=cfg.temporal_port,
|
|
50
|
+
ready_timeout=float(os.environ["TEMPORAL_SERVER_READY_TIMEOUT_SECONDS"]),
|
|
51
|
+
restart=RestartPolicy.ON_CRASH,
|
|
52
|
+
terminate_grace_seconds=float(
|
|
53
|
+
os.environ["TEMPORAL_GRACEFUL_SHUTDOWN_SECONDS"]
|
|
54
|
+
),
|
|
55
|
+
),
|
|
56
|
+
]
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
__all__ = ["temporal_specs"]
|
|
@@ -14,13 +14,13 @@ import os
|
|
|
14
14
|
import re
|
|
15
15
|
import shutil
|
|
16
16
|
import sys
|
|
17
|
-
from pathlib import Path
|
|
18
17
|
|
|
19
18
|
import typer
|
|
20
19
|
|
|
21
|
-
from
|
|
22
|
-
from
|
|
23
|
-
from
|
|
20
|
+
from cli._common import error_block
|
|
21
|
+
from cli.run import capture, run, uv_run
|
|
22
|
+
from cli.colors import console
|
|
23
|
+
from cli.platform_ import node_modules_dir, project_root, server_dir
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
# Source dirs / entry-point modules under ``server/`` that ``machina build``
|
|
@@ -44,6 +44,7 @@ COMPILEALL_SOURCE_DIRS: tuple[str, ...] = (
|
|
|
44
44
|
|
|
45
45
|
# ---------------------------------------------------------------- helpers
|
|
46
46
|
|
|
47
|
+
|
|
47
48
|
def _which_python() -> str | None:
|
|
48
49
|
"""Prefer ``python3`` so we don't pick up Python 2.x on POSIX distros."""
|
|
49
50
|
for cmd in ("python3", "python"):
|
|
@@ -84,33 +85,15 @@ def _ensure_uv(python_cmd: str) -> str:
|
|
|
84
85
|
run([python_cmd, "-m", "pip", "install", "uv"])
|
|
85
86
|
version = capture(["uv", "--version"])
|
|
86
87
|
if not version:
|
|
87
|
-
|
|
88
|
+
error_block("failed to install uv.", ["See https://docs.astral.sh/uv/"])
|
|
88
89
|
raise typer.Exit(code=1)
|
|
89
90
|
console.print(f" uv: {version}")
|
|
90
91
|
return version
|
|
91
92
|
|
|
92
93
|
|
|
93
|
-
def _ensure_temporal() -> None:
|
|
94
|
-
"""Ensure the ``temporal`` CLI (from npm package ``temporal-server``) is on PATH."""
|
|
95
|
-
version = capture(["temporal", "--version"])
|
|
96
|
-
if version:
|
|
97
|
-
console.print(f" temporal: {version}")
|
|
98
|
-
return
|
|
99
|
-
console.print(" temporal: not found, installing globally...")
|
|
100
|
-
rc = run(["npm", "install", "-g", "temporal-server"], check=False)
|
|
101
|
-
if rc != 0:
|
|
102
|
-
console.print(
|
|
103
|
-
" [yellow]Warning: temporal install failed. "
|
|
104
|
-
"Distributed execution unavailable.[/]"
|
|
105
|
-
)
|
|
106
|
-
return
|
|
107
|
-
version = capture(["temporal", "--version"])
|
|
108
|
-
if version:
|
|
109
|
-
console.print(f" temporal: {version}")
|
|
110
|
-
|
|
111
|
-
|
|
112
94
|
# ---------------------------------------------------------------- build
|
|
113
95
|
|
|
96
|
+
|
|
114
97
|
def build_command() -> None:
|
|
115
98
|
root = project_root()
|
|
116
99
|
|
|
@@ -130,7 +113,7 @@ def build_command() -> None:
|
|
|
130
113
|
node_version = capture(["node", "--version"])
|
|
131
114
|
console.print(f" Node.js: {node_version or '[red]not found[/]'}")
|
|
132
115
|
if not node_version:
|
|
133
|
-
|
|
116
|
+
error_block("Node.js is required.", [])
|
|
134
117
|
raise typer.Exit(code=1)
|
|
135
118
|
|
|
136
119
|
npm_version = capture(["npm", "--version"])
|
|
@@ -138,19 +121,18 @@ def build_command() -> None:
|
|
|
138
121
|
|
|
139
122
|
python_cmd = _which_python()
|
|
140
123
|
if not python_cmd or not _check_python(python_cmd):
|
|
141
|
-
|
|
142
|
-
"
|
|
143
|
-
"Install from https://python.org/downloads/"
|
|
124
|
+
error_block(
|
|
125
|
+
"Python 3.12+ is required.",
|
|
126
|
+
["Install from https://python.org/downloads/"],
|
|
144
127
|
)
|
|
145
128
|
raise typer.Exit(code=1)
|
|
146
129
|
|
|
147
130
|
_ensure_uv(python_cmd)
|
|
148
|
-
_ensure_temporal()
|
|
149
131
|
|
|
150
132
|
console.print("\n[green]All dependencies ready.[/]\n")
|
|
151
133
|
|
|
152
134
|
# ---- build steps -------------------------------------------------
|
|
153
|
-
|
|
135
|
+
server_cwd = server_dir(root)
|
|
154
136
|
env_path = root / ".env"
|
|
155
137
|
template_path = root / ".env.template"
|
|
156
138
|
|
|
@@ -179,9 +161,13 @@ def build_command() -> None:
|
|
|
179
161
|
run(["pnpm", "--filter", "machinaos-nodejs-executor", "run", "build"], cwd=root)
|
|
180
162
|
|
|
181
163
|
console.log("[4/6] Installing Python dependencies...")
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
164
|
+
# ``server/`` is its own standalone uv project; ``uv sync`` at that
|
|
165
|
+
# directory resolves ``server/pyproject.toml`` and materialises
|
|
166
|
+
# ``server/.venv``. The CLI lives in a separate venv (or system
|
|
167
|
+
# python via pipx) and never shares this environment -- see
|
|
168
|
+
# ``cli/platform_.py`` docstring for the rationale. ``uv sync``
|
|
169
|
+
# is idempotent and creates the venv on first run.
|
|
170
|
+
run(["uv", "sync"], cwd=server_cwd)
|
|
185
171
|
|
|
186
172
|
# Pre-compile our Python sources to optimised bytecode (.opt-1.pyc).
|
|
187
173
|
# `-O` strips `assert` statements + `__debug__` branches; `-q`
|
|
@@ -195,20 +181,24 @@ def build_command() -> None:
|
|
|
195
181
|
# template files inside packages like crawlee that aren't real Python.
|
|
196
182
|
console.log("[5/6] Compiling Python bytecode...")
|
|
197
183
|
run(
|
|
198
|
-
|
|
199
|
-
|
|
184
|
+
uv_run(
|
|
185
|
+
"python", "-O", "-m", "compileall", "-q", "-j", "0", *COMPILEALL_SOURCE_DIRS
|
|
186
|
+
),
|
|
187
|
+
cwd=server_cwd,
|
|
200
188
|
check=False, # missing pyc is non-fatal — runtime regenerates as needed
|
|
201
189
|
)
|
|
202
190
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
)
|
|
191
|
+
# Temporal is a required runtime dep: fetch + verify the binaries
|
|
192
|
+
# now so first ``machina start`` is instant instead of paying the
|
|
193
|
+
# ~90 MB pooch download cost inside ``_pre_spawn``. The ``-m
|
|
194
|
+
# services.temporal._install`` entry runs ``ensure_temporal_binaries``
|
|
195
|
+
# then asserts every extracted path exists; non-zero exit aborts
|
|
196
|
+
# the build via ``run(check=True)``. Idempotent on re-build (pooch
|
|
197
|
+
# cache hit) so this step is sub-second once the tarball is on disk.
|
|
198
|
+
console.log("[6/6] Installing Temporal binaries...")
|
|
199
|
+
run(
|
|
200
|
+
uv_run("python", "-m", "services.temporal._install"),
|
|
201
|
+
cwd=server_cwd,
|
|
202
|
+
)
|
|
213
203
|
|
|
214
204
|
console.log("[green]Build complete.[/]")
|