machinaos 0.0.76 → 0.0.77
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/README.md +142 -106
- package/client/dist/assets/ActionBar-DAHXJmEU.js +1 -0
- package/client/dist/assets/ApiKeyInput-DljozMIZ.js +1 -0
- package/client/dist/assets/ApiKeyPanel-BLCwKv-F.js +1 -0
- package/client/dist/assets/ApiUsageSection-FWVtg8Sd.js +1 -0
- package/client/dist/assets/EmailPanel-Cb1y_sxm.js +1 -0
- package/client/dist/assets/OAuthPanel-BUvQtzRH.js +1 -0
- package/client/dist/assets/QrPairingPanel-DgHdW1GW.js +1 -0
- package/client/dist/assets/RateLimitSection-B2lBVQs0.js +1 -0
- package/client/dist/assets/StatusCard-BlufvZD-.js +1 -0
- package/client/dist/assets/index-DNx1tG6T.js +232 -0
- package/client/dist/assets/index-bhvWG-f4.css +1 -0
- package/client/dist/assets/vendor-flow-apeQB2hf.js +1 -0
- package/client/dist/assets/vendor-icons-BPyNc2rK.js +22 -0
- package/client/dist/assets/vendor-markdown-Bx_GU1E7.js +62 -0
- package/client/dist/assets/vendor-misc-4my8ai2A.js +1 -0
- package/client/dist/assets/vendor-query-to9T1kjL.js +1 -0
- package/client/dist/assets/vendor-radix-BGeDhy8U.js +56 -0
- package/client/dist/assets/vendor-react-CxXU_nq3.js +1 -0
- package/client/dist/index.html +37 -3
- package/client/index.html +28 -1
- package/client/package.json +5 -1
- package/client/src/App.tsx +2 -0
- package/client/src/Dashboard.tsx +157 -45
- package/client/src/ParameterPanel.tsx +3 -5
- package/client/src/adapters/nodeSpecToDescription.ts +1 -0
- package/client/src/assets/icons/NodeIcon.tsx +32 -0
- package/client/src/assets/icons/index.ts +4 -0
- package/client/src/assets/icons/stripe.svg +1 -0
- package/client/src/assets/icons/themedGlyphs.ts +404 -0
- package/client/src/components/AIAgentNode.tsx +77 -53
- package/client/src/components/GenericNode.tsx +34 -52
- package/client/src/components/OutputPanel.tsx +64 -147
- package/client/src/components/ParameterRenderer.tsx +5 -3
- package/client/src/components/SkillEditorModal.tsx +9 -18
- package/client/src/components/SquareNode.tsx +97 -115
- package/client/src/components/StartNode.tsx +32 -42
- package/client/src/components/SvgFilterDefs.tsx +54 -0
- package/client/src/components/TeamMonitorNode.tsx +12 -14
- package/client/src/components/ToolkitNode.tsx +35 -60
- package/client/src/components/TriggerNode.tsx +43 -77
- package/client/src/components/__tests__/CredentialsModal.test.tsx +49 -45
- package/client/src/components/credentials/CredentialsModal.tsx +98 -30
- package/client/src/components/credentials/CredentialsPalette.tsx +73 -5
- package/client/src/components/credentials/catalogueAdapter.ts +17 -1
- package/client/src/components/credentials/panels/ApiKeyPanel.tsx +102 -37
- package/client/src/components/credentials/panels/EmailPanel.tsx +7 -19
- package/client/src/components/credentials/panels/OAuthPanel.tsx +5 -1
- package/client/src/components/credentials/panels/QrPairingPanel.tsx +1 -3
- package/client/src/components/credentials/primitives/ActionBar.tsx +7 -11
- package/client/src/components/credentials/primitives/OAuthConnect.tsx +19 -28
- package/client/src/components/credentials/sections/ProviderDefaultsSection.tsx +24 -3
- package/client/src/components/credentials/types.ts +12 -2
- package/client/src/components/credentials/useCredentialPanel.ts +43 -19
- package/client/src/components/icons/AIProviderIcons.tsx +16 -0
- package/client/src/components/onboarding/OnboardingWizard.tsx +23 -63
- package/client/src/components/onboarding/nodeRoleClasses.ts +23 -0
- package/client/src/components/onboarding/steps/CanvasStep.tsx +15 -21
- package/client/src/components/onboarding/steps/ConceptsStep.tsx +2 -11
- package/client/src/components/onboarding/steps/GetStartedStep.tsx +2 -10
- package/client/src/components/parameterPanel/InputSection.tsx +9 -7
- package/client/src/components/parameterPanel/MasterSkillEditor.tsx +84 -198
- package/client/src/components/parameterPanel/MiddleSection.tsx +57 -80
- package/client/src/components/parameterPanel/ToolSchemaEditor.tsx +31 -25
- package/client/src/components/parameterPanel/__tests__/InputSection.test.tsx +7 -2
- package/client/src/components/ui/AIResultModal.tsx +1 -1
- package/client/src/components/ui/CollapsibleSection.tsx +9 -5
- package/client/src/components/ui/CommandPalette.tsx +147 -0
- package/client/src/components/ui/CommandPaletteHost.tsx +189 -0
- package/client/src/components/ui/ComponentItem.tsx +13 -7
- package/client/src/components/ui/ComponentPalette.tsx +24 -13
- package/client/src/components/ui/ConsolePanel.tsx +19 -11
- package/client/src/components/ui/DropCap.tsx +28 -0
- package/client/src/components/ui/EditableNodeLabel.tsx +10 -2
- package/client/src/components/ui/InputNodesPanel.tsx +1 -1
- package/client/src/components/ui/Modal.tsx +38 -6
- package/client/src/components/ui/OutputDisplayPanel.tsx +1 -1
- package/client/src/components/ui/SettingsPanel.tsx +42 -13
- package/client/src/components/ui/StatusBar.tsx +108 -0
- package/client/src/components/ui/ThemeSwitcher.tsx +109 -0
- package/client/src/components/ui/TopToolbar.tsx +42 -25
- package/client/src/components/ui/WorkflowSidebar.tsx +32 -16
- package/client/src/components/ui/action-button.tsx +40 -15
- package/client/src/components/ui/button.tsx +24 -1
- package/client/src/components/ui/dropdown-menu.tsx +24 -2
- package/client/src/components/ui/input.tsx +19 -2
- package/client/src/components/ui/select.tsx +15 -0
- package/client/src/components/ui/textarea.tsx +15 -2
- package/client/src/contexts/AuthContext.tsx +148 -109
- package/client/src/contexts/ThemeContext.tsx +93 -17
- package/client/src/contexts/WebSocketContext.tsx +373 -206
- package/client/src/contexts/__tests__/AuthContext.test.tsx +221 -0
- package/client/src/hooks/__tests__/useDragVariable.test.ts +7 -1
- package/client/src/hooks/__tests__/useWorkflowOpsListener.test.ts +142 -0
- package/client/src/hooks/useAppTheme.ts +209 -7
- package/client/src/hooks/useAutoSkillEdges.ts +7 -2
- package/client/src/hooks/useCatalogueQuery.ts +67 -1
- package/client/src/hooks/useDragVariable.ts +1 -1
- package/client/src/hooks/useNodeAllowlist.ts +115 -8
- package/client/src/hooks/useOnboarding.ts +20 -8
- package/client/src/hooks/useParameterPanel.ts +2 -1
- package/client/src/hooks/useReactFlowNodes.ts +2 -1
- package/client/src/hooks/useSound.ts +185 -0
- package/client/src/hooks/useWorkflowManagement.ts +6 -8
- package/client/src/hooks/useWorkflowOpsListener.ts +90 -0
- package/client/src/index.css +65 -3
- package/client/src/lib/__tests__/connectionConfig.test.ts +91 -0
- package/client/src/lib/aiModelProviders.ts +8 -0
- package/client/src/lib/connectionConfig.ts +107 -0
- package/client/src/lib/queryPersist.ts +13 -5
- package/client/src/lib/sound.ts +393 -0
- package/client/src/main.tsx +20 -0
- package/client/src/store/useAppStore.ts +26 -0
- package/client/src/styles/canvasAnimations.ts +37 -36
- package/client/src/styles/theme.ts +36 -20
- package/client/src/test/setup.ts +1 -0
- package/client/src/themes/atomic.css +253 -0
- package/client/src/themes/base.css +373 -0
- package/client/src/themes/cyber.css +890 -0
- package/client/src/themes/dark.css +70 -0
- package/client/src/themes/edo.css +246 -0
- package/client/src/themes/greek.css +293 -0
- package/client/src/themes/light.css +78 -0
- package/client/src/themes/plague.css +253 -0
- package/client/src/themes/renaissance.css +727 -0
- package/client/src/themes/rot.css +249 -0
- package/client/src/themes/steampunk.css +272 -0
- package/client/src/themes/surveillance.css +289 -0
- package/client/src/themes/wasteland.css +250 -0
- package/client/src/types/INodeProperties.ts +5 -0
- package/client/src/types/NodeTypes.ts +11 -1
- package/client/src/types/__tests__/cloudEvents.test.ts +99 -0
- package/client/src/types/cloudEvents.ts +78 -0
- package/client/src/vite-env.d.ts +7 -0
- package/client/tsconfig.json +1 -1
- package/client/vite.config.js +62 -2
- package/machina/commands/build.py +51 -7
- package/machina/pyproject.toml +4 -0
- package/machina/supervisor.py +12 -2
- package/machina/tree.py +71 -21
- package/package.json +1 -1
- package/scripts/install.js +16 -1
- package/server/config/ai_cli_providers.json +54 -0
- package/server/config/credential_providers.json +109 -2
- package/server/config/llm_defaults.json +24 -0
- package/server/config/model_registry.json +338 -499
- package/server/config/node_allowlist.json +16 -1
- package/server/config/pricing.json +8 -0
- package/server/constants.py +38 -15
- package/server/core/container.py +2 -2
- package/server/core/credentials_database.py +35 -2
- package/server/core/logging.py +4 -3
- package/server/main.py +99 -13
- package/server/models/node_metadata.py +1 -0
- package/server/nodejs/package.json +4 -2
- package/server/nodes/README.md +31 -4
- package/server/nodes/agent/_inline.py +2 -0
- package/server/nodes/agent/_specialized.py +6 -3
- package/server/nodes/agent/ai_agent.py +13 -3
- package/server/nodes/agent/chat_agent.py +6 -3
- package/server/nodes/agent/claude_code_agent.py +287 -75
- package/server/nodes/agent/codex_agent.py +239 -0
- package/server/nodes/agent/deep_agent.py +3 -3
- package/server/nodes/agent/rlm_agent.py +3 -3
- package/server/nodes/android/__init__.py +31 -1
- package/server/nodes/android/_base.py +9 -5
- package/server/{services/android_service.py → nodes/android/_dispatcher.py} +2 -2
- package/server/nodes/android/_handlers.py +154 -0
- package/server/nodes/android/_option_loaders.py +44 -0
- package/server/nodes/android/_refresh.py +127 -0
- package/server/{services/android → nodes/android/_relay}/client.py +4 -4
- package/server/{routers/android.py → nodes/android/_router.py} +7 -7
- package/server/nodes/browser/browser.py +2 -2
- package/server/nodes/code/_base.py +6 -2
- package/server/nodes/code/_claude_code.py +134 -0
- package/server/nodes/document/embedding_generator.py +3 -3
- package/server/nodes/document/http_scraper.py +3 -3
- package/server/nodes/document/vector_store.py +5 -5
- package/server/nodes/email/__init__.py +11 -1
- package/server/nodes/email/_filters.py +21 -0
- package/server/{services/himalaya_service.py → nodes/email/_himalaya.py} +6 -10
- package/server/{services/email_service.py → nodes/email/_service.py} +9 -13
- package/server/nodes/email/email_read.py +1 -1
- package/server/nodes/email/email_receive.py +54 -5
- package/server/nodes/email/email_send.py +1 -1
- package/server/nodes/filesystem/shell.py +24 -1
- package/server/nodes/google/__init__.py +55 -1
- package/server/{services/handlers/google_auth.py → nodes/google/_auth_helper.py} +8 -5
- package/server/nodes/google/_base.py +2 -2
- package/server/nodes/google/_credentials.py +5 -5
- package/server/nodes/google/_filters.py +25 -0
- package/server/nodes/google/_handlers.py +57 -0
- package/server/{services/google_oauth.py → nodes/google/_oauth.py} +195 -162
- package/server/nodes/google/_option_loaders.py +107 -0
- package/server/nodes/google/_refresh.py +66 -0
- package/server/nodes/google/_router.py +131 -0
- package/server/nodes/google/gmail_receive.py +41 -4
- package/server/nodes/groups.py +1 -0
- package/server/nodes/location/_credentials.py +45 -1
- package/server/{services/maps.py → nodes/location/_service.py} +18 -3
- package/server/nodes/location/gmaps_create.py +4 -4
- package/server/nodes/location/gmaps_locations.py +4 -4
- package/server/nodes/location/gmaps_nearby_places.py +4 -4
- package/server/nodes/model/_base.py +8 -3
- package/server/nodes/model/_credentials.py +96 -8
- package/server/nodes/model/_local_validator.py +345 -0
- package/server/nodes/model/lmstudio_chat_model.py +23 -0
- package/server/nodes/model/ollama_chat_model.py +25 -0
- package/server/nodes/proxy/_usage.py +2 -2
- package/server/nodes/proxy/proxy_config.py +14 -14
- package/server/nodes/proxy/proxy_request.py +4 -4
- package/server/nodes/scraper/_credentials.py +29 -1
- package/server/nodes/scraper/apify_actor.py +9 -9
- package/server/nodes/scraper/crawlee_scraper.py +5 -5
- package/server/nodes/search/brave_search.py +4 -0
- package/server/nodes/search/perplexity_search.py +9 -0
- package/server/nodes/search/serper_search.py +3 -0
- package/server/nodes/skill/simple_memory.py +12 -0
- package/server/nodes/social/_base.py +2 -2
- package/server/nodes/stripe/__init__.py +46 -0
- package/server/nodes/stripe/_credentials.py +33 -0
- package/server/nodes/stripe/_handlers.py +270 -0
- package/server/nodes/stripe/_install.py +127 -0
- package/server/nodes/stripe/_source.py +174 -0
- package/server/nodes/stripe/stripe_action.py +81 -0
- package/server/nodes/stripe/stripe_receive.py +92 -0
- package/server/nodes/telegram/_credentials.py +52 -1
- package/server/nodes/telegram/_handlers.py +19 -18
- package/server/nodes/telegram/_service.py +134 -32
- package/server/nodes/telegram/telegram_send.py +5 -6
- package/server/nodes/text/file_handler.py +2 -2
- package/server/nodes/text/text_generator.py +2 -2
- package/server/nodes/tool/agent_builder.py +630 -0
- package/server/nodes/tool/task_manager.py +144 -2
- package/server/nodes/twitter/__init__.py +38 -1
- package/server/nodes/twitter/_base.py +7 -7
- package/server/nodes/twitter/_credentials.py +1 -1
- package/server/nodes/twitter/_filters.py +37 -0
- package/server/nodes/twitter/_handlers.py +77 -0
- package/server/nodes/twitter/_oauth.py +124 -0
- package/server/nodes/twitter/_refresh.py +78 -0
- package/server/nodes/twitter/_router.py +29 -0
- package/server/nodes/twitter/twitter_receive.py +4 -0
- package/server/nodes/visuals.json +64 -19
- package/server/nodes/whatsapp/__init__.py +45 -5
- package/server/nodes/whatsapp/_base.py +3 -3
- package/server/nodes/whatsapp/_filters.py +137 -0
- package/server/nodes/whatsapp/_handlers.py +167 -0
- package/server/nodes/whatsapp/_option_loaders.py +68 -0
- package/server/nodes/whatsapp/_refresh.py +62 -0
- package/server/nodes/whatsapp/_runtime.py +1 -1
- package/server/pyproject.toml +21 -0
- package/server/routers/schemas.py +2 -2
- package/server/routers/webhook.py +26 -9
- package/server/routers/websocket.py +149 -810
- package/server/services/ai.py +89 -8
- package/server/services/auth.py +220 -43
- package/server/services/claude_oauth.py +126 -100
- package/server/services/cli_agent/__init__.py +78 -0
- package/server/services/cli_agent/_handlers.py +237 -0
- package/server/services/cli_agent/config.py +112 -0
- package/server/services/cli_agent/factory.py +48 -0
- package/server/services/cli_agent/lockfile.py +141 -0
- package/server/services/cli_agent/mcp_server.py +482 -0
- package/server/services/cli_agent/protocol.py +173 -0
- package/server/services/cli_agent/providers/__init__.py +9 -0
- package/server/services/cli_agent/providers/anthropic_claude.py +419 -0
- package/server/services/cli_agent/providers/google_gemini.py +80 -0
- package/server/services/cli_agent/providers/openai_codex.py +310 -0
- package/server/services/cli_agent/service.py +607 -0
- package/server/services/cli_agent/session.py +618 -0
- package/server/services/cli_agent/types.py +227 -0
- package/server/services/cli_agent/workflow_tools.py +233 -0
- package/server/services/credential_registry.py +26 -1
- package/server/services/deployment/manager.py +26 -145
- package/server/services/deployment/poll_registry.py +59 -0
- package/server/services/event_waiter.py +76 -246
- package/server/services/events/__init__.py +54 -0
- package/server/services/events/cli.py +78 -0
- package/server/services/events/daemon.py +163 -0
- package/server/services/events/envelope.py +281 -0
- package/server/services/events/lifecycle.py +99 -0
- package/server/services/events/oauth_lifecycle.py +534 -0
- package/server/services/events/polling.py +60 -0
- package/server/services/events/push.py +36 -0
- package/server/services/events/source.py +63 -0
- package/server/services/events/triggers.py +118 -0
- package/server/services/events/verifiers/__init__.py +25 -0
- package/server/services/events/verifiers/base.py +28 -0
- package/server/services/events/verifiers/github.py +25 -0
- package/server/services/events/verifiers/hmac_basic.py +32 -0
- package/server/services/events/verifiers/standard_webhooks.py +47 -0
- package/server/services/events/verifiers/stripe.py +42 -0
- package/server/services/events/webhook.py +105 -0
- package/server/services/handlers/tools.py +28 -186
- package/server/services/llm/config.py +7 -0
- package/server/services/llm/factory.py +8 -2
- package/server/services/memory/__init__.py +52 -0
- package/server/services/memory/jsonl.py +80 -0
- package/server/services/memory/markdown.py +65 -0
- package/server/services/memory/state.py +112 -0
- package/server/services/memory/vector_store.py +40 -0
- package/server/services/model_registry.py +76 -0
- package/server/services/node_allowlist.py +71 -15
- package/server/services/node_executor.py +2 -2
- package/server/services/node_output_schemas.py +21 -10
- package/server/services/node_spec.py +1 -1
- package/server/services/oauth_utils.py +1 -1
- package/server/services/plugin/__init__.py +2 -0
- package/server/services/plugin/base.py +44 -2
- package/server/services/plugin/credential.py +288 -1
- package/server/services/plugin/deps.py +105 -0
- package/server/services/plugin/edge_walker.py +12 -4
- package/server/services/plugin/oauth.py +381 -0
- package/server/services/plugin/polling.py +247 -0
- package/server/services/plugin/registry.py +145 -0
- package/server/services/plugin/singleton.py +65 -0
- package/server/services/plugin/ws.py +81 -0
- package/server/services/process_service.py +31 -2
- package/server/services/status_broadcaster.py +155 -238
- package/server/services/temporal/workflow.py +7 -7
- package/server/services/workflow.py +21 -3
- package/server/services/ws_handler_registry.py +111 -28
- package/server/skills/GUIDE.md +16 -1
- package/server/skills/assistant/agent-builder-skill/SKILL.md +166 -0
- package/server/skills/payments_agent/stripe-skill/SKILL.md +306 -0
- package/server/tests/credentials/test_auth_service.py +16 -9
- package/server/tests/credentials/test_credential_broadcasts.py +219 -0
- package/server/tests/credentials/test_google_oauth.py +6 -6
- package/server/tests/credentials/test_oauth_utils.py +1 -1
- package/server/tests/credentials/test_twitter_oauth.py +2 -2
- package/server/tests/credentials/test_websocket_handlers.py +44 -20
- package/server/tests/llm/test_factory.py +1 -0
- package/server/tests/llm/test_wiring.py +5 -1
- package/server/tests/nodes/_compat.py +24 -24
- package/server/tests/nodes/test_agent_builder.py +439 -0
- package/server/tests/nodes/test_ai_tools.py +18 -14
- package/server/tests/nodes/test_code_fs_process.py +17 -8
- package/server/tests/nodes/test_email.py +10 -9
- package/server/tests/nodes/test_google_workspace.py +2 -2
- package/server/tests/nodes/test_specialized_agents.py +100 -53
- package/server/tests/nodes/test_stripe_plugin.py +293 -0
- package/server/tests/nodes/test_telegram_social.py +4 -4
- package/server/tests/nodes/test_twitter.py +1 -1
- package/server/tests/nodes/test_web_automation.py +2 -2
- package/server/tests/nodes/test_whatsapp.py +9 -9
- package/server/tests/services/cli_agent/__init__.py +0 -0
- package/server/tests/services/cli_agent/test_mcp_server.py +432 -0
- package/server/tests/services/cli_agent/test_providers.py +358 -0
- package/server/tests/services/cli_agent/test_service.py +298 -0
- package/server/tests/services/memory/__init__.py +0 -0
- package/server/tests/services/memory/test_jsonl.py +188 -0
- package/server/tests/services/test_events.py +333 -0
- package/server/tests/test_node_spec.py +56 -16
- package/server/tests/test_plugin_helpers.py +116 -0
- package/server/tests/test_plugin_self_containment.py +486 -0
- package/server/tests/test_status_broadcasts.py +425 -0
- package/workflows/{AI Assistant_workflow-1777421105154-0m4snkzjf.json → AI Assistant_workflow-1778504793388-ou1m1tz2x.json } +70 -266
- package/workflows/{AI Employee_workflow-1777720598005-u4cm858dv.json → AI Employee_example_workflow-1777720598005-u4cm858dv.json } +112 -112
- package/workflows/Claude Assistant_workflow-1778380124051-mdibn807c.json +709 -0
- package/client/dist/assets/ActionBar-vzPpSR77.js +0 -1
- package/client/dist/assets/ApiKeyInput-Ds7AKFe8.js +0 -1
- package/client/dist/assets/ApiKeyPanel-gfblELep.js +0 -1
- package/client/dist/assets/ApiUsageSection-BMNWTe2r.js +0 -1
- package/client/dist/assets/EmailPanel-B1Om64p5.js +0 -1
- package/client/dist/assets/OAuthPanel-CXyQYGBz.js +0 -1
- package/client/dist/assets/QrPairingPanel-BgNuI1we.js +0 -1
- package/client/dist/assets/RateLimitSection-YYK8sx1T.js +0 -1
- package/client/dist/assets/StatusCard-DuYA5hJR.js +0 -1
- package/client/dist/assets/index-D9tZfgvi.js +0 -363
- package/client/dist/assets/index-al7snTkG.css +0 -1
- package/client/src/components/credentials/providers.tsx +0 -177
- package/server/routers/google.py +0 -277
- package/server/routers/maps.py +0 -142
- package/server/routers/twitter.py +0 -365
- package/server/services/claude_code_service.py +0 -106
- package/server/services/memory.py +0 -159
- package/server/services/node_option_loaders/__init__.py +0 -77
- package/server/services/node_option_loaders/android_loaders.py +0 -55
- package/server/services/node_option_loaders/google_loaders.py +0 -97
- package/server/services/node_option_loaders/whatsapp_loaders.py +0 -69
- package/server/services/twitter_oauth.py +0 -411
- package/server/services/websocket_client.py +0 -29
- /package/server/{services/android → nodes/android/_relay}/__init__.py +0 -0
- /package/server/{services/android → nodes/android/_relay}/broadcaster.py +0 -0
- /package/server/{services/android → nodes/android/_relay}/manager.py +0 -0
- /package/server/{services/android → nodes/android/_relay}/protocol.py +0 -0
- /package/server/{services/browser_service.py → nodes/browser/_service.py} +0 -0
- /package/server/{services/whatsapp_service.py → nodes/whatsapp/_service.py} +0 -0
- /package/server/skills/{task_agent → assistant}/write-todos-skill/SKILL.md +0 -0
package/README.md
CHANGED
|
@@ -5,149 +5,185 @@
|
|
|
5
5
|
<a href="https://discord.gg/c9pCJ7d8Ce" target="_blank"><img src="https://img.shields.io/discord/1455977012308086895?logo=discord&logoColor=white&label=Discord" alt="Discord"></a>
|
|
6
6
|
<a href="https://deepwiki.com/trohitg/MachinaOS" target="_blank"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki"></a>
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Your own AI assistant that does real work. Drag, drop, and connect AI agents to your email, calendar, messages, phone, and 50+ other services. Runs on your own machine — your data stays with you.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
## See It In Action ↓
|
|
13
|
-
|
|
14
|
-
https://github.com/user-attachments/assets/a30979e0-8066-4412-b466-cc3a70bcf3dd
|
|
15
|
-
|
|
16
|
-
## Full Capabilities ↓
|
|
17
|
-
|
|
18
|
-
https://github.com/user-attachments/assets/9785aefb-9424-4a80-bd83-bb1205fc70af
|
|
19
|
-
|
|
20
|
-
## Prerequisites
|
|
21
|
-
|
|
22
|
-
- **Node.js 22+** - https://nodejs.org/
|
|
23
|
-
- **Python 3.12+** - https://python.org/
|
|
10
|
+
No code required. No subscription. No usage limits. Bring your own API keys (or run models locally with Ollama / LM Studio for free).
|
|
24
11
|
|
|
25
12
|
## Quick Start
|
|
26
13
|
|
|
14
|
+
**Prerequisites:** Node.js 22+, Python 3.12+
|
|
15
|
+
|
|
27
16
|
```bash
|
|
28
17
|
npm install -g machinaos
|
|
29
18
|
machina start
|
|
30
19
|
```
|
|
31
20
|
|
|
32
|
-
Open http://localhost:3000
|
|
21
|
+
Open http://localhost:3000 and click **Credentials** to connect your first AI provider.
|
|
33
22
|
|
|
34
23
|
<details>
|
|
35
|
-
<summary><b>
|
|
24
|
+
<summary><b>Run from source (for contributors)</b></summary>
|
|
36
25
|
|
|
37
|
-
**Linux/macOS:**
|
|
38
26
|
```bash
|
|
39
|
-
|
|
27
|
+
npm install -g pnpm
|
|
28
|
+
git clone https://github.com/trohitg/MachinaOS.git
|
|
29
|
+
cd MachinaOS
|
|
30
|
+
pnpm install
|
|
31
|
+
pnpm run dev
|
|
40
32
|
```
|
|
41
33
|
|
|
42
|
-
|
|
43
|
-
```powershell
|
|
44
|
-
iwr -useb https://raw.githubusercontent.com/trohitg/MachinaOS/main/install.ps1 | iex
|
|
45
|
-
```
|
|
34
|
+
The `dev` task starts the Python backend, Vite client, WhatsApp service, and Temporal in parallel. See [SETUP.md](docs-internal/SETUP.md) and [SCRIPTS.md](docs-internal/SCRIPTS.md) for details, and [CONTRIBUTING.md](CONTRIBUTING.md) for the codebase map and contribution recipes.
|
|
46
35
|
|
|
47
36
|
</details>
|
|
48
37
|
|
|
49
|
-
|
|
50
|
-
<summary><b>Clone & Run (for developers)</b></summary>
|
|
38
|
+
## See It In Action ↓
|
|
51
39
|
|
|
52
|
-
|
|
40
|
+
https://github.com/user-attachments/assets/5ee81bb3-12cf-4755-8532-7470c6f1d841
|
|
53
41
|
|
|
54
|
-
|
|
55
|
-
npm install -g pnpm # one-time
|
|
56
|
-
git clone https://github.com/trohitg/MachinaOS.git
|
|
57
|
-
cd MachinaOS
|
|
58
|
-
pnpm install
|
|
59
|
-
pnpm run build
|
|
60
|
-
pnpm run dev
|
|
61
|
-
```
|
|
42
|
+
## Full Capabilities ↓
|
|
62
43
|
|
|
63
|
-
|
|
44
|
+
https://github.com/user-attachments/assets/5798fe61-8d26-4d3a-90aa-189bf4eec79f
|
|
45
|
+
|
|
46
|
+
## How It Works
|
|
47
|
+
|
|
48
|
+
[](https://raw.githubusercontent.com/trohitg/MachinaOS/main/docs/diagrams/how-it-works.svg)
|
|
49
|
+
|
|
50
|
+
Pick nodes from the palette, drag them onto a canvas, connect them with lines, give your AI agent some memory and skills, and hit Play. Or **deploy** the workflow so it runs forever in the background — waiting for emails, responding to messages, checking in on a schedule, doing the work you'd rather not.
|
|
51
|
+
|
|
52
|
+
## Three Workflows You Get on Day One
|
|
53
|
+
|
|
54
|
+
[](https://raw.githubusercontent.com/trohitg/MachinaOS/main/docs/diagrams/default-workflows.svg)
|
|
55
|
+
|
|
56
|
+
The first time you open MachinaOS, three example workflows load automatically. Open them on the canvas to see exactly how the pieces fit together, then edit any node and save your own version.
|
|
64
57
|
|
|
65
58
|
## What You Can Build
|
|
66
59
|
|
|
67
|
-
### Personal AI
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
### Automate Your Google Workspace
|
|
71
|
-
- Send and search emails
|
|
72
|
-
- Create calendar events
|
|
73
|
-
- Upload files to Drive
|
|
74
|
-
- Update spreadsheets
|
|
75
|
-
- Manage tasks and contacts
|
|
76
|
-
|
|
77
|
-
### Universal Email (IMAP/SMTP)
|
|
78
|
-
- Send, read, search, and manage emails via the Himalaya CLI
|
|
79
|
-
- Works with Gmail, Outlook, Yahoo, iCloud, ProtonMail, Fastmail, or any custom IMAP/SMTP server
|
|
80
|
-
- Polling-based trigger for incoming email workflows
|
|
81
|
-
|
|
82
|
-
### Control Your Devices
|
|
83
|
-
- Send WhatsApp messages automatically
|
|
84
|
-
- Post to Twitter/X
|
|
85
|
-
- Send Telegram messages via bot
|
|
86
|
-
- Control your Android phone (WiFi, Bluetooth, apps, camera)
|
|
87
|
-
- Schedule tasks and reminders
|
|
88
|
-
|
|
89
|
-
### Browse the Web
|
|
90
|
-
- Interactive browser automation with accessibility-tree navigation (agent-browser)
|
|
91
|
-
- Web scraping with BeautifulSoup or Playwright (crawlee)
|
|
92
|
-
- Route requests through residential proxies with geo-targeting
|
|
93
|
-
- Run Apify actors for social media and search engine scraping
|
|
94
|
-
- DuckDuckGo, Brave, Serper (Google), and Perplexity search
|
|
95
|
-
|
|
96
|
-
### Plan Complex Tasks
|
|
97
|
-
- `writeTodos` tool lets any AI agent create and update structured task lists
|
|
98
|
-
- Real-time checklist rendering in the UI
|
|
99
|
-
- Plan-work-update loop with `pending` / `in_progress` / `completed` states
|
|
100
|
-
|
|
101
|
-
### Process Documents
|
|
102
|
-
- Parse PDFs and documents
|
|
103
|
-
- Search your files with AI
|
|
104
|
-
|
|
105
|
-
### Build Agent Teams
|
|
60
|
+
### Personal AI assistants that remember
|
|
61
|
+
Build a chat assistant that knows your calendar, reads your inbox, and follows up on tasks. Conversations are saved as readable markdown so you can edit what your agent remembers. Long-term memory uses vector search so years of conversation stay accessible.
|
|
106
62
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
| AI Employee |
|
|
110
|
-
| (Team Lead) |
|
|
111
|
-
+--------+---------+
|
|
112
|
-
| input-teammates
|
|
113
|
-
+-----------------+------------------+
|
|
114
|
-
| | |
|
|
115
|
-
+------v------+ +------v------+ +-------v-----+
|
|
116
|
-
| Coding Agent| | Web Agent | | Task Agent |
|
|
117
|
-
+-------------+ +-------------+ +-------------+
|
|
118
|
-
```
|
|
63
|
+
### Agent teams that delegate
|
|
64
|
+
Hire an **AI Employee** as a team lead. Connect specialized agents — a Coding Agent, a Web Agent, a Productivity Agent — and the team lead automatically figures out who to delegate which subtask to. Each agent has its own memory, tools, and skills.
|
|
119
65
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
- **Delegation Tools** - Connected agents become `delegate_to_*` tools automatically
|
|
123
|
-
- **16 Specialized Agents** - Android, Coding, Web, Task, Social, Travel, Tool, Productivity, Payments, Consumer, Autonomous, Orchestrator, AI Employee, RLM, Claude Code, Deep Agent
|
|
124
|
-
- **Team Monitor** - Real-time visualization of team operations
|
|
66
|
+
### Task automations that run themselves
|
|
67
|
+
Schedule recurring jobs ("every weekday at 9 AM, summarize my unread emails"), respond to incoming events ("when a customer texts on WhatsApp, draft a reply"), or build complex multi-step pipelines that run in the background. Workflows run reliably even if your computer restarts.
|
|
125
68
|
|
|
126
|
-
###
|
|
127
|
-
-
|
|
128
|
-
-
|
|
129
|
-
-
|
|
130
|
-
-
|
|
69
|
+
### Email, calendar, and document workflows
|
|
70
|
+
- Send and search Gmail, schedule and update Calendar events
|
|
71
|
+
- Upload to Drive, edit Sheets, manage Tasks and Contacts
|
|
72
|
+
- Read inbox via IMAP from Gmail, Outlook, Yahoo, iCloud, ProtonMail, Fastmail, or any custom server
|
|
73
|
+
- Parse PDFs and documents into searchable knowledge bases
|
|
131
74
|
|
|
132
|
-
|
|
75
|
+
### Messaging across every platform
|
|
76
|
+
Send and receive on **WhatsApp** (with newsletter channels, groups, contacts), **Telegram** (with bot owner detection), **Twitter/X** (post, reply, search, look up users), and a unified social node that abstracts over Discord, Slack, Signal, SMS, Matrix, Teams, and more.
|
|
133
77
|
|
|
134
|
-
|
|
78
|
+
### Phone control from a workflow
|
|
79
|
+
Pair your Android phone via QR code and control it from any agent: read battery + network status, launch apps, toggle WiFi / Bluetooth / airplane mode, take photos, read environmental sensors, manage media playback. 16 device services available.
|
|
135
80
|
|
|
136
|
-
|
|
81
|
+
### Web automation & research
|
|
82
|
+
- **Interactive browser** with accessibility-tree navigation (click, type, screenshot) — your agent can use websites the way you do
|
|
83
|
+
- **Web scraping** with Crawlee (static + JavaScript-rendered pages) and Apify actors (Instagram, TikTok, LinkedIn, Facebook, YouTube, Google Search)
|
|
84
|
+
- **Search APIs**: DuckDuckGo (free), Brave, Serper (Google), Perplexity (AI answers with citations)
|
|
85
|
+
- **Residential proxies** with geo-targeting and automatic provider rotation
|
|
137
86
|
|
|
138
|
-
|
|
87
|
+
### Code execution that's actually safe
|
|
88
|
+
Run Python, JavaScript, and TypeScript code from any workflow. Each workflow gets its own isolated workspace folder — no chance of an agent touching files outside its sandbox. The **Process Manager** node owns long-running tasks like dev servers, builds, and watchers, with live output streaming to a Terminal tab in the UI.
|
|
139
89
|
|
|
140
|
-
|
|
90
|
+
### Pay bills, take payments
|
|
91
|
+
**Stripe** integration with action node (charge customers, manage subscriptions) and webhook receiver (react to payment events in real time). Same pattern works for any service with a CLI.
|
|
141
92
|
|
|
142
|
-
|
|
93
|
+
### Build your own knowledge base
|
|
94
|
+
RAG pipeline out of the box: parse PDFs and HTML, chunk into searchable pieces, embed locally or via OpenAI, store in ChromaDB / Qdrant / Pinecone, and query from any agent.
|
|
143
95
|
|
|
144
|
-
##
|
|
96
|
+
## AI Capabilities
|
|
97
|
+
|
|
98
|
+
### 11 LLM providers — bring your own keys or run locally
|
|
99
|
+
|
|
100
|
+
| Provider | Notes |
|
|
101
|
+
|--------------|--------------------------------------------------------------------------|
|
|
102
|
+
| OpenAI | GPT-5 family, GPT-4.1, o-series reasoning models, GPT-4o |
|
|
103
|
+
| Anthropic | Claude Opus 4.x, Sonnet 4.x, Haiku 4.5 — with extended thinking |
|
|
104
|
+
| Google | Gemini 3 Pro/Flash, 2.5 Pro/Flash — with reasoning budgets |
|
|
105
|
+
| DeepSeek | DeepSeek V3, DeepSeek Reasoner |
|
|
106
|
+
| Kimi | Kimi K2.5, Kimi K2 Thinking |
|
|
107
|
+
| Mistral | Mistral Large/Small, Codestral |
|
|
108
|
+
| Groq | Llama 3/4, Qwen3, GPT-OSS (ultra-fast inference) |
|
|
109
|
+
| Cerebras | Llama 3.1, Qwen-3-235b (custom AI hardware) |
|
|
110
|
+
| OpenRouter | 200+ models via one unified API |
|
|
111
|
+
| **Ollama** | Run any local model on your machine — free, private, offline |
|
|
112
|
+
| **LM Studio**| Run any local model with a desktop app — free, private, offline |
|
|
113
|
+
|
|
114
|
+
Local providers (Ollama, LM Studio) are first-class — context length, vision support, and tool-use capability are detected automatically from your running server. No paid API needed.
|
|
115
|
+
|
|
116
|
+
### 17 specialized agent types
|
|
117
|
+
|
|
118
|
+
Pick the right agent for the job:
|
|
119
|
+
|
|
120
|
+
| Agent | Specialized for |
|
|
121
|
+
|--------------------|--------------------------------------------------------------------------|
|
|
122
|
+
| **AI Employee** / **Orchestrator** | Team leads that coordinate other agents |
|
|
123
|
+
| Android Agent | Phone control |
|
|
124
|
+
| Web Agent | Browser automation, scraping, search |
|
|
125
|
+
| Coding Agent | Writing and running code (Python / JS / TS) |
|
|
126
|
+
| Productivity Agent | Gmail, Calendar, Drive, Sheets, Tasks, Contacts |
|
|
127
|
+
| Social Agent | WhatsApp, Telegram, Twitter messaging |
|
|
128
|
+
| Task Agent | Scheduling, reminders, cron jobs |
|
|
129
|
+
| Travel Agent | Maps, location lookup, planning |
|
|
130
|
+
| Payments Agent | Stripe + financial workflows |
|
|
131
|
+
| Consumer Agent | Customer support, order management |
|
|
132
|
+
| Deep Agent | LangChain DeepAgents with filesystem tools + sub-agent delegation |
|
|
133
|
+
| Claude Code Agent | Anthropic's Claude Code CLI for advanced coding sessions |
|
|
134
|
+
| Codex Agent | OpenAI Codex CLI integration |
|
|
135
|
+
| RLM Agent | Recursive Language Model — write code that calls itself recursively |
|
|
136
|
+
| Autonomous Agent | Code-mode loops that reduce token usage 80-98% |
|
|
137
|
+
| Tool Agent | General-purpose tool orchestration |
|
|
138
|
+
|
|
139
|
+
Team leads automatically expose every connected agent as a `delegate_to_*` tool — the AI decides who to hand work off to based on the task.
|
|
140
|
+
|
|
141
|
+
### Skills you can edit yourself
|
|
145
142
|
|
|
146
|
-
|
|
143
|
+
Skills are short markdown files that teach an agent how to do something well — when to use which tool, what arguments to pass, common mistakes to avoid. Edit them in the UI; the changes apply immediately. Built-in skills cover Android control, Google Workspace, social messaging, web research, coding, terminal use (Bash, PowerShell, WSL, Nushell), and more.
|
|
147
144
|
|
|
148
|
-
|
|
145
|
+
### Memory that scales with your context window
|
|
146
|
+
|
|
147
|
+
Agents track token usage and automatically compact long conversations when you hit half your model's context limit. Compaction summarizes in five sections — Task Overview, Current State, Important Discoveries, Next Steps, Context to Preserve — so the agent picks up exactly where it left off. For Anthropic and OpenAI, native API compaction is used; everywhere else, the agent summarizes itself.
|
|
148
|
+
|
|
149
|
+
### Cost tracking, built in
|
|
150
|
+
|
|
151
|
+
Every LLM call and API request is tracked with USD cost. See per-provider spend in the Credentials panel. Configure your own pricing in `pricing.json` if you switch providers mid-flight.
|
|
152
|
+
|
|
153
|
+
## The Canvas
|
|
154
|
+
|
|
155
|
+
- **10 visual themes** — light, dark, Renaissance, Greek, Edo, Steampunk, Atomic, Cyber, Wasteland, Rot, Plague, Surveillance — each with its own icon set, sound pack, and decorative ornaments. Pick the vibe that matches your workflow.
|
|
156
|
+
- **Drag-to-map outputs** from one node's output directly onto another's input fields.
|
|
157
|
+
- **Live execution animations** — nodes glow while running, show iteration count for AI agents, and surface errors inline.
|
|
158
|
+
- **Multi-tab Console** — chat with trigger nodes, watch console logs, and view terminal output side by side.
|
|
159
|
+
- **Component palette** with search, categories, and a Normal/Dev mode toggle that hides advanced nodes when you don't need them.
|
|
160
|
+
- **5-step onboarding wizard** for first-time users, replayable any time from Settings.
|
|
161
|
+
|
|
162
|
+
## Quick Setup Tour
|
|
163
|
+
|
|
164
|
+
1. **Install** with `npm install -g machinaos` (or run from source)
|
|
165
|
+
2. **Start** with `machina start` — opens at http://localhost:3000
|
|
166
|
+
3. **Connect a provider** — click the **Credentials** button, paste an API key or click through OAuth
|
|
167
|
+
4. **Drag a node** from the left palette onto the canvas
|
|
168
|
+
5. **Connect** outputs to inputs by dragging between handles
|
|
169
|
+
6. **Run** by clicking the play button on any node, or **Deploy** the whole workflow to run on its own forever
|
|
170
|
+
|
|
171
|
+
If anything goes wrong, the [Discord](https://discord.gg/c9pCJ7d8Ce) community is the fastest way to get help.
|
|
172
|
+
|
|
173
|
+
## For Developers
|
|
174
|
+
|
|
175
|
+
Want to add a node, LLM provider, skill, or integration? One Python file = one node. The backend owns all the schemas; the frontend renders from them automatically. No frontend code required for most extensions.
|
|
176
|
+
|
|
177
|
+
- **[CONTRIBUTING.md](CONTRIBUTING.md)** — codebase map, architecture diagrams, contribution recipes
|
|
178
|
+
- **[server/nodes/README.md](server/nodes/README.md)** — 5-minute plugin recipe + folder map
|
|
179
|
+
- **[docs-internal/](docs-internal/)** — deep-dive architecture docs (execution engine, Temporal, LLM layer, credentials, event system, performance, build pipeline)
|
|
180
|
+
- **[CLAUDE.md](CLAUDE.md)** — comprehensive project memory (great for AI-assisted contributions)
|
|
181
|
+
- **Hosted docs:** https://docs.zeenie.xyz/
|
|
182
|
+
- **DeepWiki:** https://deepwiki.com/trohitg/MachinaOS
|
|
183
|
+
|
|
184
|
+
## Community
|
|
149
185
|
|
|
150
|
-
|
|
186
|
+
[Discord](https://discord.gg/c9pCJ7d8Ce) — help, feature requests, and design discussions.
|
|
151
187
|
|
|
152
188
|
## License
|
|
153
189
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{f as u,n as d,o as p,p as m,q as f,r as g,k as x}from"./index-DNx1tG6T.js";import{j as l}from"./vendor-radix-BGeDhy8U.js";import{ac as b}from"./vendor-icons-BPyNc2rK.js";function h(r){const t=u.c(7),a=d(),n=p(),s=m(),i=f(),o=g();if(!r)return null;let e;return t[0]!==n||t[1]!==i||t[2]!==r||t[3]!==s||t[4]!==o||t[5]!==a?(e={whatsapp:a,android:n,twitter:s,google:i,telegram:o}[r]??null,t[0]=n,t[1]=i,t[2]=r,t[3]=s,t[4]=o,t[5]=a,t[6]=e):e=t[6],e}const y=r=>{const t=u.c(7),{actions:a,loading:n}=r;let s;if(t[0]!==a||t[1]!==n){let o;t[3]!==n?(o=e=>{const c=n===e.key;return l.jsxs(x,{intent:e.intent,onClick:e.onClick,disabled:e.disabled||c,children:[c?l.jsx(b,{className:"h-4 w-4 animate-spin"}):e.icon,e.label]},e.key)},t[3]=n,t[4]=o):o=t[4],s=a.filter(j).map(o),t[0]=a,t[1]=n,t[2]=s}else s=t[2];let i;return t[5]!==s?(i=l.jsx("div",{className:"flex justify-center gap-2 border-t border-border pt-3",children:s}),t[5]=s,t[6]=i):i=t[6],i};function j(r){return!r.hidden}export{y as A,h as u};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as s}from"./vendor-radix-BGeDhy8U.js";import{b as j}from"./vendor-react-CxXU_nq3.js";import{I as u,B as c}from"./index-DNx1tG6T.js";import{bb as d,bc as N,ac as b,aj as v,ap as w,aa as y}from"./vendor-icons-BPyNc2rK.js";const I=({value:l,onChange:n,onSave:m,onDelete:i,placeholder:x="Enter API key...",loading:o=!1,isStored:a=!1,disabled:e=!1,saveLabel:h="Validate",savedLabel:p="Valid"})=>{const[t,f]=j.useState(!1);return s.jsxs("div",{className:"flex w-full items-stretch gap-1",children:[s.jsxs("div",{className:"relative flex-1",children:[s.jsx(u,{type:t?"text":"password",value:l,onChange:r=>n(r.target.value),placeholder:x,disabled:e,className:"font-mono pr-9"}),s.jsx("button",{type:"button",onClick:()=>f(r=>!r),className:"absolute top-1/2 right-2 -translate-y-1/2 text-muted-foreground hover:text-foreground","aria-label":t?"Hide key":"Show key",children:t?s.jsx(d,{className:"h-4 w-4"}):s.jsx(N,{className:"h-4 w-4"})})]}),s.jsxs(c,{variant:"default",onClick:m,disabled:!l.trim()||e||o,children:[o?s.jsx(b,{className:"h-4 w-4 animate-spin"}):a?s.jsx(v,{className:"h-4 w-4"}):s.jsx(w,{className:"h-4 w-4"}),a?p:h]}),a&&i&&s.jsx(c,{variant:"destructive",size:"icon",onClick:i,disabled:e,children:s.jsx(y,{className:"h-4 w-4"})})]})};export{I as A};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as s}from"./vendor-radix-BGeDhy8U.js";import{u as E,A as V,a as P,b as U,c as z,d as R,e as K,B as H,f as F,N as M,C as O,g as q,h as G,i as I,j as T,L as J,I as Q,k as W}from"./index-DNx1tG6T.js";import{A as X}from"./ApiKeyInput-DljozMIZ.js";import{u as Y,P as Z}from"./RateLimitSection-B2lBVQs0.js";import{b as A}from"./vendor-react-CxXU_nq3.js";import{ba as ee,ac as L,b7 as se,aj as ae}from"./vendor-icons-BPyNc2rK.js";import{A as te}from"./ApiUsageSection-FWVtg8Sd.js";import"./vendor-flow-apeQB2hf.js";import"./vendor-query-to9T1kjL.js";import"./vendor-misc-4my8ai2A.js";import"./vendor-markdown-Bx_GU1E7.js";const D=N=>{const e=F.c(8),{label:t,value:p,className:a}=N;let l;e[0]!==t?(l=s.jsx("span",{className:"text-xs text-muted-foreground",children:t}),e[0]=t,e[1]=l):l=e[1];const n=`text-lg font-semibold ${a??""}`;let i;e[2]!==n||e[3]!==p?(i=s.jsx("span",{className:n,children:p}),e[2]=n,e[3]=p,e[4]=i):i=e[4];let o;return e[5]!==l||e[6]!==i?(o=s.jsxs("div",{className:"flex flex-col",children:[l,i]}),e[5]=l,e[6]=i,e[7]=o):o=e[7],o},le=({providerId:N,providerName:e})=>{const{getProviderUsageSummary:t,isConnected:p}=E(),[a,l]=A.useState(null),[n,i]=A.useState(!1),[o,h]=A.useState(!1),d=A.useCallback(async()=>{if(p){i(!0);try{const r=await t();l(r.find(c=>c.provider===N)??null)}finally{i(!1)}}},[p,N,t]);return A.useEffect(()=>{o&&d()},[o,d]),s.jsx(V,{type:"single",collapsible:!0,onValueChange:r=>h(r==="usage"),children:s.jsxs(P,{value:"usage",children:[s.jsx(U,{children:s.jsxs("span",{className:"flex items-center gap-2",children:[s.jsx(ee,{className:"h-4 w-4"})," Usage & Costs"]})}),s.jsx(z,{children:n?s.jsx("div",{className:"flex justify-center p-4",children:s.jsx(L,{className:"h-4 w-4 animate-spin text-muted-foreground"})}):!a||a.execution_count===0?s.jsx(R,{variant:"info",children:s.jsxs(K,{children:["No usage data yet for ",e]})}):s.jsxs("div",{className:"flex w-full flex-col gap-4",children:[s.jsxs("div",{className:"flex flex-wrap gap-4",children:[s.jsx(D,{label:"Total Tokens",value:a.total_tokens.toLocaleString(),className:"text-dracula-cyan"}),s.jsx(D,{label:"Total Cost",value:`$${a.total_cost.toFixed(4)}`,className:"text-dracula-green"}),s.jsx(D,{label:"Executions",value:a.execution_count,className:"text-dracula-purple"})]}),s.jsxs("div",{className:"overflow-hidden rounded-md border border-border",children:[s.jsxs("div",{className:"grid grid-cols-2 divide-x divide-border border-b border-border",children:[s.jsxs("div",{className:"px-3 py-2 text-sm",children:[s.jsx("div",{className:"text-xs text-muted-foreground",children:"Input Tokens"}),s.jsxs("div",{children:[a.total_input_tokens.toLocaleString()," ",s.jsxs("span",{className:"ml-1 text-dracula-green",children:["($",a.total_input_cost.toFixed(4),")"]})]})]}),s.jsxs("div",{className:"px-3 py-2 text-sm",children:[s.jsx("div",{className:"text-xs text-muted-foreground",children:"Output Tokens"}),s.jsxs("div",{children:[a.total_output_tokens.toLocaleString()," ",s.jsxs("span",{className:"ml-1 text-dracula-green",children:["($",a.total_output_cost.toFixed(4),")"]})]})]})]}),a.total_cache_cost>0&&s.jsxs("div",{className:"px-3 py-2 text-sm",children:[s.jsx("span",{className:"text-xs text-muted-foreground",children:"Cache Cost: "}),s.jsxs("span",{className:"text-dracula-green",children:["$",a.total_cache_cost.toFixed(4)]})]})]}),a.models.length>1&&s.jsxs("div",{className:"overflow-hidden rounded-md border border-border",children:[s.jsx("div",{className:"border-b border-border bg-muted px-3 py-1.5 text-xs font-semibold",children:"By Model"}),s.jsx("div",{className:"divide-y divide-border",children:a.models.map(r=>s.jsxs("div",{className:"grid grid-cols-[1fr_auto] items-center gap-3 px-3 py-2 text-sm",children:[s.jsx("code",{className:"text-xs",children:r.model}),s.jsxs("span",{className:"text-dracula-green",children:["$",r.total_cost.toFixed(4)]})]},r.model))})]}),s.jsxs(H,{size:"sm",variant:"outline",onClick:d,disabled:n,children:[n?s.jsx(L,{className:"h-3 w-3 animate-spin"}):s.jsx(se,{className:"h-3 w-3"}),"Refresh"]})]})})]})})},ve=N=>{const e=F.c(71),{config:t,visible:p}=N,a=Y(t,p),l=t.fields?.[0];let n,i,o,h;if(e[0]!==t.color||e[1]!==t.fields||e[2]!==t.iconRef||e[3]!==t.id||e[4]!==t.name||e[5]!==l||e[6]!==a.actions||e[7]!==a.error||e[8]!==a.form||e[9]!==a.loading||e[10]!==a.stored||e[11]!==a.values){const _=(t.fields??[]).slice(1),g=l?a.values[l.key]??"":"",x=a.stored;n="flex flex-col gap-5 p-5";let m;e[16]!==t.color?(m={color:t.color},e[16]=t.color,e[17]=m):m=e[17];let u;e[18]!==t.iconRef?(u=s.jsx(M,{icon:t.iconRef,className:"h-12 w-12 text-2xl"}),e[18]=t.iconRef,e[19]=u):u=e[19];let f;e[20]!==m||e[21]!==u?(f=s.jsx("div",{className:"rounded-lg bg-tint-soft",style:m,children:u}),e[20]=m,e[21]=u,e[22]=f):f=e[22];let j;e[23]!==t.name?(j=s.jsx(O,{className:"text-lg",children:t.name}),e[23]=t.name,e[24]=j):j=e[24];let b;e[25]!==f||e[26]!==j?(b=s.jsxs("div",{className:"flex items-center gap-3",children:[f,j]}),e[25]=f,e[26]=j,e[27]=b):b=e[27];let C;e[28]!==x?(C=x&&s.jsxs(q,{variant:"success",className:"gap-1",children:[s.jsx(ae,{className:"h-3 w-3"}),"Connected"]}),e[28]=x,e[29]=C):C=e[29];let k;e[30]!==C||e[31]!==b?(k=s.jsxs(G,{className:"flex flex-row items-center justify-between gap-3 space-y-0 pb-3",children:[b,C]}),e[30]=C,e[31]=b,e[32]=k):k=e[32];let S;e[33]!==t.id||e[34]!==l||e[35]!==g||e[36]!==a.actions||e[37]!==a.form||e[38]!==a.loading||e[39]!==x?(S=l&&s.jsx(X,{value:g,onChange:v=>a.form.setFieldValue(l.key,v),onSave:()=>a.actions.validate(t.id,g.trim()),onDelete:x?async()=>{await a.actions.remove(t.id),l.key!=="apiKey"&&await a.actions.remove(l.key)}:void 0,placeholder:l.placeholder,loading:a.loading==="validate",isStored:x,saveLabel:l.key==="apiKey"?"Validate":"Fetch",savedLabel:l.key==="apiKey"?"Valid":"Connected"}),e[33]=t.id,e[34]=l,e[35]=g,e[36]=a.actions,e[37]=a.form,e[38]=a.loading,e[39]=x,e[40]=S):S=e[40];let w;e[41]!==S?(w=s.jsx(I,{children:S}),e[41]=S,e[42]=w):w=e[42],e[43]!==k||e[44]!==w?(i=s.jsxs(T,{children:[k,w]}),e[43]=k,e[44]=w,e[45]=i):i=e[45],e[46]!==a.error?(o=a.error&&s.jsx(R,{variant:"destructive",children:s.jsx(K,{children:a.error})}),e[46]=a.error,e[47]=o):o=e[47];let $;e[48]!==a.actions||e[49]!==a.form||e[50]!==a.loading||e[51]!==a.values?($=v=>s.jsx(ie,{fieldKey:v.key,label:v.label,placeholder:v.placeholder,help:v.help,secret:v.secret,value:a.values[v.key]??"",onChange:B=>a.form.setFieldValue(v.key,B),onSave:()=>a.actions.save(v.key,a.values[v.key]??""),loading:a.loading==="save"},v.key),e[48]=a.actions,e[49]=a.form,e[50]=a.loading,e[51]=a.values,e[52]=$):$=e[52],h=_.map($),e[0]=t.color,e[1]=t.fields,e[2]=t.iconRef,e[3]=t.id,e[4]=t.name,e[5]=l,e[6]=a.actions,e[7]=a.error,e[8]=a.form,e[9]=a.loading,e[10]=a.stored,e[11]=a.values,e[12]=n,e[13]=i,e[14]=o,e[15]=h}else n=e[12],i=e[13],o=e[14],h=e[15];let d;e[53]!==t.hasDefaults||e[54]!==t.id?(d=t.hasDefaults&&s.jsx(Z,{providerId:t.id}),e[53]=t.hasDefaults,e[54]=t.id,e[55]=d):d=e[55];let r;e[56]!==t.hasDefaults||e[57]!==t.id||e[58]!==t.name?(r=t.hasDefaults&&s.jsx(le,{providerId:t.id,providerName:t.name}),e[56]=t.hasDefaults,e[57]=t.id,e[58]=t.name,e[59]=r):r=e[59];let c;e[60]!==t.name||e[61]!==t.usageService?(c=t.usageService&&s.jsx(te,{service:t.usageService,serviceName:t.name}),e[60]=t.name,e[61]=t.usageService,e[62]=c):c=e[62];let y;return e[63]!==n||e[64]!==i||e[65]!==o||e[66]!==h||e[67]!==d||e[68]!==r||e[69]!==c?(y=s.jsxs("div",{className:n,children:[i,o,h,d,r,c]}),e[63]=n,e[64]=i,e[65]=o,e[66]=h,e[67]=d,e[68]=r,e[69]=c,e[70]=y):y=e[70],y},ie=N=>{const e=F.c(23),{fieldKey:t,label:p,placeholder:a,help:l,secret:n,value:i,onChange:o,onSave:h,loading:d}=N,r=`cred-${t}`;let c;e[0]!==p||e[1]!==r?(c=s.jsx(J,{htmlFor:r,className:"text-sm font-medium",children:p}),e[0]=p,e[1]=r,e[2]=c):c=e[2];const y=`cred-${t}`,_=n?"password":"text";let g;e[3]!==o?(g=b=>o(b.target.value),e[3]=o,e[4]=g):g=e[4];let x;e[5]!==a||e[6]!==y||e[7]!==_||e[8]!==g||e[9]!==i?(x=s.jsx(Q,{id:y,type:_,value:i,onChange:g,placeholder:a,className:"flex-1"}),e[5]=a,e[6]=y,e[7]=_,e[8]=g,e[9]=i,e[10]=x):x=e[10];let m;e[11]!==d||e[12]!==h?(m=s.jsx(W,{intent:"save",onClick:h,disabled:d,children:"Save"}),e[11]=d,e[12]=h,e[13]=m):m=e[13];let u;e[14]!==x||e[15]!==m?(u=s.jsxs("div",{className:"flex gap-2",children:[x,m]}),e[14]=x,e[15]=m,e[16]=u):u=e[16];let f;e[17]!==l?(f=l&&s.jsx("p",{className:"text-xs text-muted-foreground",children:l}),e[17]=l,e[18]=f):f=e[18];let j;return e[19]!==c||e[20]!==u||e[21]!==f?(j=s.jsx(T,{children:s.jsxs(I,{className:"flex flex-col gap-2 pt-4",children:[c,u,f]})}),e[19]=c,e[20]=u,e[21]=f,e[22]=j):j=e[22],j};export{ve as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as e}from"./vendor-radix-BGeDhy8U.js";import{u as h,g as u,A as g,a as b,b as v,c as N,d as y,e as w,B as A,f as C}from"./index-DNx1tG6T.js";import{b as x}from"./vendor-react-CxXU_nq3.js";import{ba as _,ac as f,b7 as S}from"./vendor-icons-BPyNc2rK.js";const E=({service:d,serviceName:s})=>{const{getAPIUsageSummary:c,isConnected:i}=h(),[a,l]=x.useState(null),[o,t]=x.useState(!1),r=x.useCallback(async()=>{if(i){t(!0);try{const n=await c(d);l(n.find(j=>j.service===d)??null)}finally{t(!1)}}},[i,d,c]);x.useEffect(()=>{r()},[r]);const p=a?e.jsxs(u,{variant:"success",children:["$",a.total_cost.toFixed(4)]}):null;return e.jsx(g,{type:"single",collapsible:!0,children:e.jsxs(b,{value:"usage",children:[e.jsx(v,{children:e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx(_,{className:"h-4 w-4 text-dracula-yellow"}),"API Usage & Costs ",p]})}),e.jsx(N,{children:o?e.jsx("div",{className:"flex justify-center p-4",children:e.jsx(f,{className:"h-4 w-4 animate-spin text-muted-foreground"})}):a?e.jsxs("div",{className:"flex w-full flex-col gap-4",children:[e.jsxs("div",{className:"flex flex-wrap gap-4",children:[e.jsx(m,{label:"Total Cost",value:`$${a.total_cost.toFixed(4)}`,className:"text-dracula-green"}),e.jsx(m,{label:"API Calls",value:a.execution_count,className:"text-dracula-cyan"}),e.jsx(m,{label:"Resources",value:a.total_resources,className:"text-dracula-purple"})]}),a.operations?.length>0&&e.jsxs("div",{className:"overflow-hidden rounded-md border border-border",children:[e.jsx("div",{className:"border-b border-border bg-muted px-3 py-1.5 text-xs font-semibold",children:"Operations Breakdown"}),e.jsx("div",{className:"divide-y divide-border",children:a.operations.map(n=>e.jsxs("div",{className:"grid grid-cols-[1fr_auto] items-center gap-3 px-3 py-2 text-sm",children:[e.jsx("code",{className:"text-xs text-muted-foreground",children:n.operation}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsxs(u,{variant:"outline",children:[n.resource_count," resources"]}),e.jsxs(u,{variant:"success",children:["$",n.total_cost.toFixed(4)]})]})]},n.operation))})]}),e.jsxs(A,{size:"sm",variant:"outline",onClick:r,disabled:o,children:[o?e.jsx(f,{className:"h-3 w-3 animate-spin"}):e.jsx(S,{className:"h-3 w-3"}),"Refresh"]})]}):e.jsx(y,{variant:"info",children:e.jsxs(w,{children:["No usage data yet. Use ",s," nodes in your workflows to track costs."]})})})]})})},m=d=>{const s=C.c(8),{label:c,value:i,className:a}=d;let l;s[0]!==c?(l=e.jsx("span",{className:"text-xs text-muted-foreground",children:c}),s[0]=c,s[1]=l):l=s[1];const o=`text-lg font-semibold ${a??""}`;let t;s[2]!==o||s[3]!==i?(t=e.jsx("span",{className:o,children:i}),s[2]=o,s[3]=i,s[4]=t):t=s[4];let r;return s[5]!==l||s[6]!==t?(r=e.jsxs("div",{className:"flex flex-col",children:[l,t]}),s[5]=l,s[6]=t,s[7]=r):r=s[7],r};export{E as A};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as e}from"./vendor-radix-BGeDhy8U.js";import{b as l,h as B}from"./vendor-react-CxXU_nq3.js";import{v as G,P as I,R as j,_ as Y,T as z,u as J,t as Q,N as W,F as X,w as m,x as n,y as d,z as Z,D as c,E as $,G as ee,H as se,J as ae,M as p,I as f,K as re,d as oe,e as te,k as M}from"./index-DNx1tG6T.js";import{S as ie}from"./StatusCard-BlufvZD-.js";import{bb as le,bc as me,ac as F}from"./vendor-icons-BPyNc2rK.js";import"./vendor-flow-apeQB2hf.js";import"./vendor-query-to9T1kjL.js";import"./vendor-misc-4my8ai2A.js";import"./vendor-markdown-Bx_GU1E7.js";const R=[{label:"Gmail",value:"gmail"},{label:"Outlook / Office 365",value:"outlook"},{label:"Yahoo Mail",value:"yahoo"},{label:"iCloud Mail",value:"icloud"},{label:"ProtonMail (Bridge)",value:"protonmail"},{label:"Fastmail",value:"fastmail"},{label:"Custom / Self-hosted",value:"custom"}],ne={gmail:"Use an App Password from Google Account > Security > 2-Step Verification.",outlook:"Use your account password or an App Password.",yahoo:"Use an App Password from Yahoo Account Security.",icloud:"Use an App-Specific Password from your Apple ID.",protonmail:"Requires ProtonMail Bridge running locally (127.0.0.1).",fastmail:"Use an App Password from Settings > Privacy & Security.",custom:"Enter credentials for your self-hosted IMAP/SMTP server below."},de=R.map(u=>u.value);function ce(u){return G({provider:Y(de),address:j().min(1,"Email address is required").pipe(z("Enter a valid email address")),password:u?j().min(1,"Password is required"):j().optional(),imapHost:j().optional(),imapPort:I().int().min(1).max(65535).optional(),smtpHost:j().optional(),smtpPort:I().int().min(1).max(65535).optional()}).superRefine((x,o)=>{x.provider==="custom"&&(x.imapHost?.trim()||o.addIssue({code:"custom",path:["imapHost"],message:"IMAP host is required for custom provider"}),x.smtpHost?.trim()||o.addIssue({code:"custom",path:["smtpHost"],message:"SMTP host is required for custom provider"}))})}const T={provider:"gmail",address:"",password:"",imapHost:"",imapPort:993,smtpHost:"",smtpPort:465},we=({config:u,visible:x})=>{const{saveApiKey:o,getStoredApiKey:h,hasStoredKey:k,removeApiKey:t,isConnected:_}=J(),[i,v]=l.useState(!1),[b,S]=l.useState(""),[P,g]=l.useState(null),[N,w]=l.useState(null),[y,U]=l.useState(!1),V=l.useMemo(()=>ce(!i),[i]),r=B({resolver:Q(V),defaultValues:T,mode:"onSubmit"}),A=r.watch("provider");l.useEffect(()=>{if(!x||!_)return;let s=!1;return(async()=>{try{const[a,H,K,L,E,q,C]=await Promise.all([h("email_provider"),h("email_address"),k("email_password"),h("email_imap_host"),h("email_imap_port"),h("email_smtp_host"),h("email_smtp_port")]);if(s)return;r.reset({provider:a||"gmail",address:H||"",password:"",imapHost:L||"",imapPort:E?parseInt(E,10):993,smtpHost:q||"",smtpPort:C?parseInt(C,10):465}),S(H||""),v(K)}catch{s||v(!1)}})(),()=>{s=!0}},[x,_]);const O=async s=>{g("save"),w(null);try{await o("email_provider",s.provider),await o("email_address",s.address.trim()),s.password?.trim()&&await o("email_password",s.password.trim()),s.provider==="custom"&&(s.imapHost&&await o("email_imap_host",s.imapHost.trim()),s.imapPort!=null&&await o("email_imap_port",String(s.imapPort)),s.smtpHost&&await o("email_smtp_host",s.smtpHost.trim()),s.smtpPort!=null&&await o("email_smtp_port",String(s.smtpPort))),v(!0),S(s.address.trim()),r.setValue("password","")}catch(a){w(a.message||"Failed to save email credentials")}finally{g(null)}},D=async()=>{g("remove"),w(null);try{await Promise.all([t("email_password"),t("email_address"),t("email_provider"),t("email_imap_host"),t("email_imap_port"),t("email_smtp_host"),t("email_smtp_port")]),v(!1),S(""),r.reset(T)}catch(s){w(s.message||"Failed to remove credentials")}finally{g(null)}};return e.jsxs("div",{className:"flex min-h-0 flex-1 flex-col gap-4 p-5",children:[e.jsx(ie,{icon:e.jsx(W,{icon:u.iconRef,className:"h-6 w-6 text-2xl"}),title:u.name,status:{stored:i,address:b},rows:[{label:"Status",ok:s=>s.stored,trueText:"Configured",falseText:"Not configured"},...i&&b?[{label:"Account",ok:()=>!0,trueText:b,falseText:""}]:[]]}),e.jsx(X,{...r,children:e.jsxs("form",{id:"email-form",onSubmit:r.handleSubmit(O),className:"flex flex-col gap-4",children:[e.jsx(m,{control:r.control,name:"provider",render:({field:s})=>e.jsxs(n,{children:[e.jsx(d,{children:"Provider"}),e.jsxs(Z,{value:s.value,onValueChange:s.onChange,children:[e.jsx(c,{children:e.jsx($,{children:e.jsx(ee,{placeholder:"Choose a provider"})})}),e.jsx(se,{children:R.map(a=>e.jsx(ae,{value:a.value,children:a.label},a.value))})]}),e.jsx(p,{})]})}),e.jsx(m,{control:r.control,name:"address",render:({field:s})=>e.jsxs(n,{children:[e.jsx(d,{children:"Email Address"}),e.jsx(c,{children:e.jsx(f,{placeholder:"you@example.com",...s})}),e.jsx(p,{})]})}),e.jsx(m,{control:r.control,name:"password",render:({field:s})=>e.jsxs(n,{children:[e.jsxs(d,{className:"flex items-center gap-2",children:["Password",i&&e.jsx("span",{className:"text-xs font-normal text-muted-foreground",children:"(leave blank to keep existing)"})]}),e.jsx(c,{children:e.jsxs("div",{className:"relative",children:[e.jsx(f,{type:y?"text":"password",placeholder:i?"••••••••":"App password or account password",className:"font-mono pr-9",...s}),e.jsx("button",{type:"button",onClick:()=>U(a=>!a),className:"absolute top-1/2 right-2 -translate-y-1/2 text-muted-foreground hover:text-foreground","aria-label":y?"Hide password":"Show password",children:y?e.jsx(le,{className:"h-4 w-4"}):e.jsx(me,{className:"h-4 w-4"})})]})}),e.jsx(re,{children:ne[A]}),e.jsx(p,{})]})}),A==="custom"&&e.jsxs("div",{className:"rounded-md border border-border bg-muted p-3",children:[e.jsx("div",{className:"mb-3 text-sm font-medium",children:"Custom IMAP / SMTP"}),e.jsxs("div",{className:"flex gap-3",children:[e.jsx(m,{control:r.control,name:"imapHost",render:({field:s})=>e.jsxs(n,{className:"flex-[2]",children:[e.jsx(d,{children:"IMAP Host"}),e.jsx(c,{children:e.jsx(f,{placeholder:"imap.example.com",...s})}),e.jsx(p,{})]})}),e.jsx(m,{control:r.control,name:"imapPort",render:({field:s})=>e.jsxs(n,{className:"flex-1",children:[e.jsx(d,{children:"IMAP Port"}),e.jsx(c,{children:e.jsx(f,{type:"number",min:1,max:65535,...s,value:s.value??"",onChange:a=>s.onChange(a.target.value===""?void 0:Number(a.target.value))})}),e.jsx(p,{})]})})]}),e.jsxs("div",{className:"mt-3 flex gap-3",children:[e.jsx(m,{control:r.control,name:"smtpHost",render:({field:s})=>e.jsxs(n,{className:"flex-[2]",children:[e.jsx(d,{children:"SMTP Host"}),e.jsx(c,{children:e.jsx(f,{placeholder:"smtp.example.com",...s})}),e.jsx(p,{})]})}),e.jsx(m,{control:r.control,name:"smtpPort",render:({field:s})=>e.jsxs(n,{className:"flex-1",children:[e.jsx(d,{children:"SMTP Port"}),e.jsx(c,{children:e.jsx(f,{type:"number",min:1,max:65535,...s,value:s.value??"",onChange:a=>s.onChange(a.target.value===""?void 0:Number(a.target.value))})}),e.jsx(p,{})]})})]})]})]})}),N&&e.jsx(oe,{variant:"destructive",children:e.jsx(te,{children:N})}),e.jsx("div",{className:"flex-1"}),e.jsxs("div",{className:"flex justify-center gap-2 border-t border-border pt-3",children:[e.jsxs(M,{intent:"save",type:"submit",form:"email-form",disabled:P==="save",children:[P==="save"&&e.jsx(F,{className:"h-4 w-4 animate-spin"}),"Save"]}),i&&e.jsxs(M,{intent:"stop",type:"button",onClick:D,disabled:P==="remove",children:[P==="remove"&&e.jsx(F,{className:"h-4 w-4 animate-spin"}),"Remove"]})]})]})};export{we as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as l}from"./vendor-radix-BGeDhy8U.js";import{f as O,L as P,I as B,k as D,d as H,e as z,N as Y}from"./index-DNx1tG6T.js";import{u as G}from"./RateLimitSection-B2lBVQs0.js";import{A as J,u as K}from"./ActionBar-DAHXJmEU.js";import{b as I}from"./vendor-react-CxXU_nq3.js";import{bb as M,bc as Q,ac as W,aq as X}from"./vendor-icons-BPyNc2rK.js";import{S as Z}from"./StatusCard-BlufvZD-.js";import{A as ee}from"./ApiUsageSection-FWVtg8Sd.js";import"./vendor-flow-apeQB2hf.js";import"./vendor-query-to9T1kjL.js";import"./vendor-misc-4my8ai2A.js";import"./vendor-markdown-Bx_GU1E7.js";const te=i=>{const e=O.c(7),{fields:t,form:c}=i;let s;if(e[0]!==t||e[1]!==c){let n;e[3]!==c?(n=o=>l.jsx(se,{field:o,form:c},o.key),e[3]=c,e[4]=n):n=e[4],s=t.map(n),e[0]=t,e[1]=c,e[2]=s}else s=e[2];let a;return e[5]!==s?(a=l.jsx("div",{className:"flex w-full flex-col gap-3",children:s}),e[5]=s,e[6]=a):a=e[6],a},se=({field:i,form:e})=>{const[t,c]=I.useState(!1),s=e.getFieldValue(i.key)??"",[a,n]=I.useState(s),o=!!i.secret;return I.useEffect(()=>{!a&&s&&n(s)},[s]),l.jsxs("div",{className:"grid gap-1.5",children:[l.jsxs(P,{htmlFor:`field-${i.key}`,className:"text-xs",children:[i.label,i.required&&l.jsx("span",{className:"ml-1 text-destructive",children:"*"})]}),l.jsxs("div",{className:"relative",children:[l.jsx(B,{id:`field-${i.key}`,type:o&&!t?"password":"text",value:a,onChange:r=>{const d=r.target.value;n(d),e.setFieldValue(i.key,d)},placeholder:i.placeholder,className:o?"font-mono pr-9":"font-mono"}),o&&l.jsx("button",{type:"button",onClick:()=>c(r=>!r),className:"absolute top-1/2 right-2 -translate-y-1/2 text-muted-foreground hover:text-foreground","aria-label":t?"Hide value":"Show value",children:t?l.jsx(M,{className:"h-4 w-4"}):l.jsx(Q,{className:"h-4 w-4"})})]})]})},le=i=>{const e=O.c(50),{config:t,form:c,connected:s,stored:a,loading:n,error:o,icon:r,onSaveCredentials:d,onLogin:u,onLogout:m,onRefresh:x,extraSection:h}=i,g=!!t.fields?.length;let v;e[0]!==s?(v={label:"Status",ok:()=>s,trueText:"Connected",falseText:"Not Connected"},e[0]=s,e[1]=v):v=e[1];let f;e[2]!==g||e[3]!==a?(f=g?[{label:"Credentials",ok:()=>a,trueText:"Configured",falseText:"Not configured"}]:[],e[2]=g,e[3]=a,e[4]=f):f=e[4];let p;e[5]!==v||e[6]!==f?(p=[v,...f],e[5]=v,e[6]=f,e[7]=p):p=e[7];const E=p,_=`Login with ${t.name}`,U=g&&!a;let b;e[8]!==s||e[9]!==u||e[10]!==_||e[11]!==U?(b={key:"login",label:_,intent:"save",onClick:u,disabled:U,hidden:s},e[8]=s,e[9]=u,e[10]=_,e[11]=U,e[12]=b):b=e[12];const V=!s;let j;e[13]!==m||e[14]!==V?(j={key:"logout",label:"Disconnect",intent:"stop",onClick:m,hidden:V},e[13]=m,e[14]=V,e[15]=j):j=e[15];let R;e[16]===Symbol.for("react.memo_cache_sentinel")?(R=l.jsx(X,{className:"h-4 w-4"}),e[16]=R):R=e[16];let k;e[17]!==x?(k={key:"refresh",label:"Refresh",intent:"save",onClick:x,icon:R},e[17]=x,e[18]=k):k=e[18];let L;e[19]!==k||e[20]!==b||e[21]!==j?(L=[b,j,k],e[19]=k,e[20]=b,e[21]=j,e[22]=L):L=e[22];const q=L,A=n==="save";let N;e[23]!==t.name||e[24]!==r||e[25]!==E?(N=l.jsx(Z,{icon:r,title:t.name,rows:E,status:null}),e[23]=t.name,e[24]=r,e[25]=E,e[26]=N):N=e[26];let S;e[27]!==t.callbackUrl||e[28]!==t.fields||e[29]!==t.instructions||e[30]!==s||e[31]!==c||e[32]!==A||e[33]!==d?(S=!s&&t.fields&&l.jsxs("div",{className:"flex w-full flex-col gap-3",children:[l.jsx(te,{fields:t.fields,form:c}),l.jsxs(D,{intent:"secret",onClick:d,disabled:A,children:[A&&l.jsx(W,{className:"h-4 w-4 animate-spin"}),"Save Credentials"]}),t.instructions&&l.jsxs("div",{className:"text-xs leading-relaxed text-muted-foreground",children:[t.instructions,t.callbackUrl&&l.jsxs(l.Fragment,{children:[l.jsx("br",{}),"Callback URL:"," ",l.jsx("code",{className:"text-accent",children:t.callbackUrl})]})]})]}),e[27]=t.callbackUrl,e[28]=t.fields,e[29]=t.instructions,e[30]=s,e[31]=c,e[32]=A,e[33]=d,e[34]=S):S=e[34];let C;e[35]!==o?(C=o&&l.jsx(H,{variant:"destructive",children:l.jsx(z,{children:o})}),e[35]=o,e[36]=C):C=e[36];const T=s?t.account_label?`Connected as ${t.account_label}.`:`Your ${t.name} account is connected.`:a||!g?"Click Login to authorize.":"Enter your credentials above to get started.";let y;e[37]!==T?(y=l.jsx("div",{className:"rounded-md border border-accent/30 bg-accent/10 p-3",children:l.jsx("div",{className:"text-sm leading-relaxed text-muted-foreground",children:T})}),e[37]=T,e[38]=y):y=e[38];let F;e[39]===Symbol.for("react.memo_cache_sentinel")?(F=l.jsx("div",{className:"flex-1"}),e[39]=F):F=e[39];let w;e[40]!==q||e[41]!==n?(w=l.jsx(J,{actions:q,loading:n}),e[40]=q,e[41]=n,e[42]=w):w=e[42];let $;return e[43]!==h||e[44]!==N||e[45]!==S||e[46]!==C||e[47]!==y||e[48]!==w?($=l.jsxs("div",{className:"flex min-h-0 flex-1 flex-col gap-4",children:[N,S,C,y,h,F,w]}),e[43]=h,e[44]=N,e[45]=S,e[46]=C,e[47]=y,e[48]=w,e[49]=$):$=e[49],$},ge=i=>{const e=O.c(25),{config:t,visible:c}=i,s=G(t,c),a=K(t.statusHook),n=a?!!a.connected:!!t.stored;let o;e[0]!==t.iconRef?(o=l.jsx(Y,{icon:t.iconRef,className:"h-6 w-6 text-2xl"}),e[0]=t.iconRef,e[1]=o):o=e[1];let r;e[2]!==t.fields||e[3]!==s?(r=()=>{const g=t.fields?.find(f=>f.required&&!s.form.getFieldValue(f.key)?.trim());if(g){s.setError(`${g.label} is required`);return}const v=s.form.getFieldsValue();s.execute("save",async()=>{for(const f of t.fields){const p=v[f.key]?.trim();p&&await s.actions.save(f.key,p)}return s.setStored(!0),{success:!0}})},e[2]=t.fields,e[3]=s,e[4]=r):r=e[4];let d,u,m;e[5]!==s.actions?(d=()=>s.actions.oauthLogin(),u=()=>s.actions.oauthLogout(),m=()=>s.actions.oauthRefresh(),e[5]=s.actions,e[6]=d,e[7]=u,e[8]=m):(d=e[6],u=e[7],m=e[8]);let x;e[9]!==t.name||e[10]!==t.usageService?(x=t.usageService&&l.jsx(ee,{service:t.usageService,serviceName:t.name}),e[9]=t.name,e[10]=t.usageService,e[11]=x):x=e[11];let h;return e[12]!==t||e[13]!==n||e[14]!==s.error||e[15]!==s.form||e[16]!==s.loading||e[17]!==s.stored||e[18]!==o||e[19]!==r||e[20]!==d||e[21]!==u||e[22]!==m||e[23]!==x?(h=l.jsx("div",{className:"flex min-h-0 flex-1 flex-col p-5",children:l.jsx(le,{config:t,form:s.form,connected:n,stored:s.stored,loading:s.loading,error:s.error,icon:o,onSaveCredentials:r,onLogin:d,onLogout:u,onRefresh:m,extraSection:x})}),e[12]=t,e[13]=n,e[14]=s.error,e[15]=s.form,e[16]=s.loading,e[17]=s.stored,e[18]=o,e[19]=r,e[20]=d,e[21]=u,e[22]=m,e[23]=x,e[24]=h):h=e[24],h};export{ge as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as e}from"./vendor-radix-BGeDhy8U.js";import{b as d,R as Q}from"./vendor-react-CxXU_nq3.js";import{d as S,l as k,e as _,m as w,N as A}from"./index-DNx1tG6T.js";import{A as v}from"./ApiKeyInput-DljozMIZ.js";import{Q as E}from"./vendor-misc-4my8ai2A.js";import{aj as W,ac as F,bd as M,ag as b}from"./vendor-icons-BPyNc2rK.js";import{u as T,R as q}from"./RateLimitSection-B2lBVQs0.js";import{u as L,A as D}from"./ActionBar-DAHXJmEU.js";import{S as P}from"./StatusCard-BlufvZD-.js";import"./vendor-flow-apeQB2hf.js";import"./vendor-query-to9T1kjL.js";import"./vendor-markdown-Bx_GU1E7.js";const V=t=>t.length<100?!1:t.startsWith("data:image/")||t.startsWith("iVBOR")||t.startsWith("/9j/")?!0:t.length>5e3?/^[A-Za-z0-9+/=]+$/.test(t):!1,B=({value:t,isConnected:c=!1,size:s=280,loading:a=!1,connectedTitle:u="Connected",connectedSubtitle:x="No QR code needed",emptyText:h="QR code not available"})=>{if(c)return e.jsxs("div",{className:"flex flex-col items-center gap-3 p-8 text-center",children:[e.jsx(W,{className:"h-10 w-10 text-success"}),e.jsx("div",{className:"text-base font-semibold",children:u}),e.jsx("div",{className:"text-sm text-muted-foreground",children:x})]});if(a)return e.jsxs("div",{className:"p-10 text-center",children:[e.jsx(F,{className:"mx-auto h-8 w-8 animate-spin text-muted-foreground"}),e.jsx("div",{className:"mt-4 text-sm text-muted-foreground",children:"Waiting for QR code..."})]});if(!t)return e.jsxs("div",{className:"p-10 text-center text-muted-foreground",children:[e.jsx(M,{className:"mx-auto h-12 w-12 opacity-30"}),e.jsx("div",{className:"mt-4",children:h})]});if(V(t)){const o=t.startsWith("data:")?t:`data:image/png;base64,${t}`;return e.jsx("div",{className:"p-4 text-center",children:e.jsx("img",{src:o,alt:"QR Code",style:{width:s,height:s,imageRendering:"pixelated"}})})}return e.jsx(I,{value:t,size:s})},I=({value:t,size:c})=>{const[s,a]=d.useState(null);return d.useEffect(()=>{a(null)},[t]),s?e.jsx("div",{className:"p-6 text-center",children:e.jsxs(S,{variant:"warning",children:[e.jsx(b,{className:"h-4 w-4"}),e.jsx(k,{children:"QR Code Error"}),e.jsx(_,{children:"The QR code data is too large to display. Please try refreshing or reconnecting."})]})}):e.jsx(G,{onError:u=>a(u),children:e.jsx("div",{className:"p-4 text-center",children:e.jsx(E,{value:t,size:c,level:"L"})})})};class G extends Q.Component{constructor(c){super(c),this.state={hasError:!1}}static getDerivedStateFromError(c){return{hasError:!0}}componentDidCatch(c){console.error("[QRCodeDisplay] QR code rendering error:",c.message),this.props.onError(c.message)}render(){return this.state.hasError?e.jsx("div",{className:"p-6 text-center",children:e.jsxs(S,{variant:"warning",children:[e.jsx(b,{className:"h-4 w-4"}),e.jsx(k,{children:"QR Code Error"}),e.jsx(_,{children:"The QR code data is too large to display. Please try refreshing or reconnecting."})]})}):this.props.children}}const H=()=>{const{getWhatsAppStatus:t,getWhatsAppQR:c,sendWhatsAppMessage:s,startWhatsAppConnection:a,restartWhatsAppConnection:u,isConnected:x}=w(),[h,o]=d.useState(!1),[y,n]=d.useState(null),[p,j]=d.useState(null),m=d.useCallback(async()=>{o(!0),n(null);try{const r=await t();return j(r),r}catch(r){const l=r.message||"Failed to get status";return n(l),{connected:!1}}finally{o(!1)}},[t]),C=d.useCallback(async()=>{o(!0),n(null);try{const r=await c();return r.connected&&j({connected:!0}),r}catch(r){const l=r.message||"Failed to get QR code";return n(l),{connected:!1,message:l}}finally{o(!1)}},[c]),R=d.useCallback(async(r,l)=>{o(!0),n(null);try{const f=await s(r,l);return!f.success&&f.error&&n(f.error),f}catch(f){const N=f.message||"Failed to send message";return n(N),{success:!1,error:N}}finally{o(!1)}},[s]),i=d.useCallback(async()=>{o(!0),n(null);try{const r=await a();return!r.success&&r.message&&n(r.message),r}catch(r){const l=r.message||"Failed to start connection";return n(l),{success:!1,message:l}}finally{o(!1)}},[a]),g=d.useCallback(async()=>{o(!0),n(null);try{const r=await u();return!r.success&&r.message&&n(r.message),r}catch(r){const l=r.message||"Failed to restart connection";return n(l),{success:!1,message:l}}finally{o(!1)}},[u]);return{getStatus:m,getQRCode:C,sendMessage:R,startConnection:i,restartConnection:g,isLoading:h,lastError:y,connectionStatus:p,isConnected:x}},re=({config:t,visible:c})=>{const s=T(t,c),a=L(t.statusHook),{startConnection:u,restartConnection:x,getStatus:h}=H(),{sendRequest:o,setAndroidStatus:y}=w(),n=t.qr,p=n.isConnected(a),j=a?.[n.qrField],m=t.fields?.[0],C=d.useMemo(()=>({start:()=>s.execute("start",u),restart:()=>s.execute("restart",x),refresh:()=>s.execute("refresh",h),connect:()=>s.execute("connect",async()=>{const i=s.form.getFieldValue("android_remote")?.trim();if(!i){s.setError("No API key configured");return}const g=await o("android_relay_connect",{url:"",api_key:i});return g.qr_data&&y(r=>({...r,connected:!0,paired:!1,qr_data:g.qr_data,session_token:g.session_token||r.session_token})),g}),disconnect:()=>s.execute("disconnect",()=>o("android_relay_disconnect",{}))}),[s,u,x,h,o,y]),R=(t.actions??[]).map(i=>({key:i.key,label:i.label,intent:i.intent,onClick:C[i.key]??(()=>{}),hidden:i.hidden?.(a,s.stored),disabled:i.disabled?.(a,s.stored)}));return e.jsxs("div",{className:"flex min-h-0 flex-1 flex-col gap-4 p-5",children:[m&&e.jsx(v,{value:s.form.getFieldValue(m.key)||"",onChange:i=>s.form.setFieldValue(m.key,i),onSave:()=>s.actions.save(m.key,(s.form.getFieldValue(m.key)??"").trim()).then(()=>s.setStored(!0)),onDelete:()=>s.actions.remove(m.key),placeholder:m.placeholder,loading:s.loading==="save",isStored:s.stored}),t.statusRows&&e.jsx(P,{icon:e.jsx(A,{icon:t.iconRef,className:"h-6 w-6 text-2xl"}),title:t.name,rows:t.statusRows,status:a}),e.jsxs("div",{className:"flex min-h-[300px] flex-1 flex-col items-center justify-center rounded-lg bg-muted p-5",children:[e.jsx(B,{value:j,isConnected:p,size:280,connectedTitle:n.connectedTitle,connectedSubtitle:n.connectedSubtitle(a),loading:n.isLoading(a),emptyText:n.emptyText(a,s.stored)}),!p&&j&&e.jsx("div",{className:"mt-3 text-sm text-muted-foreground",children:n.scanText})]}),t.hasRateLimits&&p&&e.jsx(q,{}),s.error&&e.jsx(S,{variant:"destructive",children:e.jsx(_,{children:s.error})}),e.jsx(D,{actions:R,loading:s.loading})]})};export{re as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{b as o,h as le}from"./vendor-react-CxXU_nq3.js";import{a as pe,u as je}from"./vendor-query-to9T1kjL.js";import{u as re,m as se,s as G,S as ge,t as oe,v as ie,A as ce,a as de,b as ue,c as me,F as xe,w as _,x as w,y as S,z as J,D as C,E as Y,G as I,H as X,J as O,K as D,M as Q,g as B,I as $,O as Z,B as ee,_ as ne,P as b,Q as H,R as ye,d as _e,e as ve,f as be}from"./index-DNx1tG6T.js";import{j as e}from"./vendor-radix-BGeDhy8U.js";import{ab as we,ac as he}from"./vendor-icons-BPyNc2rK.js";const W={};function Ve(n,l){const x=pe(),[h,j]=o.useState(null),[p,c]=o.useState(null),[F,v]=o.useState(!1);o.useEffect(()=>{c(null),j(null),v(!1)},[n.id]);const{validateApiKey:u,saveApiKey:y,removeApiKey:A,getProviderDefaults:R,saveProviderDefaults:P,getProviderUsageSummary:i,getAPIUsageSummary:a,getStoredModels:d,getModelConstraints:g,isConnected:T}=re(),{sendRequest:k}=se(),E=je({queryKey:G.credentialValues.byProvider(n.id).queryKey,queryFn:async()=>{if(!n.fields)return{values:W,hadStored:!1};const t=await Promise.all(n.fields.map(async K=>{const fe=K.key==="apiKey"?n.id:K.key,ae=await k("get_stored_api_key",{provider:fe});return{key:K.key,hasKey:ae.hasKey,apiKey:ae.apiKey}})),f={};let m=!1;for(const K of t)K.apiKey&&(f[K.key]=K.apiKey),K.hasKey&&(m=!0);return{values:f,hadStored:m}},enabled:l&&T&&!!n.fields,staleTime:ge.FOREVER}),L=E.data?.values??W,M=o.useRef(L);M.current=L;const N=n.id,q=o.useCallback(t=>{x.setQueryData(G.credentialValues.byProvider(N).queryKey,f=>({values:t(f?.values??W),hadStored:f?.hadStored??!1}))},[x,N]),z=o.useMemo(()=>({getFieldValue:t=>M.current[t],getFieldsValue:()=>({...M.current}),setFieldValue:(t,f)=>{q(m=>({...m,[t]:f}))},setFieldsValue:t=>{q(f=>({...f,...t}))},resetFields:()=>q(()=>W)}),[q]);(E.data?.hadStored??!1)&&!F&&v(!0);const r=o.useCallback(async(t,f)=>{j(t),c(null);try{const m=await f();return m&&!m.success&&m.error&&c(m.error),m}catch(m){c(m.message||`Failed: ${t}`);return}finally{j(null)}},[]),V=o.useCallback(()=>x.invalidateQueries({queryKey:G.credentialValues.byProvider(N).queryKey}),[x,N]);return{form:z,values:L,loading:h,error:p,stored:F,setStored:v,setError:c,execute:r,actions:{validate:(t,f)=>r("validate",async()=>{const m=await u(t,f);return m?.isValid&&(v(!0),await V()),m}),save:(t,f)=>r("save",async()=>{const m=await y(t,f);return m?.isValid&&(v(!0),await V()),m}),remove:t=>r("remove",async()=>{await A(t),v(!1),await V()}),oauthLogin:()=>r("login",async()=>{const t=await k(n.ws.login,{});return t.success&&t.url&&window.open(t.url,"_blank"),t}),oauthLogout:()=>r("logout",()=>k(n.ws.logout,{})),oauthRefresh:()=>r("refresh",()=>k(n.ws.status,{})),sendWs:(t,f)=>r(t,()=>k(t,f??{}))},isConnected:T,getProviderDefaults:R,saveProviderDefaults:P,getProviderUsageSummary:i,getAPIUsageSummary:a,getStoredModels:d,getModelConstraints:g}}const Se=ie({default_model:ye().optional().default(""),temperature:b().optional(),max_tokens:b().int().min(1).optional(),thinking_enabled:H().optional().default(!1),thinking_budget:b().int().min(1024).max(16e3).optional(),reasoning_effort:ne(["low","medium","high"]).optional(),reasoning_format:ne(["parsed","hidden"]).optional()}),Ke=({providerId:n})=>{const{getProviderDefaults:l,saveProviderDefaults:x,getStoredModels:h,getModelConstraints:j,isConnected:p}=re(),{apiKeyStatuses:c}=se(),F=c[n],[v,u]=o.useState([]),[y,A]=o.useState(null),[R,P]=o.useState(!1),i=le({resolver:oe(Se),defaultValues:{}}),a=i.watch("default_model"),d=i.watch("thinking_enabled"),{isDirty:g}=i.formState;o.useEffect(()=>{if(!p)return;u([]),A(null);let s=!1;return(async()=>{P(!0);try{const[r,V]=await Promise.all([l(n),h(n)]);s||(i.reset(r??{}),u(V??[]))}finally{s||P(!1)}})(),()=>{s=!0}},[n,p,F]),o.useEffect(()=>{if(!p||!a)return;let s=!1;return j(a,n).then(r=>{s||(A(r),r?.max_output_tokens&&i.getValues("max_tokens")!==r.max_output_tokens&&i.setValue("max_tokens",r.max_output_tokens,{shouldDirty:!1}))}),()=>{s=!0}},[a,n,p]);const T=o.useCallback(async s=>{P(!0);try{await x(n,s)&&i.reset(s)}finally{P(!1)}},[n,x,i]),[k,E]=y?.temperature_range??[0,2],L=y?.max_output_tokens,M=y?.thinking_type,N=y?.supports_thinking,q=y?.is_reasoning_model&&k===E,z=s=>r=>{const V=r.target.value;s.onChange(V===""?void 0:Number(V))};return e.jsx(ce,{type:"single",collapsible:!0,defaultValue:"defaults",children:e.jsxs(de,{value:"defaults",children:[e.jsx(ue,{children:e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx(we,{className:"h-4 w-4"})," Default Parameters"]})}),e.jsx(me,{children:e.jsx("div",{className:R?"pointer-events-none opacity-60":"",children:e.jsx(xe,{...i,children:e.jsxs("form",{id:`provider-defaults-form-${n}`,onSubmit:i.handleSubmit(T),className:"flex flex-col gap-3",children:[e.jsx(_,{control:i.control,name:"default_model",render:({field:s})=>e.jsxs(w,{children:[e.jsx(S,{children:"Default Model"}),e.jsxs(J,{value:s.value??"",onValueChange:s.onChange,children:[e.jsx(C,{children:e.jsx(Y,{children:e.jsx(I,{placeholder:v.length?"Select model":"Validate API key first"})})}),e.jsx(X,{children:v.map(r=>e.jsx(O,{value:r,children:r},r))})]}),e.jsx(D,{children:"Model used when none specified"}),e.jsx(Q,{})]})}),y&&e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5",children:[L!=null&&e.jsxs(B,{variant:"success",children:["Max Output: ",L.toLocaleString()]}),y.context_length!=null&&e.jsxs(B,{variant:"info",children:["Context: ",y.context_length.toLocaleString()]}),e.jsxs(B,{variant:"secondary",children:["Temp: ",k,"-",E]}),N&&e.jsxs(B,{variant:"warning",children:["Thinking: ",M]}),y.is_reasoning_model&&e.jsx(B,{variant:"outline",children:"Reasoning"})]}),!q&&e.jsx(_,{control:i.control,name:"temperature",render:({field:s})=>e.jsxs(w,{children:[e.jsx(S,{children:"Temperature"}),e.jsx(C,{children:e.jsx($,{type:"number",min:k,max:E,step:.1,className:"w-24",value:s.value??"",onChange:z(s)})}),e.jsxs(D,{children:["Controls randomness (",k,"-",E,")"]}),e.jsx(Q,{})]})}),e.jsx(_,{control:i.control,name:"max_tokens",render:({field:s})=>e.jsxs(w,{children:[e.jsx(S,{children:"Max Tokens"}),e.jsx(C,{children:e.jsx($,{type:"number",min:1,max:L||void 0,className:"w-32",value:s.value??"",onChange:z(s)})}),e.jsx(D,{children:L!=null?`Up to ${L.toLocaleString()}`:"Maximum response length"}),e.jsx(Q,{})]})}),N&&e.jsx(_,{control:i.control,name:"thinking_enabled",render:({field:s})=>e.jsxs(w,{className:"flex flex-row items-center justify-between rounded-md border border-border p-3",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(S,{children:"Thinking / Reasoning"}),e.jsxs(D,{children:["Extended thinking (",M,")"]})]}),e.jsx(C,{children:e.jsx(Z,{checked:!!s.value,onCheckedChange:s.onChange})})]})}),N&&M==="budget"&&d&&e.jsx(_,{control:i.control,name:"thinking_budget",render:({field:s})=>e.jsxs(w,{children:[e.jsx(S,{children:"Thinking Budget"}),e.jsx(C,{children:e.jsx($,{type:"number",min:1024,max:16e3,className:"w-28",value:s.value??"",onChange:z(s)})}),e.jsx(D,{children:"Token budget (1024-16000)"}),e.jsx(Q,{})]})}),N&&M==="effort"&&d&&e.jsx(_,{control:i.control,name:"reasoning_effort",render:({field:s})=>e.jsxs(w,{children:[e.jsx(S,{children:"Reasoning Effort"}),e.jsxs(J,{value:s.value??"",onValueChange:s.onChange,children:[e.jsx(C,{children:e.jsx(Y,{className:"w-32",children:e.jsx(I,{placeholder:"Select"})})}),e.jsxs(X,{children:[e.jsx(O,{value:"low",children:"Low"}),e.jsx(O,{value:"medium",children:"Medium"}),e.jsx(O,{value:"high",children:"High"})]})]}),e.jsx(D,{children:"Low, medium, or high"}),e.jsx(Q,{})]})}),N&&M==="format"&&d&&e.jsx(_,{control:i.control,name:"reasoning_format",render:({field:s})=>e.jsxs(w,{children:[e.jsx(S,{children:"Reasoning Format"}),e.jsxs(J,{value:s.value??"",onValueChange:s.onChange,children:[e.jsx(C,{children:e.jsx(Y,{className:"w-32",children:e.jsx(I,{placeholder:"Select"})})}),e.jsxs(X,{children:[e.jsx(O,{value:"parsed",children:"Parsed"}),e.jsx(O,{value:"hidden",children:"Hidden"})]})]}),e.jsx(D,{children:"Parsed or hidden"}),e.jsx(Q,{})]})}),e.jsxs(ee,{type:"submit",disabled:!g||R,variant:g?"default":"outline",className:"w-full",children:[R&&e.jsx(he,{className:"h-4 w-4 animate-spin"}),"Save Defaults"]})]})})})})]})})},Ce=ie({enabled:H().default(!1),min_delay_ms:b().int().min(0).optional(),max_delay_ms:b().int().min(0).optional(),typing_delay_ms:b().int().min(0).optional(),link_extra_delay_ms:b().int().min(0).optional(),max_messages_per_minute:b().int().min(0).optional(),max_messages_per_hour:b().int().min(0).optional(),max_new_contacts_per_day:b().int().min(0).optional(),simulate_typing:H().optional(),randomize_delays:H().optional(),pause_on_low_response:H().optional(),response_rate_threshold:b().min(0).max(1).optional()}),U=n=>{const l=be.c(7),{label:x,value:h}=n;let j;l[0]!==x?(j=e.jsx("span",{className:"text-xs text-muted-foreground",children:x}),l[0]=x,l[1]=j):j=l[1];let p;l[2]!==h?(p=e.jsx("span",{className:"text-lg font-semibold",children:h}),l[2]=h,l[3]=p):p=l[3];let c;return l[4]!==j||l[5]!==p?(c=e.jsxs("div",{className:"flex flex-col",children:[j,p]}),l[4]=j,l[5]=p,l[6]=c):c=l[6],c},te=n=>l=>{const x=l.target.value;n.onChange(x===""?void 0:Number(x))},De=()=>{const{getWhatsAppRateLimitConfig:n,setWhatsAppRateLimitConfig:l,unpauseWhatsAppRateLimit:x}=se(),[h,j]=o.useState(null),[p,c]=o.useState(!1),[F,v]=o.useState(!1),u=le({resolver:oe(Ce),defaultValues:{enabled:!1}}),y=u.watch("pause_on_low_response"),{isDirty:A}=u.formState,R=o.useCallback(async()=>{c(!0);try{const a=await n();a.success&&a.config&&(u.reset(a.config),j(a.stats??null),v(!0))}finally{c(!1)}},[u,n]);o.useEffect(()=>{R()},[R]);const P=o.useCallback(async a=>{c(!0);try{const d=await l(a);d.success&&d.config&&u.reset(d.config)}finally{c(!1)}},[u,l]),i=o.useCallback(async()=>{c(!0);try{const a=await x();a.success&&a.stats&&j(a.stats)}finally{c(!1)}},[x]);return e.jsx(ce,{type:"single",collapsible:!0,children:e.jsxs(de,{value:"ratelimits",children:[e.jsx(ue,{children:e.jsxs("div",{className:"flex w-full items-center justify-between gap-2",children:[e.jsx("span",{children:"Rate Limits"}),e.jsx(_,{control:u.control,name:"enabled",render:({field:a})=>e.jsx("span",{onClick:d=>d.stopPropagation(),children:e.jsx(Z,{checked:!!a.value,onCheckedChange:a.onChange})})})]})}),e.jsx(me,{children:F?e.jsx(xe,{...u,children:e.jsxs("form",{onSubmit:u.handleSubmit(P),className:"flex flex-col gap-3",children:[h&&e.jsxs("div",{className:"mb-3 flex flex-wrap gap-4",children:[e.jsx(U,{label:"Last Minute",value:h.messages_sent_last_minute}),e.jsx(U,{label:"Last Hour",value:h.messages_sent_last_hour}),e.jsx(U,{label:"Today",value:h.messages_sent_today}),e.jsx(U,{label:"New Contacts",value:h.new_contacts_today}),e.jsx(U,{label:"Responses",value:h.responses_received}),e.jsx(U,{label:"Response Rate",value:`${Math.round((h.response_rate||0)*100)}%`})]}),h?.is_paused&&e.jsx(_e,{variant:"warning",children:e.jsxs(ve,{className:"flex items-center justify-between gap-3",children:[e.jsx("span",{children:h.pause_reason||"Paused"}),e.jsx(ee,{size:"sm",variant:"outline",type:"button",onClick:i,children:"Unpause"})]})}),e.jsx("div",{className:"text-xs font-medium text-muted-foreground",children:"Message Delays (milliseconds)"}),e.jsx("div",{className:"flex flex-wrap gap-3",children:[["min_delay_ms","Min Delay"],["max_delay_ms","Max Delay"],["typing_delay_ms","Typing Duration"],["link_extra_delay_ms","Link Extra Delay"]].map(([a,d])=>e.jsx(_,{control:u.control,name:a,render:({field:g})=>e.jsxs(w,{children:[e.jsx(S,{className:"text-xs",children:d}),e.jsx(C,{children:e.jsx($,{type:"number",min:0,className:"w-28",value:g.value??"",onChange:te(g)})})]})},a))}),e.jsx("div",{className:"text-xs font-medium text-muted-foreground",children:"Message Limits"}),e.jsx("div",{className:"flex flex-wrap gap-3",children:[["max_messages_per_minute","Per Minute"],["max_messages_per_hour","Per Hour"],["max_new_contacts_per_day","New Contacts/Day"]].map(([a,d])=>e.jsx(_,{control:u.control,name:a,render:({field:g})=>e.jsxs(w,{children:[e.jsx(S,{className:"text-xs",children:d}),e.jsx(C,{children:e.jsx($,{type:"number",min:0,className:"w-32",value:g.value??"",onChange:te(g)})})]})},a))}),e.jsx("div",{className:"text-xs font-medium text-muted-foreground",children:"Behavior"}),e.jsxs("div",{className:"flex w-full flex-col gap-2",children:[[["simulate_typing","Simulate Typing","Show typing indicator before sending"],["randomize_delays","Randomize Delays","Add variance between min/max delay"],["pause_on_low_response","Pause on Low Response","Auto-pause if response rate drops below threshold"]].map(([a,d,g])=>e.jsx(_,{control:u.control,name:a,render:({field:T})=>e.jsxs(w,{className:"flex flex-row items-center justify-between rounded-md border border-border p-3",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(S,{children:d}),e.jsx(D,{children:g})]}),e.jsx(C,{children:e.jsx(Z,{checked:!!T.value,onCheckedChange:T.onChange})})]})},a)),y&&e.jsx(_,{control:u.control,name:"response_rate_threshold",render:({field:a})=>e.jsxs(w,{children:[e.jsx(S,{children:"Response Rate Threshold (%)"}),e.jsx(C,{children:e.jsx($,{type:"number",min:0,max:100,value:Math.round((a.value??.3)*100),onChange:d=>{const g=d.target.value;a.onChange(g===""?void 0:Number(g)/100)}})})]})})]}),e.jsxs(ee,{type:"submit",disabled:!A||p,variant:A?"default":"outline",className:"w-full",children:[p&&e.jsx(he,{className:"h-4 w-4 animate-spin"}),"Save Changes"]})]})}):e.jsx("div",{className:"flex justify-center p-4 text-sm text-muted-foreground",children:"Loading..."})})]})})};export{Ke as P,De as R,Ve as u};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{j as s}from"./vendor-radix-BGeDhy8U.js";import{f as b,g}from"./index-DNx1tG6T.js";const h=p=>{const e=b.c(15),{icon:c,title:m,rows:x,status:o}=p;let t;e[0]!==m?(t=s.jsx("span",{children:m}),e[0]=m,e[1]=t):t=e[1];let r;e[2]!==c||e[3]!==t?(r=s.jsxs("div",{className:"flex items-center gap-2 border-b border-border bg-muted px-3 py-2 text-sm font-semibold",children:[c,t]}),e[2]=c,e[3]=t,e[4]=r):r=e[4];let i;if(e[5]!==x||e[6]!==o){let n;e[8]!==o?(n=l=>{const f=l.ok(o),u=f?"success":l.warn?"warning":"destructive";return s.jsxs("div",{className:"grid grid-cols-[1fr_auto] items-center gap-3 px-3 py-2 text-sm",children:[s.jsx("span",{className:"text-muted-foreground",children:l.label}),s.jsx(g,{variant:u,children:f?l.trueText:l.falseText})]},l.label)},e[8]=o,e[9]=n):n=e[9],i=x.map(n),e[5]=x,e[6]=o,e[7]=i}else i=e[7];let d;e[10]!==i?(d=s.jsx("div",{className:"divide-y divide-border",children:i}),e[10]=i,e[11]=d):d=e[11];let a;return e[12]!==r||e[13]!==d?(a=s.jsxs("div",{className:"overflow-hidden rounded-md border border-border",children:[r,d]}),e[12]=r,e[13]=d,e[14]=a):a=e[14],a};export{h as S};
|