@elizaos/app-core 2.0.0-alpha.37
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/.turbo/turbo-build.log +2 -0
- package/LICENSE +21 -0
- package/dist/App.d.ts +5 -0
- package/dist/App.d.ts.map +1 -0
- package/dist/App.js +198 -0
- package/dist/actions/character.d.ts +27 -0
- package/dist/actions/character.d.ts.map +1 -0
- package/dist/actions/character.js +97 -0
- package/dist/actions/chat-helpers.d.ts +47 -0
- package/dist/actions/chat-helpers.d.ts.map +1 -0
- package/dist/actions/chat-helpers.js +79 -0
- package/dist/actions/cloud.d.ts +17 -0
- package/dist/actions/cloud.d.ts.map +1 -0
- package/dist/actions/cloud.js +43 -0
- package/dist/actions/index.d.ts +12 -0
- package/dist/actions/index.d.ts.map +1 -0
- package/dist/actions/index.js +11 -0
- package/dist/actions/lifecycle.d.ts +43 -0
- package/dist/actions/lifecycle.d.ts.map +1 -0
- package/dist/actions/lifecycle.js +118 -0
- package/dist/actions/onboarding.d.ts +12 -0
- package/dist/actions/onboarding.d.ts.map +1 -0
- package/dist/actions/onboarding.js +28 -0
- package/dist/actions/triggers.d.ts +23 -0
- package/dist/actions/triggers.d.ts.map +1 -0
- package/dist/actions/triggers.js +148 -0
- package/dist/api/client.d.ts +2823 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +2392 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +1 -0
- package/dist/autonomy/index.d.ts +48 -0
- package/dist/autonomy/index.d.ts.map +1 -0
- package/dist/autonomy/index.js +330 -0
- package/dist/bridge/capacitor-bridge.d.ts +153 -0
- package/dist/bridge/capacitor-bridge.d.ts.map +1 -0
- package/dist/bridge/capacitor-bridge.js +193 -0
- package/dist/bridge/electrobun-rpc.d.ts +19 -0
- package/dist/bridge/electrobun-rpc.d.ts.map +1 -0
- package/dist/bridge/electrobun-rpc.js +27 -0
- package/dist/bridge/electrobun-runtime.d.ts +3 -0
- package/dist/bridge/electrobun-runtime.d.ts.map +1 -0
- package/dist/bridge/electrobun-runtime.js +17 -0
- package/dist/bridge/index.d.ts +6 -0
- package/dist/bridge/index.d.ts.map +1 -0
- package/dist/bridge/index.js +5 -0
- package/dist/bridge/native-plugins.d.ts +82 -0
- package/dist/bridge/native-plugins.d.ts.map +1 -0
- package/dist/bridge/native-plugins.js +39 -0
- package/dist/bridge/plugin-bridge.d.ts +116 -0
- package/dist/bridge/plugin-bridge.d.ts.map +1 -0
- package/dist/bridge/plugin-bridge.js +203 -0
- package/dist/bridge/storage-bridge.d.ts +39 -0
- package/dist/bridge/storage-bridge.d.ts.map +1 -0
- package/dist/bridge/storage-bridge.js +135 -0
- package/dist/chat/index.d.ts +57 -0
- package/dist/chat/index.d.ts.map +1 -0
- package/dist/chat/index.js +161 -0
- package/dist/coding/index.d.ts +25 -0
- package/dist/coding/index.d.ts.map +1 -0
- package/dist/coding/index.js +25 -0
- package/dist/components/AdvancedPageView.d.ts +17 -0
- package/dist/components/AdvancedPageView.d.ts.map +1 -0
- package/dist/components/AdvancedPageView.js +137 -0
- package/dist/components/AgentActivityBox.d.ts +7 -0
- package/dist/components/AgentActivityBox.d.ts.map +1 -0
- package/dist/components/AgentActivityBox.js +25 -0
- package/dist/components/ApiKeyConfig.d.ts +26 -0
- package/dist/components/ApiKeyConfig.d.ts.map +1 -0
- package/dist/components/ApiKeyConfig.js +121 -0
- package/dist/components/AppsPageView.d.ts +7 -0
- package/dist/components/AppsPageView.d.ts.map +1 -0
- package/dist/components/AppsPageView.js +31 -0
- package/dist/components/AppsView.d.ts +8 -0
- package/dist/components/AppsView.d.ts.map +1 -0
- package/dist/components/AppsView.js +149 -0
- package/dist/components/AvatarLoader.d.ts +9 -0
- package/dist/components/AvatarLoader.d.ts.map +1 -0
- package/dist/components/AvatarLoader.js +45 -0
- package/dist/components/AvatarSelector.d.ts +23 -0
- package/dist/components/AvatarSelector.d.ts.map +1 -0
- package/dist/components/AvatarSelector.js +105 -0
- package/dist/components/BscTradePanel.d.ts +22 -0
- package/dist/components/BscTradePanel.d.ts.map +1 -0
- package/dist/components/BscTradePanel.js +221 -0
- package/dist/components/BugReportModal.d.ts +2 -0
- package/dist/components/BugReportModal.d.ts.map +1 -0
- package/dist/components/BugReportModal.js +218 -0
- package/dist/components/CharacterView.d.ts +8 -0
- package/dist/components/CharacterView.d.ts.map +1 -0
- package/dist/components/CharacterView.js +703 -0
- package/dist/components/ChatAvatar.d.ts +8 -0
- package/dist/components/ChatAvatar.d.ts.map +1 -0
- package/dist/components/ChatAvatar.js +89 -0
- package/dist/components/ChatComposer.d.ts +37 -0
- package/dist/components/ChatComposer.d.ts.map +1 -0
- package/dist/components/ChatComposer.js +136 -0
- package/dist/components/ChatMessage.d.ts +24 -0
- package/dist/components/ChatMessage.d.ts.map +1 -0
- package/dist/components/ChatMessage.js +167 -0
- package/dist/components/ChatModalView.d.ts +10 -0
- package/dist/components/ChatModalView.d.ts.map +1 -0
- package/dist/components/ChatModalView.js +57 -0
- package/dist/components/ChatView.d.ts +14 -0
- package/dist/components/ChatView.d.ts.map +1 -0
- package/dist/components/ChatView.js +511 -0
- package/dist/components/CloudSourceControls.d.ts +13 -0
- package/dist/components/CloudSourceControls.d.ts.map +1 -0
- package/dist/components/CloudSourceControls.js +14 -0
- package/dist/components/CodingAgentSettingsSection.d.ts +2 -0
- package/dist/components/CodingAgentSettingsSection.d.ts.map +1 -0
- package/dist/components/CodingAgentSettingsSection.js +268 -0
- package/dist/components/CommandPalette.d.ts +2 -0
- package/dist/components/CommandPalette.d.ts.map +1 -0
- package/dist/components/CommandPalette.js +181 -0
- package/dist/components/CompanionSceneHost.d.ts +15 -0
- package/dist/components/CompanionSceneHost.d.ts.map +1 -0
- package/dist/components/CompanionSceneHost.js +343 -0
- package/dist/components/CompanionShell.d.ts +17 -0
- package/dist/components/CompanionShell.d.ts.map +1 -0
- package/dist/components/CompanionShell.js +15 -0
- package/dist/components/CompanionView.d.ts +2 -0
- package/dist/components/CompanionView.d.ts.map +1 -0
- package/dist/components/CompanionView.js +22 -0
- package/dist/components/ConfigPageView.d.ts +11 -0
- package/dist/components/ConfigPageView.d.ts.map +1 -0
- package/dist/components/ConfigPageView.js +275 -0
- package/dist/components/ConfigSaveFooter.d.ts +8 -0
- package/dist/components/ConfigSaveFooter.d.ts.map +1 -0
- package/dist/components/ConfigSaveFooter.js +10 -0
- package/dist/components/ConfirmModal.d.ts +61 -0
- package/dist/components/ConfirmModal.d.ts.map +1 -0
- package/dist/components/ConfirmModal.js +164 -0
- package/dist/components/ConnectionFailedBanner.d.ts +6 -0
- package/dist/components/ConnectionFailedBanner.d.ts.map +1 -0
- package/dist/components/ConnectionFailedBanner.js +22 -0
- package/dist/components/ConnectorsPageView.d.ts +7 -0
- package/dist/components/ConnectorsPageView.d.ts.map +1 -0
- package/dist/components/ConnectorsPageView.js +8 -0
- package/dist/components/ConversationsSidebar.d.ts +9 -0
- package/dist/components/ConversationsSidebar.d.ts.map +1 -0
- package/dist/components/ConversationsSidebar.js +116 -0
- package/dist/components/CustomActionEditor.d.ts +10 -0
- package/dist/components/CustomActionEditor.d.ts.map +1 -0
- package/dist/components/CustomActionEditor.js +578 -0
- package/dist/components/CustomActionsPanel.d.ts +9 -0
- package/dist/components/CustomActionsPanel.d.ts.map +1 -0
- package/dist/components/CustomActionsPanel.js +107 -0
- package/dist/components/CustomActionsView.d.ts +2 -0
- package/dist/components/CustomActionsView.d.ts.map +1 -0
- package/dist/components/CustomActionsView.js +134 -0
- package/dist/components/DatabasePageView.d.ts +5 -0
- package/dist/components/DatabasePageView.d.ts.map +1 -0
- package/dist/components/DatabasePageView.js +28 -0
- package/dist/components/DatabaseView.d.ts +9 -0
- package/dist/components/DatabaseView.d.ts.map +1 -0
- package/dist/components/DatabaseView.js +311 -0
- package/dist/components/ElizaCloudDashboard.d.ts +2 -0
- package/dist/components/ElizaCloudDashboard.d.ts.map +1 -0
- package/dist/components/ElizaCloudDashboard.js +657 -0
- package/dist/components/EmotePicker.d.ts +2 -0
- package/dist/components/EmotePicker.d.ts.map +1 -0
- package/dist/components/EmotePicker.js +343 -0
- package/dist/components/ErrorBoundary.d.ts +22 -0
- package/dist/components/ErrorBoundary.d.ts.map +1 -0
- package/dist/components/ErrorBoundary.js +31 -0
- package/dist/components/FineTuningView.d.ts +2 -0
- package/dist/components/FineTuningView.d.ts.map +1 -0
- package/dist/components/FineTuningView.js +433 -0
- package/dist/components/GameView.d.ts +11 -0
- package/dist/components/GameView.d.ts.map +1 -0
- package/dist/components/GameView.js +295 -0
- package/dist/components/GameViewOverlay.d.ts +8 -0
- package/dist/components/GameViewOverlay.d.ts.map +1 -0
- package/dist/components/GameViewOverlay.js +70 -0
- package/dist/components/GlobalEmoteOverlay.d.ts +2 -0
- package/dist/components/GlobalEmoteOverlay.d.ts.map +1 -0
- package/dist/components/GlobalEmoteOverlay.js +112 -0
- package/dist/components/Header.d.ts +8 -0
- package/dist/components/Header.d.ts.map +1 -0
- package/dist/components/Header.js +121 -0
- package/dist/components/HeartbeatsView.d.ts +2 -0
- package/dist/components/HeartbeatsView.d.ts.map +1 -0
- package/dist/components/HeartbeatsView.js +378 -0
- package/dist/components/InventoryView.d.ts +10 -0
- package/dist/components/InventoryView.d.ts.map +1 -0
- package/dist/components/InventoryView.js +162 -0
- package/dist/components/KnowledgeView.d.ts +20 -0
- package/dist/components/KnowledgeView.d.ts.map +1 -0
- package/dist/components/KnowledgeView.js +480 -0
- package/dist/components/LanguageDropdown.d.ts +30 -0
- package/dist/components/LanguageDropdown.d.ts.map +1 -0
- package/dist/components/LanguageDropdown.js +98 -0
- package/dist/components/LifoMonitorPanel.d.ts +21 -0
- package/dist/components/LifoMonitorPanel.d.ts.map +1 -0
- package/dist/components/LifoMonitorPanel.js +24 -0
- package/dist/components/LifoSandboxView.d.ts +5 -0
- package/dist/components/LifoSandboxView.d.ts.map +1 -0
- package/dist/components/LifoSandboxView.js +333 -0
- package/dist/components/LoadingScreen.d.ts +13 -0
- package/dist/components/LoadingScreen.d.ts.map +1 -0
- package/dist/components/LoadingScreen.js +39 -0
- package/dist/components/LogsPageView.d.ts +2 -0
- package/dist/components/LogsPageView.d.ts.map +1 -0
- package/dist/components/LogsPageView.js +7 -0
- package/dist/components/LogsView.d.ts +5 -0
- package/dist/components/LogsView.d.ts.map +1 -0
- package/dist/components/LogsView.js +71 -0
- package/dist/components/MediaGalleryView.d.ts +9 -0
- package/dist/components/MediaGalleryView.d.ts.map +1 -0
- package/dist/components/MediaGalleryView.js +236 -0
- package/dist/components/MediaSettingsSection.d.ts +11 -0
- package/dist/components/MediaSettingsSection.d.ts.map +1 -0
- package/dist/components/MediaSettingsSection.js +329 -0
- package/dist/components/MessageContent.d.ts +51 -0
- package/dist/components/MessageContent.d.ts.map +1 -0
- package/dist/components/MessageContent.js +553 -0
- package/dist/components/OnboardingWizard.d.ts +2 -0
- package/dist/components/OnboardingWizard.d.ts.map +1 -0
- package/dist/components/OnboardingWizard.js +59 -0
- package/dist/components/PairingView.d.ts +5 -0
- package/dist/components/PairingView.d.ts.map +1 -0
- package/dist/components/PairingView.js +28 -0
- package/dist/components/PermissionsSection.d.ts +20 -0
- package/dist/components/PermissionsSection.d.ts.map +1 -0
- package/dist/components/PermissionsSection.js +368 -0
- package/dist/components/PluginsPageView.d.ts +5 -0
- package/dist/components/PluginsPageView.d.ts.map +1 -0
- package/dist/components/PluginsPageView.js +8 -0
- package/dist/components/PluginsView.d.ts +21 -0
- package/dist/components/PluginsView.d.ts.map +1 -0
- package/dist/components/PluginsView.js +1531 -0
- package/dist/components/ProviderSwitcher.d.ts +42 -0
- package/dist/components/ProviderSwitcher.d.ts.map +1 -0
- package/dist/components/ProviderSwitcher.js +480 -0
- package/dist/components/RestartBanner.d.ts +2 -0
- package/dist/components/RestartBanner.d.ts.map +1 -0
- package/dist/components/RestartBanner.js +36 -0
- package/dist/components/RuntimeView.d.ts +10 -0
- package/dist/components/RuntimeView.d.ts.map +1 -0
- package/dist/components/RuntimeView.js +165 -0
- package/dist/components/SaveCommandModal.d.ts +12 -0
- package/dist/components/SaveCommandModal.d.ts.map +1 -0
- package/dist/components/SaveCommandModal.js +84 -0
- package/dist/components/SecretsView.d.ts +9 -0
- package/dist/components/SecretsView.d.ts.map +1 -0
- package/dist/components/SecretsView.js +249 -0
- package/dist/components/SettingsView.d.ts +9 -0
- package/dist/components/SettingsView.d.ts.map +1 -0
- package/dist/components/SettingsView.js +230 -0
- package/dist/components/ShellOverlays.d.ts +8 -0
- package/dist/components/ShellOverlays.d.ts.map +1 -0
- package/dist/components/ShellOverlays.js +10 -0
- package/dist/components/ShortcutsOverlay.d.ts +2 -0
- package/dist/components/ShortcutsOverlay.d.ts.map +1 -0
- package/dist/components/ShortcutsOverlay.js +79 -0
- package/dist/components/SkillsView.d.ts +11 -0
- package/dist/components/SkillsView.d.ts.map +1 -0
- package/dist/components/SkillsView.js +358 -0
- package/dist/components/StartupFailureView.d.ts +8 -0
- package/dist/components/StartupFailureView.d.ts.map +1 -0
- package/dist/components/StartupFailureView.js +15 -0
- package/dist/components/StreamView.d.ts +16 -0
- package/dist/components/StreamView.d.ts.map +1 -0
- package/dist/components/StreamView.js +300 -0
- package/dist/components/StripeEmbeddedCheckout.d.ts +24 -0
- package/dist/components/StripeEmbeddedCheckout.d.ts.map +1 -0
- package/dist/components/StripeEmbeddedCheckout.js +101 -0
- package/dist/components/SubscriptionStatus.d.ts +22 -0
- package/dist/components/SubscriptionStatus.d.ts.map +1 -0
- package/dist/components/SubscriptionStatus.js +301 -0
- package/dist/components/SystemWarningBanner.d.ts +6 -0
- package/dist/components/SystemWarningBanner.d.ts.map +1 -0
- package/dist/components/SystemWarningBanner.js +46 -0
- package/dist/components/ThemeToggle.d.ts +21 -0
- package/dist/components/ThemeToggle.d.ts.map +1 -0
- package/dist/components/ThemeToggle.js +24 -0
- package/dist/components/TrajectoriesView.d.ts +12 -0
- package/dist/components/TrajectoriesView.d.ts.map +1 -0
- package/dist/components/TrajectoriesView.js +183 -0
- package/dist/components/TrajectoryDetailView.d.ts +13 -0
- package/dist/components/TrajectoryDetailView.d.ts.map +1 -0
- package/dist/components/TrajectoryDetailView.js +112 -0
- package/dist/components/TriggersView.d.ts +2 -0
- package/dist/components/TriggersView.d.ts.map +1 -0
- package/dist/components/TriggersView.js +1 -0
- package/dist/components/VectorBrowserView.d.ts +10 -0
- package/dist/components/VectorBrowserView.d.ts.map +1 -0
- package/dist/components/VectorBrowserView.js +997 -0
- package/dist/components/VoiceConfigView.d.ts +11 -0
- package/dist/components/VoiceConfigView.d.ts.map +1 -0
- package/dist/components/VoiceConfigView.js +329 -0
- package/dist/components/VrmStage.d.ts +21 -0
- package/dist/components/VrmStage.d.ts.map +1 -0
- package/dist/components/VrmStage.js +252 -0
- package/dist/components/WhatsAppQrOverlay.d.ts +8 -0
- package/dist/components/WhatsAppQrOverlay.d.ts.map +1 -0
- package/dist/components/WhatsAppQrOverlay.js +63 -0
- package/dist/components/apps/AppDetailPane.d.ts +15 -0
- package/dist/components/apps/AppDetailPane.d.ts.map +1 -0
- package/dist/components/apps/AppDetailPane.js +13 -0
- package/dist/components/apps/AppsCatalogGrid.d.ts +20 -0
- package/dist/components/apps/AppsCatalogGrid.d.ts.map +1 -0
- package/dist/components/apps/AppsCatalogGrid.js +18 -0
- package/dist/components/apps/extensions/HyperscapeAppDetailPanel.d.ts +3 -0
- package/dist/components/apps/extensions/HyperscapeAppDetailPanel.d.ts.map +1 -0
- package/dist/components/apps/extensions/HyperscapeAppDetailPanel.js +253 -0
- package/dist/components/apps/extensions/registry.d.ts +4 -0
- package/dist/components/apps/extensions/registry.d.ts.map +1 -0
- package/dist/components/apps/extensions/registry.js +10 -0
- package/dist/components/apps/extensions/types.d.ts +7 -0
- package/dist/components/apps/extensions/types.d.ts.map +1 -0
- package/dist/components/apps/extensions/types.js +1 -0
- package/dist/components/apps/helpers.d.ts +7 -0
- package/dist/components/apps/helpers.d.ts.map +1 -0
- package/dist/components/apps/helpers.js +46 -0
- package/dist/components/avatar/VrmAnimationLoader.d.ts +30 -0
- package/dist/components/avatar/VrmAnimationLoader.d.ts.map +1 -0
- package/dist/components/avatar/VrmAnimationLoader.js +99 -0
- package/dist/components/avatar/VrmBlinkController.d.ts +37 -0
- package/dist/components/avatar/VrmBlinkController.d.ts.map +1 -0
- package/dist/components/avatar/VrmBlinkController.js +98 -0
- package/dist/components/avatar/VrmCameraManager.d.ts +57 -0
- package/dist/components/avatar/VrmCameraManager.d.ts.map +1 -0
- package/dist/components/avatar/VrmCameraManager.js +277 -0
- package/dist/components/avatar/VrmEngine.d.ts +229 -0
- package/dist/components/avatar/VrmEngine.d.ts.map +1 -0
- package/dist/components/avatar/VrmEngine.js +1950 -0
- package/dist/components/avatar/VrmFootShadow.d.ts +18 -0
- package/dist/components/avatar/VrmFootShadow.d.ts.map +1 -0
- package/dist/components/avatar/VrmFootShadow.js +83 -0
- package/dist/components/avatar/VrmViewer.d.ts +45 -0
- package/dist/components/avatar/VrmViewer.d.ts.map +1 -0
- package/dist/components/avatar/VrmViewer.js +341 -0
- package/dist/components/avatar/mixamoVRMRigMap.d.ts +3 -0
- package/dist/components/avatar/mixamoVRMRigMap.d.ts.map +1 -0
- package/dist/components/avatar/mixamoVRMRigMap.js +56 -0
- package/dist/components/avatar/retargetMixamoFbxToVrm.d.ts +9 -0
- package/dist/components/avatar/retargetMixamoFbxToVrm.d.ts.map +1 -0
- package/dist/components/avatar/retargetMixamoFbxToVrm.js +88 -0
- package/dist/components/avatar/retargetMixamoGltfToVrm.d.ts +11 -0
- package/dist/components/avatar/retargetMixamoGltfToVrm.d.ts.map +1 -0
- package/dist/components/avatar/retargetMixamoGltfToVrm.js +80 -0
- package/dist/components/chainConfig.d.ts +84 -0
- package/dist/components/chainConfig.d.ts.map +1 -0
- package/dist/components/chainConfig.js +268 -0
- package/dist/components/companion/CompanionHeader.d.ts +15 -0
- package/dist/components/companion/CompanionHeader.d.ts.map +1 -0
- package/dist/components/companion/CompanionHeader.js +7 -0
- package/dist/components/companion/CompanionSceneHost.d.ts +2 -0
- package/dist/components/companion/CompanionSceneHost.d.ts.map +1 -0
- package/dist/components/companion/CompanionSceneHost.js +1 -0
- package/dist/components/companion/VrmStage.d.ts +3 -0
- package/dist/components/companion/VrmStage.d.ts.map +1 -0
- package/dist/components/companion/VrmStage.js +1 -0
- package/dist/components/companion/walletUtils.d.ts +95 -0
- package/dist/components/companion/walletUtils.d.ts.map +1 -0
- package/dist/components/companion/walletUtils.js +167 -0
- package/dist/components/companion-shell-styles.d.ts +38 -0
- package/dist/components/companion-shell-styles.d.ts.map +1 -0
- package/dist/components/companion-shell-styles.js +248 -0
- package/dist/components/confirm-delete-control.d.ts +16 -0
- package/dist/components/confirm-delete-control.d.ts.map +1 -0
- package/dist/components/confirm-delete-control.js +12 -0
- package/dist/components/conversations/ConversationListItem.d.ts +31 -0
- package/dist/components/conversations/ConversationListItem.d.ts.map +1 -0
- package/dist/components/conversations/ConversationListItem.js +52 -0
- package/dist/components/conversations/conversation-utils.d.ts +9 -0
- package/dist/components/conversations/conversation-utils.d.ts.map +1 -0
- package/dist/components/conversations/conversation-utils.js +138 -0
- package/dist/components/format.d.ts +54 -0
- package/dist/components/format.d.ts.map +1 -0
- package/dist/components/format.js +82 -0
- package/dist/components/index.d.ts +93 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +92 -0
- package/dist/components/inventory/CopyableAddress.d.ts +8 -0
- package/dist/components/inventory/CopyableAddress.d.ts.map +1 -0
- package/dist/components/inventory/CopyableAddress.js +18 -0
- package/dist/components/inventory/InventoryToolbar.d.ts +25 -0
- package/dist/components/inventory/InventoryToolbar.d.ts.map +1 -0
- package/dist/components/inventory/InventoryToolbar.js +28 -0
- package/dist/components/inventory/NftGrid.d.ts +13 -0
- package/dist/components/inventory/NftGrid.d.ts.map +1 -0
- package/dist/components/inventory/NftGrid.js +29 -0
- package/dist/components/inventory/TokenLogo.d.ts +12 -0
- package/dist/components/inventory/TokenLogo.d.ts.map +1 -0
- package/dist/components/inventory/TokenLogo.js +33 -0
- package/dist/components/inventory/TokensTable.d.ts +24 -0
- package/dist/components/inventory/TokensTable.d.ts.map +1 -0
- package/dist/components/inventory/TokensTable.js +26 -0
- package/dist/components/inventory/constants.d.ts +52 -0
- package/dist/components/inventory/constants.d.ts.map +1 -0
- package/dist/components/inventory/constants.js +121 -0
- package/dist/components/inventory/index.d.ts +9 -0
- package/dist/components/inventory/index.d.ts.map +1 -0
- package/dist/components/inventory/index.js +8 -0
- package/dist/components/inventory/media-url.d.ts +6 -0
- package/dist/components/inventory/media-url.d.ts.map +1 -0
- package/dist/components/inventory/media-url.js +28 -0
- package/dist/components/inventory/useInventoryData.d.ts +53 -0
- package/dist/components/inventory/useInventoryData.d.ts.map +1 -0
- package/dist/components/inventory/useInventoryData.js +332 -0
- package/dist/components/knowledge-upload-image.d.ts +27 -0
- package/dist/components/knowledge-upload-image.d.ts.map +1 -0
- package/dist/components/knowledge-upload-image.js +146 -0
- package/dist/components/labels.d.ts +6 -0
- package/dist/components/labels.d.ts.map +1 -0
- package/dist/components/labels.js +40 -0
- package/dist/components/onboarding/ActivateStep.d.ts +2 -0
- package/dist/components/onboarding/ActivateStep.d.ts.map +1 -0
- package/dist/components/onboarding/ActivateStep.js +6 -0
- package/dist/components/onboarding/ConnectionStep.d.ts +2 -0
- package/dist/components/onboarding/ConnectionStep.d.ts.map +1 -0
- package/dist/components/onboarding/ConnectionStep.js +552 -0
- package/dist/components/onboarding/OnboardingPanel.d.ts +9 -0
- package/dist/components/onboarding/OnboardingPanel.d.ts.map +1 -0
- package/dist/components/onboarding/OnboardingPanel.js +24 -0
- package/dist/components/onboarding/OnboardingStepNav.d.ts +2 -0
- package/dist/components/onboarding/OnboardingStepNav.d.ts.map +1 -0
- package/dist/components/onboarding/OnboardingStepNav.js +14 -0
- package/dist/components/onboarding/PermissionsStep.d.ts +2 -0
- package/dist/components/onboarding/PermissionsStep.d.ts.map +1 -0
- package/dist/components/onboarding/PermissionsStep.js +7 -0
- package/dist/components/onboarding/RpcStep.d.ts +2 -0
- package/dist/components/onboarding/RpcStep.d.ts.map +1 -0
- package/dist/components/onboarding/RpcStep.js +125 -0
- package/dist/components/onboarding/WakeUpStep.d.ts +2 -0
- package/dist/components/onboarding/WakeUpStep.d.ts.map +1 -0
- package/dist/components/onboarding/WakeUpStep.js +82 -0
- package/dist/components/permissions/PermissionIcon.d.ts +4 -0
- package/dist/components/permissions/PermissionIcon.d.ts.map +1 -0
- package/dist/components/permissions/PermissionIcon.js +12 -0
- package/dist/components/permissions/StreamingPermissions.d.ts +20 -0
- package/dist/components/permissions/StreamingPermissions.d.ts.map +1 -0
- package/dist/components/permissions/StreamingPermissions.js +173 -0
- package/dist/components/plugins/showcase-data.d.ts +7 -0
- package/dist/components/plugins/showcase-data.d.ts.map +1 -0
- package/dist/components/plugins/showcase-data.js +464 -0
- package/dist/components/shared/ShellHeaderControls.d.ts +27 -0
- package/dist/components/shared/ShellHeaderControls.d.ts.map +1 -0
- package/dist/components/shared/ShellHeaderControls.js +60 -0
- package/dist/components/skeletons.d.ts +17 -0
- package/dist/components/skeletons.d.ts.map +1 -0
- package/dist/components/skeletons.js +22 -0
- package/dist/components/stream/ActivityFeed.d.ts +5 -0
- package/dist/components/stream/ActivityFeed.d.ts.map +1 -0
- package/dist/components/stream/ActivityFeed.js +57 -0
- package/dist/components/stream/AvatarPip.d.ts +5 -0
- package/dist/components/stream/AvatarPip.d.ts.map +1 -0
- package/dist/components/stream/AvatarPip.js +6 -0
- package/dist/components/stream/ChatContent.d.ts +6 -0
- package/dist/components/stream/ChatContent.d.ts.map +1 -0
- package/dist/components/stream/ChatContent.js +69 -0
- package/dist/components/stream/ChatTicker.d.ts +5 -0
- package/dist/components/stream/ChatTicker.d.ts.map +1 -0
- package/dist/components/stream/ChatTicker.js +34 -0
- package/dist/components/stream/IdleContent.d.ts +5 -0
- package/dist/components/stream/IdleContent.d.ts.map +1 -0
- package/dist/components/stream/IdleContent.js +17 -0
- package/dist/components/stream/StatusBar.d.ts +36 -0
- package/dist/components/stream/StatusBar.d.ts.map +1 -0
- package/dist/components/stream/StatusBar.js +140 -0
- package/dist/components/stream/StreamSettings.d.ts +33 -0
- package/dist/components/stream/StreamSettings.d.ts.map +1 -0
- package/dist/components/stream/StreamSettings.js +99 -0
- package/dist/components/stream/StreamTerminal.d.ts +2 -0
- package/dist/components/stream/StreamTerminal.d.ts.map +1 -0
- package/dist/components/stream/StreamTerminal.js +52 -0
- package/dist/components/stream/StreamVoiceConfig.d.ts +10 -0
- package/dist/components/stream/StreamVoiceConfig.d.ts.map +1 -0
- package/dist/components/stream/StreamVoiceConfig.js +88 -0
- package/dist/components/stream/helpers.d.ts +32 -0
- package/dist/components/stream/helpers.d.ts.map +1 -0
- package/dist/components/stream/helpers.js +110 -0
- package/dist/components/stream/overlays/OverlayLayer.d.ts +20 -0
- package/dist/components/stream/overlays/OverlayLayer.d.ts.map +1 -0
- package/dist/components/stream/overlays/OverlayLayer.js +24 -0
- package/dist/components/stream/overlays/built-in/ActionTickerWidget.d.ts +8 -0
- package/dist/components/stream/overlays/built-in/ActionTickerWidget.d.ts.map +1 -0
- package/dist/components/stream/overlays/built-in/ActionTickerWidget.js +44 -0
- package/dist/components/stream/overlays/built-in/AlertPopupWidget.d.ts +7 -0
- package/dist/components/stream/overlays/built-in/AlertPopupWidget.d.ts.map +1 -0
- package/dist/components/stream/overlays/built-in/AlertPopupWidget.js +62 -0
- package/dist/components/stream/overlays/built-in/BrandingWidget.d.ts +7 -0
- package/dist/components/stream/overlays/built-in/BrandingWidget.d.ts.map +1 -0
- package/dist/components/stream/overlays/built-in/BrandingWidget.js +36 -0
- package/dist/components/stream/overlays/built-in/CustomHtmlWidget.d.ts +26 -0
- package/dist/components/stream/overlays/built-in/CustomHtmlWidget.d.ts.map +1 -0
- package/dist/components/stream/overlays/built-in/CustomHtmlWidget.js +78 -0
- package/dist/components/stream/overlays/built-in/PeonGlassWidget.d.ts +11 -0
- package/dist/components/stream/overlays/built-in/PeonGlassWidget.d.ts.map +1 -0
- package/dist/components/stream/overlays/built-in/PeonGlassWidget.js +188 -0
- package/dist/components/stream/overlays/built-in/PeonHudWidget.d.ts +10 -0
- package/dist/components/stream/overlays/built-in/PeonHudWidget.d.ts.map +1 -0
- package/dist/components/stream/overlays/built-in/PeonHudWidget.js +168 -0
- package/dist/components/stream/overlays/built-in/PeonSakuraWidget.d.ts +11 -0
- package/dist/components/stream/overlays/built-in/PeonSakuraWidget.d.ts.map +1 -0
- package/dist/components/stream/overlays/built-in/PeonSakuraWidget.js +213 -0
- package/dist/components/stream/overlays/built-in/ThoughtBubbleWidget.d.ts +8 -0
- package/dist/components/stream/overlays/built-in/ThoughtBubbleWidget.d.ts.map +1 -0
- package/dist/components/stream/overlays/built-in/ThoughtBubbleWidget.js +59 -0
- package/dist/components/stream/overlays/built-in/ViewerCountWidget.d.ts +7 -0
- package/dist/components/stream/overlays/built-in/ViewerCountWidget.d.ts.map +1 -0
- package/dist/components/stream/overlays/built-in/ViewerCountWidget.js +34 -0
- package/dist/components/stream/overlays/built-in/index.d.ts +13 -0
- package/dist/components/stream/overlays/built-in/index.d.ts.map +1 -0
- package/dist/components/stream/overlays/built-in/index.js +12 -0
- package/dist/components/stream/overlays/registry.d.ts +11 -0
- package/dist/components/stream/overlays/registry.d.ts.map +1 -0
- package/dist/components/stream/overlays/registry.js +16 -0
- package/dist/components/stream/overlays/types.d.ts +67 -0
- package/dist/components/stream/overlays/types.d.ts.map +1 -0
- package/dist/components/stream/overlays/types.js +7 -0
- package/dist/components/stream/overlays/useOverlayLayout.d.ts +27 -0
- package/dist/components/stream/overlays/useOverlayLayout.d.ts.map +1 -0
- package/dist/components/stream/overlays/useOverlayLayout.js +162 -0
- package/dist/components/trajectory-format.d.ts +6 -0
- package/dist/components/trajectory-format.d.ts.map +1 -0
- package/dist/components/trajectory-format.js +43 -0
- package/dist/components/ui-badges.d.ts +23 -0
- package/dist/components/ui-badges.d.ts.map +1 -0
- package/dist/components/ui-badges.js +38 -0
- package/dist/components/ui-switch.d.ts +14 -0
- package/dist/components/ui-switch.d.ts.map +1 -0
- package/dist/components/ui-switch.js +15 -0
- package/dist/components/vector-browser-three.d.ts +4 -0
- package/dist/components/vector-browser-three.d.ts.map +1 -0
- package/dist/components/vector-browser-three.js +19 -0
- package/dist/config/config-catalog.d.ts +376 -0
- package/dist/config/config-catalog.d.ts.map +1 -0
- package/dist/config/config-catalog.js +724 -0
- package/dist/config/config-field.d.ts +68 -0
- package/dist/config/config-field.d.ts.map +1 -0
- package/dist/config/config-field.js +821 -0
- package/dist/config/config-renderer.d.ts +176 -0
- package/dist/config/config-renderer.d.ts.map +1 -0
- package/dist/config/config-renderer.js +403 -0
- package/dist/config/index.d.ts +5 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +4 -0
- package/dist/config/ui-renderer.d.ts +26 -0
- package/dist/config/ui-renderer.d.ts.map +1 -0
- package/dist/config/ui-renderer.js +815 -0
- package/dist/config/ui-spec.d.ts +164 -0
- package/dist/config/ui-spec.d.ts.map +1 -0
- package/dist/config/ui-spec.js +13 -0
- package/dist/events/index.d.ts +42 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +41 -0
- package/dist/hooks/index.d.ts +14 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +13 -0
- package/dist/hooks/useBugReport.d.ts +14 -0
- package/dist/hooks/useBugReport.d.ts.map +1 -0
- package/dist/hooks/useBugReport.js +18 -0
- package/dist/hooks/useCanvasWindow.d.ts +38 -0
- package/dist/hooks/useCanvasWindow.d.ts.map +1 -0
- package/dist/hooks/useCanvasWindow.js +273 -0
- package/dist/hooks/useChatAvatarVoice.d.ts +10 -0
- package/dist/hooks/useChatAvatarVoice.d.ts.map +1 -0
- package/dist/hooks/useChatAvatarVoice.js +71 -0
- package/dist/hooks/useContextMenu.d.ts +17 -0
- package/dist/hooks/useContextMenu.d.ts.map +1 -0
- package/dist/hooks/useContextMenu.js +100 -0
- package/dist/hooks/useKeyboardShortcuts.d.ts +17 -0
- package/dist/hooks/useKeyboardShortcuts.d.ts.map +1 -0
- package/dist/hooks/useKeyboardShortcuts.js +67 -0
- package/dist/hooks/useLifoSync.d.ts +18 -0
- package/dist/hooks/useLifoSync.d.ts.map +1 -0
- package/dist/hooks/useLifoSync.js +113 -0
- package/dist/hooks/useMemoryMonitor.d.ts +87 -0
- package/dist/hooks/useMemoryMonitor.d.ts.map +1 -0
- package/dist/hooks/useMemoryMonitor.js +210 -0
- package/dist/hooks/useRenderGuard.d.ts +17 -0
- package/dist/hooks/useRenderGuard.d.ts.map +1 -0
- package/dist/hooks/useRenderGuard.js +36 -0
- package/dist/hooks/useRetakeCapture.d.ts +12 -0
- package/dist/hooks/useRetakeCapture.d.ts.map +1 -0
- package/dist/hooks/useRetakeCapture.js +59 -0
- package/dist/hooks/useStreamPopoutNavigation.d.ts +3 -0
- package/dist/hooks/useStreamPopoutNavigation.d.ts.map +1 -0
- package/dist/hooks/useStreamPopoutNavigation.js +17 -0
- package/dist/hooks/useTimeout.d.ts +11 -0
- package/dist/hooks/useTimeout.d.ts.map +1 -0
- package/dist/hooks/useTimeout.js +32 -0
- package/dist/hooks/useVoiceChat.d.ts +129 -0
- package/dist/hooks/useVoiceChat.d.ts.map +1 -0
- package/dist/hooks/useVoiceChat.js +1071 -0
- package/dist/hooks/useWhatsAppPairing.d.ts +11 -0
- package/dist/hooks/useWhatsAppPairing.d.ts.map +1 -0
- package/dist/hooks/useWhatsAppPairing.js +95 -0
- package/dist/i18n/index.d.ts +7 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +53 -0
- package/dist/i18n/locales/en.json +1196 -0
- package/dist/i18n/locales/es.json +1196 -0
- package/dist/i18n/locales/ko.json +1196 -0
- package/dist/i18n/locales/pt.json +1196 -0
- package/dist/i18n/locales/zh-CN.json +1196 -0
- package/dist/i18n/messages.d.ts +6 -0
- package/dist/i18n/messages.d.ts.map +1 -0
- package/dist/i18n/messages.js +14 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/navigation/index.d.ts +27 -0
- package/dist/navigation/index.d.ts.map +1 -0
- package/dist/navigation/index.js +230 -0
- package/dist/package.json +161 -0
- package/dist/platform/browser-launch.d.ts +2 -0
- package/dist/platform/browser-launch.d.ts.map +1 -0
- package/dist/platform/browser-launch.js +109 -0
- package/dist/platform/index.d.ts +64 -0
- package/dist/platform/index.d.ts.map +1 -0
- package/dist/platform/index.js +155 -0
- package/dist/platform/init.d.ts +40 -0
- package/dist/platform/init.d.ts.map +1 -0
- package/dist/platform/init.js +158 -0
- package/dist/providers/index.d.ts +13 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +72 -0
- package/dist/state/AppContext.d.ts +11 -0
- package/dist/state/AppContext.d.ts.map +1 -0
- package/dist/state/AppContext.js +4496 -0
- package/dist/state/index.d.ts +7 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +6 -0
- package/dist/state/internal.d.ts +6 -0
- package/dist/state/internal.d.ts.map +1 -0
- package/dist/state/internal.js +5 -0
- package/dist/state/parsers.d.ts +26 -0
- package/dist/state/parsers.d.ts.map +1 -0
- package/dist/state/parsers.js +255 -0
- package/dist/state/persistence.d.ts +36 -0
- package/dist/state/persistence.d.ts.map +1 -0
- package/dist/state/persistence.js +254 -0
- package/dist/state/types.d.ts +402 -0
- package/dist/state/types.d.ts.map +1 -0
- package/dist/state/types.js +70 -0
- package/dist/state/ui-preferences.d.ts +3 -0
- package/dist/state/ui-preferences.d.ts.map +1 -0
- package/dist/state/ui-preferences.js +1 -0
- package/dist/state/useApp.d.ts +4 -0
- package/dist/state/useApp.d.ts.map +1 -0
- package/dist/state/useApp.js +22 -0
- package/dist/state/vrm.d.ts +19 -0
- package/dist/state/vrm.d.ts.map +1 -0
- package/dist/state/vrm.js +65 -0
- package/dist/stories/AppMockProvider.d.ts +15 -0
- package/dist/stories/AppMockProvider.d.ts.map +1 -0
- package/dist/stories/AppMockProvider.js +14 -0
- package/dist/styles/anime.css +6324 -0
- package/dist/styles/base.css +196 -0
- package/dist/styles/onboarding-game.css +716 -0
- package/dist/styles/styles.css +2085 -0
- package/dist/styles/xterm.css +241 -0
- package/dist/types/index.d.ts +657 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +1 -0
- package/dist/utils/asset-url.d.ts +26 -0
- package/dist/utils/asset-url.d.ts.map +1 -0
- package/dist/utils/asset-url.js +99 -0
- package/dist/utils/assistant-text.d.ts +2 -0
- package/dist/utils/assistant-text.d.ts.map +1 -0
- package/dist/utils/assistant-text.js +161 -0
- package/dist/utils/clipboard.d.ts +2 -0
- package/dist/utils/clipboard.d.ts.map +1 -0
- package/dist/utils/clipboard.js +38 -0
- package/dist/utils/desktop-dialogs.d.ts +19 -0
- package/dist/utils/desktop-dialogs.d.ts.map +1 -0
- package/dist/utils/desktop-dialogs.js +50 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/number-parsing.d.ts +44 -0
- package/dist/utils/number-parsing.d.ts.map +1 -0
- package/dist/utils/number-parsing.js +56 -0
- package/dist/utils/openExternalUrl.d.ts +2 -0
- package/dist/utils/openExternalUrl.d.ts.map +1 -0
- package/dist/utils/openExternalUrl.js +17 -0
- package/dist/utils/spoken-text.d.ts +2 -0
- package/dist/utils/spoken-text.d.ts.map +1 -0
- package/dist/utils/spoken-text.js +56 -0
- package/dist/utils/streaming-text.d.ts +3 -0
- package/dist/utils/streaming-text.d.ts.map +1 -0
- package/dist/utils/streaming-text.js +87 -0
- package/dist/voice/index.d.ts +2 -0
- package/dist/voice/index.d.ts.map +1 -0
- package/dist/voice/index.js +1 -0
- package/dist/voice/types.d.ts +25 -0
- package/dist/voice/types.d.ts.map +1 -0
- package/dist/voice/types.js +166 -0
- package/package.json +86 -0
- package/src/App.tsx +469 -0
- package/src/actions/character.ts +113 -0
- package/src/actions/chat-helpers.ts +100 -0
- package/src/actions/cloud.ts +59 -0
- package/src/actions/index.ts +12 -0
- package/src/actions/lifecycle.ts +175 -0
- package/src/actions/onboarding.ts +46 -0
- package/src/actions/triggers.ts +190 -0
- package/src/ambient.d.ts +16 -0
- package/src/api/client.ts +5616 -0
- package/src/api/index.ts +1 -0
- package/src/autonomy/index.ts +477 -0
- package/src/bridge/capacitor-bridge.ts +295 -0
- package/src/bridge/electrobun-rpc.ts +58 -0
- package/src/bridge/electrobun-runtime.ts +28 -0
- package/src/bridge/index.ts +5 -0
- package/src/bridge/native-plugins.ts +134 -0
- package/src/bridge/plugin-bridge.ts +352 -0
- package/src/bridge/storage-bridge.ts +162 -0
- package/src/chat/index.ts +251 -0
- package/src/coding/index.ts +43 -0
- package/src/components/AdvancedPageView.tsx +362 -0
- package/src/components/AgentActivityBox.tsx +49 -0
- package/src/components/ApiKeyConfig.tsx +224 -0
- package/src/components/AppsPageView.tsx +52 -0
- package/src/components/AppsView.tsx +293 -0
- package/src/components/AvatarLoader.tsx +86 -0
- package/src/components/AvatarSelector.tsx +223 -0
- package/src/components/BscTradePanel.tsx +549 -0
- package/src/components/BugReportModal.tsx +499 -0
- package/src/components/CharacterView.tsx +1623 -0
- package/src/components/ChatAvatar.test.ts +96 -0
- package/src/components/ChatAvatar.tsx +147 -0
- package/src/components/ChatComposer.tsx +330 -0
- package/src/components/ChatMessage.tsx +448 -0
- package/src/components/ChatModalView.test.tsx +118 -0
- package/src/components/ChatModalView.tsx +125 -0
- package/src/components/ChatView.tsx +999 -0
- package/src/components/CloudSourceControls.tsx +80 -0
- package/src/components/CodingAgentSettingsSection.tsx +536 -0
- package/src/components/CommandPalette.tsx +284 -0
- package/src/components/CompanionSceneHost.tsx +498 -0
- package/src/components/CompanionShell.tsx +31 -0
- package/src/components/CompanionView.tsx +109 -0
- package/src/components/ConfigPageView.tsx +722 -0
- package/src/components/ConfigSaveFooter.tsx +41 -0
- package/src/components/ConfirmModal.tsx +379 -0
- package/src/components/ConnectionFailedBanner.tsx +91 -0
- package/src/components/ConnectorsPageView.tsx +13 -0
- package/src/components/ConversationsSidebar.tsx +279 -0
- package/src/components/CustomActionEditor.tsx +1125 -0
- package/src/components/CustomActionsPanel.tsx +288 -0
- package/src/components/CustomActionsView.tsx +322 -0
- package/src/components/DatabasePageView.tsx +55 -0
- package/src/components/DatabaseView.tsx +814 -0
- package/src/components/ElizaCloudDashboard.tsx +1696 -0
- package/src/components/EmotePicker.tsx +529 -0
- package/src/components/ErrorBoundary.tsx +76 -0
- package/src/components/FineTuningView.tsx +1080 -0
- package/src/components/GameView.tsx +551 -0
- package/src/components/GameViewOverlay.tsx +133 -0
- package/src/components/GlobalEmoteOverlay.tsx +152 -0
- package/src/components/Header.test.tsx +413 -0
- package/src/components/Header.tsx +400 -0
- package/src/components/HeartbeatsView.tsx +1002 -0
- package/src/components/InventoryView.tsx +372 -0
- package/src/components/KnowledgeView.tsx +1128 -0
- package/src/components/LanguageDropdown.tsx +187 -0
- package/src/components/LifoMonitorPanel.tsx +196 -0
- package/src/components/LifoSandboxView.tsx +499 -0
- package/src/components/LoadingScreen.tsx +77 -0
- package/src/components/LogsPageView.tsx +17 -0
- package/src/components/LogsView.tsx +239 -0
- package/src/components/MediaGalleryView.tsx +432 -0
- package/src/components/MediaSettingsSection.tsx +893 -0
- package/src/components/MessageContent.tsx +815 -0
- package/src/components/OnboardingWizard.test.tsx +107 -0
- package/src/components/OnboardingWizard.tsx +186 -0
- package/src/components/PairingView.tsx +110 -0
- package/src/components/PermissionsSection.tsx +818 -0
- package/src/components/PluginsPageView.tsx +9 -0
- package/src/components/PluginsView.tsx +3152 -0
- package/src/components/ProviderSwitcher.tsx +874 -0
- package/src/components/RestartBanner.tsx +76 -0
- package/src/components/RuntimeView.tsx +460 -0
- package/src/components/SaveCommandModal.tsx +211 -0
- package/src/components/SecretsView.tsx +569 -0
- package/src/components/SettingsView.tsx +825 -0
- package/src/components/ShellOverlays.tsx +41 -0
- package/src/components/ShortcutsOverlay.tsx +155 -0
- package/src/components/SkillsView.tsx +1435 -0
- package/src/components/StartupFailureView.tsx +63 -0
- package/src/components/StreamView.tsx +483 -0
- package/src/components/StripeEmbeddedCheckout.tsx +155 -0
- package/src/components/SubscriptionStatus.tsx +634 -0
- package/src/components/SystemWarningBanner.tsx +71 -0
- package/src/components/ThemeToggle.tsx +100 -0
- package/src/components/TrajectoriesView.tsx +526 -0
- package/src/components/TrajectoryDetailView.tsx +426 -0
- package/src/components/TriggersView.tsx +1 -0
- package/src/components/VectorBrowserView.tsx +1633 -0
- package/src/components/VoiceConfigView.tsx +674 -0
- package/src/components/VrmStage.test.ts +219 -0
- package/src/components/VrmStage.tsx +432 -0
- package/src/components/WhatsAppQrOverlay.tsx +230 -0
- package/src/components/__tests__/chainConfig.test.ts +220 -0
- package/src/components/apps/AppDetailPane.tsx +242 -0
- package/src/components/apps/AppsCatalogGrid.tsx +137 -0
- package/src/components/apps/extensions/HyperscapeAppDetailPanel.tsx +577 -0
- package/src/components/apps/extensions/registry.ts +16 -0
- package/src/components/apps/extensions/types.ts +9 -0
- package/src/components/apps/helpers.ts +44 -0
- package/src/components/avatar/VrmAnimationLoader.test.ts +164 -0
- package/src/components/avatar/VrmAnimationLoader.ts +151 -0
- package/src/components/avatar/VrmBlinkController.ts +118 -0
- package/src/components/avatar/VrmCameraManager.ts +407 -0
- package/src/components/avatar/VrmEngine.ts +2678 -0
- package/src/components/avatar/VrmFootShadow.ts +96 -0
- package/src/components/avatar/VrmViewer.tsx +421 -0
- package/src/components/avatar/__tests__/VrmCameraManager.test.ts +168 -0
- package/src/components/avatar/__tests__/VrmEngine.test.ts +1574 -0
- package/src/components/avatar/mixamoVRMRigMap.ts +62 -0
- package/src/components/avatar/retargetMixamoFbxToVrm.ts +144 -0
- package/src/components/avatar/retargetMixamoGltfToVrm.ts +119 -0
- package/src/components/chainConfig.ts +380 -0
- package/src/components/companion/CompanionHeader.tsx +47 -0
- package/src/components/companion/CompanionSceneHost.tsx +5 -0
- package/src/components/companion/VrmStage.tsx +2 -0
- package/src/components/companion/__tests__/walletUtils.test.ts +742 -0
- package/src/components/companion/walletUtils.ts +290 -0
- package/src/components/companion-shell-styles.test.ts +146 -0
- package/src/components/companion-shell-styles.ts +270 -0
- package/src/components/confirm-delete-control.tsx +69 -0
- package/src/components/conversations/ConversationListItem.tsx +185 -0
- package/src/components/conversations/conversation-utils.ts +151 -0
- package/src/components/format.ts +131 -0
- package/src/components/index.ts +92 -0
- package/src/components/inventory/CopyableAddress.tsx +41 -0
- package/src/components/inventory/InventoryToolbar.tsx +142 -0
- package/src/components/inventory/NftGrid.tsx +99 -0
- package/src/components/inventory/TokenLogo.tsx +71 -0
- package/src/components/inventory/TokensTable.tsx +216 -0
- package/src/components/inventory/constants.ts +170 -0
- package/src/components/inventory/index.ts +29 -0
- package/src/components/inventory/media-url.test.ts +38 -0
- package/src/components/inventory/media-url.ts +36 -0
- package/src/components/inventory/useInventoryData.ts +460 -0
- package/src/components/knowledge-upload-image.ts +215 -0
- package/src/components/labels.ts +46 -0
- package/src/components/onboarding/ActivateStep.tsx +30 -0
- package/src/components/onboarding/ConnectionStep.tsx +1530 -0
- package/src/components/onboarding/OnboardingPanel.tsx +39 -0
- package/src/components/onboarding/OnboardingStepNav.tsx +31 -0
- package/src/components/onboarding/PermissionsStep.tsx +20 -0
- package/src/components/onboarding/RpcStep.tsx +402 -0
- package/src/components/onboarding/WakeUpStep.tsx +184 -0
- package/src/components/permissions/PermissionIcon.tsx +25 -0
- package/src/components/permissions/StreamingPermissions.tsx +376 -0
- package/src/components/plugins/showcase-data.ts +481 -0
- package/src/components/shared/ShellHeaderControls.tsx +193 -0
- package/src/components/skeletons.tsx +88 -0
- package/src/components/stream/ActivityFeed.tsx +113 -0
- package/src/components/stream/AvatarPip.tsx +10 -0
- package/src/components/stream/ChatContent.tsx +126 -0
- package/src/components/stream/ChatTicker.tsx +55 -0
- package/src/components/stream/IdleContent.tsx +73 -0
- package/src/components/stream/StatusBar.tsx +469 -0
- package/src/components/stream/StreamSettings.tsx +506 -0
- package/src/components/stream/StreamTerminal.tsx +94 -0
- package/src/components/stream/StreamVoiceConfig.tsx +160 -0
- package/src/components/stream/helpers.ts +134 -0
- package/src/components/stream/overlays/OverlayLayer.tsx +75 -0
- package/src/components/stream/overlays/built-in/ActionTickerWidget.tsx +64 -0
- package/src/components/stream/overlays/built-in/AlertPopupWidget.tsx +87 -0
- package/src/components/stream/overlays/built-in/BrandingWidget.tsx +51 -0
- package/src/components/stream/overlays/built-in/CustomHtmlWidget.tsx +105 -0
- package/src/components/stream/overlays/built-in/PeonGlassWidget.tsx +265 -0
- package/src/components/stream/overlays/built-in/PeonHudWidget.tsx +247 -0
- package/src/components/stream/overlays/built-in/PeonSakuraWidget.tsx +278 -0
- package/src/components/stream/overlays/built-in/ThoughtBubbleWidget.tsx +77 -0
- package/src/components/stream/overlays/built-in/ViewerCountWidget.tsx +46 -0
- package/src/components/stream/overlays/built-in/index.ts +13 -0
- package/src/components/stream/overlays/registry.ts +22 -0
- package/src/components/stream/overlays/types.ts +90 -0
- package/src/components/stream/overlays/useOverlayLayout.ts +218 -0
- package/src/components/trajectory-format.ts +50 -0
- package/src/components/ui-badges.tsx +109 -0
- package/src/components/ui-switch.tsx +57 -0
- package/src/components/vector-browser-three.ts +27 -0
- package/src/config/config-catalog.ts +1092 -0
- package/src/config/config-field.tsx +1900 -0
- package/src/config/config-renderer.tsx +730 -0
- package/src/config/index.ts +11 -0
- package/src/config/ui-renderer.tsx +1751 -0
- package/src/config/ui-spec.ts +256 -0
- package/src/events/index.ts +89 -0
- package/src/hooks/index.ts +13 -0
- package/src/hooks/useBugReport.tsx +43 -0
- package/src/hooks/useCanvasWindow.ts +372 -0
- package/src/hooks/useChatAvatarVoice.ts +111 -0
- package/src/hooks/useContextMenu.ts +127 -0
- package/src/hooks/useKeyboardShortcuts.ts +86 -0
- package/src/hooks/useLifoSync.ts +143 -0
- package/src/hooks/useMemoryMonitor.ts +335 -0
- package/src/hooks/useRenderGuard.ts +43 -0
- package/src/hooks/useRetakeCapture.ts +67 -0
- package/src/hooks/useStreamPopoutNavigation.ts +27 -0
- package/src/hooks/useTimeout.ts +37 -0
- package/src/hooks/useVoiceChat.ts +1443 -0
- package/src/hooks/useWhatsAppPairing.ts +123 -0
- package/src/i18n/index.ts +76 -0
- package/src/i18n/locales/en.json +1196 -0
- package/src/i18n/locales/es.json +1196 -0
- package/src/i18n/locales/ko.json +1196 -0
- package/src/i18n/locales/pt.json +1196 -0
- package/src/i18n/locales/zh-CN.json +1196 -0
- package/src/i18n/messages.ts +21 -0
- package/src/index.ts +6 -0
- package/src/navigation/index.ts +282 -0
- package/src/navigation.test.ts +189 -0
- package/src/platform/browser-launch.test.ts +94 -0
- package/src/platform/browser-launch.ts +149 -0
- package/src/platform/index.ts +261 -0
- package/src/platform/init.ts +236 -0
- package/src/providers/index.ts +82 -0
- package/src/state/AppContext.tsx +5737 -0
- package/src/state/index.ts +6 -0
- package/src/state/internal.ts +77 -0
- package/src/state/parsers.test.ts +124 -0
- package/src/state/parsers.ts +309 -0
- package/src/state/persistence.ts +278 -0
- package/src/state/types.ts +694 -0
- package/src/state/ui-preferences.ts +3 -0
- package/src/state/useApp.ts +23 -0
- package/src/state/vrm.ts +76 -0
- package/src/stories/AppMockProvider.tsx +32 -0
- package/src/stories/ChatEmptyState.stories.tsx +27 -0
- package/src/stories/ChatMessage.stories.tsx +115 -0
- package/src/stories/CompanionHeader.stories.tsx +74 -0
- package/src/stories/CompanionView.stories.tsx +33 -0
- package/src/stories/ConversationListItem.stories.tsx +102 -0
- package/src/stories/TypingIndicator.stories.tsx +28 -0
- package/src/styles/anime.css +6324 -0
- package/src/styles/base.css +196 -0
- package/src/styles/onboarding-game.css +716 -0
- package/src/styles/styles.css +2085 -0
- package/src/styles/xterm.css +241 -0
- package/src/types/index.ts +715 -0
- package/src/types/react-test-renderer.d.ts +45 -0
- package/src/utils/asset-url.ts +110 -0
- package/src/utils/assistant-text.ts +172 -0
- package/src/utils/clipboard.ts +41 -0
- package/src/utils/desktop-dialogs.ts +80 -0
- package/src/utils/index.ts +6 -0
- package/src/utils/number-parsing.ts +125 -0
- package/src/utils/openExternalUrl.ts +20 -0
- package/src/utils/spoken-text.ts +65 -0
- package/src/utils/streaming-text.ts +120 -0
- package/src/voice/index.ts +1 -0
- package/src/voice/types.ts +197 -0
- package/test/app/AppContext.pty-sessions.test.tsx +143 -0
- package/test/app/MessageContent.test.tsx +326 -0
- package/test/app/PermissionsOnboarding.test.tsx +216 -0
- package/test/app/PermissionsSection.test.tsx +186 -0
- package/test/app/advanced-trajectory-fine-tuning.e2e.test.ts +397 -0
- package/test/app/agent-activity-box.test.tsx +132 -0
- package/test/app/agent-transfer-lock.test.ts +274 -0
- package/test/app/api-client-electron-fallback.test.ts +139 -0
- package/test/app/api-client-timeout.test.ts +75 -0
- package/test/app/api-client-ws.test.ts +98 -0
- package/test/app/api-client.ws-max-reconnect.test.ts +139 -0
- package/test/app/api-client.ws-reconnect.test.ts +157 -0
- package/test/app/app-context-autonomy-events.test.ts +478 -0
- package/test/app/apps-page-view.test.ts +114 -0
- package/test/app/apps-view.test.ts +769 -0
- package/test/app/autonomous-workflows.e2e.test.ts +765 -0
- package/test/app/autonomy-events.test.ts +150 -0
- package/test/app/avatar-selector.test.tsx +52 -0
- package/test/app/bsc-trade-panel.test.tsx +134 -0
- package/test/app/bug-report-modal.test.tsx +353 -0
- package/test/app/character-customization.e2e.test.ts +1168 -0
- package/test/app/chat-advanced-features.e2e.test.ts +706 -0
- package/test/app/chat-composer.test.tsx +181 -0
- package/test/app/chat-language-header.test.ts +64 -0
- package/test/app/chat-message.test.tsx +222 -0
- package/test/app/chat-modal-view.test.tsx +191 -0
- package/test/app/chat-routine-filter.test.ts +96 -0
- package/test/app/chat-send-lock.test.ts +1302 -0
- package/test/app/chat-stream-api-client.test.tsx +390 -0
- package/test/app/chat-view-game-modal.test.tsx +661 -0
- package/test/app/chat-view.test.tsx +877 -0
- package/test/app/cloud-api.e2e.test.ts +258 -0
- package/test/app/cloud-login-flow.e2e.test.ts +494 -0
- package/test/app/cloud-login-lock.test.ts +411 -0
- package/test/app/command-palette.test.tsx +184 -0
- package/test/app/command-registry.test.ts +75 -0
- package/test/app/companion-greeting-wave.test.tsx +443 -0
- package/test/app/companion-stale-conversation.test.tsx +424 -0
- package/test/app/companion-view.test.tsx +686 -0
- package/test/app/confirm-delete-control.test.ts +79 -0
- package/test/app/confirm-modal.test.tsx +219 -0
- package/test/app/connectors-ui.e2e.test.ts +508 -0
- package/test/app/conversations-sidebar-game-modal.test.tsx +260 -0
- package/test/app/conversations-sidebar.test.tsx +160 -0
- package/test/app/custom-actions-smoke.test.ts +387 -0
- package/test/app/custom-avatar-api-client.test.ts +207 -0
- package/test/app/desktop-utils.test.ts +145 -0
- package/test/app/electrobun-rpc-bridge.test.ts +83 -0
- package/test/app/events.test.ts +88 -0
- package/test/app/export-import-flows.e2e.test.ts +700 -0
- package/test/app/fine-tuning-view.test.ts +471 -0
- package/test/app/game-view-auth-session.test.tsx +186 -0
- package/test/app/game-view.test.ts +444 -0
- package/test/app/global-emote-overlay.test.tsx +106 -0
- package/test/app/header-status.test.tsx +149 -0
- package/test/app/i18n.test.ts +152 -0
- package/test/app/inventory-bsc-view.test.ts +908 -0
- package/test/app/knowledge-ui.e2e.test.ts +762 -0
- package/test/app/knowledge-upload-helpers.test.ts +124 -0
- package/test/app/lifecycle-lock.test.ts +267 -0
- package/test/app/lifo-popout-utils.test.ts +208 -0
- package/test/app/lifo-safe-endpoint.test.ts +34 -0
- package/test/app/loading-screen.test.tsx +45 -0
- package/test/app/memory-monitor.test.ts +332 -0
- package/test/app/navigation.test.tsx +29 -0
- package/test/app/onboarding-finish-lock.test.ts +500 -0
- package/test/app/onboarding-language.test.tsx +161 -0
- package/test/app/onboarding-steps.test.tsx +371 -0
- package/test/app/open-external-url.test.ts +65 -0
- package/test/app/pages-navigation-smoke.e2e.test.ts +633 -0
- package/test/app/pairing-lock.test.ts +260 -0
- package/test/app/pairing-view.test.tsx +74 -0
- package/test/app/permissions-section.test.ts +432 -0
- package/test/app/plugin-bridge.test.ts +109 -0
- package/test/app/plugins-ui.e2e.test.ts +605 -0
- package/test/app/plugins-view-game-modal.test.tsx +650 -0
- package/test/app/plugins-view-toggle-restart.test.ts +129 -0
- package/test/app/provider-dropdown-default.test.tsx +164 -0
- package/test/app/restart-banner.test.tsx +197 -0
- package/test/app/retake-capture.test.ts +84 -0
- package/test/app/sandbox-api-client.test.ts +108 -0
- package/test/app/save-command-modal.test.tsx +109 -0
- package/test/app/secrets-view.test.tsx +92 -0
- package/test/app/settings-control-styles.test.tsx +142 -0
- package/test/app/settings-reset.e2e.test.ts +728 -0
- package/test/app/settings-sections.e2e.test.ts +614 -0
- package/test/app/shared-format.test.ts +44 -0
- package/test/app/shared-switch.test.ts +69 -0
- package/test/app/shell-mode-switching.e2e.test.ts +829 -0
- package/test/app/shell-mode-tab-memory.test.tsx +283 -0
- package/test/app/shell-overlays.test.tsx +50 -0
- package/test/app/shortcuts-overlay.test.tsx +111 -0
- package/test/app/sse-interruption.test.ts +122 -0
- package/test/app/startup-asset-missing.e2e.test.ts +126 -0
- package/test/app/startup-backend-missing.e2e.test.ts +118 -0
- package/test/app/startup-chat.e2e.test.ts +305 -0
- package/test/app/startup-conversation-restore.test.tsx +344 -0
- package/test/app/startup-failure-view.test.tsx +103 -0
- package/test/app/startup-onboarding.e2e.test.ts +612 -0
- package/test/app/startup-timeout.test.tsx +80 -0
- package/test/app/startup-token-401.e2e.test.ts +103 -0
- package/test/app/stream-helpers.test.ts +46 -0
- package/test/app/stream-popout-navigation.test.tsx +41 -0
- package/test/app/stream-status-bar.test.tsx +89 -0
- package/test/app/theme-toggle.test.tsx +33 -0
- package/test/app/training-api-client.test.ts +128 -0
- package/test/app/trajectories-view.test.tsx +220 -0
- package/test/app/triggers-api-client.test.ts +77 -0
- package/test/app/triggers-navigation.test.ts +118 -0
- package/test/app/triggers-view.e2e.test.ts +674 -0
- package/test/app/update-channel-lock.test.ts +259 -0
- package/test/app/vector-browser.async-cleanup.test.tsx +367 -0
- package/test/app/vector-browser.e2e.test.ts +653 -0
- package/test/app/vrm-stage.test.tsx +351 -0
- package/test/app/vrm-viewer.test.tsx +298 -0
- package/test/app/wallet-api-save-lock.test.ts +277 -0
- package/test/app/wallet-hooks.test.ts +405 -0
- package/test/app/wallet-ui-flows.e2e.test.ts +556 -0
- package/test/avatar/asset-url.test.ts +90 -0
- package/test/avatar/avatar-selector.test.ts +173 -0
- package/test/avatar/mixamo-vrm-rig-map.test.ts +111 -0
- package/test/avatar/voice-chat-streaming-text.test.ts +96 -0
- package/test/avatar/voice-chat.test.ts +391 -0
- package/test/ui/command-palette-commands.test.ts +57 -0
- package/test/ui/ui-renderer.test.ts +39 -0
- package/tsconfig.build.json +19 -0
- package/tsconfig.json +21 -0
|
@@ -0,0 +1,2392 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API client for the Milady backend.
|
|
3
|
+
*
|
|
4
|
+
* Thin fetch wrapper + WebSocket for real-time chat/events.
|
|
5
|
+
* Replaces the gateway WebSocket protocol entirely.
|
|
6
|
+
*/
|
|
7
|
+
import { stripAssistantStageDirections } from "../utils/assistant-text";
|
|
8
|
+
import { mergeStreamingText } from "../utils/streaming-text";
|
|
9
|
+
export class ApiError extends Error {
|
|
10
|
+
kind;
|
|
11
|
+
status;
|
|
12
|
+
path;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
super(options.message);
|
|
15
|
+
this.name = "ApiError";
|
|
16
|
+
this.kind = options.kind;
|
|
17
|
+
this.path = options.path;
|
|
18
|
+
this.status = options.status;
|
|
19
|
+
if (options.cause !== undefined) {
|
|
20
|
+
this.cause = options.cause;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function isApiError(value) {
|
|
25
|
+
return value instanceof ApiError;
|
|
26
|
+
}
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Client
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
const GENERIC_NO_RESPONSE_TEXT = "Sorry, I couldn't generate a response right now. Please try again.";
|
|
31
|
+
const AGENT_TRANSFER_MIN_PASSWORD_LENGTH = 4;
|
|
32
|
+
const DEFAULT_FETCH_TIMEOUT_MS = 10_000;
|
|
33
|
+
const SESSION_STORAGE_API_BASE_KEY = "milady_api_base";
|
|
34
|
+
const SESSION_STORAGE_API_TOKEN_KEY = "milady_api_token";
|
|
35
|
+
export class MiladyClient {
|
|
36
|
+
_baseUrl;
|
|
37
|
+
_explicitBase;
|
|
38
|
+
_token;
|
|
39
|
+
clientId;
|
|
40
|
+
ws = null;
|
|
41
|
+
wsHandlers = new Map();
|
|
42
|
+
wsSendQueue = [];
|
|
43
|
+
wsSendQueueLimit = 32;
|
|
44
|
+
reconnectTimer = null;
|
|
45
|
+
backoffMs = 500;
|
|
46
|
+
wsHasConnectedOnce = false;
|
|
47
|
+
// Connection state tracking for backend crash handling
|
|
48
|
+
connectionState = "disconnected";
|
|
49
|
+
reconnectAttempt = 0;
|
|
50
|
+
disconnectedAt = null;
|
|
51
|
+
connectionStateListeners = new Set();
|
|
52
|
+
maxReconnectAttempts = 15;
|
|
53
|
+
// UI language propagation — set by AppContext so the backend can
|
|
54
|
+
// localise responses when needed.
|
|
55
|
+
_uiLanguage = null;
|
|
56
|
+
/** Store the current UI language so it can be sent as a header on every request. */
|
|
57
|
+
setUiLanguage(lang) {
|
|
58
|
+
this._uiLanguage = lang || null;
|
|
59
|
+
}
|
|
60
|
+
static resolveElectronLocalFallbackBase() {
|
|
61
|
+
if (typeof window === "undefined")
|
|
62
|
+
return "";
|
|
63
|
+
const proto = window.location.protocol;
|
|
64
|
+
// In capacitor-electron mode the main process injects the live API base
|
|
65
|
+
// once the embedded agent has bound a port. Avoid eager localhost probes
|
|
66
|
+
// to prevent noisy ERR_CONNECTION_REFUSED logs during startup.
|
|
67
|
+
if (proto === "capacitor-electron:")
|
|
68
|
+
return "";
|
|
69
|
+
// Legacy Electron file:// mode fallback.
|
|
70
|
+
if (proto === "file:" && /\bElectron\b/i.test(window.navigator.userAgent)) {
|
|
71
|
+
return "http://localhost:2138";
|
|
72
|
+
}
|
|
73
|
+
return "";
|
|
74
|
+
}
|
|
75
|
+
static generateClientId() {
|
|
76
|
+
const random = typeof globalThis.crypto?.randomUUID === "function"
|
|
77
|
+
? globalThis.crypto.randomUUID()
|
|
78
|
+
: `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`;
|
|
79
|
+
return `ui-${random.replace(/[^a-zA-Z0-9._-]/g, "")}`;
|
|
80
|
+
}
|
|
81
|
+
constructor(baseUrl, token) {
|
|
82
|
+
this.clientId = MiladyClient.generateClientId();
|
|
83
|
+
const stored = typeof window !== "undefined"
|
|
84
|
+
? window.sessionStorage.getItem(SESSION_STORAGE_API_TOKEN_KEY)
|
|
85
|
+
: null;
|
|
86
|
+
const storedBase = typeof window !== "undefined"
|
|
87
|
+
? window.sessionStorage.getItem(SESSION_STORAGE_API_BASE_KEY)
|
|
88
|
+
: null;
|
|
89
|
+
this._explicitBase = baseUrl != null || Boolean(storedBase?.trim());
|
|
90
|
+
this._token = token?.trim() || stored || null;
|
|
91
|
+
// Priority: explicit arg > Capacitor/Electron injected global > same origin (Vite proxy)
|
|
92
|
+
const injectedBase = typeof window !== "undefined" ? window.__MILADY_API_BASE__ : undefined;
|
|
93
|
+
this._baseUrl =
|
|
94
|
+
baseUrl ??
|
|
95
|
+
storedBase ??
|
|
96
|
+
injectedBase ??
|
|
97
|
+
MiladyClient.resolveElectronLocalFallbackBase();
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Resolve the API base URL lazily.
|
|
101
|
+
* In Electron the main process injects window.__MILADY_API_BASE__ after the
|
|
102
|
+
* page loads (once the agent runtime starts). Re-checking on every call
|
|
103
|
+
* ensures we pick up the injected value even if it wasn't set at construction.
|
|
104
|
+
*/
|
|
105
|
+
get baseUrl() {
|
|
106
|
+
if (!this._explicitBase && typeof window !== "undefined") {
|
|
107
|
+
const injected = window.__MILADY_API_BASE__;
|
|
108
|
+
// In Electron the API base can be injected after initial render. Always
|
|
109
|
+
// prefer the injected value when present so the client can switch away
|
|
110
|
+
// from the localhost fallback once the main process publishes the real
|
|
111
|
+
// endpoint.
|
|
112
|
+
if (injected && injected !== this._baseUrl) {
|
|
113
|
+
this._baseUrl = injected;
|
|
114
|
+
}
|
|
115
|
+
else if (!this._baseUrl) {
|
|
116
|
+
this._baseUrl = MiladyClient.resolveElectronLocalFallbackBase();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return this._baseUrl;
|
|
120
|
+
}
|
|
121
|
+
get apiToken() {
|
|
122
|
+
if (this._token)
|
|
123
|
+
return this._token;
|
|
124
|
+
if (typeof window === "undefined")
|
|
125
|
+
return null;
|
|
126
|
+
const injected = window.__MILADY_API_TOKEN__;
|
|
127
|
+
if (typeof injected === "string" && injected.trim())
|
|
128
|
+
return injected.trim();
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
hasToken() {
|
|
132
|
+
return Boolean(this.apiToken);
|
|
133
|
+
}
|
|
134
|
+
setToken(token) {
|
|
135
|
+
this._token = token?.trim() || null;
|
|
136
|
+
if (typeof window !== "undefined") {
|
|
137
|
+
if (this._token) {
|
|
138
|
+
window.__MILADY_API_TOKEN__ = this._token;
|
|
139
|
+
window.sessionStorage.setItem(SESSION_STORAGE_API_TOKEN_KEY, this._token);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
delete window.__MILADY_API_TOKEN__;
|
|
143
|
+
window.sessionStorage.removeItem(SESSION_STORAGE_API_TOKEN_KEY);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
setBaseUrl(baseUrl) {
|
|
148
|
+
const normalized = baseUrl?.trim().replace(/\/+$/, "") || "";
|
|
149
|
+
this._explicitBase = normalized.length > 0;
|
|
150
|
+
this._baseUrl = normalized;
|
|
151
|
+
this.disconnectWs();
|
|
152
|
+
if (typeof window !== "undefined") {
|
|
153
|
+
if (normalized) {
|
|
154
|
+
window.__MILADY_API_BASE__ = normalized;
|
|
155
|
+
window.sessionStorage.setItem(SESSION_STORAGE_API_BASE_KEY, normalized);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
delete window.__MILADY_API_BASE__;
|
|
159
|
+
window.sessionStorage.removeItem(SESSION_STORAGE_API_BASE_KEY);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/** True when we have a usable HTTP(S) API endpoint. */
|
|
164
|
+
get apiAvailable() {
|
|
165
|
+
if (this.baseUrl)
|
|
166
|
+
return true;
|
|
167
|
+
if (typeof window !== "undefined") {
|
|
168
|
+
const proto = window.location.protocol;
|
|
169
|
+
return proto === "http:" || proto === "https:";
|
|
170
|
+
}
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
// --- REST API ---
|
|
174
|
+
async rawRequest(path, init, options) {
|
|
175
|
+
if (!this.apiAvailable) {
|
|
176
|
+
throw new ApiError({
|
|
177
|
+
kind: "network",
|
|
178
|
+
path,
|
|
179
|
+
message: "API not available (no HTTP origin)",
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
const makeRequest = async (token) => {
|
|
183
|
+
let timeoutId;
|
|
184
|
+
let abortListener;
|
|
185
|
+
const requestInit = {
|
|
186
|
+
...init,
|
|
187
|
+
headers: {
|
|
188
|
+
"X-Milady-Client-Id": this.clientId,
|
|
189
|
+
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
|
190
|
+
...(this._uiLanguage
|
|
191
|
+
? { "X-Milady-UI-Language": this._uiLanguage }
|
|
192
|
+
: {}),
|
|
193
|
+
...init?.headers,
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
const fetchPromise = fetch(`${this.baseUrl}${path}`, requestInit);
|
|
197
|
+
const pending = [fetchPromise];
|
|
198
|
+
pending.push(new Promise((_, reject) => {
|
|
199
|
+
timeoutId = setTimeout(() => {
|
|
200
|
+
reject(new ApiError({
|
|
201
|
+
kind: "timeout",
|
|
202
|
+
path,
|
|
203
|
+
message: `Request timed out after ${DEFAULT_FETCH_TIMEOUT_MS}ms`,
|
|
204
|
+
}));
|
|
205
|
+
}, DEFAULT_FETCH_TIMEOUT_MS);
|
|
206
|
+
}));
|
|
207
|
+
if (init?.signal) {
|
|
208
|
+
if (init.signal.aborted) {
|
|
209
|
+
throw new ApiError({
|
|
210
|
+
kind: "network",
|
|
211
|
+
path,
|
|
212
|
+
message: "Request aborted",
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
pending.push(new Promise((_, reject) => {
|
|
216
|
+
abortListener = () => {
|
|
217
|
+
reject(new ApiError({
|
|
218
|
+
kind: "network",
|
|
219
|
+
path,
|
|
220
|
+
message: "Request aborted",
|
|
221
|
+
}));
|
|
222
|
+
};
|
|
223
|
+
init.signal?.addEventListener("abort", abortListener, {
|
|
224
|
+
once: true,
|
|
225
|
+
});
|
|
226
|
+
}));
|
|
227
|
+
}
|
|
228
|
+
try {
|
|
229
|
+
return await Promise.race(pending);
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
if (err instanceof ApiError) {
|
|
233
|
+
throw err;
|
|
234
|
+
}
|
|
235
|
+
throw new ApiError({
|
|
236
|
+
kind: "network",
|
|
237
|
+
path,
|
|
238
|
+
message: err instanceof Error && err.message
|
|
239
|
+
? err.message
|
|
240
|
+
: "Network request failed",
|
|
241
|
+
cause: err,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
finally {
|
|
245
|
+
if (timeoutId !== undefined) {
|
|
246
|
+
clearTimeout(timeoutId);
|
|
247
|
+
}
|
|
248
|
+
if (init?.signal && abortListener) {
|
|
249
|
+
init.signal.removeEventListener("abort", abortListener);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
const token = this.apiToken;
|
|
254
|
+
let res = await makeRequest(token);
|
|
255
|
+
if (res.status === 401 && !token) {
|
|
256
|
+
const retryToken = this.apiToken;
|
|
257
|
+
if (retryToken) {
|
|
258
|
+
res = await makeRequest(retryToken);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if (!res.ok && !options?.allowNonOk) {
|
|
262
|
+
const body = (await res
|
|
263
|
+
.json()
|
|
264
|
+
.catch(() => ({ error: res.statusText })));
|
|
265
|
+
throw new ApiError({
|
|
266
|
+
kind: "http",
|
|
267
|
+
path,
|
|
268
|
+
status: res.status,
|
|
269
|
+
message: body.error ?? `HTTP ${res.status}`,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
return res;
|
|
273
|
+
}
|
|
274
|
+
async fetch(path, init) {
|
|
275
|
+
const res = await this.rawRequest(path, {
|
|
276
|
+
...init,
|
|
277
|
+
headers: {
|
|
278
|
+
"Content-Type": "application/json",
|
|
279
|
+
...init?.headers,
|
|
280
|
+
},
|
|
281
|
+
});
|
|
282
|
+
return res.json();
|
|
283
|
+
}
|
|
284
|
+
async getStatus() {
|
|
285
|
+
return this.fetch("/api/status");
|
|
286
|
+
}
|
|
287
|
+
async getAgentSelfStatus() {
|
|
288
|
+
return this.fetch("/api/agent/self-status");
|
|
289
|
+
}
|
|
290
|
+
async getRuntimeSnapshot(opts) {
|
|
291
|
+
const params = new URLSearchParams();
|
|
292
|
+
if (typeof opts?.depth === "number")
|
|
293
|
+
params.set("depth", String(opts.depth));
|
|
294
|
+
if (typeof opts?.maxArrayLength === "number") {
|
|
295
|
+
params.set("maxArrayLength", String(opts.maxArrayLength));
|
|
296
|
+
}
|
|
297
|
+
if (typeof opts?.maxObjectEntries === "number") {
|
|
298
|
+
params.set("maxObjectEntries", String(opts.maxObjectEntries));
|
|
299
|
+
}
|
|
300
|
+
if (typeof opts?.maxStringLength === "number") {
|
|
301
|
+
params.set("maxStringLength", String(opts.maxStringLength));
|
|
302
|
+
}
|
|
303
|
+
const qs = params.toString();
|
|
304
|
+
return this.fetch(`/api/runtime${qs ? `?${qs}` : ""}`);
|
|
305
|
+
}
|
|
306
|
+
async setAutomationMode(mode) {
|
|
307
|
+
return this.fetch("/api/permissions/automation-mode", {
|
|
308
|
+
method: "PUT",
|
|
309
|
+
body: JSON.stringify({ mode }),
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
async setTradeMode(mode) {
|
|
313
|
+
return this.fetch("/api/permissions/trade-mode", {
|
|
314
|
+
method: "PUT",
|
|
315
|
+
body: JSON.stringify({ mode }),
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
async playEmote(emoteId) {
|
|
319
|
+
return this.fetch("/api/emote", {
|
|
320
|
+
method: "POST",
|
|
321
|
+
body: JSON.stringify({ emoteId }),
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
async runTerminalCommand(command) {
|
|
325
|
+
return this.fetch("/api/terminal/run", {
|
|
326
|
+
method: "POST",
|
|
327
|
+
body: JSON.stringify({ command }),
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
async getOnboardingStatus() {
|
|
331
|
+
return this.fetch("/api/onboarding/status");
|
|
332
|
+
}
|
|
333
|
+
async getAuthStatus() {
|
|
334
|
+
try {
|
|
335
|
+
return await this.fetch("/api/auth/status");
|
|
336
|
+
}
|
|
337
|
+
catch (err) {
|
|
338
|
+
const status = err?.status;
|
|
339
|
+
if (status === 401) {
|
|
340
|
+
// Server requires auth
|
|
341
|
+
return { required: true, pairingEnabled: false, expiresAt: null };
|
|
342
|
+
}
|
|
343
|
+
if (status === 404) {
|
|
344
|
+
// npm-installed server without auth routes — no auth required
|
|
345
|
+
return { required: false, pairingEnabled: false, expiresAt: null };
|
|
346
|
+
}
|
|
347
|
+
// Other errors (500, network) — re-throw so caller can handle
|
|
348
|
+
throw err;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
async pair(code) {
|
|
352
|
+
const res = await this.fetch("/api/auth/pair", {
|
|
353
|
+
method: "POST",
|
|
354
|
+
body: JSON.stringify({ code }),
|
|
355
|
+
});
|
|
356
|
+
return res;
|
|
357
|
+
}
|
|
358
|
+
async getOnboardingOptions() {
|
|
359
|
+
return this.fetch("/api/onboarding/options");
|
|
360
|
+
}
|
|
361
|
+
async submitOnboarding(data) {
|
|
362
|
+
await this.fetch("/api/onboarding", {
|
|
363
|
+
method: "POST",
|
|
364
|
+
body: JSON.stringify(data),
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
async startAnthropicLogin() {
|
|
368
|
+
return this.fetch("/api/subscription/anthropic/start", { method: "POST" });
|
|
369
|
+
}
|
|
370
|
+
async exchangeAnthropicCode(code) {
|
|
371
|
+
return this.fetch("/api/subscription/anthropic/exchange", {
|
|
372
|
+
method: "POST",
|
|
373
|
+
headers: { "Content-Type": "application/json" },
|
|
374
|
+
body: JSON.stringify({ code }),
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
async submitAnthropicSetupToken(token) {
|
|
378
|
+
return this.fetch("/api/subscription/anthropic/setup-token", {
|
|
379
|
+
method: "POST",
|
|
380
|
+
headers: { "Content-Type": "application/json" },
|
|
381
|
+
body: JSON.stringify({ token }),
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
async getSubscriptionStatus() {
|
|
385
|
+
return this.fetch("/api/subscription/status");
|
|
386
|
+
}
|
|
387
|
+
async deleteSubscription(provider) {
|
|
388
|
+
return this.fetch(`/api/subscription/${encodeURIComponent(provider)}`, {
|
|
389
|
+
method: "DELETE",
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
async switchProvider(provider, apiKey) {
|
|
393
|
+
return this.fetch("/api/provider/switch", {
|
|
394
|
+
method: "POST",
|
|
395
|
+
headers: { "Content-Type": "application/json" },
|
|
396
|
+
body: JSON.stringify({ provider, ...(apiKey ? { apiKey } : {}) }),
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
async startOpenAILogin() {
|
|
400
|
+
return this.fetch("/api/subscription/openai/start", { method: "POST" });
|
|
401
|
+
}
|
|
402
|
+
async exchangeOpenAICode(code) {
|
|
403
|
+
return this.fetch("/api/subscription/openai/exchange", {
|
|
404
|
+
method: "POST",
|
|
405
|
+
headers: { "Content-Type": "application/json" },
|
|
406
|
+
body: JSON.stringify({ code }),
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
async getSandboxPlatform() {
|
|
410
|
+
return this.fetch("/api/sandbox/platform");
|
|
411
|
+
}
|
|
412
|
+
async getSandboxBrowser() {
|
|
413
|
+
return this.fetch("/api/sandbox/browser");
|
|
414
|
+
}
|
|
415
|
+
async getSandboxScreenshot(region) {
|
|
416
|
+
if (!region) {
|
|
417
|
+
return this.fetch("/api/sandbox/screen/screenshot", {
|
|
418
|
+
method: "POST",
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
return this.fetch("/api/sandbox/screen/screenshot", {
|
|
422
|
+
method: "POST",
|
|
423
|
+
headers: { "Content-Type": "application/json" },
|
|
424
|
+
body: JSON.stringify(region),
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
async getSandboxWindows() {
|
|
428
|
+
return this.fetch("/api/sandbox/screen/windows");
|
|
429
|
+
}
|
|
430
|
+
async startDocker() {
|
|
431
|
+
return this.fetch("/api/sandbox/docker/start", { method: "POST" });
|
|
432
|
+
}
|
|
433
|
+
async startAgent() {
|
|
434
|
+
const res = await this.fetch("/api/agent/start", {
|
|
435
|
+
method: "POST",
|
|
436
|
+
});
|
|
437
|
+
return res.status;
|
|
438
|
+
}
|
|
439
|
+
async stopAgent() {
|
|
440
|
+
const res = await this.fetch("/api/agent/stop", {
|
|
441
|
+
method: "POST",
|
|
442
|
+
});
|
|
443
|
+
return res.status;
|
|
444
|
+
}
|
|
445
|
+
async pauseAgent() {
|
|
446
|
+
const res = await this.fetch("/api/agent/pause", {
|
|
447
|
+
method: "POST",
|
|
448
|
+
});
|
|
449
|
+
return res.status;
|
|
450
|
+
}
|
|
451
|
+
async resumeAgent() {
|
|
452
|
+
const res = await this.fetch("/api/agent/resume", {
|
|
453
|
+
method: "POST",
|
|
454
|
+
});
|
|
455
|
+
return res.status;
|
|
456
|
+
}
|
|
457
|
+
async restartAgent() {
|
|
458
|
+
const res = await this.fetch("/api/agent/restart", { method: "POST" });
|
|
459
|
+
return res.status;
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Restart the agent if possible, or wait for an in-progress restart to finish.
|
|
463
|
+
* Polls status until the agent state is "running".
|
|
464
|
+
*/
|
|
465
|
+
async restartAndWait(maxWaitMs = 30000) {
|
|
466
|
+
// Try triggering a restart; 409 means one is already in progress
|
|
467
|
+
try {
|
|
468
|
+
await this.restartAgent();
|
|
469
|
+
}
|
|
470
|
+
catch {
|
|
471
|
+
// Already restarting — that's fine, we'll poll
|
|
472
|
+
}
|
|
473
|
+
// Poll until running
|
|
474
|
+
const start = Date.now();
|
|
475
|
+
const interval = 1000;
|
|
476
|
+
while (Date.now() - start < maxWaitMs) {
|
|
477
|
+
await new Promise((r) => setTimeout(r, interval));
|
|
478
|
+
try {
|
|
479
|
+
const status = await this.getStatus();
|
|
480
|
+
if (status.state === "running")
|
|
481
|
+
return status;
|
|
482
|
+
}
|
|
483
|
+
catch {
|
|
484
|
+
// Server may be briefly unavailable during restart
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
// Return whatever we get after timeout
|
|
488
|
+
return this.getStatus();
|
|
489
|
+
}
|
|
490
|
+
async resetAgent() {
|
|
491
|
+
await this.fetch("/api/agent/reset", { method: "POST" });
|
|
492
|
+
}
|
|
493
|
+
async getConfig() {
|
|
494
|
+
return this.fetch("/api/config");
|
|
495
|
+
}
|
|
496
|
+
async getConfigSchema() {
|
|
497
|
+
return this.fetch("/api/config/schema");
|
|
498
|
+
}
|
|
499
|
+
async updateConfig(patch) {
|
|
500
|
+
return this.fetch("/api/config", {
|
|
501
|
+
method: "PUT",
|
|
502
|
+
headers: { "Content-Type": "application/json" },
|
|
503
|
+
body: JSON.stringify(patch),
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
// ── Custom VRM avatar ────────────────────────────────────────────────
|
|
507
|
+
async uploadCustomVrm(file) {
|
|
508
|
+
const buf = await file.arrayBuffer();
|
|
509
|
+
await this.fetch("/api/avatar/vrm", {
|
|
510
|
+
method: "POST",
|
|
511
|
+
headers: { "Content-Type": "application/octet-stream" },
|
|
512
|
+
body: buf,
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
/** Uses raw fetch instead of this.fetch() because HEAD returns no JSON body. */
|
|
516
|
+
async hasCustomVrm() {
|
|
517
|
+
try {
|
|
518
|
+
const res = await this.rawRequest("/api/avatar/vrm", { method: "HEAD" }, { allowNonOk: true });
|
|
519
|
+
return res.ok;
|
|
520
|
+
}
|
|
521
|
+
catch {
|
|
522
|
+
return false;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
// ── Custom background image ─────────────────────────────────────────
|
|
526
|
+
async uploadCustomBackground(file) {
|
|
527
|
+
const buf = await file.arrayBuffer();
|
|
528
|
+
await this.fetch("/api/avatar/background", {
|
|
529
|
+
method: "POST",
|
|
530
|
+
headers: { "Content-Type": "application/octet-stream" },
|
|
531
|
+
body: buf,
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
/** Uses raw fetch instead of this.fetch() because HEAD returns no JSON body. */
|
|
535
|
+
async hasCustomBackground() {
|
|
536
|
+
try {
|
|
537
|
+
const res = await this.rawRequest("/api/avatar/background", { method: "HEAD" }, { allowNonOk: true });
|
|
538
|
+
return res.ok;
|
|
539
|
+
}
|
|
540
|
+
catch {
|
|
541
|
+
return false;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
// ── Connectors ──────────────────────────────────────────────────────
|
|
545
|
+
async getConnectors() {
|
|
546
|
+
return this.fetch("/api/connectors");
|
|
547
|
+
}
|
|
548
|
+
async saveConnector(name, config) {
|
|
549
|
+
return this.fetch("/api/connectors", {
|
|
550
|
+
method: "POST",
|
|
551
|
+
body: JSON.stringify({ name, config }),
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
async deleteConnector(name) {
|
|
555
|
+
return this.fetch(`/api/connectors/${encodeURIComponent(name)}`, {
|
|
556
|
+
method: "DELETE",
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
async getTriggers() {
|
|
560
|
+
return this.fetch("/api/triggers");
|
|
561
|
+
}
|
|
562
|
+
async getTrigger(id) {
|
|
563
|
+
return this.fetch(`/api/triggers/${encodeURIComponent(id)}`);
|
|
564
|
+
}
|
|
565
|
+
async createTrigger(request) {
|
|
566
|
+
return this.fetch("/api/triggers", {
|
|
567
|
+
method: "POST",
|
|
568
|
+
body: JSON.stringify(request),
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
async updateTrigger(id, request) {
|
|
572
|
+
return this.fetch(`/api/triggers/${encodeURIComponent(id)}`, {
|
|
573
|
+
method: "PUT",
|
|
574
|
+
body: JSON.stringify(request),
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
async deleteTrigger(id) {
|
|
578
|
+
return this.fetch(`/api/triggers/${encodeURIComponent(id)}`, {
|
|
579
|
+
method: "DELETE",
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
async runTriggerNow(id) {
|
|
583
|
+
return this.fetch(`/api/triggers/${encodeURIComponent(id)}/execute`, {
|
|
584
|
+
method: "POST",
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
async getTriggerRuns(id) {
|
|
588
|
+
return this.fetch(`/api/triggers/${encodeURIComponent(id)}/runs`);
|
|
589
|
+
}
|
|
590
|
+
async getTriggerHealth() {
|
|
591
|
+
return this.fetch("/api/triggers/health");
|
|
592
|
+
}
|
|
593
|
+
// Fine-tuning / training
|
|
594
|
+
async getTrainingStatus() {
|
|
595
|
+
return this.fetch("/api/training/status");
|
|
596
|
+
}
|
|
597
|
+
async listTrainingTrajectories(opts) {
|
|
598
|
+
const params = new URLSearchParams();
|
|
599
|
+
if (typeof opts?.limit === "number")
|
|
600
|
+
params.set("limit", String(opts.limit));
|
|
601
|
+
if (typeof opts?.offset === "number")
|
|
602
|
+
params.set("offset", String(opts.offset));
|
|
603
|
+
const qs = params.toString();
|
|
604
|
+
return this.fetch(`/api/training/trajectories${qs ? `?${qs}` : ""}`);
|
|
605
|
+
}
|
|
606
|
+
async getTrainingTrajectory(trajectoryId) {
|
|
607
|
+
return this.fetch(`/api/training/trajectories/${encodeURIComponent(trajectoryId)}`);
|
|
608
|
+
}
|
|
609
|
+
async listTrainingDatasets() {
|
|
610
|
+
return this.fetch("/api/training/datasets");
|
|
611
|
+
}
|
|
612
|
+
async buildTrainingDataset(options) {
|
|
613
|
+
return this.fetch("/api/training/datasets/build", {
|
|
614
|
+
method: "POST",
|
|
615
|
+
body: JSON.stringify(options ?? {}),
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
async listTrainingJobs() {
|
|
619
|
+
return this.fetch("/api/training/jobs");
|
|
620
|
+
}
|
|
621
|
+
async startTrainingJob(options) {
|
|
622
|
+
return this.fetch("/api/training/jobs", {
|
|
623
|
+
method: "POST",
|
|
624
|
+
body: JSON.stringify(options ?? {}),
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
async getTrainingJob(jobId) {
|
|
628
|
+
return this.fetch(`/api/training/jobs/${encodeURIComponent(jobId)}`);
|
|
629
|
+
}
|
|
630
|
+
async cancelTrainingJob(jobId) {
|
|
631
|
+
return this.fetch(`/api/training/jobs/${encodeURIComponent(jobId)}/cancel`, {
|
|
632
|
+
method: "POST",
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
async listTrainingModels() {
|
|
636
|
+
return this.fetch("/api/training/models");
|
|
637
|
+
}
|
|
638
|
+
async importTrainingModelToOllama(modelId, options) {
|
|
639
|
+
return this.fetch(`/api/training/models/${encodeURIComponent(modelId)}/import-ollama`, {
|
|
640
|
+
method: "POST",
|
|
641
|
+
body: JSON.stringify(options ?? {}),
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
async activateTrainingModel(modelId, providerModel) {
|
|
645
|
+
return this.fetch(`/api/training/models/${encodeURIComponent(modelId)}/activate`, {
|
|
646
|
+
method: "POST",
|
|
647
|
+
body: JSON.stringify({ providerModel }),
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
async benchmarkTrainingModel(modelId) {
|
|
651
|
+
return this.fetch(`/api/training/models/${encodeURIComponent(modelId)}/benchmark`, {
|
|
652
|
+
method: "POST",
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
async getPlugins() {
|
|
656
|
+
return this.fetch("/api/plugins");
|
|
657
|
+
}
|
|
658
|
+
async fetchModels(provider, refresh = true) {
|
|
659
|
+
const params = new URLSearchParams({ provider });
|
|
660
|
+
if (refresh)
|
|
661
|
+
params.set("refresh", "true");
|
|
662
|
+
return this.fetch(`/api/models?${params.toString()}`);
|
|
663
|
+
}
|
|
664
|
+
async getCorePlugins() {
|
|
665
|
+
return this.fetch("/api/plugins/core");
|
|
666
|
+
}
|
|
667
|
+
async toggleCorePlugin(npmName, enabled) {
|
|
668
|
+
return this.fetch("/api/plugins/core/toggle", {
|
|
669
|
+
method: "POST",
|
|
670
|
+
body: JSON.stringify({ npmName, enabled }),
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
async updatePlugin(id, config) {
|
|
674
|
+
return this.fetch(`/api/plugins/${id}`, {
|
|
675
|
+
method: "PUT",
|
|
676
|
+
body: JSON.stringify(config),
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
async getSecrets() {
|
|
680
|
+
return this.fetch("/api/secrets");
|
|
681
|
+
}
|
|
682
|
+
async updateSecrets(secrets) {
|
|
683
|
+
return this.fetch("/api/secrets", {
|
|
684
|
+
method: "PUT",
|
|
685
|
+
body: JSON.stringify({ secrets }),
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
async testPluginConnection(id) {
|
|
689
|
+
return this.fetch(`/api/plugins/${encodeURIComponent(id)}/test`, {
|
|
690
|
+
method: "POST",
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
async restart() {
|
|
694
|
+
return this.fetch("/api/restart", { method: "POST" });
|
|
695
|
+
}
|
|
696
|
+
async getSkills() {
|
|
697
|
+
return this.fetch("/api/skills");
|
|
698
|
+
}
|
|
699
|
+
async refreshSkills() {
|
|
700
|
+
return this.fetch("/api/skills/refresh", { method: "POST" });
|
|
701
|
+
}
|
|
702
|
+
async getLogs(filter) {
|
|
703
|
+
const params = new URLSearchParams();
|
|
704
|
+
if (filter?.source)
|
|
705
|
+
params.set("source", filter.source);
|
|
706
|
+
if (filter?.level)
|
|
707
|
+
params.set("level", filter.level);
|
|
708
|
+
if (filter?.tag)
|
|
709
|
+
params.set("tag", filter.tag);
|
|
710
|
+
if (filter?.since)
|
|
711
|
+
params.set("since", String(filter.since));
|
|
712
|
+
const qs = params.toString();
|
|
713
|
+
return this.fetch(`/api/logs${qs ? `?${qs}` : ""}`);
|
|
714
|
+
}
|
|
715
|
+
buildSecurityAuditParams(filter, includeStream = false) {
|
|
716
|
+
const params = new URLSearchParams();
|
|
717
|
+
if (filter?.type)
|
|
718
|
+
params.set("type", filter.type);
|
|
719
|
+
if (filter?.severity)
|
|
720
|
+
params.set("severity", filter.severity);
|
|
721
|
+
if (filter?.since !== undefined) {
|
|
722
|
+
const sinceValue = filter.since instanceof Date
|
|
723
|
+
? filter.since.toISOString()
|
|
724
|
+
: String(filter.since);
|
|
725
|
+
params.set("since", sinceValue);
|
|
726
|
+
}
|
|
727
|
+
if (filter?.limit !== undefined)
|
|
728
|
+
params.set("limit", String(filter.limit));
|
|
729
|
+
if (includeStream)
|
|
730
|
+
params.set("stream", "1");
|
|
731
|
+
return params;
|
|
732
|
+
}
|
|
733
|
+
async getSecurityAudit(filter) {
|
|
734
|
+
const qs = this.buildSecurityAuditParams(filter).toString();
|
|
735
|
+
return this.fetch(`/api/security/audit${qs ? `?${qs}` : ""}`);
|
|
736
|
+
}
|
|
737
|
+
async streamSecurityAudit(onEvent, filter, signal) {
|
|
738
|
+
if (!this.apiAvailable) {
|
|
739
|
+
throw new Error("API not available (no HTTP origin)");
|
|
740
|
+
}
|
|
741
|
+
const token = this.apiToken;
|
|
742
|
+
const qs = this.buildSecurityAuditParams(filter, true).toString();
|
|
743
|
+
const res = await fetch(`${this.baseUrl}/api/security/audit${qs ? `?${qs}` : ""}`, {
|
|
744
|
+
method: "GET",
|
|
745
|
+
headers: {
|
|
746
|
+
Accept: "text/event-stream",
|
|
747
|
+
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
|
748
|
+
},
|
|
749
|
+
signal,
|
|
750
|
+
});
|
|
751
|
+
if (!res.ok) {
|
|
752
|
+
const body = (await res
|
|
753
|
+
.json()
|
|
754
|
+
.catch(() => ({ error: res.statusText })));
|
|
755
|
+
const err = new Error(body.error ?? `HTTP ${res.status}`);
|
|
756
|
+
err.status = res.status;
|
|
757
|
+
throw err;
|
|
758
|
+
}
|
|
759
|
+
if (!res.body) {
|
|
760
|
+
throw new Error("Streaming not supported by this browser");
|
|
761
|
+
}
|
|
762
|
+
const parsePayload = (payload) => {
|
|
763
|
+
if (!payload)
|
|
764
|
+
return;
|
|
765
|
+
try {
|
|
766
|
+
const parsed = JSON.parse(payload);
|
|
767
|
+
if (parsed.type === "snapshot" || parsed.type === "entry") {
|
|
768
|
+
onEvent(parsed);
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
catch {
|
|
772
|
+
// Ignore malformed payloads to keep stream consumption resilient.
|
|
773
|
+
}
|
|
774
|
+
};
|
|
775
|
+
const decoder = new TextDecoder();
|
|
776
|
+
const reader = res.body.getReader();
|
|
777
|
+
let buffer = "";
|
|
778
|
+
const findSseEventBreak = (chunkBuffer) => {
|
|
779
|
+
const lfBreak = chunkBuffer.indexOf("\n\n");
|
|
780
|
+
const crlfBreak = chunkBuffer.indexOf("\r\n\r\n");
|
|
781
|
+
if (lfBreak === -1 && crlfBreak === -1)
|
|
782
|
+
return null;
|
|
783
|
+
if (lfBreak === -1)
|
|
784
|
+
return { index: crlfBreak, length: 4 };
|
|
785
|
+
if (crlfBreak === -1)
|
|
786
|
+
return { index: lfBreak, length: 2 };
|
|
787
|
+
return lfBreak < crlfBreak
|
|
788
|
+
? { index: lfBreak, length: 2 }
|
|
789
|
+
: { index: crlfBreak, length: 4 };
|
|
790
|
+
};
|
|
791
|
+
while (true) {
|
|
792
|
+
const { done, value } = await reader.read();
|
|
793
|
+
if (done)
|
|
794
|
+
break;
|
|
795
|
+
buffer += decoder.decode(value, { stream: true });
|
|
796
|
+
let eventBreak = findSseEventBreak(buffer);
|
|
797
|
+
while (eventBreak) {
|
|
798
|
+
const rawEvent = buffer.slice(0, eventBreak.index);
|
|
799
|
+
buffer = buffer.slice(eventBreak.index + eventBreak.length);
|
|
800
|
+
for (const line of rawEvent.split(/\r?\n/)) {
|
|
801
|
+
if (!line.startsWith("data:"))
|
|
802
|
+
continue;
|
|
803
|
+
parsePayload(line.slice(5).trim());
|
|
804
|
+
}
|
|
805
|
+
eventBreak = findSseEventBreak(buffer);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
if (buffer.trim()) {
|
|
809
|
+
for (const line of buffer.split(/\r?\n/)) {
|
|
810
|
+
if (!line.startsWith("data:"))
|
|
811
|
+
continue;
|
|
812
|
+
parsePayload(line.slice(5).trim());
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
async getAgentEvents(opts) {
|
|
817
|
+
const params = new URLSearchParams();
|
|
818
|
+
if (opts?.afterEventId)
|
|
819
|
+
params.set("after", opts.afterEventId);
|
|
820
|
+
if (typeof opts?.limit === "number")
|
|
821
|
+
params.set("limit", String(opts.limit));
|
|
822
|
+
if (opts?.runId)
|
|
823
|
+
params.set("runId", opts.runId);
|
|
824
|
+
if (typeof opts?.fromSeq === "number")
|
|
825
|
+
params.set("fromSeq", String(Math.trunc(opts.fromSeq)));
|
|
826
|
+
const qs = params.toString();
|
|
827
|
+
return this.fetch(`/api/agent/events${qs ? `?${qs}` : ""}`);
|
|
828
|
+
}
|
|
829
|
+
async getExtensionStatus() {
|
|
830
|
+
return this.fetch("/api/extension/status");
|
|
831
|
+
}
|
|
832
|
+
// Skill Catalog
|
|
833
|
+
async getSkillCatalog(opts) {
|
|
834
|
+
const params = new URLSearchParams();
|
|
835
|
+
if (opts?.page)
|
|
836
|
+
params.set("page", String(opts.page));
|
|
837
|
+
if (opts?.perPage)
|
|
838
|
+
params.set("perPage", String(opts.perPage));
|
|
839
|
+
if (opts?.sort)
|
|
840
|
+
params.set("sort", opts.sort);
|
|
841
|
+
const qs = params.toString();
|
|
842
|
+
return this.fetch(`/api/skills/catalog${qs ? `?${qs}` : ""}`);
|
|
843
|
+
}
|
|
844
|
+
async searchSkillCatalog(query, limit = 30) {
|
|
845
|
+
return this.fetch(`/api/skills/catalog/search?q=${encodeURIComponent(query)}&limit=${limit}`);
|
|
846
|
+
}
|
|
847
|
+
async getSkillCatalogDetail(slug) {
|
|
848
|
+
return this.fetch(`/api/skills/catalog/${encodeURIComponent(slug)}`);
|
|
849
|
+
}
|
|
850
|
+
async refreshSkillCatalog() {
|
|
851
|
+
return this.fetch("/api/skills/catalog/refresh", { method: "POST" });
|
|
852
|
+
}
|
|
853
|
+
async installCatalogSkill(slug, version) {
|
|
854
|
+
return this.fetch("/api/skills/catalog/install", {
|
|
855
|
+
method: "POST",
|
|
856
|
+
body: JSON.stringify({ slug, version }),
|
|
857
|
+
});
|
|
858
|
+
}
|
|
859
|
+
async uninstallCatalogSkill(slug) {
|
|
860
|
+
return this.fetch("/api/skills/catalog/uninstall", {
|
|
861
|
+
method: "POST",
|
|
862
|
+
body: JSON.stringify({ slug }),
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
// Registry / Plugin Store
|
|
866
|
+
async getRegistryPlugins() {
|
|
867
|
+
return this.fetch("/api/registry/plugins");
|
|
868
|
+
}
|
|
869
|
+
async getRegistryPluginInfo(name) {
|
|
870
|
+
return this.fetch(`/api/registry/plugins/${encodeURIComponent(name)}`);
|
|
871
|
+
}
|
|
872
|
+
async getInstalledPlugins() {
|
|
873
|
+
return this.fetch("/api/plugins/installed");
|
|
874
|
+
}
|
|
875
|
+
async installRegistryPlugin(name, autoRestart = true) {
|
|
876
|
+
return this.fetch("/api/plugins/install", {
|
|
877
|
+
method: "POST",
|
|
878
|
+
body: JSON.stringify({ name, autoRestart }),
|
|
879
|
+
});
|
|
880
|
+
}
|
|
881
|
+
async uninstallRegistryPlugin(name, autoRestart = true) {
|
|
882
|
+
return this.fetch("/api/plugins/uninstall", {
|
|
883
|
+
method: "POST",
|
|
884
|
+
body: JSON.stringify({ name, autoRestart }),
|
|
885
|
+
});
|
|
886
|
+
}
|
|
887
|
+
// Agent Export / Import
|
|
888
|
+
/**
|
|
889
|
+
* Export the agent as a password-encrypted .eliza-agent file.
|
|
890
|
+
* Returns the raw Response so the caller can stream the binary body.
|
|
891
|
+
*/
|
|
892
|
+
async exportAgent(password, includeLogs = false) {
|
|
893
|
+
if (password.length < AGENT_TRANSFER_MIN_PASSWORD_LENGTH) {
|
|
894
|
+
throw new Error(`Password must be at least ${AGENT_TRANSFER_MIN_PASSWORD_LENGTH} characters.`);
|
|
895
|
+
}
|
|
896
|
+
return this.rawRequest("/api/agent/export", {
|
|
897
|
+
method: "POST",
|
|
898
|
+
headers: {
|
|
899
|
+
"Content-Type": "application/json",
|
|
900
|
+
},
|
|
901
|
+
body: JSON.stringify({ password, includeLogs }),
|
|
902
|
+
});
|
|
903
|
+
}
|
|
904
|
+
/** Get an estimate of the export size. */
|
|
905
|
+
async getExportEstimate() {
|
|
906
|
+
return this.fetch("/api/agent/export/estimate");
|
|
907
|
+
}
|
|
908
|
+
/**
|
|
909
|
+
* Import an agent from a password-encrypted .eliza-agent file.
|
|
910
|
+
* Encodes the password and file into a binary envelope.
|
|
911
|
+
*/
|
|
912
|
+
async importAgent(password, fileBuffer) {
|
|
913
|
+
if (password.length < AGENT_TRANSFER_MIN_PASSWORD_LENGTH) {
|
|
914
|
+
throw new Error(`Password must be at least ${AGENT_TRANSFER_MIN_PASSWORD_LENGTH} characters.`);
|
|
915
|
+
}
|
|
916
|
+
const passwordBytes = new TextEncoder().encode(password);
|
|
917
|
+
const envelope = new Uint8Array(4 + passwordBytes.length + fileBuffer.byteLength);
|
|
918
|
+
const view = new DataView(envelope.buffer);
|
|
919
|
+
view.setUint32(0, passwordBytes.length, false);
|
|
920
|
+
envelope.set(passwordBytes, 4);
|
|
921
|
+
envelope.set(new Uint8Array(fileBuffer), 4 + passwordBytes.length);
|
|
922
|
+
const res = await this.rawRequest("/api/agent/import", {
|
|
923
|
+
method: "POST",
|
|
924
|
+
headers: {
|
|
925
|
+
"Content-Type": "application/octet-stream",
|
|
926
|
+
},
|
|
927
|
+
body: envelope,
|
|
928
|
+
});
|
|
929
|
+
const data = (await res.json());
|
|
930
|
+
if (!data.success) {
|
|
931
|
+
throw new Error(data.error ?? `Import failed (${res.status})`);
|
|
932
|
+
}
|
|
933
|
+
return data;
|
|
934
|
+
}
|
|
935
|
+
// Character
|
|
936
|
+
async getCharacter() {
|
|
937
|
+
return this.fetch("/api/character");
|
|
938
|
+
}
|
|
939
|
+
async getRandomName() {
|
|
940
|
+
return this.fetch("/api/character/random-name");
|
|
941
|
+
}
|
|
942
|
+
async generateCharacterField(field, context, mode) {
|
|
943
|
+
return this.fetch("/api/character/generate", {
|
|
944
|
+
method: "POST",
|
|
945
|
+
body: JSON.stringify({ field, context, mode }),
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
async updateCharacter(character) {
|
|
949
|
+
return this.fetch("/api/character", {
|
|
950
|
+
method: "PUT",
|
|
951
|
+
body: JSON.stringify(character),
|
|
952
|
+
});
|
|
953
|
+
}
|
|
954
|
+
// Wallet
|
|
955
|
+
async getWalletAddresses() {
|
|
956
|
+
return this.fetch("/api/wallet/addresses");
|
|
957
|
+
}
|
|
958
|
+
async getWalletBalances() {
|
|
959
|
+
return this.fetch("/api/wallet/balances");
|
|
960
|
+
}
|
|
961
|
+
async getWalletNfts() {
|
|
962
|
+
return this.fetch("/api/wallet/nfts");
|
|
963
|
+
}
|
|
964
|
+
async getWalletConfig() {
|
|
965
|
+
return this.fetch("/api/wallet/config");
|
|
966
|
+
}
|
|
967
|
+
async updateWalletConfig(config) {
|
|
968
|
+
return this.fetch("/api/wallet/config", {
|
|
969
|
+
method: "PUT",
|
|
970
|
+
body: JSON.stringify(config),
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
async exportWalletKeys(exportToken) {
|
|
974
|
+
return this.fetch("/api/wallet/export", {
|
|
975
|
+
method: "POST",
|
|
976
|
+
body: JSON.stringify({ confirm: true, exportToken }),
|
|
977
|
+
});
|
|
978
|
+
}
|
|
979
|
+
// BSC Trading
|
|
980
|
+
async getBscTradePreflight(tokenAddress) {
|
|
981
|
+
return this.fetch("/api/wallet/trade/preflight", {
|
|
982
|
+
method: "POST",
|
|
983
|
+
body: JSON.stringify(tokenAddress?.trim() ? { tokenAddress: tokenAddress.trim() } : {}),
|
|
984
|
+
});
|
|
985
|
+
}
|
|
986
|
+
async getBscTradeQuote(request) {
|
|
987
|
+
return this.fetch("/api/wallet/trade/quote", {
|
|
988
|
+
method: "POST",
|
|
989
|
+
body: JSON.stringify(request),
|
|
990
|
+
});
|
|
991
|
+
}
|
|
992
|
+
async executeBscTrade(request) {
|
|
993
|
+
return this.fetch("/api/wallet/trade/execute", {
|
|
994
|
+
method: "POST",
|
|
995
|
+
body: JSON.stringify(request),
|
|
996
|
+
});
|
|
997
|
+
}
|
|
998
|
+
async executeBscTransfer(request) {
|
|
999
|
+
return this.fetch("/api/wallet/transfer/execute", {
|
|
1000
|
+
method: "POST",
|
|
1001
|
+
body: JSON.stringify(request),
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
async getBscTradeTxStatus(hash) {
|
|
1005
|
+
return this.fetch(`/api/wallet/trade/tx-status?hash=${encodeURIComponent(hash)}`);
|
|
1006
|
+
}
|
|
1007
|
+
async getWalletTradingProfile(window = "30d", source = "all") {
|
|
1008
|
+
const params = new URLSearchParams({
|
|
1009
|
+
window,
|
|
1010
|
+
source,
|
|
1011
|
+
});
|
|
1012
|
+
return this.fetch(`/api/wallet/trading/profile?${params.toString()}`);
|
|
1013
|
+
}
|
|
1014
|
+
async applyProductionWalletDefaults() {
|
|
1015
|
+
return this.fetch("/api/wallet/production-defaults", {
|
|
1016
|
+
method: "POST",
|
|
1017
|
+
body: JSON.stringify({ confirm: true }),
|
|
1018
|
+
});
|
|
1019
|
+
}
|
|
1020
|
+
// Software Updates
|
|
1021
|
+
async getUpdateStatus(force = false) {
|
|
1022
|
+
return this.fetch(`/api/update/status${force ? "?force=true" : ""}`);
|
|
1023
|
+
}
|
|
1024
|
+
async setUpdateChannel(channel) {
|
|
1025
|
+
return this.fetch("/api/update/channel", {
|
|
1026
|
+
method: "PUT",
|
|
1027
|
+
body: JSON.stringify({ channel }),
|
|
1028
|
+
});
|
|
1029
|
+
}
|
|
1030
|
+
// Cloud
|
|
1031
|
+
async getCloudStatus() {
|
|
1032
|
+
return this.fetch("/api/cloud/status");
|
|
1033
|
+
}
|
|
1034
|
+
async getCloudCredits() {
|
|
1035
|
+
return this.fetch("/api/cloud/credits");
|
|
1036
|
+
}
|
|
1037
|
+
async getCloudBillingSummary() {
|
|
1038
|
+
return this.fetch("/api/cloud/billing/summary");
|
|
1039
|
+
}
|
|
1040
|
+
async getCloudBillingSettings() {
|
|
1041
|
+
return this.fetch("/api/cloud/billing/settings");
|
|
1042
|
+
}
|
|
1043
|
+
async updateCloudBillingSettings(request) {
|
|
1044
|
+
return this.fetch("/api/cloud/billing/settings", {
|
|
1045
|
+
method: "PUT",
|
|
1046
|
+
body: JSON.stringify(request),
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
async getCloudBillingPaymentMethods() {
|
|
1050
|
+
return this.fetch("/api/cloud/billing/payment-methods");
|
|
1051
|
+
}
|
|
1052
|
+
async getCloudBillingHistory() {
|
|
1053
|
+
return this.fetch("/api/cloud/billing/history");
|
|
1054
|
+
}
|
|
1055
|
+
async createCloudBillingCheckout(request) {
|
|
1056
|
+
return this.fetch("/api/cloud/billing/checkout", {
|
|
1057
|
+
method: "POST",
|
|
1058
|
+
body: JSON.stringify(request),
|
|
1059
|
+
});
|
|
1060
|
+
}
|
|
1061
|
+
async createCloudBillingCryptoQuote(request) {
|
|
1062
|
+
return this.fetch("/api/cloud/billing/crypto/quote", {
|
|
1063
|
+
method: "POST",
|
|
1064
|
+
body: JSON.stringify(request),
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
async cloudLogin() {
|
|
1068
|
+
return this.fetch("/api/cloud/login", { method: "POST" });
|
|
1069
|
+
}
|
|
1070
|
+
async cloudLoginPoll(sessionId) {
|
|
1071
|
+
return this.fetch(`/api/cloud/login/status?sessionId=${encodeURIComponent(sessionId)}`);
|
|
1072
|
+
}
|
|
1073
|
+
async cloudDisconnect() {
|
|
1074
|
+
return this.fetch("/api/cloud/disconnect", { method: "POST" });
|
|
1075
|
+
}
|
|
1076
|
+
// Cloud Compat (Eliza Cloud v2 thin-client endpoints)
|
|
1077
|
+
/** List all cloud-hosted agents for the authenticated user. */
|
|
1078
|
+
async getCloudCompatAgents() {
|
|
1079
|
+
return this.fetch("/api/cloud/compat/agents");
|
|
1080
|
+
}
|
|
1081
|
+
/** Create a new cloud-hosted agent. */
|
|
1082
|
+
async createCloudCompatAgent(opts) {
|
|
1083
|
+
return this.fetch("/api/cloud/compat/agents", {
|
|
1084
|
+
method: "POST",
|
|
1085
|
+
body: JSON.stringify(opts),
|
|
1086
|
+
});
|
|
1087
|
+
}
|
|
1088
|
+
/** Get a specific cloud-hosted agent by ID. */
|
|
1089
|
+
async getCloudCompatAgent(agentId) {
|
|
1090
|
+
return this.fetch(`/api/cloud/compat/agents/${encodeURIComponent(agentId)}`);
|
|
1091
|
+
}
|
|
1092
|
+
/** Delete a cloud-hosted agent. */
|
|
1093
|
+
async deleteCloudCompatAgent(agentId) {
|
|
1094
|
+
return this.fetch(`/api/cloud/compat/agents/${encodeURIComponent(agentId)}`, { method: "DELETE" });
|
|
1095
|
+
}
|
|
1096
|
+
/** Get status of a cloud-hosted agent. */
|
|
1097
|
+
async getCloudCompatAgentStatus(agentId) {
|
|
1098
|
+
return this.fetch(`/api/cloud/compat/agents/${encodeURIComponent(agentId)}/status`);
|
|
1099
|
+
}
|
|
1100
|
+
/** Get logs from a cloud-hosted agent. */
|
|
1101
|
+
async getCloudCompatAgentLogs(agentId, tail = 100) {
|
|
1102
|
+
return this.fetch(`/api/cloud/compat/agents/${encodeURIComponent(agentId)}/logs?tail=${tail}`);
|
|
1103
|
+
}
|
|
1104
|
+
/** Restart a cloud-hosted agent. */
|
|
1105
|
+
async restartCloudCompatAgent(agentId) {
|
|
1106
|
+
return this.fetch(`/api/cloud/compat/agents/${encodeURIComponent(agentId)}/restart`, { method: "POST" });
|
|
1107
|
+
}
|
|
1108
|
+
/** Suspend a cloud-hosted agent. */
|
|
1109
|
+
async suspendCloudCompatAgent(agentId) {
|
|
1110
|
+
return this.fetch(`/api/cloud/compat/agents/${encodeURIComponent(agentId)}/suspend`, { method: "POST" });
|
|
1111
|
+
}
|
|
1112
|
+
/** Resume a cloud-hosted agent. */
|
|
1113
|
+
async resumeCloudCompatAgent(agentId) {
|
|
1114
|
+
return this.fetch(`/api/cloud/compat/agents/${encodeURIComponent(agentId)}/resume`, { method: "POST" });
|
|
1115
|
+
}
|
|
1116
|
+
/** Launch a managed cloud agent into the Milady app. */
|
|
1117
|
+
async launchCloudCompatAgent(agentId) {
|
|
1118
|
+
return this.fetch(`/api/cloud/compat/agents/${encodeURIComponent(agentId)}/launch`, { method: "POST" });
|
|
1119
|
+
}
|
|
1120
|
+
/** Get cloud availability (capacity info). */
|
|
1121
|
+
async getCloudCompatAvailability() {
|
|
1122
|
+
return this.fetch("/api/cloud/compat/availability");
|
|
1123
|
+
}
|
|
1124
|
+
/** Poll a cloud job status by job ID. */
|
|
1125
|
+
async getCloudCompatJobStatus(jobId) {
|
|
1126
|
+
return this.fetch(`/api/cloud/compat/jobs/${encodeURIComponent(jobId)}`);
|
|
1127
|
+
}
|
|
1128
|
+
// Apps & Registry
|
|
1129
|
+
async listApps() {
|
|
1130
|
+
return this.fetch("/api/apps");
|
|
1131
|
+
}
|
|
1132
|
+
async searchApps(query) {
|
|
1133
|
+
return this.fetch(`/api/apps/search?q=${encodeURIComponent(query)}`);
|
|
1134
|
+
}
|
|
1135
|
+
async listInstalledApps() {
|
|
1136
|
+
return this.fetch("/api/apps/installed");
|
|
1137
|
+
}
|
|
1138
|
+
async stopApp(name) {
|
|
1139
|
+
return this.fetch("/api/apps/stop", {
|
|
1140
|
+
method: "POST",
|
|
1141
|
+
body: JSON.stringify({ name }),
|
|
1142
|
+
});
|
|
1143
|
+
}
|
|
1144
|
+
async getAppInfo(name) {
|
|
1145
|
+
return this.fetch(`/api/apps/info/${encodeURIComponent(name)}`);
|
|
1146
|
+
}
|
|
1147
|
+
/** Launch an app: installs its plugin (if needed), returns viewer config for iframe. */
|
|
1148
|
+
async launchApp(name) {
|
|
1149
|
+
return this.fetch("/api/apps/launch", {
|
|
1150
|
+
method: "POST",
|
|
1151
|
+
body: JSON.stringify({ name }),
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1154
|
+
async listRegistryPlugins() {
|
|
1155
|
+
return this.fetch("/api/apps/plugins");
|
|
1156
|
+
}
|
|
1157
|
+
async searchRegistryPlugins(query) {
|
|
1158
|
+
return this.fetch(`/api/apps/plugins/search?q=${encodeURIComponent(query)}`);
|
|
1159
|
+
}
|
|
1160
|
+
async listHyperscapeEmbeddedAgents() {
|
|
1161
|
+
return this.fetch("/api/apps/hyperscape/embedded-agents");
|
|
1162
|
+
}
|
|
1163
|
+
async createHyperscapeEmbeddedAgent(input) {
|
|
1164
|
+
return this.fetch("/api/apps/hyperscape/embedded-agents", {
|
|
1165
|
+
method: "POST",
|
|
1166
|
+
body: JSON.stringify(input),
|
|
1167
|
+
});
|
|
1168
|
+
}
|
|
1169
|
+
async controlHyperscapeEmbeddedAgent(characterId, action) {
|
|
1170
|
+
return this.fetch(`/api/apps/hyperscape/embedded-agents/${encodeURIComponent(characterId)}/${action}`, { method: "POST" });
|
|
1171
|
+
}
|
|
1172
|
+
async sendHyperscapeEmbeddedAgentCommand(characterId, command, data) {
|
|
1173
|
+
return this.fetch(`/api/apps/hyperscape/embedded-agents/${encodeURIComponent(characterId)}/command`, {
|
|
1174
|
+
method: "POST",
|
|
1175
|
+
body: JSON.stringify({ command, data }),
|
|
1176
|
+
});
|
|
1177
|
+
}
|
|
1178
|
+
async sendHyperscapeAgentMessage(agentId, content) {
|
|
1179
|
+
return this.fetch(`/api/apps/hyperscape/agents/${encodeURIComponent(agentId)}/message`, {
|
|
1180
|
+
method: "POST",
|
|
1181
|
+
body: JSON.stringify({ content }),
|
|
1182
|
+
});
|
|
1183
|
+
}
|
|
1184
|
+
async getHyperscapeAgentGoal(agentId) {
|
|
1185
|
+
return this.fetch(`/api/apps/hyperscape/agents/${encodeURIComponent(agentId)}/goal`);
|
|
1186
|
+
}
|
|
1187
|
+
async getHyperscapeAgentQuickActions(agentId) {
|
|
1188
|
+
return this.fetch(`/api/apps/hyperscape/agents/${encodeURIComponent(agentId)}/quick-actions`);
|
|
1189
|
+
}
|
|
1190
|
+
// Skills Marketplace
|
|
1191
|
+
async searchSkillsMarketplace(query, installed, limit) {
|
|
1192
|
+
const params = new URLSearchParams({
|
|
1193
|
+
q: query,
|
|
1194
|
+
installed: String(installed),
|
|
1195
|
+
limit: String(limit),
|
|
1196
|
+
});
|
|
1197
|
+
return this.fetch(`/api/skills/marketplace/search?${params}`);
|
|
1198
|
+
}
|
|
1199
|
+
async getSkillsMarketplaceConfig() {
|
|
1200
|
+
return this.fetch("/api/skills/marketplace/config");
|
|
1201
|
+
}
|
|
1202
|
+
async updateSkillsMarketplaceConfig(apiKey) {
|
|
1203
|
+
return this.fetch("/api/skills/marketplace/config", {
|
|
1204
|
+
method: "PUT",
|
|
1205
|
+
body: JSON.stringify({ apiKey }),
|
|
1206
|
+
});
|
|
1207
|
+
}
|
|
1208
|
+
async installMarketplaceSkill(data) {
|
|
1209
|
+
await this.fetch("/api/skills/marketplace/install", {
|
|
1210
|
+
method: "POST",
|
|
1211
|
+
body: JSON.stringify(data),
|
|
1212
|
+
});
|
|
1213
|
+
}
|
|
1214
|
+
async uninstallMarketplaceSkill(skillId, autoRefresh) {
|
|
1215
|
+
await this.fetch("/api/skills/marketplace/uninstall", {
|
|
1216
|
+
method: "POST",
|
|
1217
|
+
body: JSON.stringify({ id: skillId, autoRefresh }),
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
1220
|
+
async updateSkill(skillId, enabled) {
|
|
1221
|
+
return this.fetch(`/api/skills/${encodeURIComponent(skillId)}`, {
|
|
1222
|
+
method: "PUT",
|
|
1223
|
+
body: JSON.stringify({ enabled }),
|
|
1224
|
+
});
|
|
1225
|
+
}
|
|
1226
|
+
// ── Skill CRUD & Security ────────────────────────────────────────────────
|
|
1227
|
+
async createSkill(name, description) {
|
|
1228
|
+
return this.fetch("/api/skills/create", {
|
|
1229
|
+
method: "POST",
|
|
1230
|
+
body: JSON.stringify({ name, description }),
|
|
1231
|
+
});
|
|
1232
|
+
}
|
|
1233
|
+
async openSkill(id) {
|
|
1234
|
+
return this.fetch(`/api/skills/${encodeURIComponent(id)}/open`, {
|
|
1235
|
+
method: "POST",
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
async getSkillSource(id) {
|
|
1239
|
+
return this.fetch(`/api/skills/${encodeURIComponent(id)}/source`);
|
|
1240
|
+
}
|
|
1241
|
+
async saveSkillSource(id, content) {
|
|
1242
|
+
return this.fetch(`/api/skills/${encodeURIComponent(id)}/source`, {
|
|
1243
|
+
method: "PUT",
|
|
1244
|
+
body: JSON.stringify({ content }),
|
|
1245
|
+
});
|
|
1246
|
+
}
|
|
1247
|
+
async deleteSkill(id) {
|
|
1248
|
+
return this.fetch(`/api/skills/${encodeURIComponent(id)}`, {
|
|
1249
|
+
method: "DELETE",
|
|
1250
|
+
});
|
|
1251
|
+
}
|
|
1252
|
+
async getSkillScanReport(id) {
|
|
1253
|
+
return this.fetch(`/api/skills/${encodeURIComponent(id)}/scan`);
|
|
1254
|
+
}
|
|
1255
|
+
async acknowledgeSkill(id, enable) {
|
|
1256
|
+
return this.fetch(`/api/skills/${encodeURIComponent(id)}/acknowledge`, {
|
|
1257
|
+
method: "POST",
|
|
1258
|
+
body: JSON.stringify({ enable }),
|
|
1259
|
+
});
|
|
1260
|
+
}
|
|
1261
|
+
// Workbench
|
|
1262
|
+
async getWorkbenchOverview() {
|
|
1263
|
+
return this.fetch("/api/workbench/overview");
|
|
1264
|
+
}
|
|
1265
|
+
async listWorkbenchTasks() {
|
|
1266
|
+
return this.fetch("/api/workbench/tasks");
|
|
1267
|
+
}
|
|
1268
|
+
async getWorkbenchTask(taskId) {
|
|
1269
|
+
return this.fetch(`/api/workbench/tasks/${encodeURIComponent(taskId)}`);
|
|
1270
|
+
}
|
|
1271
|
+
async createWorkbenchTask(data) {
|
|
1272
|
+
return this.fetch("/api/workbench/tasks", {
|
|
1273
|
+
method: "POST",
|
|
1274
|
+
body: JSON.stringify(data),
|
|
1275
|
+
});
|
|
1276
|
+
}
|
|
1277
|
+
async updateWorkbenchTask(taskId, data) {
|
|
1278
|
+
return this.fetch(`/api/workbench/tasks/${encodeURIComponent(taskId)}`, {
|
|
1279
|
+
method: "PUT",
|
|
1280
|
+
body: JSON.stringify(data),
|
|
1281
|
+
});
|
|
1282
|
+
}
|
|
1283
|
+
async deleteWorkbenchTask(taskId) {
|
|
1284
|
+
return this.fetch(`/api/workbench/tasks/${encodeURIComponent(taskId)}`, {
|
|
1285
|
+
method: "DELETE",
|
|
1286
|
+
});
|
|
1287
|
+
}
|
|
1288
|
+
async listWorkbenchTodos() {
|
|
1289
|
+
return this.fetch("/api/workbench/todos");
|
|
1290
|
+
}
|
|
1291
|
+
async getWorkbenchTodo(todoId) {
|
|
1292
|
+
return this.fetch(`/api/workbench/todos/${encodeURIComponent(todoId)}`);
|
|
1293
|
+
}
|
|
1294
|
+
async createWorkbenchTodo(data) {
|
|
1295
|
+
return this.fetch("/api/workbench/todos", {
|
|
1296
|
+
method: "POST",
|
|
1297
|
+
body: JSON.stringify(data),
|
|
1298
|
+
});
|
|
1299
|
+
}
|
|
1300
|
+
async updateWorkbenchTodo(todoId, data) {
|
|
1301
|
+
return this.fetch(`/api/workbench/todos/${encodeURIComponent(todoId)}`, {
|
|
1302
|
+
method: "PUT",
|
|
1303
|
+
body: JSON.stringify(data),
|
|
1304
|
+
});
|
|
1305
|
+
}
|
|
1306
|
+
async setWorkbenchTodoCompleted(todoId, isCompleted) {
|
|
1307
|
+
await this.fetch(`/api/workbench/todos/${encodeURIComponent(todoId)}/complete`, {
|
|
1308
|
+
method: "POST",
|
|
1309
|
+
body: JSON.stringify({ isCompleted }),
|
|
1310
|
+
});
|
|
1311
|
+
}
|
|
1312
|
+
async deleteWorkbenchTodo(todoId) {
|
|
1313
|
+
return this.fetch(`/api/workbench/todos/${encodeURIComponent(todoId)}`, {
|
|
1314
|
+
method: "DELETE",
|
|
1315
|
+
});
|
|
1316
|
+
}
|
|
1317
|
+
// Registry
|
|
1318
|
+
async refreshRegistry() {
|
|
1319
|
+
await this.fetch("/api/apps/refresh", { method: "POST" });
|
|
1320
|
+
}
|
|
1321
|
+
// Knowledge
|
|
1322
|
+
async getKnowledgeStats() {
|
|
1323
|
+
return this.fetch("/api/knowledge/stats");
|
|
1324
|
+
}
|
|
1325
|
+
async listKnowledgeDocuments(options) {
|
|
1326
|
+
const params = new URLSearchParams();
|
|
1327
|
+
if (options?.limit)
|
|
1328
|
+
params.set("limit", String(options.limit));
|
|
1329
|
+
if (options?.offset)
|
|
1330
|
+
params.set("offset", String(options.offset));
|
|
1331
|
+
const query = params.toString();
|
|
1332
|
+
return this.fetch(`/api/knowledge/documents${query ? `?${query}` : ""}`);
|
|
1333
|
+
}
|
|
1334
|
+
async getKnowledgeDocument(documentId) {
|
|
1335
|
+
return this.fetch(`/api/knowledge/documents/${encodeURIComponent(documentId)}`);
|
|
1336
|
+
}
|
|
1337
|
+
async deleteKnowledgeDocument(documentId) {
|
|
1338
|
+
return this.fetch(`/api/knowledge/documents/${encodeURIComponent(documentId)}`, {
|
|
1339
|
+
method: "DELETE",
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1342
|
+
async uploadKnowledgeDocument(data) {
|
|
1343
|
+
return this.fetch("/api/knowledge/documents", {
|
|
1344
|
+
method: "POST",
|
|
1345
|
+
body: JSON.stringify(data),
|
|
1346
|
+
});
|
|
1347
|
+
}
|
|
1348
|
+
async uploadKnowledgeDocumentsBulk(data) {
|
|
1349
|
+
return this.fetch("/api/knowledge/documents/bulk", {
|
|
1350
|
+
method: "POST",
|
|
1351
|
+
body: JSON.stringify(data),
|
|
1352
|
+
});
|
|
1353
|
+
}
|
|
1354
|
+
async uploadKnowledgeFromUrl(url, metadata) {
|
|
1355
|
+
return this.fetch("/api/knowledge/documents/url", {
|
|
1356
|
+
method: "POST",
|
|
1357
|
+
body: JSON.stringify({ url, metadata }),
|
|
1358
|
+
});
|
|
1359
|
+
}
|
|
1360
|
+
async searchKnowledge(query, options) {
|
|
1361
|
+
const params = new URLSearchParams({ q: query });
|
|
1362
|
+
if (options?.threshold !== undefined)
|
|
1363
|
+
params.set("threshold", String(options.threshold));
|
|
1364
|
+
if (options?.limit !== undefined)
|
|
1365
|
+
params.set("limit", String(options.limit));
|
|
1366
|
+
return this.fetch(`/api/knowledge/search?${params}`);
|
|
1367
|
+
}
|
|
1368
|
+
async getKnowledgeFragments(documentId) {
|
|
1369
|
+
return this.fetch(`/api/knowledge/fragments/${encodeURIComponent(documentId)}`);
|
|
1370
|
+
}
|
|
1371
|
+
// Memory commands
|
|
1372
|
+
async rememberMemory(text) {
|
|
1373
|
+
return this.fetch("/api/memory/remember", {
|
|
1374
|
+
method: "POST",
|
|
1375
|
+
body: JSON.stringify({ text }),
|
|
1376
|
+
});
|
|
1377
|
+
}
|
|
1378
|
+
async searchMemory(query, options) {
|
|
1379
|
+
const params = new URLSearchParams({ q: query });
|
|
1380
|
+
if (options?.limit !== undefined)
|
|
1381
|
+
params.set("limit", String(options.limit));
|
|
1382
|
+
return this.fetch(`/api/memory/search?${params}`);
|
|
1383
|
+
}
|
|
1384
|
+
async quickContext(query, options) {
|
|
1385
|
+
const params = new URLSearchParams({ q: query });
|
|
1386
|
+
if (options?.limit !== undefined)
|
|
1387
|
+
params.set("limit", String(options.limit));
|
|
1388
|
+
return this.fetch(`/api/context/quick?${params}`);
|
|
1389
|
+
}
|
|
1390
|
+
// MCP
|
|
1391
|
+
async getMcpConfig() {
|
|
1392
|
+
return this.fetch("/api/mcp/config");
|
|
1393
|
+
}
|
|
1394
|
+
async getMcpStatus() {
|
|
1395
|
+
return this.fetch("/api/mcp/status");
|
|
1396
|
+
}
|
|
1397
|
+
async searchMcpMarketplace(query, limit) {
|
|
1398
|
+
const params = new URLSearchParams({ q: query, limit: String(limit) });
|
|
1399
|
+
return this.fetch(`/api/mcp/marketplace/search?${params}`);
|
|
1400
|
+
}
|
|
1401
|
+
async getMcpServerDetails(name) {
|
|
1402
|
+
return this.fetch(`/api/mcp/marketplace/${encodeURIComponent(name)}`);
|
|
1403
|
+
}
|
|
1404
|
+
async addMcpServer(name, config) {
|
|
1405
|
+
await this.fetch("/api/mcp/servers", {
|
|
1406
|
+
method: "POST",
|
|
1407
|
+
body: JSON.stringify({ name, config }),
|
|
1408
|
+
});
|
|
1409
|
+
}
|
|
1410
|
+
async removeMcpServer(name) {
|
|
1411
|
+
await this.fetch(`/api/mcp/servers/${encodeURIComponent(name)}`, {
|
|
1412
|
+
method: "DELETE",
|
|
1413
|
+
});
|
|
1414
|
+
}
|
|
1415
|
+
// Share Ingest
|
|
1416
|
+
async ingestShare(payload) {
|
|
1417
|
+
return this.fetch("/api/ingest/share", {
|
|
1418
|
+
method: "POST",
|
|
1419
|
+
body: JSON.stringify(payload),
|
|
1420
|
+
});
|
|
1421
|
+
}
|
|
1422
|
+
async consumeShareIngest() {
|
|
1423
|
+
return this.fetch("/api/share/consume", { method: "POST" });
|
|
1424
|
+
}
|
|
1425
|
+
// WebSocket
|
|
1426
|
+
connectWs() {
|
|
1427
|
+
if (this.ws?.readyState === WebSocket.OPEN)
|
|
1428
|
+
return;
|
|
1429
|
+
let host;
|
|
1430
|
+
if (this.baseUrl) {
|
|
1431
|
+
host = new URL(this.baseUrl).host;
|
|
1432
|
+
}
|
|
1433
|
+
else {
|
|
1434
|
+
// In non-HTTP environments (Electron capacitor-electron://, file://, etc.)
|
|
1435
|
+
// window.location.host may be empty or a non-routable placeholder like "-".
|
|
1436
|
+
const loc = window.location;
|
|
1437
|
+
if (loc.protocol !== "http:" && loc.protocol !== "https:")
|
|
1438
|
+
return;
|
|
1439
|
+
host = loc.host;
|
|
1440
|
+
}
|
|
1441
|
+
if (!host)
|
|
1442
|
+
return;
|
|
1443
|
+
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
|
|
1444
|
+
let url = `${protocol}//${host}/ws`;
|
|
1445
|
+
const params = new URLSearchParams({ clientId: this.clientId });
|
|
1446
|
+
const token = this.apiToken;
|
|
1447
|
+
if (token)
|
|
1448
|
+
params.set("token", token);
|
|
1449
|
+
url += `?${params.toString()}`;
|
|
1450
|
+
this.ws = new WebSocket(url);
|
|
1451
|
+
this.ws.onopen = () => {
|
|
1452
|
+
this.backoffMs = 500;
|
|
1453
|
+
// Reset connection state on successful connection
|
|
1454
|
+
this.reconnectAttempt = 0;
|
|
1455
|
+
this.disconnectedAt = null;
|
|
1456
|
+
this.connectionState = "connected";
|
|
1457
|
+
this.emitConnectionStateChange();
|
|
1458
|
+
// Notify listeners when the WS reconnects (not on the first connect)
|
|
1459
|
+
// so they can re-hydrate state that may have been lost during the gap.
|
|
1460
|
+
if (this.wsHasConnectedOnce) {
|
|
1461
|
+
const handlers = this.wsHandlers.get("ws-reconnected");
|
|
1462
|
+
if (handlers) {
|
|
1463
|
+
for (const handler of handlers) {
|
|
1464
|
+
handler({ type: "ws-reconnected" });
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
this.wsHasConnectedOnce = true;
|
|
1469
|
+
if (this.wsSendQueue.length > 0 &&
|
|
1470
|
+
this.ws?.readyState === WebSocket.OPEN) {
|
|
1471
|
+
const pending = this.wsSendQueue;
|
|
1472
|
+
this.wsSendQueue = [];
|
|
1473
|
+
for (let i = 0; i < pending.length; i++) {
|
|
1474
|
+
if (this.ws?.readyState !== WebSocket.OPEN) {
|
|
1475
|
+
this.wsSendQueue = pending.slice(i).concat(this.wsSendQueue);
|
|
1476
|
+
break;
|
|
1477
|
+
}
|
|
1478
|
+
try {
|
|
1479
|
+
this.ws.send(pending[i]);
|
|
1480
|
+
}
|
|
1481
|
+
catch {
|
|
1482
|
+
this.wsSendQueue = pending.slice(i).concat(this.wsSendQueue);
|
|
1483
|
+
break;
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
};
|
|
1488
|
+
this.ws.onmessage = (event) => {
|
|
1489
|
+
try {
|
|
1490
|
+
const data = JSON.parse(event.data);
|
|
1491
|
+
const type = data.type;
|
|
1492
|
+
const handlers = this.wsHandlers.get(type);
|
|
1493
|
+
if (handlers) {
|
|
1494
|
+
for (const handler of handlers) {
|
|
1495
|
+
handler(data);
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
// Also fire "all" handlers
|
|
1499
|
+
const allHandlers = this.wsHandlers.get("*");
|
|
1500
|
+
if (allHandlers) {
|
|
1501
|
+
for (const handler of allHandlers) {
|
|
1502
|
+
handler(data);
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
catch {
|
|
1507
|
+
// ignore parse errors
|
|
1508
|
+
}
|
|
1509
|
+
};
|
|
1510
|
+
this.ws.onclose = () => {
|
|
1511
|
+
this.ws = null;
|
|
1512
|
+
// Track disconnection time if not already set
|
|
1513
|
+
if (this.disconnectedAt === null) {
|
|
1514
|
+
this.disconnectedAt = Date.now();
|
|
1515
|
+
}
|
|
1516
|
+
this.reconnectAttempt++;
|
|
1517
|
+
// Update state based on attempt count
|
|
1518
|
+
if (this.reconnectAttempt >= this.maxReconnectAttempts) {
|
|
1519
|
+
this.connectionState = "failed";
|
|
1520
|
+
}
|
|
1521
|
+
else {
|
|
1522
|
+
this.connectionState = "reconnecting";
|
|
1523
|
+
}
|
|
1524
|
+
this.emitConnectionStateChange();
|
|
1525
|
+
this.scheduleReconnect();
|
|
1526
|
+
};
|
|
1527
|
+
this.ws.onerror = () => {
|
|
1528
|
+
// close handler will fire
|
|
1529
|
+
};
|
|
1530
|
+
}
|
|
1531
|
+
scheduleReconnect() {
|
|
1532
|
+
if (this.reconnectTimer)
|
|
1533
|
+
return;
|
|
1534
|
+
// Stop reconnecting if we've hit max attempts
|
|
1535
|
+
if (this.reconnectAttempt >= this.maxReconnectAttempts) {
|
|
1536
|
+
return;
|
|
1537
|
+
}
|
|
1538
|
+
this.reconnectTimer = setTimeout(() => {
|
|
1539
|
+
this.reconnectTimer = null;
|
|
1540
|
+
this.connectWs();
|
|
1541
|
+
}, this.backoffMs);
|
|
1542
|
+
this.backoffMs = Math.min(this.backoffMs * 1.5, 10000);
|
|
1543
|
+
}
|
|
1544
|
+
emitConnectionStateChange() {
|
|
1545
|
+
const state = this.getConnectionState();
|
|
1546
|
+
for (const listener of this.connectionStateListeners) {
|
|
1547
|
+
try {
|
|
1548
|
+
listener(state);
|
|
1549
|
+
}
|
|
1550
|
+
catch {
|
|
1551
|
+
// ignore listener errors
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
/** Get the current WebSocket connection state. */
|
|
1556
|
+
getConnectionState() {
|
|
1557
|
+
return {
|
|
1558
|
+
state: this.connectionState,
|
|
1559
|
+
reconnectAttempt: this.reconnectAttempt,
|
|
1560
|
+
maxReconnectAttempts: this.maxReconnectAttempts,
|
|
1561
|
+
disconnectedAt: this.disconnectedAt,
|
|
1562
|
+
};
|
|
1563
|
+
}
|
|
1564
|
+
/** Subscribe to connection state changes. Returns an unsubscribe function. */
|
|
1565
|
+
onConnectionStateChange(listener) {
|
|
1566
|
+
this.connectionStateListeners.add(listener);
|
|
1567
|
+
return () => {
|
|
1568
|
+
this.connectionStateListeners.delete(listener);
|
|
1569
|
+
};
|
|
1570
|
+
}
|
|
1571
|
+
/** Reset connection state and restart reconnection attempts. */
|
|
1572
|
+
resetConnection() {
|
|
1573
|
+
this.reconnectAttempt = 0;
|
|
1574
|
+
this.disconnectedAt = null;
|
|
1575
|
+
this.connectionState = "disconnected";
|
|
1576
|
+
if (this.reconnectTimer) {
|
|
1577
|
+
clearTimeout(this.reconnectTimer);
|
|
1578
|
+
this.reconnectTimer = null;
|
|
1579
|
+
}
|
|
1580
|
+
this.backoffMs = 500;
|
|
1581
|
+
this.emitConnectionStateChange();
|
|
1582
|
+
this.connectWs();
|
|
1583
|
+
}
|
|
1584
|
+
/** Send an arbitrary JSON message over the WebSocket connection. */
|
|
1585
|
+
sendWsMessage(data) {
|
|
1586
|
+
const payload = JSON.stringify(data);
|
|
1587
|
+
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
1588
|
+
this.ws.send(payload);
|
|
1589
|
+
return;
|
|
1590
|
+
}
|
|
1591
|
+
// Keep only the newest active-conversation update while disconnected.
|
|
1592
|
+
if (data.type === "active-conversation") {
|
|
1593
|
+
this.wsSendQueue = this.wsSendQueue.filter((queued) => {
|
|
1594
|
+
try {
|
|
1595
|
+
const parsed = JSON.parse(queued);
|
|
1596
|
+
return parsed.type !== "active-conversation";
|
|
1597
|
+
}
|
|
1598
|
+
catch {
|
|
1599
|
+
return true;
|
|
1600
|
+
}
|
|
1601
|
+
});
|
|
1602
|
+
}
|
|
1603
|
+
if (this.wsSendQueue.length >= this.wsSendQueueLimit) {
|
|
1604
|
+
this.wsSendQueue.shift();
|
|
1605
|
+
}
|
|
1606
|
+
this.wsSendQueue.push(payload);
|
|
1607
|
+
if (!this.ws || this.ws.readyState === WebSocket.CLOSED) {
|
|
1608
|
+
this.connectWs();
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
onWsEvent(type, handler) {
|
|
1612
|
+
if (!this.wsHandlers.has(type)) {
|
|
1613
|
+
this.wsHandlers.set(type, new Set());
|
|
1614
|
+
}
|
|
1615
|
+
this.wsHandlers.get(type)?.add(handler);
|
|
1616
|
+
return () => {
|
|
1617
|
+
this.wsHandlers.get(type)?.delete(handler);
|
|
1618
|
+
};
|
|
1619
|
+
}
|
|
1620
|
+
normalizeAssistantText(text) {
|
|
1621
|
+
const stripped = stripAssistantStageDirections(text);
|
|
1622
|
+
const trimmed = stripped.trim();
|
|
1623
|
+
if (trimmed.length === 0) {
|
|
1624
|
+
if (text.trim().length === 0 ||
|
|
1625
|
+
/^\(?no response\)?$/i.test(text.trim())) {
|
|
1626
|
+
return GENERIC_NO_RESPONSE_TEXT;
|
|
1627
|
+
}
|
|
1628
|
+
return "";
|
|
1629
|
+
}
|
|
1630
|
+
if (/^\(?no response\)?$/i.test(trimmed)) {
|
|
1631
|
+
return GENERIC_NO_RESPONSE_TEXT;
|
|
1632
|
+
}
|
|
1633
|
+
return trimmed;
|
|
1634
|
+
}
|
|
1635
|
+
normalizeGreetingText(text) {
|
|
1636
|
+
const stripped = stripAssistantStageDirections(text);
|
|
1637
|
+
const trimmed = stripped.trim();
|
|
1638
|
+
if (trimmed.length === 0 || /^\(?no response\)?$/i.test(trimmed)) {
|
|
1639
|
+
return "";
|
|
1640
|
+
}
|
|
1641
|
+
return trimmed;
|
|
1642
|
+
}
|
|
1643
|
+
normalizeConversationMessage(message) {
|
|
1644
|
+
if (message.role !== "assistant")
|
|
1645
|
+
return message;
|
|
1646
|
+
const text = this.normalizeAssistantText(message.text);
|
|
1647
|
+
return text === message.text ? message : { ...message, text };
|
|
1648
|
+
}
|
|
1649
|
+
async streamChatEndpoint(path, text, onToken, channelType = "DM", signal, images, conversationMode) {
|
|
1650
|
+
const res = await this.rawRequest(path, {
|
|
1651
|
+
method: "POST",
|
|
1652
|
+
headers: {
|
|
1653
|
+
"Content-Type": "application/json",
|
|
1654
|
+
Accept: "text/event-stream",
|
|
1655
|
+
},
|
|
1656
|
+
body: JSON.stringify({
|
|
1657
|
+
text,
|
|
1658
|
+
channelType,
|
|
1659
|
+
...(images?.length ? { images } : {}),
|
|
1660
|
+
...(conversationMode ? { conversationMode } : {}),
|
|
1661
|
+
}),
|
|
1662
|
+
signal,
|
|
1663
|
+
});
|
|
1664
|
+
if (!res.body) {
|
|
1665
|
+
throw new Error("Streaming not supported by this browser");
|
|
1666
|
+
}
|
|
1667
|
+
const decoder = new TextDecoder();
|
|
1668
|
+
const reader = res.body.getReader();
|
|
1669
|
+
let buffer = "";
|
|
1670
|
+
let fullText = "";
|
|
1671
|
+
let doneText = null;
|
|
1672
|
+
let doneAgentName = null;
|
|
1673
|
+
let doneUsage;
|
|
1674
|
+
let receivedDone = false;
|
|
1675
|
+
const findSseEventBreak = (chunkBuffer) => {
|
|
1676
|
+
const lfBreak = chunkBuffer.indexOf("\n\n");
|
|
1677
|
+
const crlfBreak = chunkBuffer.indexOf("\r\n\r\n");
|
|
1678
|
+
if (lfBreak === -1 && crlfBreak === -1)
|
|
1679
|
+
return null;
|
|
1680
|
+
if (lfBreak === -1)
|
|
1681
|
+
return { index: crlfBreak, length: 4 };
|
|
1682
|
+
if (crlfBreak === -1)
|
|
1683
|
+
return { index: lfBreak, length: 2 };
|
|
1684
|
+
return lfBreak < crlfBreak
|
|
1685
|
+
? { index: lfBreak, length: 2 }
|
|
1686
|
+
: { index: crlfBreak, length: 4 };
|
|
1687
|
+
};
|
|
1688
|
+
const parseDataLine = (line) => {
|
|
1689
|
+
const payload = line.startsWith("data:") ? line.slice(5).trim() : "";
|
|
1690
|
+
if (!payload)
|
|
1691
|
+
return;
|
|
1692
|
+
let parsed;
|
|
1693
|
+
try {
|
|
1694
|
+
parsed = JSON.parse(payload);
|
|
1695
|
+
}
|
|
1696
|
+
catch {
|
|
1697
|
+
return;
|
|
1698
|
+
}
|
|
1699
|
+
if (parsed.type === "token") {
|
|
1700
|
+
const chunk = parsed.text ?? "";
|
|
1701
|
+
const nextFullText = typeof parsed.fullText === "string"
|
|
1702
|
+
? parsed.fullText
|
|
1703
|
+
: chunk
|
|
1704
|
+
? mergeStreamingText(fullText, chunk)
|
|
1705
|
+
: fullText;
|
|
1706
|
+
if (nextFullText === fullText)
|
|
1707
|
+
return;
|
|
1708
|
+
fullText = nextFullText;
|
|
1709
|
+
onToken(chunk, fullText);
|
|
1710
|
+
return;
|
|
1711
|
+
}
|
|
1712
|
+
if (parsed.type === "done") {
|
|
1713
|
+
receivedDone = true;
|
|
1714
|
+
if (typeof parsed.fullText === "string")
|
|
1715
|
+
doneText = parsed.fullText;
|
|
1716
|
+
if (typeof parsed.agentName === "string" && parsed.agentName.trim()) {
|
|
1717
|
+
doneAgentName = parsed.agentName;
|
|
1718
|
+
}
|
|
1719
|
+
if (parsed.usage) {
|
|
1720
|
+
doneUsage = {
|
|
1721
|
+
promptTokens: parsed.usage.promptTokens ?? 0,
|
|
1722
|
+
completionTokens: parsed.usage.completionTokens ?? 0,
|
|
1723
|
+
totalTokens: parsed.usage.totalTokens ?? 0,
|
|
1724
|
+
model: parsed.usage.model,
|
|
1725
|
+
};
|
|
1726
|
+
}
|
|
1727
|
+
return;
|
|
1728
|
+
}
|
|
1729
|
+
if (parsed.type === "error") {
|
|
1730
|
+
throw new Error(parsed.message ?? "generation failed");
|
|
1731
|
+
}
|
|
1732
|
+
// Backward compatibility with legacy stream payloads: { text: "..." }
|
|
1733
|
+
if (parsed.text) {
|
|
1734
|
+
fullText = mergeStreamingText(fullText, parsed.text);
|
|
1735
|
+
onToken(parsed.text, fullText);
|
|
1736
|
+
}
|
|
1737
|
+
};
|
|
1738
|
+
while (true) {
|
|
1739
|
+
let done = false;
|
|
1740
|
+
let value;
|
|
1741
|
+
try {
|
|
1742
|
+
({ done, value } = await reader.read());
|
|
1743
|
+
}
|
|
1744
|
+
catch (streamErr) {
|
|
1745
|
+
console.warn("[api-client] SSE stream interrupted:", streamErr);
|
|
1746
|
+
break;
|
|
1747
|
+
}
|
|
1748
|
+
if (done || !value)
|
|
1749
|
+
break;
|
|
1750
|
+
buffer += decoder.decode(value, { stream: true });
|
|
1751
|
+
let eventBreak = findSseEventBreak(buffer);
|
|
1752
|
+
while (eventBreak) {
|
|
1753
|
+
const rawEvent = buffer.slice(0, eventBreak.index);
|
|
1754
|
+
buffer = buffer.slice(eventBreak.index + eventBreak.length);
|
|
1755
|
+
for (const line of rawEvent.split(/\r?\n/)) {
|
|
1756
|
+
if (!line.startsWith("data:"))
|
|
1757
|
+
continue;
|
|
1758
|
+
parseDataLine(line);
|
|
1759
|
+
}
|
|
1760
|
+
eventBreak = findSseEventBreak(buffer);
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
if (buffer.trim()) {
|
|
1764
|
+
for (const line of buffer.split(/\r?\n/)) {
|
|
1765
|
+
if (line.startsWith("data:"))
|
|
1766
|
+
parseDataLine(line);
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
const resolvedText = this.normalizeAssistantText(doneText ?? fullText);
|
|
1770
|
+
return {
|
|
1771
|
+
text: resolvedText,
|
|
1772
|
+
agentName: doneAgentName ?? "Milady",
|
|
1773
|
+
completed: receivedDone,
|
|
1774
|
+
...(doneUsage ? { usage: doneUsage } : {}),
|
|
1775
|
+
};
|
|
1776
|
+
}
|
|
1777
|
+
/**
|
|
1778
|
+
* Send a chat message via the REST endpoint (reliable — does not depend on
|
|
1779
|
+
* a WebSocket connection). Returns the agent's response text.
|
|
1780
|
+
*/
|
|
1781
|
+
async sendChatRest(text, channelType = "DM", conversationMode) {
|
|
1782
|
+
const response = await this.fetch("/api/chat", {
|
|
1783
|
+
method: "POST",
|
|
1784
|
+
body: JSON.stringify({
|
|
1785
|
+
text,
|
|
1786
|
+
channelType,
|
|
1787
|
+
...(conversationMode ? { conversationMode } : {}),
|
|
1788
|
+
}),
|
|
1789
|
+
});
|
|
1790
|
+
return {
|
|
1791
|
+
...response,
|
|
1792
|
+
text: this.normalizeAssistantText(response.text),
|
|
1793
|
+
};
|
|
1794
|
+
}
|
|
1795
|
+
async sendChatStream(text, onToken, channelType = "DM", signal, conversationMode) {
|
|
1796
|
+
return this.streamChatEndpoint("/api/chat/stream", text, onToken, channelType, signal, undefined, conversationMode);
|
|
1797
|
+
}
|
|
1798
|
+
// Conversations
|
|
1799
|
+
async listConversations() {
|
|
1800
|
+
return this.fetch("/api/conversations");
|
|
1801
|
+
}
|
|
1802
|
+
async createConversation(title, options) {
|
|
1803
|
+
const response = await this.fetch("/api/conversations", {
|
|
1804
|
+
method: "POST",
|
|
1805
|
+
body: JSON.stringify({
|
|
1806
|
+
title,
|
|
1807
|
+
...(options?.bootstrapGreeting === true
|
|
1808
|
+
? { bootstrapGreeting: true }
|
|
1809
|
+
: {}),
|
|
1810
|
+
...(typeof options?.lang === "string" && options.lang.trim()
|
|
1811
|
+
? { lang: options.lang.trim() }
|
|
1812
|
+
: {}),
|
|
1813
|
+
}),
|
|
1814
|
+
});
|
|
1815
|
+
if (!response.greeting) {
|
|
1816
|
+
return response;
|
|
1817
|
+
}
|
|
1818
|
+
return {
|
|
1819
|
+
...response,
|
|
1820
|
+
greeting: {
|
|
1821
|
+
...response.greeting,
|
|
1822
|
+
text: this.normalizeGreetingText(response.greeting.text),
|
|
1823
|
+
},
|
|
1824
|
+
};
|
|
1825
|
+
}
|
|
1826
|
+
async getConversationMessages(id) {
|
|
1827
|
+
const response = await this.fetch(`/api/conversations/${encodeURIComponent(id)}/messages`);
|
|
1828
|
+
return {
|
|
1829
|
+
messages: response.messages.map((message) => this.normalizeConversationMessage(message)),
|
|
1830
|
+
};
|
|
1831
|
+
}
|
|
1832
|
+
async truncateConversationMessages(id, messageId, options) {
|
|
1833
|
+
return this.fetch(`/api/conversations/${encodeURIComponent(id)}/messages/truncate`, {
|
|
1834
|
+
method: "POST",
|
|
1835
|
+
body: JSON.stringify({
|
|
1836
|
+
messageId,
|
|
1837
|
+
inclusive: options?.inclusive === true,
|
|
1838
|
+
}),
|
|
1839
|
+
});
|
|
1840
|
+
}
|
|
1841
|
+
async sendConversationMessage(id, text, channelType = "DM", images, conversationMode) {
|
|
1842
|
+
const response = await this.fetch(`/api/conversations/${encodeURIComponent(id)}/messages`, {
|
|
1843
|
+
method: "POST",
|
|
1844
|
+
body: JSON.stringify({
|
|
1845
|
+
text,
|
|
1846
|
+
channelType,
|
|
1847
|
+
...(images?.length ? { images } : {}),
|
|
1848
|
+
...(conversationMode ? { conversationMode } : {}),
|
|
1849
|
+
}),
|
|
1850
|
+
});
|
|
1851
|
+
return {
|
|
1852
|
+
...response,
|
|
1853
|
+
text: this.normalizeAssistantText(response.text),
|
|
1854
|
+
};
|
|
1855
|
+
}
|
|
1856
|
+
async sendConversationMessageStream(id, text, onToken, channelType = "DM", signal, images, conversationMode) {
|
|
1857
|
+
return this.streamChatEndpoint(`/api/conversations/${encodeURIComponent(id)}/messages/stream`, text, onToken, channelType, signal, images, conversationMode);
|
|
1858
|
+
}
|
|
1859
|
+
async requestGreeting(id, lang) {
|
|
1860
|
+
const qs = lang ? `?lang=${encodeURIComponent(lang)}` : "";
|
|
1861
|
+
const response = await this.fetch(`/api/conversations/${encodeURIComponent(id)}/greeting${qs}`, {
|
|
1862
|
+
method: "POST",
|
|
1863
|
+
});
|
|
1864
|
+
return {
|
|
1865
|
+
...response,
|
|
1866
|
+
text: this.normalizeGreetingText(response.text),
|
|
1867
|
+
};
|
|
1868
|
+
}
|
|
1869
|
+
async renameConversation(id, title) {
|
|
1870
|
+
return this.fetch(`/api/conversations/${encodeURIComponent(id)}`, {
|
|
1871
|
+
method: "PATCH",
|
|
1872
|
+
body: JSON.stringify({ title }),
|
|
1873
|
+
});
|
|
1874
|
+
}
|
|
1875
|
+
async deleteConversation(id) {
|
|
1876
|
+
return this.fetch(`/api/conversations/${encodeURIComponent(id)}`, {
|
|
1877
|
+
method: "DELETE",
|
|
1878
|
+
});
|
|
1879
|
+
}
|
|
1880
|
+
/** @deprecated Prefer {@link sendChatRest} — WebSocket chat may silently drop messages. */
|
|
1881
|
+
sendChat(text) {
|
|
1882
|
+
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
1883
|
+
this.ws.send(JSON.stringify({ type: "chat", text }));
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
// ── Database API ──────────────────────────────────────────────────────
|
|
1887
|
+
async getDatabaseStatus() {
|
|
1888
|
+
return this.fetch("/api/database/status");
|
|
1889
|
+
}
|
|
1890
|
+
async getDatabaseConfig() {
|
|
1891
|
+
return this.fetch("/api/database/config");
|
|
1892
|
+
}
|
|
1893
|
+
async saveDatabaseConfig(config) {
|
|
1894
|
+
return this.fetch("/api/database/config", {
|
|
1895
|
+
method: "PUT",
|
|
1896
|
+
body: JSON.stringify(config),
|
|
1897
|
+
});
|
|
1898
|
+
}
|
|
1899
|
+
async testDatabaseConnection(creds) {
|
|
1900
|
+
return this.fetch("/api/database/test", {
|
|
1901
|
+
method: "POST",
|
|
1902
|
+
body: JSON.stringify(creds),
|
|
1903
|
+
});
|
|
1904
|
+
}
|
|
1905
|
+
async getDatabaseTables() {
|
|
1906
|
+
return this.fetch("/api/database/tables");
|
|
1907
|
+
}
|
|
1908
|
+
async getDatabaseRows(table, opts) {
|
|
1909
|
+
const params = new URLSearchParams();
|
|
1910
|
+
if (opts?.offset != null)
|
|
1911
|
+
params.set("offset", String(opts.offset));
|
|
1912
|
+
if (opts?.limit != null)
|
|
1913
|
+
params.set("limit", String(opts.limit));
|
|
1914
|
+
if (opts?.sort)
|
|
1915
|
+
params.set("sort", opts.sort);
|
|
1916
|
+
if (opts?.order)
|
|
1917
|
+
params.set("order", opts.order);
|
|
1918
|
+
if (opts?.search)
|
|
1919
|
+
params.set("search", opts.search);
|
|
1920
|
+
const qs = params.toString();
|
|
1921
|
+
return this.fetch(`/api/database/tables/${encodeURIComponent(table)}/rows${qs ? `?${qs}` : ""}`);
|
|
1922
|
+
}
|
|
1923
|
+
async insertDatabaseRow(table, data) {
|
|
1924
|
+
return this.fetch(`/api/database/tables/${encodeURIComponent(table)}/rows`, {
|
|
1925
|
+
method: "POST",
|
|
1926
|
+
body: JSON.stringify({ data }),
|
|
1927
|
+
});
|
|
1928
|
+
}
|
|
1929
|
+
async updateDatabaseRow(table, where, data) {
|
|
1930
|
+
return this.fetch(`/api/database/tables/${encodeURIComponent(table)}/rows`, {
|
|
1931
|
+
method: "PUT",
|
|
1932
|
+
body: JSON.stringify({ where, data }),
|
|
1933
|
+
});
|
|
1934
|
+
}
|
|
1935
|
+
async deleteDatabaseRow(table, where) {
|
|
1936
|
+
return this.fetch(`/api/database/tables/${encodeURIComponent(table)}/rows`, {
|
|
1937
|
+
method: "DELETE",
|
|
1938
|
+
body: JSON.stringify({ where }),
|
|
1939
|
+
});
|
|
1940
|
+
}
|
|
1941
|
+
async executeDatabaseQuery(sql, readOnly = true) {
|
|
1942
|
+
return this.fetch("/api/database/query", {
|
|
1943
|
+
method: "POST",
|
|
1944
|
+
body: JSON.stringify({ sql, readOnly }),
|
|
1945
|
+
});
|
|
1946
|
+
}
|
|
1947
|
+
// ── Trajectories ─────────────────────────────────────────────────────
|
|
1948
|
+
async getTrajectories(options) {
|
|
1949
|
+
const params = new URLSearchParams();
|
|
1950
|
+
if (options?.limit)
|
|
1951
|
+
params.set("limit", String(options.limit));
|
|
1952
|
+
if (options?.offset)
|
|
1953
|
+
params.set("offset", String(options.offset));
|
|
1954
|
+
if (options?.source)
|
|
1955
|
+
params.set("source", options.source);
|
|
1956
|
+
if (options?.status)
|
|
1957
|
+
params.set("status", options.status);
|
|
1958
|
+
if (options?.startDate)
|
|
1959
|
+
params.set("startDate", options.startDate);
|
|
1960
|
+
if (options?.endDate)
|
|
1961
|
+
params.set("endDate", options.endDate);
|
|
1962
|
+
if (options?.search)
|
|
1963
|
+
params.set("search", options.search);
|
|
1964
|
+
const query = params.toString();
|
|
1965
|
+
return this.fetch(`/api/trajectories${query ? `?${query}` : ""}`);
|
|
1966
|
+
}
|
|
1967
|
+
async getTrajectoryDetail(trajectoryId) {
|
|
1968
|
+
return this.fetch(`/api/trajectories/${encodeURIComponent(trajectoryId)}`);
|
|
1969
|
+
}
|
|
1970
|
+
async getTrajectoryStats() {
|
|
1971
|
+
return this.fetch("/api/trajectories/stats");
|
|
1972
|
+
}
|
|
1973
|
+
async getTrajectoryConfig() {
|
|
1974
|
+
return this.fetch("/api/trajectories/config");
|
|
1975
|
+
}
|
|
1976
|
+
async updateTrajectoryConfig(config) {
|
|
1977
|
+
return this.fetch("/api/trajectories/config", {
|
|
1978
|
+
method: "PUT",
|
|
1979
|
+
body: JSON.stringify(config),
|
|
1980
|
+
});
|
|
1981
|
+
}
|
|
1982
|
+
async exportTrajectories(options) {
|
|
1983
|
+
const res = await this.rawRequest("/api/trajectories/export", {
|
|
1984
|
+
method: "POST",
|
|
1985
|
+
headers: {
|
|
1986
|
+
"Content-Type": "application/json",
|
|
1987
|
+
},
|
|
1988
|
+
body: JSON.stringify(options),
|
|
1989
|
+
});
|
|
1990
|
+
return res.blob();
|
|
1991
|
+
}
|
|
1992
|
+
async deleteTrajectories(trajectoryIds) {
|
|
1993
|
+
return this.fetch("/api/trajectories", {
|
|
1994
|
+
method: "DELETE",
|
|
1995
|
+
body: JSON.stringify({ trajectoryIds }),
|
|
1996
|
+
});
|
|
1997
|
+
}
|
|
1998
|
+
async clearAllTrajectories() {
|
|
1999
|
+
return this.fetch("/api/trajectories", {
|
|
2000
|
+
method: "DELETE",
|
|
2001
|
+
body: JSON.stringify({ clearAll: true }),
|
|
2002
|
+
});
|
|
2003
|
+
}
|
|
2004
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
2005
|
+
// System Permissions
|
|
2006
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
2007
|
+
/**
|
|
2008
|
+
* Get all system permission states.
|
|
2009
|
+
*/
|
|
2010
|
+
async getPermissions() {
|
|
2011
|
+
return this.fetch("/api/permissions");
|
|
2012
|
+
}
|
|
2013
|
+
/**
|
|
2014
|
+
* Get a single permission state.
|
|
2015
|
+
*/
|
|
2016
|
+
async getPermission(id) {
|
|
2017
|
+
return this.fetch(`/api/permissions/${id}`);
|
|
2018
|
+
}
|
|
2019
|
+
/**
|
|
2020
|
+
* Request a specific permission (triggers OS prompt if applicable).
|
|
2021
|
+
*/
|
|
2022
|
+
async requestPermission(id) {
|
|
2023
|
+
return this.fetch(`/api/permissions/${id}/request`, { method: "POST" });
|
|
2024
|
+
}
|
|
2025
|
+
/**
|
|
2026
|
+
* Open system settings for a specific permission.
|
|
2027
|
+
*/
|
|
2028
|
+
async openPermissionSettings(id) {
|
|
2029
|
+
await this.fetch(`/api/permissions/${id}/open-settings`, {
|
|
2030
|
+
method: "POST",
|
|
2031
|
+
});
|
|
2032
|
+
}
|
|
2033
|
+
/**
|
|
2034
|
+
* Refresh all permission states from the OS.
|
|
2035
|
+
*/
|
|
2036
|
+
async refreshPermissions() {
|
|
2037
|
+
return this.fetch("/api/permissions/refresh", { method: "POST" });
|
|
2038
|
+
}
|
|
2039
|
+
/**
|
|
2040
|
+
* Enable or disable shell access.
|
|
2041
|
+
*/
|
|
2042
|
+
async setShellEnabled(enabled) {
|
|
2043
|
+
return this.fetch("/api/permissions/shell", {
|
|
2044
|
+
method: "PUT",
|
|
2045
|
+
body: JSON.stringify({ enabled }),
|
|
2046
|
+
});
|
|
2047
|
+
}
|
|
2048
|
+
/**
|
|
2049
|
+
* Get shell enabled status.
|
|
2050
|
+
*/
|
|
2051
|
+
async isShellEnabled() {
|
|
2052
|
+
const result = await this.fetch("/api/permissions/shell");
|
|
2053
|
+
return result.enabled;
|
|
2054
|
+
}
|
|
2055
|
+
/**
|
|
2056
|
+
* Get agent automation permission mode.
|
|
2057
|
+
*/
|
|
2058
|
+
async getAgentAutomationMode() {
|
|
2059
|
+
return this.fetch("/api/permissions/automation-mode");
|
|
2060
|
+
}
|
|
2061
|
+
/**
|
|
2062
|
+
* Set agent automation permission mode.
|
|
2063
|
+
*/
|
|
2064
|
+
async setAgentAutomationMode(mode) {
|
|
2065
|
+
return this.fetch("/api/permissions/automation-mode", {
|
|
2066
|
+
method: "PUT",
|
|
2067
|
+
body: JSON.stringify({ mode }),
|
|
2068
|
+
});
|
|
2069
|
+
}
|
|
2070
|
+
/**
|
|
2071
|
+
* Get wallet trade execution permission mode.
|
|
2072
|
+
*/
|
|
2073
|
+
async getTradePermissionMode() {
|
|
2074
|
+
return this.fetch("/api/permissions/trade-mode");
|
|
2075
|
+
}
|
|
2076
|
+
/**
|
|
2077
|
+
* Set wallet trade execution permission mode.
|
|
2078
|
+
*/
|
|
2079
|
+
async setTradePermissionMode(mode) {
|
|
2080
|
+
return this.fetch("/api/permissions/trade-mode", {
|
|
2081
|
+
method: "PUT",
|
|
2082
|
+
body: JSON.stringify({ mode }),
|
|
2083
|
+
});
|
|
2084
|
+
}
|
|
2085
|
+
disconnectWs() {
|
|
2086
|
+
if (this.reconnectTimer) {
|
|
2087
|
+
clearTimeout(this.reconnectTimer);
|
|
2088
|
+
this.reconnectTimer = null;
|
|
2089
|
+
}
|
|
2090
|
+
this.ws?.close();
|
|
2091
|
+
this.ws = null;
|
|
2092
|
+
this.wsSendQueue = [];
|
|
2093
|
+
// Reset connection state on intentional disconnect
|
|
2094
|
+
this.reconnectAttempt = 0;
|
|
2095
|
+
this.disconnectedAt = null;
|
|
2096
|
+
this.connectionState = "disconnected";
|
|
2097
|
+
this.emitConnectionStateChange();
|
|
2098
|
+
}
|
|
2099
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
2100
|
+
// ERC-8004 Registry
|
|
2101
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
2102
|
+
async getRegistryStatus() {
|
|
2103
|
+
return this.fetch("/api/registry/status");
|
|
2104
|
+
}
|
|
2105
|
+
async registerAgent(params) {
|
|
2106
|
+
return this.fetch("/api/registry/register", {
|
|
2107
|
+
method: "POST",
|
|
2108
|
+
body: JSON.stringify(params ?? {}),
|
|
2109
|
+
});
|
|
2110
|
+
}
|
|
2111
|
+
async updateRegistryTokenURI(tokenURI) {
|
|
2112
|
+
return this.fetch("/api/registry/update-uri", {
|
|
2113
|
+
method: "POST",
|
|
2114
|
+
body: JSON.stringify({ tokenURI }),
|
|
2115
|
+
});
|
|
2116
|
+
}
|
|
2117
|
+
async syncRegistryProfile(params) {
|
|
2118
|
+
return this.fetch("/api/registry/sync", {
|
|
2119
|
+
method: "POST",
|
|
2120
|
+
body: JSON.stringify(params ?? {}),
|
|
2121
|
+
});
|
|
2122
|
+
}
|
|
2123
|
+
async getRegistryConfig() {
|
|
2124
|
+
return this.fetch("/api/registry/config");
|
|
2125
|
+
}
|
|
2126
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
2127
|
+
// Drop / Mint
|
|
2128
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
2129
|
+
async getDropStatus() {
|
|
2130
|
+
return this.fetch("/api/drop/status");
|
|
2131
|
+
}
|
|
2132
|
+
async mintAgent(params) {
|
|
2133
|
+
return this.fetch("/api/drop/mint", {
|
|
2134
|
+
method: "POST",
|
|
2135
|
+
body: JSON.stringify(params ?? {}),
|
|
2136
|
+
});
|
|
2137
|
+
}
|
|
2138
|
+
async mintAgentWhitelist(params) {
|
|
2139
|
+
return this.fetch("/api/drop/mint-whitelist", {
|
|
2140
|
+
method: "POST",
|
|
2141
|
+
body: JSON.stringify(params),
|
|
2142
|
+
});
|
|
2143
|
+
}
|
|
2144
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
2145
|
+
// Whitelist
|
|
2146
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
2147
|
+
async getWhitelistStatus() {
|
|
2148
|
+
return this.fetch("/api/whitelist/status");
|
|
2149
|
+
}
|
|
2150
|
+
async generateTwitterVerificationMessage() {
|
|
2151
|
+
return this.fetch("/api/whitelist/twitter/message", { method: "POST" });
|
|
2152
|
+
}
|
|
2153
|
+
async verifyTwitter(tweetUrl) {
|
|
2154
|
+
return this.fetch("/api/whitelist/twitter/verify", {
|
|
2155
|
+
method: "POST",
|
|
2156
|
+
body: JSON.stringify({ tweetUrl }),
|
|
2157
|
+
});
|
|
2158
|
+
}
|
|
2159
|
+
// ── Custom Actions ─────────────────────────────────────────────────────
|
|
2160
|
+
async listCustomActions() {
|
|
2161
|
+
const data = await this.fetch("/api/custom-actions");
|
|
2162
|
+
return data.actions;
|
|
2163
|
+
}
|
|
2164
|
+
async createCustomAction(action) {
|
|
2165
|
+
const data = await this.fetch("/api/custom-actions", { method: "POST", body: JSON.stringify(action) });
|
|
2166
|
+
return data.action;
|
|
2167
|
+
}
|
|
2168
|
+
async updateCustomAction(id, action) {
|
|
2169
|
+
const data = await this.fetch(`/api/custom-actions/${encodeURIComponent(id)}`, { method: "PUT", body: JSON.stringify(action) });
|
|
2170
|
+
return data.action;
|
|
2171
|
+
}
|
|
2172
|
+
async deleteCustomAction(id) {
|
|
2173
|
+
await this.fetch(`/api/custom-actions/${encodeURIComponent(id)}`, {
|
|
2174
|
+
method: "DELETE",
|
|
2175
|
+
});
|
|
2176
|
+
}
|
|
2177
|
+
async testCustomAction(id, params) {
|
|
2178
|
+
return this.fetch(`/api/custom-actions/${encodeURIComponent(id)}/test`, {
|
|
2179
|
+
method: "POST",
|
|
2180
|
+
body: JSON.stringify({ params }),
|
|
2181
|
+
});
|
|
2182
|
+
}
|
|
2183
|
+
async generateCustomAction(prompt) {
|
|
2184
|
+
return this.fetch("/api/custom-actions/generate", {
|
|
2185
|
+
method: "POST",
|
|
2186
|
+
body: JSON.stringify({ prompt }),
|
|
2187
|
+
});
|
|
2188
|
+
}
|
|
2189
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
2190
|
+
// WhatsApp Pairing
|
|
2191
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
2192
|
+
async getWhatsAppStatus(accountId = "default") {
|
|
2193
|
+
return this.fetch(`/api/whatsapp/status?accountId=${encodeURIComponent(accountId)}`);
|
|
2194
|
+
}
|
|
2195
|
+
async startWhatsAppPairing(accountId = "default") {
|
|
2196
|
+
return this.fetch("/api/whatsapp/pair", {
|
|
2197
|
+
method: "POST",
|
|
2198
|
+
body: JSON.stringify({ accountId }),
|
|
2199
|
+
});
|
|
2200
|
+
}
|
|
2201
|
+
async stopWhatsAppPairing(accountId = "default") {
|
|
2202
|
+
return this.fetch("/api/whatsapp/pair/stop", {
|
|
2203
|
+
method: "POST",
|
|
2204
|
+
body: JSON.stringify({ accountId }),
|
|
2205
|
+
});
|
|
2206
|
+
}
|
|
2207
|
+
async disconnectWhatsApp(accountId = "default") {
|
|
2208
|
+
return this.fetch("/api/whatsapp/disconnect", {
|
|
2209
|
+
method: "POST",
|
|
2210
|
+
body: JSON.stringify({ accountId }),
|
|
2211
|
+
});
|
|
2212
|
+
}
|
|
2213
|
+
// --- Bug Report ---
|
|
2214
|
+
async checkBugReportInfo() {
|
|
2215
|
+
return this.fetch("/api/bug-report/info");
|
|
2216
|
+
}
|
|
2217
|
+
async submitBugReport(report) {
|
|
2218
|
+
return this.fetch("/api/bug-report", {
|
|
2219
|
+
method: "POST",
|
|
2220
|
+
body: JSON.stringify(report),
|
|
2221
|
+
});
|
|
2222
|
+
}
|
|
2223
|
+
// ── Coding Agents ───────────────────────────────────────────────────
|
|
2224
|
+
async getCodingAgentStatus() {
|
|
2225
|
+
try {
|
|
2226
|
+
return await this.fetch("/api/coding-agents/coordinator/status");
|
|
2227
|
+
}
|
|
2228
|
+
catch {
|
|
2229
|
+
return null;
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
async stopCodingAgent(sessionId) {
|
|
2233
|
+
try {
|
|
2234
|
+
await this.fetch(`/api/coding-agents/${encodeURIComponent(sessionId)}/stop`, { method: "POST" });
|
|
2235
|
+
return true;
|
|
2236
|
+
}
|
|
2237
|
+
catch {
|
|
2238
|
+
return false;
|
|
2239
|
+
}
|
|
2240
|
+
}
|
|
2241
|
+
async listCodingAgentScratchWorkspaces() {
|
|
2242
|
+
try {
|
|
2243
|
+
return await this.fetch("/api/coding-agents/scratch");
|
|
2244
|
+
}
|
|
2245
|
+
catch {
|
|
2246
|
+
return [];
|
|
2247
|
+
}
|
|
2248
|
+
}
|
|
2249
|
+
async keepCodingAgentScratchWorkspace(sessionId) {
|
|
2250
|
+
try {
|
|
2251
|
+
await this.fetch(`/api/coding-agents/${encodeURIComponent(sessionId)}/scratch/keep`, { method: "POST" });
|
|
2252
|
+
return true;
|
|
2253
|
+
}
|
|
2254
|
+
catch {
|
|
2255
|
+
return false;
|
|
2256
|
+
}
|
|
2257
|
+
}
|
|
2258
|
+
async deleteCodingAgentScratchWorkspace(sessionId) {
|
|
2259
|
+
try {
|
|
2260
|
+
// Keep POST for compatibility with plugin route handlers.
|
|
2261
|
+
await this.fetch(`/api/coding-agents/${encodeURIComponent(sessionId)}/scratch/delete`, { method: "POST" });
|
|
2262
|
+
return true;
|
|
2263
|
+
}
|
|
2264
|
+
catch {
|
|
2265
|
+
return false;
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
async promoteCodingAgentScratchWorkspace(sessionId, name) {
|
|
2269
|
+
try {
|
|
2270
|
+
const response = await this.fetch(`/api/coding-agents/${encodeURIComponent(sessionId)}/scratch/promote`, {
|
|
2271
|
+
method: "POST",
|
|
2272
|
+
body: JSON.stringify(name ? { name } : {}),
|
|
2273
|
+
});
|
|
2274
|
+
return response.scratch ?? null;
|
|
2275
|
+
}
|
|
2276
|
+
catch {
|
|
2277
|
+
return null;
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
// ── PTY Terminal (xterm.js bridge) ─────────────────────────────────────
|
|
2281
|
+
/** Subscribe to live PTY output for a session over WebSocket. */
|
|
2282
|
+
subscribePtyOutput(sessionId) {
|
|
2283
|
+
this.sendWsMessage({ type: "pty-subscribe", sessionId });
|
|
2284
|
+
}
|
|
2285
|
+
/** Unsubscribe from live PTY output for a session. */
|
|
2286
|
+
unsubscribePtyOutput(sessionId) {
|
|
2287
|
+
this.sendWsMessage({ type: "pty-unsubscribe", sessionId });
|
|
2288
|
+
}
|
|
2289
|
+
/** Send raw keyboard input to a PTY session. */
|
|
2290
|
+
sendPtyInput(sessionId, data) {
|
|
2291
|
+
this.sendWsMessage({ type: "pty-input", sessionId, data });
|
|
2292
|
+
}
|
|
2293
|
+
/** Resize a PTY session's terminal dimensions. */
|
|
2294
|
+
resizePty(sessionId, cols, rows) {
|
|
2295
|
+
this.sendWsMessage({ type: "pty-resize", sessionId, cols, rows });
|
|
2296
|
+
}
|
|
2297
|
+
/** Fetch buffered terminal output (raw ANSI) for xterm.js hydration. */
|
|
2298
|
+
async getPtyBufferedOutput(sessionId) {
|
|
2299
|
+
try {
|
|
2300
|
+
const res = await this.fetch(`/api/coding-agents/${encodeURIComponent(sessionId)}/buffered-output`);
|
|
2301
|
+
return res.output ?? "";
|
|
2302
|
+
}
|
|
2303
|
+
catch {
|
|
2304
|
+
return "";
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
// ── Stream controls ─────────────────────────────────────────────────────
|
|
2308
|
+
async streamGoLive() {
|
|
2309
|
+
return this.fetch("/api/stream/live", { method: "POST" });
|
|
2310
|
+
}
|
|
2311
|
+
async streamGoOffline() {
|
|
2312
|
+
return this.fetch("/api/stream/offline", { method: "POST" });
|
|
2313
|
+
}
|
|
2314
|
+
async streamStatus() {
|
|
2315
|
+
return this.fetch("/api/stream/status");
|
|
2316
|
+
}
|
|
2317
|
+
async getStreamingDestinations() {
|
|
2318
|
+
return this.fetch("/api/streaming/destinations");
|
|
2319
|
+
}
|
|
2320
|
+
async setActiveDestination(destinationId) {
|
|
2321
|
+
return this.fetch("/api/streaming/destination", {
|
|
2322
|
+
method: "POST",
|
|
2323
|
+
body: JSON.stringify({ destinationId }),
|
|
2324
|
+
});
|
|
2325
|
+
}
|
|
2326
|
+
async setStreamVolume(volume) {
|
|
2327
|
+
return this.fetch("/api/stream/volume", {
|
|
2328
|
+
method: "POST",
|
|
2329
|
+
body: JSON.stringify({ volume }),
|
|
2330
|
+
});
|
|
2331
|
+
}
|
|
2332
|
+
async muteStream() {
|
|
2333
|
+
return this.fetch("/api/stream/mute", { method: "POST" });
|
|
2334
|
+
}
|
|
2335
|
+
async unmuteStream() {
|
|
2336
|
+
return this.fetch("/api/stream/unmute", { method: "POST" });
|
|
2337
|
+
}
|
|
2338
|
+
// ── Stream voice (TTS) ───────────────────────────────────────────────
|
|
2339
|
+
async getStreamVoice() {
|
|
2340
|
+
return this.fetch("/api/stream/voice");
|
|
2341
|
+
}
|
|
2342
|
+
async saveStreamVoice(settings) {
|
|
2343
|
+
return this.fetch("/api/stream/voice", {
|
|
2344
|
+
method: "POST",
|
|
2345
|
+
body: JSON.stringify(settings),
|
|
2346
|
+
});
|
|
2347
|
+
}
|
|
2348
|
+
async streamVoiceSpeak(text) {
|
|
2349
|
+
return this.fetch("/api/stream/voice/speak", {
|
|
2350
|
+
method: "POST",
|
|
2351
|
+
body: JSON.stringify({ text }),
|
|
2352
|
+
});
|
|
2353
|
+
}
|
|
2354
|
+
// ── Overlay layout ────────────────────────────────────────────────────
|
|
2355
|
+
async getOverlayLayout(destinationId) {
|
|
2356
|
+
const qs = destinationId
|
|
2357
|
+
? `?destination=${encodeURIComponent(destinationId)}`
|
|
2358
|
+
: "";
|
|
2359
|
+
return this.fetch(`/api/stream/overlay-layout${qs}`);
|
|
2360
|
+
}
|
|
2361
|
+
async saveOverlayLayout(layout, destinationId) {
|
|
2362
|
+
const qs = destinationId
|
|
2363
|
+
? `?destination=${encodeURIComponent(destinationId)}`
|
|
2364
|
+
: "";
|
|
2365
|
+
return this.fetch(`/api/stream/overlay-layout${qs}`, {
|
|
2366
|
+
method: "POST",
|
|
2367
|
+
body: JSON.stringify({ layout }),
|
|
2368
|
+
});
|
|
2369
|
+
}
|
|
2370
|
+
// ── Stream source picker ──────────────────────────────────────────────
|
|
2371
|
+
async getStreamSource() {
|
|
2372
|
+
return this.fetch("/api/stream/source");
|
|
2373
|
+
}
|
|
2374
|
+
async setStreamSource(sourceType, customUrl) {
|
|
2375
|
+
return this.fetch("/api/stream/source", {
|
|
2376
|
+
method: "POST",
|
|
2377
|
+
body: JSON.stringify({ sourceType, customUrl }),
|
|
2378
|
+
});
|
|
2379
|
+
}
|
|
2380
|
+
// ── Stream visual settings (theme, avatar for headless parity) ────────
|
|
2381
|
+
async getStreamSettings() {
|
|
2382
|
+
return this.fetch("/api/stream/settings");
|
|
2383
|
+
}
|
|
2384
|
+
async saveStreamSettings(settings) {
|
|
2385
|
+
return this.fetch("/api/stream/settings", {
|
|
2386
|
+
method: "POST",
|
|
2387
|
+
body: JSON.stringify({ settings }),
|
|
2388
|
+
});
|
|
2389
|
+
}
|
|
2390
|
+
}
|
|
2391
|
+
// Singleton
|
|
2392
|
+
export const client = new MiladyClient();
|