neoagent 2.3.1-beta.11 → 2.3.1-beta.111
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +53 -5
- package/README.md +16 -7
- package/com.neoagent.plist +1 -1
- package/docs/automation.md +82 -41
- package/docs/capabilities.md +85 -89
- package/docs/configuration.md +87 -94
- package/docs/getting-started.md +46 -27
- package/docs/hardware.md +1 -1
- package/docs/index.md +24 -30
- package/docs/integrations.md +46 -64
- package/docs/migration.md +41 -146
- package/docs/operations.md +23 -20
- package/docs/skills.md +20 -20
- package/docs/why-neoagent.md +15 -13
- package/extensions/chrome-browser/background.mjs +10 -2
- package/flutter_app/.metadata +42 -0
- package/flutter_app/DESIGN_SYSTEM.md +166 -0
- package/flutter_app/README.md +21 -0
- package/flutter_app/analysis_options.yaml +32 -0
- package/flutter_app/android/app/build.gradle.kts +111 -0
- package/flutter_app/android/app/src/debug/AndroidManifest.xml +7 -0
- package/flutter_app/android/app/src/main/AndroidManifest.xml +185 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/MainActivity.kt +888 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/auto/NeoAgentCarAppService.kt +114 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/HealthConnectGateway.kt +280 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/HealthSyncNotifications.kt +113 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/HealthSyncPayload.kt +57 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/HealthSyncScheduler.kt +78 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/HealthSyncWorker.kt +253 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/PermissionsRationaleActivity.kt +46 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/recording/RecordingBootReceiver.kt +21 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/recording/RecordingForegroundService.kt +586 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/recording/RecordingStateStore.kt +78 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/recording/RecordingUploadClient.kt +104 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/telecom/NeoAgentConnection.kt +118 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/telecom/NeoAgentConnectionService.kt +86 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/AiHomeWidgetProvider.kt +457 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/AiWidgetStore.kt +194 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/VoiceLaunchWidgetProvider.kt +67 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/WidgetConfigActivity.kt +228 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/WidgetSyncScheduler.kt +72 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/WidgetSyncWorker.kt +186 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/WidgetTaskRunWorker.kt +210 -0
- package/flutter_app/android/app/src/main/res/drawable/launch_background.xml +12 -0
- package/flutter_app/android/app/src/main/res/drawable/neoagent_ai_widget_bg.xml +11 -0
- package/flutter_app/android/app/src/main/res/drawable/neoagent_ai_widget_task_bg.xml +8 -0
- package/flutter_app/android/app/src/main/res/drawable-v21/launch_background.xml +12 -0
- package/flutter_app/android/app/src/main/res/layout/neoagent_ai_widget.xml +138 -0
- package/flutter_app/android/app/src/main/res/layout/neoagent_ai_widget_task_row.xml +52 -0
- package/flutter_app/android/app/src/main/res/layout/neoagent_voice_widget.xml +49 -0
- package/flutter_app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/flutter_app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/flutter_app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/flutter_app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/flutter_app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/flutter_app/android/app/src/main/res/values/arrays.xml +8 -0
- package/flutter_app/android/app/src/main/res/values/strings.xml +12 -0
- package/flutter_app/android/app/src/main/res/values/styles.xml +18 -0
- package/flutter_app/android/app/src/main/res/values-night/styles.xml +18 -0
- package/flutter_app/android/app/src/main/res/xml/automotive_app_desc.xml +4 -0
- package/flutter_app/android/app/src/main/res/xml/file_paths.xml +6 -0
- package/flutter_app/android/app/src/main/res/xml/neoagent_ai_widget_info.xml +12 -0
- package/flutter_app/android/app/src/main/res/xml/neoagent_voice_widget_info.xml +12 -0
- package/flutter_app/android/app/src/profile/AndroidManifest.xml +7 -0
- package/flutter_app/android/build.gradle.kts +24 -0
- package/flutter_app/android/ci-release.keystore +0 -0
- package/flutter_app/android/gradle/wrapper/gradle-wrapper.properties +5 -0
- package/flutter_app/android/gradle.properties +3 -0
- package/flutter_app/android/key.properties +4 -0
- package/flutter_app/android/settings.gradle.kts +26 -0
- package/flutter_app/assets/branding/app_icon_1024.png +0 -0
- package/flutter_app/assets/branding/app_icon_128.png +0 -0
- package/flutter_app/assets/branding/app_icon_192.png +0 -0
- package/flutter_app/assets/branding/app_icon_256.png +0 -0
- package/flutter_app/assets/branding/app_icon_32.png +0 -0
- package/flutter_app/assets/branding/app_icon_512.png +0 -0
- package/flutter_app/assets/branding/app_icon_64.png +0 -0
- package/flutter_app/assets/branding/onboarding_intro.mp4 +0 -0
- package/flutter_app/assets/branding/tray_icon_template.png +0 -0
- package/flutter_app/lib/features/location/location_service.dart +117 -0
- package/flutter_app/lib/features/notifications/notification_interceptor.dart +73 -0
- package/flutter_app/lib/features/onboarding/onboarding_chrome.dart +571 -0
- package/flutter_app/lib/features/onboarding/onboarding_messaging_step.dart +275 -0
- package/flutter_app/lib/features/onboarding/onboarding_model_step.dart +366 -0
- package/flutter_app/lib/features/onboarding/onboarding_shell.dart +57 -0
- package/flutter_app/lib/features/onboarding/onboarding_video_step.dart +218 -0
- package/flutter_app/lib/features/onboarding/onboarding_welcome_step.dart +46 -0
- package/flutter_app/lib/main.dart +107 -0
- package/flutter_app/lib/main_account_settings.dart +1340 -0
- package/flutter_app/lib/main_admin.dart +900 -0
- package/flutter_app/lib/main_app_shell.dart +2162 -0
- package/flutter_app/lib/main_chat.dart +3902 -0
- package/flutter_app/lib/main_controller.dart +7229 -0
- package/flutter_app/lib/main_devices.dart +1738 -0
- package/flutter_app/lib/main_integrations.dart +917 -0
- package/flutter_app/lib/main_launcher.dart +959 -0
- package/flutter_app/lib/main_launcher_entry.dart +5 -0
- package/flutter_app/lib/main_models.dart +3807 -0
- package/flutter_app/lib/main_navigation.dart +206 -0
- package/flutter_app/lib/main_operations.dart +5249 -0
- package/flutter_app/lib/main_recordings.dart +920 -0
- package/flutter_app/lib/main_runtime.dart +869 -0
- package/flutter_app/lib/main_settings.dart +2288 -0
- package/flutter_app/lib/main_shared.dart +3393 -0
- package/flutter_app/lib/main_spacing.dart +33 -0
- package/flutter_app/lib/main_theme.dart +276 -0
- package/flutter_app/lib/main_unified.dart +388 -0
- package/flutter_app/lib/main_voice_assistant.dart +957 -0
- package/flutter_app/lib/src/analytics_service.dart +294 -0
- package/flutter_app/lib/src/android_apk_drop_zone.dart +32 -0
- package/flutter_app/lib/src/android_apk_drop_zone_stub.dart +16 -0
- package/flutter_app/lib/src/android_apk_drop_zone_web.dart +348 -0
- package/flutter_app/lib/src/android_app_installer.dart +22 -0
- package/flutter_app/lib/src/android_app_installer_io.dart +122 -0
- package/flutter_app/lib/src/android_app_installer_stub.dart +21 -0
- package/flutter_app/lib/src/android_auto_bridge.dart +59 -0
- package/flutter_app/lib/src/android_launcher_bridge.dart +239 -0
- package/flutter_app/lib/src/app_launch_bridge.dart +58 -0
- package/flutter_app/lib/src/app_release_updater.dart +511 -0
- package/flutter_app/lib/src/backend_client.dart +1870 -0
- package/flutter_app/lib/src/desktop_companion.dart +2 -0
- package/flutter_app/lib/src/desktop_companion_actions.dart +586 -0
- package/flutter_app/lib/src/desktop_companion_io.dart +538 -0
- package/flutter_app/lib/src/desktop_companion_stub.dart +59 -0
- package/flutter_app/lib/src/desktop_native_bridge.dart +91 -0
- package/flutter_app/lib/src/desktop_screen_capture.dart +21 -0
- package/flutter_app/lib/src/desktop_screen_capture_io.dart +142 -0
- package/flutter_app/lib/src/desktop_screen_capture_stub.dart +12 -0
- package/flutter_app/lib/src/diagnostics_logger.dart +119 -0
- package/flutter_app/lib/src/health_bridge.dart +136 -0
- package/flutter_app/lib/src/live_voice_capture.dart +85 -0
- package/flutter_app/lib/src/messaging_access_summary.dart +46 -0
- package/flutter_app/lib/src/network/app_http_client.dart +53 -0
- package/flutter_app/lib/src/network/app_http_client_factory.dart +6 -0
- package/flutter_app/lib/src/network/app_http_client_io.dart +138 -0
- package/flutter_app/lib/src/network/app_http_client_stub.dart +3 -0
- package/flutter_app/lib/src/network/app_http_client_web.dart +94 -0
- package/flutter_app/lib/src/oauth_launcher.dart +33 -0
- package/flutter_app/lib/src/oauth_launcher_io.dart +95 -0
- package/flutter_app/lib/src/oauth_launcher_stub.dart +33 -0
- package/flutter_app/lib/src/oauth_launcher_web.dart +107 -0
- package/flutter_app/lib/src/recording_bridge.dart +232 -0
- package/flutter_app/lib/src/recording_bridge_io.dart +1019 -0
- package/flutter_app/lib/src/recording_bridge_stub.dart +120 -0
- package/flutter_app/lib/src/recording_bridge_web.dart +689 -0
- package/flutter_app/lib/src/recording_payloads.dart +86 -0
- package/flutter_app/lib/src/theme/palette.dart +81 -0
- package/flutter_app/lib/src/web_app_update_monitor.dart +17 -0
- package/flutter_app/lib/src/web_app_update_monitor_stub.dart +24 -0
- package/flutter_app/lib/src/web_app_update_monitor_web.dart +123 -0
- package/flutter_app/lib/src/widget_bridge.dart +49 -0
- package/flutter_app/linux/CMakeLists.txt +128 -0
- package/flutter_app/linux/flutter/CMakeLists.txt +88 -0
- package/flutter_app/linux/flutter/generated_plugin_registrant.cc +47 -0
- package/flutter_app/linux/flutter/generated_plugin_registrant.h +15 -0
- package/flutter_app/linux/flutter/generated_plugins.cmake +32 -0
- package/flutter_app/linux/runner/CMakeLists.txt +26 -0
- package/flutter_app/linux/runner/main.cc +6 -0
- package/flutter_app/linux/runner/my_application.cc +144 -0
- package/flutter_app/linux/runner/my_application.h +18 -0
- package/flutter_app/linux/runner/resources/app_icon.png +0 -0
- package/flutter_app/macos/Flutter/Flutter-Debug.xcconfig +2 -0
- package/flutter_app/macos/Flutter/Flutter-Release.xcconfig +2 -0
- package/flutter_app/macos/Flutter/GeneratedPluginRegistrant.swift +48 -0
- package/flutter_app/macos/Podfile +42 -0
- package/flutter_app/macos/Podfile.lock +87 -0
- package/flutter_app/macos/Runner/AppDelegate.swift +576 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +68 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png +0 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png +0 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png +0 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png +0 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png +0 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png +0 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png +0 -0
- package/flutter_app/macos/Runner/Base.lproj/MainMenu.xib +342 -0
- package/flutter_app/macos/Runner/Configs/AppInfo.xcconfig +14 -0
- package/flutter_app/macos/Runner/Configs/Debug.xcconfig +2 -0
- package/flutter_app/macos/Runner/Configs/Release.xcconfig +2 -0
- package/flutter_app/macos/Runner/Configs/Warnings.xcconfig +13 -0
- package/flutter_app/macos/Runner/DebugProfile.entitlements +16 -0
- package/flutter_app/macos/Runner/Info.plist +36 -0
- package/flutter_app/macos/Runner/MainFlutterWindow.swift +19 -0
- package/flutter_app/macos/Runner/Release.entitlements +12 -0
- package/flutter_app/macos/Runner.xcodeproj/project.pbxproj +801 -0
- package/flutter_app/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/flutter_app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +99 -0
- package/flutter_app/macos/Runner.xcworkspace/contents.xcworkspacedata +10 -0
- package/flutter_app/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/flutter_app/macos/RunnerTests/RunnerTests.swift +12 -0
- package/flutter_app/patch_strings.py +12 -0
- package/flutter_app/pubspec.lock +1256 -0
- package/flutter_app/pubspec.yaml +59 -0
- package/flutter_app/third_party/desktop_audio_capture/LICENSE +21 -0
- package/flutter_app/third_party/desktop_audio_capture/README.md +262 -0
- package/flutter_app/third_party/desktop_audio_capture/lib/audio_capture.dart +65 -0
- package/flutter_app/third_party/desktop_audio_capture/lib/config/mic_audio_config.dart +153 -0
- package/flutter_app/third_party/desktop_audio_capture/lib/config/system_adudio_config.dart +110 -0
- package/flutter_app/third_party/desktop_audio_capture/lib/mic/mic_audio_capture.dart +461 -0
- package/flutter_app/third_party/desktop_audio_capture/lib/model/audio_status.dart +91 -0
- package/flutter_app/third_party/desktop_audio_capture/lib/model/decibel_data.dart +106 -0
- package/flutter_app/third_party/desktop_audio_capture/lib/model/input_device_type.dart +219 -0
- package/flutter_app/third_party/desktop_audio_capture/lib/system/system_audio_capture.dart +336 -0
- package/flutter_app/third_party/desktop_audio_capture/linux/CMakeLists.txt +101 -0
- package/flutter_app/third_party/desktop_audio_capture/linux/audio_capture_plugin.cc +692 -0
- package/flutter_app/third_party/desktop_audio_capture/linux/include/audio_capture/audio_capture_plugin.h +35 -0
- package/flutter_app/third_party/desktop_audio_capture/linux/include/audio_capture/mic_capture_plugin.h +36 -0
- package/flutter_app/third_party/desktop_audio_capture/linux/include/desktop_audio_capture/audio_capture_plugin.h +32 -0
- package/flutter_app/third_party/desktop_audio_capture/linux/include/desktop_audio_capture/mic_capture_plugin.h +32 -0
- package/flutter_app/third_party/desktop_audio_capture/linux/mic_capture_plugin.cc +878 -0
- package/flutter_app/third_party/desktop_audio_capture/macos/Classes/AudioCapturePlugin.swift +27 -0
- package/flutter_app/third_party/desktop_audio_capture/macos/Classes/MicCapturePlugin.swift +1172 -0
- package/flutter_app/third_party/desktop_audio_capture/macos/Classes/SystemCapturePlugin.swift +655 -0
- package/flutter_app/third_party/desktop_audio_capture/macos/Resources/PrivacyInfo.xcprivacy +12 -0
- package/flutter_app/third_party/desktop_audio_capture/macos/desktop_audio_capture.podspec +30 -0
- package/flutter_app/third_party/desktop_audio_capture/pubspec.yaml +87 -0
- package/flutter_app/third_party/desktop_audio_capture/windows/CMakeLists.txt +105 -0
- package/flutter_app/third_party/desktop_audio_capture/windows/audio_capture_plugin.cpp +80 -0
- package/flutter_app/third_party/desktop_audio_capture/windows/audio_capture_plugin.h +31 -0
- package/flutter_app/third_party/desktop_audio_capture/windows/audio_capture_plugin_c_api.cpp +12 -0
- package/flutter_app/third_party/desktop_audio_capture/windows/include/audio_capture/audio_capture_plugin_c_api.h +23 -0
- package/flutter_app/third_party/desktop_audio_capture/windows/include/desktop_audio_capture/audio_capture_plugin.h +25 -0
- package/flutter_app/third_party/desktop_audio_capture/windows/mic_capture_plugin.cpp +1117 -0
- package/flutter_app/third_party/desktop_audio_capture/windows/mic_capture_plugin.h +115 -0
- package/flutter_app/third_party/desktop_audio_capture/windows/system_audio_capture_plugin.cpp +777 -0
- package/flutter_app/third_party/desktop_audio_capture/windows/system_audio_capture_plugin.h +87 -0
- package/flutter_app/third_party/flutter_secure_storage_linux/linux/CMakeLists.txt +30 -0
- package/flutter_app/third_party/flutter_secure_storage_linux/linux/flutter_secure_storage_linux_plugin.cc +215 -0
- package/flutter_app/third_party/flutter_secure_storage_linux/linux/include/flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h +27 -0
- package/flutter_app/third_party/flutter_secure_storage_linux/pubspec.yaml +20 -0
- package/flutter_app/tool/generate_desktop_branding.py +219 -0
- package/flutter_app/web/favicon.png +0 -0
- package/flutter_app/web/favicon.svg +12 -0
- package/flutter_app/web/icons/Icon-192.png +0 -0
- package/flutter_app/web/icons/Icon-512.png +0 -0
- package/flutter_app/web/icons/Icon-maskable-192.png +0 -0
- package/flutter_app/web/icons/Icon-maskable-512.png +0 -0
- package/flutter_app/web/index.html +39 -0
- package/flutter_app/web/manifest.json +35 -0
- package/flutter_app/windows/CMakeLists.txt +108 -0
- package/flutter_app/windows/flutter/CMakeLists.txt +109 -0
- package/flutter_app/windows/flutter/generated_plugin_registrant.cc +50 -0
- package/flutter_app/windows/flutter/generated_plugin_registrant.h +15 -0
- package/flutter_app/windows/flutter/generated_plugins.cmake +36 -0
- package/flutter_app/windows/runner/CMakeLists.txt +41 -0
- package/flutter_app/windows/runner/Runner.rc +121 -0
- package/flutter_app/windows/runner/flutter_window.cpp +533 -0
- package/flutter_app/windows/runner/flutter_window.h +37 -0
- package/flutter_app/windows/runner/main.cpp +53 -0
- package/flutter_app/windows/runner/resource.h +16 -0
- package/flutter_app/windows/runner/resources/app_icon.ico +0 -0
- package/flutter_app/windows/runner/runner.exe.manifest +14 -0
- package/flutter_app/windows/runner/utils.cpp +65 -0
- package/flutter_app/windows/runner/utils.h +19 -0
- package/flutter_app/windows/runner/win32_window.cpp +299 -0
- package/flutter_app/windows/runner/win32_window.h +102 -0
- package/lib/install_helpers.js +31 -0
- package/lib/manager.js +579 -122
- package/package.json +10 -3
- package/runtime/paths.js +137 -0
- package/server/config/analytics.js +30 -0
- package/server/db/database.js +296 -22
- package/server/guest-agent.android.package.json +13 -0
- package/server/guest-agent.browser.package.json +14 -0
- package/server/guest_agent.js +98 -52
- package/server/http/middleware.js +5 -2
- package/server/http/routes.js +3 -0
- package/server/http/static.js +41 -1
- package/server/index.js +15 -16
- package/server/public/.last_build_id +1 -1
- package/server/public/assets/AssetManifest.bin +1 -1
- package/server/public/assets/AssetManifest.bin.json +1 -1
- package/server/public/assets/AssetManifest.json +1 -1
- package/server/public/assets/NOTICES +644 -155
- package/server/public/assets/assets/branding/onboarding_intro.mp4 +0 -0
- package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
- package/server/public/assets/packages/mixpanel_flutter/assets/mixpanel.js +3 -0
- package/server/public/canvaskit/wimp.wasm +0 -0
- package/server/public/flutter_bootstrap.js +2 -2
- package/server/public/main.dart.js +96067 -88139
- package/server/routes/account.js +26 -1
- package/server/routes/agents.js +6 -2
- package/server/routes/android.js +22 -6
- package/server/routes/auth.js +25 -5
- package/server/routes/browser.js +47 -13
- package/server/routes/integrations.js +22 -1
- package/server/routes/memory.js +168 -6
- package/server/routes/runtime.js +14 -0
- package/server/routes/settings.js +102 -24
- package/server/routes/skills.js +12 -0
- package/server/routes/social_video.js +66 -0
- package/server/routes/tasks.js +22 -2
- package/server/routes/triggers.js +44 -35
- package/server/routes/wearable.js +67 -0
- package/server/routes/widgets.js +4 -4
- package/server/services/ai/capabilityHealth.js +23 -51
- package/server/services/ai/compaction.js +1 -1
- package/server/services/ai/deliverables/artifact_helpers.js +190 -0
- package/server/services/ai/deliverables/contracts.js +113 -0
- package/server/services/ai/deliverables/index.js +20 -0
- package/server/services/ai/deliverables/selector.js +94 -0
- package/server/services/ai/deliverables/validator.js +63 -0
- package/server/services/ai/deliverables/workflows.js +207 -0
- package/server/services/ai/engine.js +363 -27
- package/server/services/ai/hooks.js +127 -0
- package/server/services/ai/integrated_tools/index.js +98 -0
- package/server/services/ai/integrated_tools/remotion.js +373 -0
- package/server/services/ai/integrated_tools/shared.js +204 -0
- package/server/services/ai/integrated_tools/slidev.js +207 -0
- package/server/services/ai/loopPolicy.js +146 -0
- package/server/services/ai/models.js +31 -4
- package/server/services/ai/providers/claudeCode.js +49 -0
- package/server/services/ai/providers/openai.js +2 -1
- package/server/services/ai/providers/openaiCodex.js +422 -15
- package/server/services/ai/recordingInsights.js +11 -13
- package/server/services/ai/runEvents.js +100 -0
- package/server/services/ai/settings.js +12 -2
- package/server/services/ai/systemPrompt.js +15 -1
- package/server/services/ai/taskAnalysis.js +2 -0
- package/server/services/ai/toolResult.js +20 -0
- package/server/services/ai/toolRunner.js +46 -6
- package/server/services/ai/toolSelector.js +54 -1
- package/server/services/ai/tools.js +210 -116
- package/server/services/android/android_bootstrap_worker.js +63 -0
- package/server/services/android/controller.js +442 -1760
- package/server/services/bootstrap_helpers.js +0 -34
- package/server/services/browser/controller.js +279 -49
- package/server/services/cli/executor.js +40 -1
- package/server/services/desktop/screenRecorder.js +65 -9
- package/server/services/integrations/figma/provider.js +1 -0
- package/server/services/integrations/github/provider.js +3 -3
- package/server/services/integrations/google/provider.js +1 -0
- package/server/services/integrations/manager.js +25 -5
- package/server/services/integrations/microsoft/provider.js +1 -0
- package/server/services/integrations/oauth_provider.js +15 -5
- package/server/services/integrations/provider_config_store.js +22 -13
- package/server/services/integrations/registry.js +2 -4
- package/server/services/integrations/spotify/provider.js +1 -0
- package/server/services/integrations/trello/provider.js +842 -0
- package/server/services/manager.js +88 -155
- package/server/services/mcp/client.js +120 -23
- package/server/services/memory/llm_transfer.js +218 -0
- package/server/services/memory/manager.js +260 -33
- package/server/services/messaging/access_policy.js +10 -0
- package/server/services/messaging/automation.js +1 -1
- package/server/services/messaging/manager.js +64 -1
- package/server/services/messaging/meshtastic.js +277 -0
- package/server/services/messaging/meshtastic_env.js +40 -0
- package/server/services/messaging/meshtastic_protocol.js +530 -0
- package/server/services/messaging/meshtastic_tcp_transport.js +25 -0
- package/server/services/runtime/backends/local-vm.js +221 -158
- package/server/services/runtime/docker-vm-manager.js +392 -0
- package/server/services/runtime/guest_bootstrap.js +654 -0
- package/server/services/runtime/manager.js +85 -29
- package/server/services/runtime/settings.js +22 -31
- package/server/services/runtime/validation.js +16 -31
- package/server/services/social_video/adapters/base.js +26 -0
- package/server/services/social_video/adapters/index.js +27 -0
- package/server/services/social_video/adapters/instagram.js +17 -0
- package/server/services/social_video/adapters/tiktok.js +17 -0
- package/server/services/social_video/adapters/x.js +17 -0
- package/server/services/social_video/adapters/youtube.js +17 -0
- package/server/services/social_video/captions.js +187 -0
- package/server/services/social_video/frame.js +42 -0
- package/server/services/social_video/index.js +7 -0
- package/server/services/social_video/metadata.js +63 -0
- package/server/services/social_video/result.js +63 -0
- package/server/services/social_video/service.js +720 -0
- package/server/services/social_video/url.js +83 -0
- package/server/services/tasks/integration_runtime.js +1 -1
- package/server/services/tasks/runtime.js +1 -1
- package/server/services/tasks/task_repository.js +3 -6
- package/server/services/voice/openaiSpeech.js +6 -1
- package/server/services/voice/providers.js +142 -14
- package/server/services/voice/runtime.js +8 -8
- package/server/services/voice/runtimeManager.js +156 -19
- package/server/services/voice/turnRunner.js +29 -9
- package/server/services/wearable/firmware_manifest.js +353 -0
- package/server/services/wearable/gateway.js +350 -0
- package/server/services/wearable/protocol.js +45 -0
- package/server/services/wearable/service.js +240 -0
- package/server/services/websocket.js +3 -1
- package/server/services/widgets/focus_widget.js +137 -0
- package/server/services/widgets/service.js +133 -2
- package/server/services/workspace/manager.js +301 -0
- package/server/utils/deployment.js +16 -9
- package/server/services/integrations/home_assistant/provider.js +0 -630
- package/server/services/messaging/access_policy.test.js +0 -228
- package/server/services/runtime/backends/host.js +0 -37
- package/server/services/runtime/qemu.js +0 -391
|
@@ -12,16 +12,52 @@ const { getErrorMessage } = require('../bootstrap_helpers');
|
|
|
12
12
|
const execAsync = promisify(exec);
|
|
13
13
|
|
|
14
14
|
class ScreenRecorder {
|
|
15
|
-
constructor() {
|
|
15
|
+
constructor(options = {}) {
|
|
16
16
|
this.intervalMs = 10000; // 10 seconds
|
|
17
17
|
this.intervalId = null;
|
|
18
18
|
this.cleanupIntervalId = null;
|
|
19
19
|
this.isRecording = false;
|
|
20
20
|
this.isProcessing = false;
|
|
21
21
|
this.tempFilePath = path.join(os.tmpdir(), `neoagent-screen-${Date.now()}.png`);
|
|
22
|
+
this.lastBenignSkipAt = 0;
|
|
23
|
+
this.hasActiveRemoteCaptureSession = typeof options.hasActiveRemoteCaptureSession === 'function'
|
|
24
|
+
? options.hasActiveRemoteCaptureSession
|
|
25
|
+
: () => false;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
_isCaptureInactiveApp(appName) {
|
|
29
|
+
const normalized = String(appName || '').trim().toLowerCase();
|
|
30
|
+
return normalized === '' || normalized === 'loginwindow' || normalized === 'screensaverengine';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
_isBenignCaptureError(message) {
|
|
34
|
+
const text = String(message || '').toLowerCase();
|
|
35
|
+
return (
|
|
36
|
+
text.includes('operation not permitted') ||
|
|
37
|
+
text.includes('not authorized') ||
|
|
38
|
+
text.includes('user canceled') ||
|
|
39
|
+
text.includes('cgwindowlistcreateimage') ||
|
|
40
|
+
text.includes('screencapture') ||
|
|
41
|
+
text.includes('timed out')
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
_logBenignSkip(reason) {
|
|
46
|
+
const now = Date.now();
|
|
47
|
+
if (now - this.lastBenignSkipAt < 5 * 60 * 1000) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
this.lastBenignSkipAt = now;
|
|
51
|
+
console.log(`[ScreenRecorder] Capture skipped: ${reason}`);
|
|
22
52
|
}
|
|
23
53
|
|
|
24
54
|
start() {
|
|
55
|
+
const enabledEnv = String(process.env.NEOAGENT_SCREEN_RECORDER_ENABLED || '').trim().toLowerCase();
|
|
56
|
+
if (enabledEnv === '0' || enabledEnv === 'false' || enabledEnv === 'off' || enabledEnv === 'no') {
|
|
57
|
+
console.log('[ScreenRecorder] Not starting: disabled by NEOAGENT_SCREEN_RECORDER_ENABLED.');
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
25
61
|
if (process.platform !== 'darwin') {
|
|
26
62
|
console.log('[ScreenRecorder] Not starting: Screen recording is currently macOS only.');
|
|
27
63
|
return;
|
|
@@ -61,6 +97,27 @@ class ScreenRecorder {
|
|
|
61
97
|
this.isProcessing = true;
|
|
62
98
|
|
|
63
99
|
try {
|
|
100
|
+
// Only capture while at least one external device/session is actively connected.
|
|
101
|
+
// This prevents host-level screenshots when no user-side capture source is live.
|
|
102
|
+
if (!this.hasActiveRemoteCaptureSession()) {
|
|
103
|
+
this._logBenignSkip('no active external capture session');
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Skip capture when the desktop session is inactive (e.g. locked screen).
|
|
108
|
+
let frontmostApp = '';
|
|
109
|
+
try {
|
|
110
|
+
const { stdout } = await execAsync(`osascript -e 'tell application "System Events" to get name of first application process whose frontmost is true'`);
|
|
111
|
+
frontmostApp = (stdout || '').trim();
|
|
112
|
+
} catch {
|
|
113
|
+
frontmostApp = '';
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (this._isCaptureInactiveApp(frontmostApp)) {
|
|
117
|
+
this._logBenignSkip('no active frontmost app');
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
64
121
|
// Capture screen silently (-x) to file
|
|
65
122
|
await execAsync(`screencapture -x "${this.tempFilePath}"`);
|
|
66
123
|
|
|
@@ -80,13 +137,7 @@ class ScreenRecorder {
|
|
|
80
137
|
const userRow = db.prepare('SELECT id FROM users ORDER BY id ASC LIMIT 1').get();
|
|
81
138
|
if (userRow) {
|
|
82
139
|
// Identify the active foreground app via AppleScript
|
|
83
|
-
let appName = 'Unknown';
|
|
84
|
-
try {
|
|
85
|
-
const { stdout } = await execAsync(`osascript -e 'tell application "System Events" to get name of first application process whose frontmost is true'`);
|
|
86
|
-
appName = stdout.trim();
|
|
87
|
-
} catch (e) {
|
|
88
|
-
// Ignore AppleScript errors
|
|
89
|
-
}
|
|
140
|
+
let appName = frontmostApp || 'Unknown';
|
|
90
141
|
|
|
91
142
|
db.prepare(`
|
|
92
143
|
INSERT INTO screen_history (user_id, app_name, text_content)
|
|
@@ -96,7 +147,12 @@ class ScreenRecorder {
|
|
|
96
147
|
}
|
|
97
148
|
|
|
98
149
|
} catch (err) {
|
|
99
|
-
|
|
150
|
+
const errorMessage = getErrorMessage(err);
|
|
151
|
+
if (this._isBenignCaptureError(errorMessage)) {
|
|
152
|
+
this._logBenignSkip(errorMessage);
|
|
153
|
+
} else {
|
|
154
|
+
console.error('[ScreenRecorder] Capture/OCR failed:', errorMessage);
|
|
155
|
+
}
|
|
100
156
|
} finally {
|
|
101
157
|
// Always cleanup the screenshot image immediately
|
|
102
158
|
try {
|
|
@@ -240,6 +240,7 @@ function createFigmaProvider() {
|
|
|
240
240
|
description:
|
|
241
241
|
'Official Figma OAuth account connections for future design file and collaboration workflows.',
|
|
242
242
|
icon: 'figma',
|
|
243
|
+
requiresRefreshToken: true,
|
|
243
244
|
apps: FIGMA_APPS,
|
|
244
245
|
toolDefinitions: figmaToolDefinitions,
|
|
245
246
|
connectPrompt:
|
|
@@ -337,15 +337,15 @@ function createGithubProvider() {
|
|
|
337
337
|
method: 'POST',
|
|
338
338
|
headers: {
|
|
339
339
|
'Accept': 'application/json',
|
|
340
|
-
'Content-Type': 'application/
|
|
340
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
341
341
|
},
|
|
342
|
-
body:
|
|
342
|
+
body: new URLSearchParams({
|
|
343
343
|
client_id: config.clientId,
|
|
344
344
|
client_secret: config.clientSecret,
|
|
345
345
|
code,
|
|
346
346
|
code_verifier: codeVerifier,
|
|
347
347
|
redirect_uri: config.redirectUri,
|
|
348
|
-
}),
|
|
348
|
+
}).toString(),
|
|
349
349
|
});
|
|
350
350
|
|
|
351
351
|
const tokenBody = await tokenResponse.text();
|
|
@@ -300,6 +300,7 @@ function createGoogleWorkspaceProvider() {
|
|
|
300
300
|
description:
|
|
301
301
|
'Official Gmail, Calendar, Drive, Docs, and Sheets integrations with app-specific accounts.',
|
|
302
302
|
icon: 'google',
|
|
303
|
+
requiresRefreshToken: true,
|
|
303
304
|
apps: GOOGLE_WORKSPACE_APPS.map(({ id, label, description }) => ({
|
|
304
305
|
id,
|
|
305
306
|
label,
|
|
@@ -29,6 +29,27 @@ function isLikelyExpiredConnectionError(error) {
|
|
|
29
29
|
].some((hint) => message.includes(hint));
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
function assertDurableOAuthCredentials(provider, credentials) {
|
|
33
|
+
const label = String(provider?.label || 'This integration').trim() || 'This integration';
|
|
34
|
+
const normalizedCredentials =
|
|
35
|
+
credentials && typeof credentials === 'object' ? credentials : {};
|
|
36
|
+
|
|
37
|
+
if (!String(normalizedCredentials.access_token || '').trim()) {
|
|
38
|
+
throw new Error(
|
|
39
|
+
`${label} did not return an access token, so the connection could not be completed.`,
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (
|
|
44
|
+
provider?.requiresRefreshToken === true &&
|
|
45
|
+
!String(normalizedCredentials.refresh_token || '').trim()
|
|
46
|
+
) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`${label} did not return a refresh token, so the connection would expire. Revoke the existing app grant for this provider and reconnect it so offline access is granted.`,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
32
53
|
class IntegrationManager {
|
|
33
54
|
constructor(options = {}) {
|
|
34
55
|
this.app = options.app || null;
|
|
@@ -217,6 +238,7 @@ class IntegrationManager {
|
|
|
217
238
|
state,
|
|
218
239
|
codeVerifier,
|
|
219
240
|
userId,
|
|
241
|
+
agentId,
|
|
220
242
|
appKey,
|
|
221
243
|
});
|
|
222
244
|
|
|
@@ -288,6 +310,7 @@ class IntegrationManager {
|
|
|
288
310
|
|
|
289
311
|
const result = await provider.finishOAuth({
|
|
290
312
|
userId: stateRow.user_id,
|
|
313
|
+
agentId: stateRow.agent_id || resolveAgentId(stateRow.user_id, null),
|
|
291
314
|
state: stateRow.state,
|
|
292
315
|
code: normalizedCode,
|
|
293
316
|
codeVerifier: decryptValue(stateRow.code_verifier),
|
|
@@ -301,11 +324,7 @@ class IntegrationManager {
|
|
|
301
324
|
result.accountEmail,
|
|
302
325
|
result.credentials,
|
|
303
326
|
);
|
|
304
|
-
|
|
305
|
-
throw new Error(
|
|
306
|
-
`${provider.label} did not return a refresh token, so the connection would expire. Revoke the existing app grant for this provider and reconnect it so offline access is granted.`,
|
|
307
|
-
);
|
|
308
|
-
}
|
|
327
|
+
assertDurableOAuthCredentials(provider, mergedCredentials);
|
|
309
328
|
|
|
310
329
|
db.prepare(
|
|
311
330
|
`INSERT INTO integration_connections (
|
|
@@ -725,5 +744,6 @@ class IntegrationManager {
|
|
|
725
744
|
}
|
|
726
745
|
|
|
727
746
|
module.exports = {
|
|
747
|
+
assertDurableOAuthCredentials,
|
|
728
748
|
IntegrationManager,
|
|
729
749
|
};
|
|
@@ -346,6 +346,7 @@ function createMicrosoftProvider() {
|
|
|
346
346
|
description:
|
|
347
347
|
'Official Microsoft 365 OAuth account connections for Outlook, Calendar, OneDrive, and Teams.',
|
|
348
348
|
icon: 'microsoft',
|
|
349
|
+
requiresRefreshToken: true,
|
|
349
350
|
apps: MICROSOFT_APPS,
|
|
350
351
|
toolDefinitions: microsoftToolDefinitions,
|
|
351
352
|
connectPrompt:
|
|
@@ -241,8 +241,11 @@ function createOAuthProvider(options = {}) {
|
|
|
241
241
|
label: options.label,
|
|
242
242
|
description: options.description,
|
|
243
243
|
icon: options.icon,
|
|
244
|
+
requiresRefreshToken: options.requiresRefreshToken === true,
|
|
244
245
|
apps: apps.map(({ id, label, description }) => ({ id, label, description })),
|
|
245
246
|
connectPrompt: options.connectPrompt || null,
|
|
247
|
+
supportsMultipleAccounts: options.supportsMultipleAccounts !== false,
|
|
248
|
+
connectionMethod: options.connectionMethod || 'oauth',
|
|
246
249
|
getApp,
|
|
247
250
|
getToolAppId(toolName) {
|
|
248
251
|
return toolAppMap.get(String(toolName || '').trim()) || null;
|
|
@@ -311,15 +314,17 @@ function createOAuthProvider(options = {}) {
|
|
|
311
314
|
0,
|
|
312
315
|
),
|
|
313
316
|
connectPrompt: this.connectPrompt,
|
|
317
|
+
supportsMultipleAccounts: this.supportsMultipleAccounts,
|
|
318
|
+
connectionMethod: this.connectionMethod,
|
|
314
319
|
};
|
|
315
320
|
},
|
|
316
|
-
async beginOAuth({ state, codeVerifier, appKey, userId }) {
|
|
321
|
+
async beginOAuth({ state, codeVerifier, appKey, userId, agentId }) {
|
|
317
322
|
const app = getApp(appKey);
|
|
318
323
|
if (!app) {
|
|
319
324
|
throw new Error(`Unknown ${this.label} app: ${appKey}`);
|
|
320
325
|
}
|
|
321
326
|
const normalizedState = assertValidOAuthState(state);
|
|
322
|
-
const env = this.getEnvStatus({ userId });
|
|
327
|
+
const env = this.getEnvStatus({ userId, agentId });
|
|
323
328
|
if (!env.configured) {
|
|
324
329
|
throw new Error(env.summary);
|
|
325
330
|
}
|
|
@@ -327,11 +332,12 @@ function createOAuthProvider(options = {}) {
|
|
|
327
332
|
state: normalizedState,
|
|
328
333
|
codeVerifier,
|
|
329
334
|
userId,
|
|
335
|
+
agentId,
|
|
330
336
|
app,
|
|
331
337
|
env,
|
|
332
338
|
});
|
|
333
339
|
},
|
|
334
|
-
async finishOAuth({ code, codeVerifier, appKey, userId, state }) {
|
|
340
|
+
async finishOAuth({ code, codeVerifier, appKey, userId, agentId, state }) {
|
|
335
341
|
const app = getApp(appKey);
|
|
336
342
|
if (!app) {
|
|
337
343
|
throw new Error(`Unknown ${this.label} app: ${appKey}`);
|
|
@@ -341,9 +347,10 @@ function createOAuthProvider(options = {}) {
|
|
|
341
347
|
code,
|
|
342
348
|
codeVerifier,
|
|
343
349
|
userId,
|
|
350
|
+
agentId,
|
|
344
351
|
state: normalizedState,
|
|
345
352
|
app,
|
|
346
|
-
env: this.getEnvStatus({ userId }),
|
|
353
|
+
env: this.getEnvStatus({ userId, agentId }),
|
|
347
354
|
});
|
|
348
355
|
},
|
|
349
356
|
async disconnect(connectionRow) {
|
|
@@ -368,7 +375,10 @@ function createOAuthProvider(options = {}) {
|
|
|
368
375
|
appId: toolAppMap.get(String(toolName || '').trim()) || connectionRow.app_key,
|
|
369
376
|
connection: connectionRow,
|
|
370
377
|
credentials,
|
|
371
|
-
env: this.getEnvStatus({
|
|
378
|
+
env: this.getEnvStatus({
|
|
379
|
+
userId: connectionRow?.user_id,
|
|
380
|
+
agentId: connectionRow?.agent_id,
|
|
381
|
+
}),
|
|
372
382
|
});
|
|
373
383
|
},
|
|
374
384
|
summarizeConnection(connectionRows) {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const db = require('../../db/database');
|
|
4
4
|
const { decryptValue, encryptValue } = require('./secrets');
|
|
5
|
+
const { resolveAgentId } = require('../agents/manager');
|
|
5
6
|
|
|
6
7
|
function normalizeProviderKey(providerKey) {
|
|
7
8
|
return String(providerKey || '').trim();
|
|
@@ -16,57 +17,65 @@ function parseConfig(value) {
|
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
function getProviderConfig(userId, providerKey) {
|
|
20
|
+
function getProviderConfig(userId, providerKey, agentId = null) {
|
|
20
21
|
const normalizedProviderKey = normalizeProviderKey(providerKey);
|
|
21
|
-
|
|
22
|
+
const normalizedUserId = Number(userId);
|
|
23
|
+
if (!Number.isInteger(normalizedUserId) || normalizedUserId <= 0 || !normalizedProviderKey) {
|
|
22
24
|
return {};
|
|
23
25
|
}
|
|
26
|
+
const scopedAgentId = resolveAgentId(normalizedUserId, agentId);
|
|
24
27
|
|
|
25
28
|
const row = db
|
|
26
29
|
.prepare(
|
|
27
30
|
`SELECT config_json
|
|
28
31
|
FROM integration_provider_configs
|
|
29
|
-
WHERE user_id = ? AND provider_key = ?`,
|
|
32
|
+
WHERE user_id = ? AND agent_id = ? AND provider_key = ?`,
|
|
30
33
|
)
|
|
31
|
-
.get(
|
|
34
|
+
.get(normalizedUserId, scopedAgentId, normalizedProviderKey);
|
|
32
35
|
|
|
33
36
|
return parseConfig(row?.config_json);
|
|
34
37
|
}
|
|
35
38
|
|
|
36
|
-
function setProviderConfig(userId, providerKey, config) {
|
|
39
|
+
function setProviderConfig(userId, providerKey, config, agentId = null) {
|
|
37
40
|
const normalizedProviderKey = normalizeProviderKey(providerKey);
|
|
38
|
-
|
|
41
|
+
const normalizedUserId = Number(userId);
|
|
42
|
+
if (!Number.isInteger(normalizedUserId) || normalizedUserId <= 0 || !normalizedProviderKey) {
|
|
39
43
|
throw new Error('A valid user and provider are required to save integration config.');
|
|
40
44
|
}
|
|
45
|
+
const scopedAgentId = resolveAgentId(normalizedUserId, agentId);
|
|
41
46
|
|
|
42
47
|
const payload = config && typeof config === 'object' ? config : {};
|
|
43
48
|
db.prepare(
|
|
44
49
|
`INSERT INTO integration_provider_configs (
|
|
45
50
|
user_id,
|
|
51
|
+
agent_id,
|
|
46
52
|
provider_key,
|
|
47
53
|
config_json,
|
|
48
54
|
created_at,
|
|
49
55
|
updated_at
|
|
50
|
-
) VALUES (?, ?, ?, datetime('now'), datetime('now'))
|
|
51
|
-
ON CONFLICT(user_id, provider_key) DO UPDATE SET
|
|
56
|
+
) VALUES (?, ?, ?, ?, datetime('now'), datetime('now'))
|
|
57
|
+
ON CONFLICT(user_id, agent_id, provider_key) DO UPDATE SET
|
|
52
58
|
config_json = excluded.config_json,
|
|
53
59
|
updated_at = excluded.updated_at`,
|
|
54
60
|
).run(
|
|
55
|
-
|
|
61
|
+
normalizedUserId,
|
|
62
|
+
scopedAgentId,
|
|
56
63
|
normalizedProviderKey,
|
|
57
64
|
encryptValue(JSON.stringify(payload)),
|
|
58
65
|
);
|
|
59
66
|
}
|
|
60
67
|
|
|
61
|
-
function deleteProviderConfig(userId, providerKey) {
|
|
68
|
+
function deleteProviderConfig(userId, providerKey, agentId = null) {
|
|
62
69
|
const normalizedProviderKey = normalizeProviderKey(providerKey);
|
|
63
|
-
|
|
70
|
+
const normalizedUserId = Number(userId);
|
|
71
|
+
if (!Number.isInteger(normalizedUserId) || normalizedUserId <= 0 || !normalizedProviderKey) {
|
|
64
72
|
return;
|
|
65
73
|
}
|
|
74
|
+
const scopedAgentId = resolveAgentId(normalizedUserId, agentId);
|
|
66
75
|
|
|
67
76
|
db.prepare(
|
|
68
|
-
'DELETE FROM integration_provider_configs WHERE user_id = ? AND provider_key = ?',
|
|
69
|
-
).run(
|
|
77
|
+
'DELETE FROM integration_provider_configs WHERE user_id = ? AND agent_id = ? AND provider_key = ?',
|
|
78
|
+
).run(normalizedUserId, scopedAgentId, normalizedProviderKey);
|
|
70
79
|
}
|
|
71
80
|
|
|
72
81
|
module.exports = {
|
|
@@ -3,14 +3,13 @@
|
|
|
3
3
|
const { createFigmaProvider } = require('./figma/provider');
|
|
4
4
|
const { createGoogleWorkspaceProvider } = require('./google/provider');
|
|
5
5
|
const { createGithubProvider } = require('./github/provider');
|
|
6
|
-
const {
|
|
6
|
+
const { createTrelloProvider } = require('./trello/provider');
|
|
7
7
|
const { createMicrosoftProvider } = require('./microsoft/provider');
|
|
8
8
|
const { createNotionProvider } = require('./notion/provider');
|
|
9
9
|
const { createSpotifyProvider } = require('./spotify/provider');
|
|
10
10
|
const { createSlackProvider } = require('./slack/provider');
|
|
11
11
|
const { createWeatherProvider } = require('./weather/provider');
|
|
12
12
|
const { createWhatsAppPersonalProvider } = require('./whatsapp');
|
|
13
|
-
const { createCodexProvider } = require('./codex/provider');
|
|
14
13
|
|
|
15
14
|
function createIntegrationRegistry(options = {}) {
|
|
16
15
|
const providers = [
|
|
@@ -20,11 +19,10 @@ function createIntegrationRegistry(options = {}) {
|
|
|
20
19
|
createMicrosoftProvider(),
|
|
21
20
|
createSlackProvider(),
|
|
22
21
|
createFigmaProvider(),
|
|
23
|
-
|
|
22
|
+
createTrelloProvider(),
|
|
24
23
|
createWeatherProvider(),
|
|
25
24
|
createSpotifyProvider(),
|
|
26
25
|
createWhatsAppPersonalProvider(options),
|
|
27
|
-
createCodexProvider(),
|
|
28
26
|
];
|
|
29
27
|
const byKey = new Map(providers.map((provider) => [provider.key, provider]));
|
|
30
28
|
|
|
@@ -394,6 +394,7 @@ function createSpotifyProvider() {
|
|
|
394
394
|
label: 'Spotify',
|
|
395
395
|
description: 'Official Spotify account integration for music search and playback control.',
|
|
396
396
|
icon: 'spotify',
|
|
397
|
+
requiresRefreshToken: true,
|
|
397
398
|
apps: SPOTIFY_APPS,
|
|
398
399
|
toolDefinitions: spotifyToolDefinitions,
|
|
399
400
|
connectPrompt:
|