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
|
@@ -43,7 +43,7 @@ from services.cli_agent.mcp_server import (
|
|
|
43
43
|
)
|
|
44
44
|
from services.cli_agent.protocol import BatchResult, SessionResult
|
|
45
45
|
from services.cli_agent.session import AICliSession
|
|
46
|
-
from services.cli_agent.types import BaseAICliTaskSpec
|
|
46
|
+
from services.cli_agent.types import BaseAICliTaskSpec, ClaudeTaskSpec
|
|
47
47
|
|
|
48
48
|
logger = get_logger(__name__)
|
|
49
49
|
|
|
@@ -92,27 +92,63 @@ class AICliService:
|
|
|
92
92
|
"""
|
|
93
93
|
provider = create_cli_provider(provider_name)
|
|
94
94
|
task_list: List[BaseAICliTaskSpec] = list(tasks)
|
|
95
|
+
|
|
96
|
+
# Pass the per-workflow workspace dir
|
|
97
|
+
# (``data/workspaces/<workflow_id>/`` — injected into ctx by
|
|
98
|
+
# ``workflow.py:_get_workspace_dir``) to the spawned claude via
|
|
99
|
+
# ``--add-dir`` so claude's built-in filesystem tools (``Read``,
|
|
100
|
+
# ``Edit``, ``Glob``, ``Grep``, ``Write``, ``Bash``) can access
|
|
101
|
+
# files produced by upstream nodes (``fileDownloader``,
|
|
102
|
+
# ``documentParser``, ``code`` executors, etc.). Without this
|
|
103
|
+
# the workspace is invisible to claude: memory-bound runs spawn
|
|
104
|
+
# with ``cwd=repo_root`` and non-memory runs with
|
|
105
|
+
# ``cwd=worktree``, neither of which sees the workflow's
|
|
106
|
+
# workspace files.
|
|
107
|
+
#
|
|
108
|
+
# Mirrors the ai_agent pattern (``services/ai.py:1899`` —
|
|
109
|
+
# ``config['workspace_dir'] = context.get('workspace_dir', '')``),
|
|
110
|
+
# but uses claude's native ``--add-dir`` mechanism instead of
|
|
111
|
+
# tool-config injection because claude has its own filesystem
|
|
112
|
+
# tools rather than MCP-injected ones.
|
|
113
|
+
workspace_str = str(Path(workspace_dir).resolve())
|
|
114
|
+
for t in task_list:
|
|
115
|
+
existing_add_dir = list(getattr(t, "add_dir", []) or [])
|
|
116
|
+
if workspace_str not in existing_add_dir:
|
|
117
|
+
existing_add_dir.append(workspace_str)
|
|
118
|
+
# ``ClaudeTaskSpec.add_dir`` is ``List[str]`` per
|
|
119
|
+
# ``types.py``; ``model_copy(update=...)`` is the
|
|
120
|
+
# Pydantic-clean way to splice it without mutating.
|
|
121
|
+
if hasattr(t, "model_copy"):
|
|
122
|
+
task_list[task_list.index(t)] = t.model_copy(
|
|
123
|
+
update={"add_dir": existing_add_dir},
|
|
124
|
+
)
|
|
125
|
+
|
|
95
126
|
tool_names = [t.get("node_type") for t in (connected_tools or [])]
|
|
96
|
-
memory_node = (
|
|
97
|
-
connected_memory.get("node_id") if connected_memory else None
|
|
98
|
-
)
|
|
127
|
+
memory_node = connected_memory.get("node_id") if connected_memory else None
|
|
99
128
|
logger.info(
|
|
100
|
-
"[CC-Agent run_batch] enter provider=%s node=%s wf=%s tasks=%d "
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
129
|
+
"[CC-Agent run_batch] enter provider=%s node=%s wf=%s tasks=%d " "skills=%s tools=%s creds=%s memory=%s workspace=%s",
|
|
130
|
+
provider_name,
|
|
131
|
+
node_id,
|
|
132
|
+
workflow_id,
|
|
133
|
+
len(task_list),
|
|
134
|
+
connected_skill_names or [],
|
|
135
|
+
tool_names,
|
|
136
|
+
allowed_credentials or [],
|
|
137
|
+
memory_node,
|
|
138
|
+
workspace_dir,
|
|
105
139
|
)
|
|
106
140
|
|
|
107
141
|
# Verify the working directory is under a git repo.
|
|
108
142
|
resolved_repo_root = await self._resolve_repo_root(
|
|
109
|
-
workspace_dir=workspace_dir,
|
|
143
|
+
workspace_dir=workspace_dir,
|
|
144
|
+
override=repo_root,
|
|
110
145
|
)
|
|
111
146
|
if resolved_repo_root is None:
|
|
112
147
|
logger.warning(
|
|
113
148
|
"[CC-Agent run_batch] aborting: workspace=%s is not inside a git "
|
|
114
149
|
"repo (run `git init` there or set `working_directory` to "
|
|
115
|
-
"an existing repo).",
|
|
150
|
+
"an existing repo).",
|
|
151
|
+
workspace_dir,
|
|
116
152
|
)
|
|
117
153
|
return self._abort_not_git_repo(
|
|
118
154
|
provider_name=provider_name,
|
|
@@ -120,7 +156,8 @@ class AICliService:
|
|
|
120
156
|
)
|
|
121
157
|
logger.info(
|
|
122
158
|
"[CC-Agent run_batch] resolved repo_root=%s for workspace=%s",
|
|
123
|
-
resolved_repo_root,
|
|
159
|
+
resolved_repo_root,
|
|
160
|
+
workspace_dir,
|
|
124
161
|
)
|
|
125
162
|
|
|
126
163
|
# Per-batch bearer token + MCP context
|
|
@@ -144,7 +181,8 @@ class AICliService:
|
|
|
144
181
|
async with self._lock:
|
|
145
182
|
if key in self._active_sessions:
|
|
146
183
|
logger.warning(
|
|
147
|
-
"[CC-Agent service] replacing stale session list for %s",
|
|
184
|
+
"[CC-Agent service] replacing stale session list for %s",
|
|
185
|
+
key,
|
|
148
186
|
)
|
|
149
187
|
# Cancel anything previously left dangling.
|
|
150
188
|
for sess in self._active_sessions[key]:
|
|
@@ -155,27 +193,35 @@ class AICliService:
|
|
|
155
193
|
self._active_sessions[key] = []
|
|
156
194
|
|
|
157
195
|
start = time.monotonic()
|
|
158
|
-
await self._broadcast_phase(
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
"
|
|
163
|
-
|
|
196
|
+
await self._broadcast_phase(
|
|
197
|
+
broadcaster,
|
|
198
|
+
node_id,
|
|
199
|
+
workflow_id,
|
|
200
|
+
"batch_started",
|
|
201
|
+
{
|
|
202
|
+
"provider": provider_name,
|
|
203
|
+
"n_tasks": len(task_list),
|
|
204
|
+
"max_parallel": max_parallel,
|
|
205
|
+
"isolation": "worktree",
|
|
206
|
+
},
|
|
207
|
+
)
|
|
164
208
|
|
|
165
209
|
sem = asyncio.Semaphore(max(1, int(max_parallel)))
|
|
166
210
|
|
|
167
211
|
async def run_one(task: BaseAICliTaskSpec) -> SessionResult:
|
|
168
212
|
async with sem:
|
|
169
213
|
session = AICliSession(
|
|
170
|
-
provider=provider,
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
214
|
+
provider=provider,
|
|
215
|
+
task=task,
|
|
216
|
+
repo_root=resolved_repo_root,
|
|
217
|
+
workspace_dir=workspace_dir,
|
|
218
|
+
node_id=node_id,
|
|
219
|
+
workflow_id=workflow_id,
|
|
220
|
+
broadcaster=broadcaster,
|
|
221
|
+
defaults=defaults,
|
|
222
|
+
mcp_port=port,
|
|
223
|
+
batch_token=token,
|
|
224
|
+
connected_tool_names=[t.get("node_type") for t in (connected_tools or []) if t.get("node_type")],
|
|
179
225
|
connected_skill_names=list(connected_skill_names or []),
|
|
180
226
|
memory_bound=bool(connected_memory),
|
|
181
227
|
)
|
|
@@ -185,16 +231,13 @@ class AICliService:
|
|
|
185
231
|
try:
|
|
186
232
|
await session.start()
|
|
187
233
|
except FileNotFoundError as exc:
|
|
188
|
-
return self._fail_result(provider_name, task, session.task_id,
|
|
189
|
-
f"cli_not_installed: {exc}")
|
|
234
|
+
return self._fail_result(provider_name, task, session.task_id, f"cli_not_installed: {exc}")
|
|
190
235
|
except RuntimeError as exc:
|
|
191
236
|
# `_pre_spawn` raises on git-worktree failure.
|
|
192
|
-
return self._fail_result(provider_name, task, session.task_id,
|
|
193
|
-
f"worktree_setup_failed: {exc}")
|
|
237
|
+
return self._fail_result(provider_name, task, session.task_id, f"worktree_setup_failed: {exc}")
|
|
194
238
|
except Exception as exc:
|
|
195
239
|
logger.exception("[CC-Agent service] start failed")
|
|
196
|
-
return self._fail_result(provider_name, task, session.task_id,
|
|
197
|
-
f"start_failed: {exc}")
|
|
240
|
+
return self._fail_result(provider_name, task, session.task_id, f"start_failed: {exc}")
|
|
198
241
|
return await session.wait_for_completion(task.timeout_seconds)
|
|
199
242
|
finally:
|
|
200
243
|
try:
|
|
@@ -207,15 +250,57 @@ class AICliService:
|
|
|
207
250
|
except (KeyError, ValueError):
|
|
208
251
|
pass
|
|
209
252
|
|
|
253
|
+
# Pool branch: when memory is connected to a claude task, route
|
|
254
|
+
# through ``ClaudeSessionPool`` so successive turns reuse the
|
|
255
|
+
# warm PTY via ``/clear`` (saves ~1-2 s per turn). The
|
|
256
|
+
# ``claude_code_agent`` plugin already enforces ``len(tasks)==1``
|
|
257
|
+
# when memory is wired, so this branch is single-task. The pool
|
|
258
|
+
# owns the PTY lifetime; the bearer token stays embedded in the
|
|
259
|
+
# spawned claude's argv across batches (CLI handles its own MCP
|
|
260
|
+
# auth — we don't issue/unregister per turn).
|
|
261
|
+
use_pool = bool(connected_memory) and provider_name == "claude" and len(task_list) == 1
|
|
262
|
+
results: List[SessionResult]
|
|
210
263
|
try:
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
264
|
+
if use_pool:
|
|
265
|
+
results = [
|
|
266
|
+
await self._run_pooled_turn(
|
|
267
|
+
task=task_list[0],
|
|
268
|
+
memory_node_id=connected_memory["node_id"],
|
|
269
|
+
cwd=resolved_repo_root,
|
|
270
|
+
workspace_dir=Path(workspace_dir).resolve(),
|
|
271
|
+
defaults=defaults,
|
|
272
|
+
mcp_port=port,
|
|
273
|
+
mcp_bearer_token=token,
|
|
274
|
+
connected_tools=connected_tools or [],
|
|
275
|
+
connected_skill_names=list(connected_skill_names or []),
|
|
276
|
+
workflow_id=workflow_id,
|
|
277
|
+
)
|
|
278
|
+
]
|
|
279
|
+
else:
|
|
280
|
+
results = await asyncio.gather(
|
|
281
|
+
*(run_one(t) for t in task_list),
|
|
282
|
+
return_exceptions=False,
|
|
283
|
+
)
|
|
215
284
|
finally:
|
|
216
285
|
async with self._lock:
|
|
217
286
|
self._active_sessions.pop(key, None)
|
|
218
|
-
|
|
287
|
+
# When ``use_pool`` is True, the bearer token for THIS batch
|
|
288
|
+
# is consumed by ``ClaudeSessionPool.acquire`` directly:
|
|
289
|
+
# - Cold spawn: pool stores ``token`` on
|
|
290
|
+
# ``PooledClaudeSession.batch_token`` so it survives
|
|
291
|
+
# across subsequent batches; ``_terminate_locked``
|
|
292
|
+
# unregisters it when the subprocess dies (drains
|
|
293
|
+
# FastMCP tool refcounts cleanly on eviction / pool
|
|
294
|
+
# shutdown).
|
|
295
|
+
# - Warm reuse: pool rebinds the surviving warm
|
|
296
|
+
# subprocess's persistent BatchContext to this batch's
|
|
297
|
+
# surface in place and unregisters ``token`` (which
|
|
298
|
+
# was redundant the moment we picked the warm path).
|
|
299
|
+
# Either way the pool owns the token's fate, so we must
|
|
300
|
+
# NOT unregister here for the pool path — doing so on
|
|
301
|
+
# cold spawn would 401 every subsequent warm-reuse turn.
|
|
302
|
+
if not use_pool:
|
|
303
|
+
unregister_batch(token)
|
|
219
304
|
|
|
220
305
|
# Memory bridge: persist claude's session_id + append the
|
|
221
306
|
# rendered exchange to simpleMemory's markdown transcript so the
|
|
@@ -225,7 +310,9 @@ class AICliService:
|
|
|
225
310
|
if connected_memory:
|
|
226
311
|
try:
|
|
227
312
|
await self._persist_memory(
|
|
228
|
-
connected_memory,
|
|
313
|
+
connected_memory,
|
|
314
|
+
results,
|
|
315
|
+
broadcaster=broadcaster,
|
|
229
316
|
)
|
|
230
317
|
except Exception as exc: # pragma: no cover — best-effort
|
|
231
318
|
logger.warning(
|
|
@@ -249,9 +336,7 @@ class AICliService:
|
|
|
249
336
|
r.cost_usd = derived
|
|
250
337
|
|
|
251
338
|
costs = [r.cost_usd for r in results]
|
|
252
|
-
total_cost = (
|
|
253
|
-
None if any(c is None for c in costs) else round(sum(c or 0 for c in costs), 6)
|
|
254
|
-
)
|
|
339
|
+
total_cost = None if any(c is None for c in costs) else round(sum(c or 0 for c in costs), 6)
|
|
255
340
|
|
|
256
341
|
result = BatchResult(
|
|
257
342
|
tasks=results,
|
|
@@ -265,13 +350,19 @@ class AICliService:
|
|
|
265
350
|
timestamp=datetime.now(timezone.utc).isoformat(),
|
|
266
351
|
)
|
|
267
352
|
|
|
268
|
-
await self._broadcast_phase(
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
"
|
|
273
|
-
|
|
274
|
-
|
|
353
|
+
await self._broadcast_phase(
|
|
354
|
+
broadcaster,
|
|
355
|
+
node_id,
|
|
356
|
+
workflow_id,
|
|
357
|
+
"batch_complete",
|
|
358
|
+
{
|
|
359
|
+
"provider": provider_name,
|
|
360
|
+
"n_succeeded": n_succeeded,
|
|
361
|
+
"n_failed": n_failed,
|
|
362
|
+
"total_cost_usd": total_cost,
|
|
363
|
+
"wall_clock_ms": elapsed_ms,
|
|
364
|
+
},
|
|
365
|
+
)
|
|
275
366
|
return result
|
|
276
367
|
|
|
277
368
|
async def cancel_workflow(self, workflow_id: str) -> int:
|
|
@@ -310,6 +401,82 @@ class AICliService:
|
|
|
310
401
|
# Internals
|
|
311
402
|
# ------------------------------------------------------------------
|
|
312
403
|
|
|
404
|
+
async def _run_pooled_turn(
|
|
405
|
+
self,
|
|
406
|
+
*,
|
|
407
|
+
task: BaseAICliTaskSpec,
|
|
408
|
+
memory_node_id: str,
|
|
409
|
+
cwd: Path,
|
|
410
|
+
workspace_dir: Path,
|
|
411
|
+
defaults: Dict[str, Any],
|
|
412
|
+
mcp_port: int,
|
|
413
|
+
mcp_bearer_token: str,
|
|
414
|
+
connected_tools: List[Dict[str, Any]],
|
|
415
|
+
connected_skill_names: List[str],
|
|
416
|
+
workflow_id: str,
|
|
417
|
+
) -> SessionResult:
|
|
418
|
+
"""Route one memory-bound claude turn through ``ClaudeSessionPool``.
|
|
419
|
+
|
|
420
|
+
Cold spawn or warm reuse is hidden behind ``pool.acquire``; the
|
|
421
|
+
``/clear`` rotation and new-UUID capture happen inside the pool.
|
|
422
|
+
The MCP bearer token stays with the spawned claude across batches
|
|
423
|
+
— see the use-pool branch in :meth:`run_batch` for the rationale.
|
|
424
|
+
|
|
425
|
+
The pool lives in the plugin folder (per the canonical
|
|
426
|
+
plugin-folder layout); we look it up through the
|
|
427
|
+
:func:`services.cli_agent.factory.get_session_pool` registry
|
|
428
|
+
instead of importing directly so the framework stays free of
|
|
429
|
+
any ``services → nodes`` layering violation.
|
|
430
|
+
"""
|
|
431
|
+
from services.cli_agent.factory import get_session_pool
|
|
432
|
+
|
|
433
|
+
if not isinstance(task, ClaudeTaskSpec):
|
|
434
|
+
raise TypeError("Pooled turns require ClaudeTaskSpec, got " f"{type(task).__name__}")
|
|
435
|
+
|
|
436
|
+
pool = get_session_pool("claude")
|
|
437
|
+
if pool is None:
|
|
438
|
+
raise RuntimeError(
|
|
439
|
+
"No session pool registered for 'claude'. The "
|
|
440
|
+
"claude_code_agent plugin's __init__.py should call "
|
|
441
|
+
"register_session_pool('claude', get_session_pool). "
|
|
442
|
+
"Did its module fail to import?"
|
|
443
|
+
)
|
|
444
|
+
await pool.start_reaper()
|
|
445
|
+
|
|
446
|
+
mcp_endpoint_url = f"http://127.0.0.1:{mcp_port}/mcp/ide/mcp"
|
|
447
|
+
tool_names = [t.get("node_type") for t in (connected_tools or []) if t.get("node_type")]
|
|
448
|
+
|
|
449
|
+
env = {**os.environ, "PYTHONUNBUFFERED": "1"}
|
|
450
|
+
# Project-local claude auth dir — same as ``AICliSession.env``.
|
|
451
|
+
from nodes.agent.claude_code_agent._oauth import MACHINA_CLAUDE_DIR
|
|
452
|
+
|
|
453
|
+
env["CLAUDE_CONFIG_DIR"] = str(MACHINA_CLAUDE_DIR)
|
|
454
|
+
# Composio-style parent-run-ID for MCP correlation.
|
|
455
|
+
env["MACHINA_PARENT_RUN_ID"] = f"{workflow_id}:{memory_node_id}:{mcp_bearer_token[:8]}"
|
|
456
|
+
|
|
457
|
+
pooled = await pool.acquire(
|
|
458
|
+
memory_node_id,
|
|
459
|
+
spec=task,
|
|
460
|
+
cwd=cwd,
|
|
461
|
+
env=env,
|
|
462
|
+
defaults=defaults,
|
|
463
|
+
mcp_endpoint_url=mcp_endpoint_url,
|
|
464
|
+
mcp_bearer_token=mcp_bearer_token,
|
|
465
|
+
connected_tool_names=tool_names,
|
|
466
|
+
connected_skill_names=connected_skill_names,
|
|
467
|
+
workspace_dir=workspace_dir,
|
|
468
|
+
workflow_id=workflow_id,
|
|
469
|
+
)
|
|
470
|
+
try:
|
|
471
|
+
return await pool.send_turn(
|
|
472
|
+
pooled,
|
|
473
|
+
task.prompt,
|
|
474
|
+
timeout_seconds=task.timeout_seconds,
|
|
475
|
+
workflow_id=workflow_id,
|
|
476
|
+
)
|
|
477
|
+
finally:
|
|
478
|
+
await pool.release(pooled)
|
|
479
|
+
|
|
313
480
|
@staticmethod
|
|
314
481
|
async def _clear_stale_session_id(
|
|
315
482
|
connected_memory: Dict[str, Any],
|
|
@@ -336,7 +503,8 @@ class AICliService:
|
|
|
336
503
|
"[CC-Agent _persist_memory] cleared stale last_session_id=%s "
|
|
337
504
|
"from memory_node=%s; next run will spawn a fresh claude "
|
|
338
505
|
"session and persist its new UUID.",
|
|
339
|
-
prior,
|
|
506
|
+
prior,
|
|
507
|
+
memory_node_id,
|
|
340
508
|
)
|
|
341
509
|
|
|
342
510
|
@staticmethod
|
|
@@ -347,14 +515,13 @@ class AICliService:
|
|
|
347
515
|
) -> None:
|
|
348
516
|
"""Append each successful run's user prompt + assistant response
|
|
349
517
|
to ``simpleMemory.memory_content`` (markdown). Mirrors aiAgent /
|
|
350
|
-
chatAgent /
|
|
518
|
+
chatAgent / rlm_agent's persistence pattern exactly
|
|
351
519
|
— same helpers (``append_to_memory_markdown``,
|
|
352
520
|
``trim_markdown_window``), same field. One DB write.
|
|
353
521
|
"""
|
|
354
522
|
successful = [r for r in results if r.success]
|
|
355
523
|
logger.info(
|
|
356
|
-
"[CC-Agent _persist_memory] memory_node=%s results=%d "
|
|
357
|
-
"successful=%d session_ids=%s",
|
|
524
|
+
"[CC-Agent _persist_memory] memory_node=%s results=%d " "successful=%d session_ids=%s",
|
|
358
525
|
connected_memory.get("node_id"),
|
|
359
526
|
len(results),
|
|
360
527
|
len(successful),
|
|
@@ -362,14 +529,9 @@ class AICliService:
|
|
|
362
529
|
)
|
|
363
530
|
if not successful:
|
|
364
531
|
logger.warning(
|
|
365
|
-
"[CC-Agent _persist_memory] no successful runs; skipping "
|
|
366
|
-
"save (memory_node=%s). Per-result: %s",
|
|
532
|
+
"[CC-Agent _persist_memory] no successful runs; skipping " "save (memory_node=%s). Per-result: %s",
|
|
367
533
|
connected_memory.get("node_id"),
|
|
368
|
-
[
|
|
369
|
-
{"success": r.success, "session_id": r.session_id,
|
|
370
|
-
"error": (r.error or "")[:80]}
|
|
371
|
-
for r in results
|
|
372
|
-
],
|
|
534
|
+
[{"success": r.success, "session_id": r.session_id, "error": (r.error or "")[:80]} for r in results],
|
|
373
535
|
)
|
|
374
536
|
# Auto-recovery: claude returns
|
|
375
537
|
# ``No conversation found with session ID: <UUID>`` when the
|
|
@@ -380,10 +542,7 @@ class AICliService:
|
|
|
380
542
|
# would re-fire on every retry and lock the user out
|
|
381
543
|
# forever. The next run after this point will spawn a
|
|
382
544
|
# fresh session and `_persist_memory` will save its UUID.
|
|
383
|
-
stale = any(
|
|
384
|
-
r.error and "No conversation found with session ID" in r.error
|
|
385
|
-
for r in results
|
|
386
|
-
)
|
|
545
|
+
stale = any(r.error and "No conversation found with session ID" in r.error for r in results)
|
|
387
546
|
if stale:
|
|
388
547
|
await AICliService._clear_stale_session_id(connected_memory)
|
|
389
548
|
return
|
|
@@ -406,13 +565,13 @@ class AICliService:
|
|
|
406
565
|
params["last_session_id"] = last_run.session_id
|
|
407
566
|
|
|
408
567
|
# 2. Update the user-visible markdown mirror.
|
|
409
|
-
content = params.get("memory_content") or (
|
|
410
|
-
"# Conversation History\n\n*No messages yet.*\n"
|
|
411
|
-
)
|
|
568
|
+
content = params.get("memory_content") or ("# Conversation History\n\n*No messages yet.*\n")
|
|
412
569
|
for r in successful:
|
|
413
570
|
content = append_to_memory_markdown(content, "human", r.prompt)
|
|
414
571
|
content = append_to_memory_markdown(
|
|
415
|
-
content,
|
|
572
|
+
content,
|
|
573
|
+
"ai",
|
|
574
|
+
r.response or "",
|
|
416
575
|
)
|
|
417
576
|
|
|
418
577
|
window = int(connected_memory.get("window_size") or 100)
|
|
@@ -424,28 +583,30 @@ class AICliService:
|
|
|
424
583
|
"[CC-Agent _persist_memory] saved memory_node=%s "
|
|
425
584
|
"last_session_id=%s appended_turns=%d archived_blocks=%d "
|
|
426
585
|
"content_length=%d",
|
|
427
|
-
memory_node_id,
|
|
428
|
-
|
|
586
|
+
memory_node_id,
|
|
587
|
+
params.get("last_session_id"),
|
|
588
|
+
len(successful),
|
|
589
|
+
len(removed_texts),
|
|
590
|
+
len(content),
|
|
429
591
|
)
|
|
430
592
|
|
|
431
593
|
# Broadcast `node_parameters_updated` so the simpleMemory's
|
|
432
594
|
# parameter panel + memory editor refetch live without a page
|
|
433
|
-
# reload.
|
|
434
|
-
#
|
|
435
|
-
# this
|
|
436
|
-
#
|
|
595
|
+
# reload. CloudEvents v1.0 envelope (RFC §6.4) — type is
|
|
596
|
+
# ``com.machinaos.node.parameters.updated``; ``source_hint="cli"``
|
|
597
|
+
# distinguishes this Claude-CLI autonomous write from a user
|
|
598
|
+
# parameter-panel save.
|
|
437
599
|
if broadcaster is not None:
|
|
438
600
|
try:
|
|
439
|
-
await broadcaster.
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
"
|
|
443
|
-
|
|
444
|
-
"timestamp": time.time(),
|
|
445
|
-
})
|
|
601
|
+
await broadcaster.broadcast_node_parameters_updated(
|
|
602
|
+
memory_node_id,
|
|
603
|
+
parameters=params,
|
|
604
|
+
source_hint="cli",
|
|
605
|
+
)
|
|
446
606
|
except Exception as exc:
|
|
447
607
|
logger.warning(
|
|
448
|
-
"[CC-Agent _persist_memory] broadcast failed: %s",
|
|
608
|
+
"[CC-Agent _persist_memory] broadcast failed: %s",
|
|
609
|
+
exc,
|
|
449
610
|
)
|
|
450
611
|
|
|
451
612
|
if connected_memory.get("long_term_enabled") and removed_texts:
|
|
@@ -513,6 +674,7 @@ class AICliService:
|
|
|
513
674
|
|
|
514
675
|
try:
|
|
515
676
|
from services.pricing import get_pricing_service
|
|
677
|
+
|
|
516
678
|
pricing = get_pricing_service()
|
|
517
679
|
breakdown = pricing.calculate_cost(
|
|
518
680
|
provider=result.provider,
|