@base44/superagent-native 0.0.1 → 0.0.3
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/LICENSE +21 -0
- package/README.md +12 -20
- package/lib/commonjs/AgentSettingsPanel.js +155 -62
- package/lib/commonjs/AgentSettingsPanel.js.map +1 -1
- package/lib/commonjs/AgentSphereIcon.js +14 -118
- package/lib/commonjs/AgentSphereIcon.js.map +1 -1
- package/lib/commonjs/AttachmentPickerStatusModal.js +5 -4
- package/lib/commonjs/AttachmentPickerStatusModal.js.map +1 -1
- package/lib/commonjs/ChannelsPanel.js +66 -44
- package/lib/commonjs/ChannelsPanel.js.map +1 -1
- package/lib/commonjs/ConversationChat.js +38 -13
- package/lib/commonjs/ConversationChat.js.map +1 -1
- package/lib/commonjs/ConversationComposer.js +18 -13
- package/lib/commonjs/ConversationComposer.js.map +1 -1
- package/lib/commonjs/ConversationScreen.js +4 -0
- package/lib/commonjs/ConversationScreen.js.map +1 -1
- package/lib/commonjs/EditorDrawer.js +54 -24
- package/lib/commonjs/EditorDrawer.js.map +1 -1
- package/lib/commonjs/FilesPanel.js +56 -20
- package/lib/commonjs/FilesPanel.js.map +1 -1
- package/lib/commonjs/MarkdownText.js +1 -1
- package/lib/commonjs/MarkdownText.js.map +1 -1
- package/lib/commonjs/MessageActionBar.js +10 -3
- package/lib/commonjs/MessageActionBar.js.map +1 -1
- package/lib/commonjs/RenameAgentModal.js +2 -1
- package/lib/commonjs/RenameAgentModal.js.map +1 -1
- package/lib/commonjs/ShareAgentModal.js +11 -10
- package/lib/commonjs/ShareAgentModal.js.map +1 -1
- package/lib/commonjs/ShareAgentModal.styles.js +2 -2
- package/lib/commonjs/ShareAgentModal.styles.js.map +1 -1
- package/lib/commonjs/SuperagentHomeScreen.js +44 -12
- package/lib/commonjs/SuperagentHomeScreen.js.map +1 -1
- package/lib/commonjs/ToolApprovalCard.js +73 -15
- package/lib/commonjs/ToolApprovalCard.js.map +1 -1
- package/lib/commonjs/ToolCallSummary.js +19 -10
- package/lib/commonjs/ToolCallSummary.js.map +1 -1
- package/lib/commonjs/agentSphereAssets.js +327 -0
- package/lib/commonjs/agentSphereAssets.js.map +1 -0
- package/lib/commonjs/agentSphereStyles.js +3 -3
- package/lib/commonjs/agentSphereStyles.js.map +1 -1
- package/lib/commonjs/apiClient.js +7 -0
- package/lib/commonjs/apiClient.js.map +1 -1
- package/lib/commonjs/attachmentUpload.js +2 -1
- package/lib/commonjs/attachmentUpload.js.map +1 -1
- package/lib/commonjs/composerStyles.js +2 -2
- package/lib/commonjs/composerStyles.js.map +1 -1
- package/lib/commonjs/connectorBrandIcons.generated.js +625 -0
- package/lib/commonjs/connectorBrandIcons.generated.js.map +1 -0
- package/lib/commonjs/connectorBrandIcons.js +3 -55
- package/lib/commonjs/connectorBrandIcons.js.map +1 -1
- package/lib/commonjs/connectorCatalog.js +19 -1
- package/lib/commonjs/connectorCatalog.js.map +1 -1
- package/lib/commonjs/conversationParts.js +5 -4
- package/lib/commonjs/conversationParts.js.map +1 -1
- package/lib/commonjs/conversationRuntime.js +152 -9
- package/lib/commonjs/conversationRuntime.js.map +1 -1
- package/lib/commonjs/conversationStyles.js +2 -1
- package/lib/commonjs/conversationStyles.js.map +1 -1
- package/lib/commonjs/editorShellStyles.js +6 -2
- package/lib/commonjs/editorShellStyles.js.map +1 -1
- package/lib/commonjs/fileTreeUtils.js +7 -0
- package/lib/commonjs/fileTreeUtils.js.map +1 -1
- package/lib/commonjs/index.js +7 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/markdownStyles.js +2 -2
- package/lib/commonjs/markdownStyles.js.map +1 -1
- package/lib/commonjs/messageActionStyles.js +2 -2
- package/lib/commonjs/messageActionStyles.js.map +1 -1
- package/lib/commonjs/realtimeClient.js +4 -1
- package/lib/commonjs/realtimeClient.js.map +1 -1
- package/lib/commonjs/renameAgentModalStyles.js +2 -2
- package/lib/commonjs/renameAgentModalStyles.js.map +1 -1
- package/lib/commonjs/screenParts.js +24 -41
- package/lib/commonjs/screenParts.js.map +1 -1
- package/lib/commonjs/styles.js +32 -21
- package/lib/commonjs/styles.js.map +1 -1
- package/lib/commonjs/superagentApiClient.js +63 -18
- package/lib/commonjs/superagentApiClient.js.map +1 -1
- package/lib/commonjs/theme.js +249 -0
- package/lib/commonjs/theme.js.map +1 -0
- package/lib/commonjs/useSuperagentConversation.js +240 -44
- package/lib/commonjs/useSuperagentConversation.js.map +1 -1
- package/lib/commonjs/useSuperagentRuntime.js +245 -105
- package/lib/commonjs/useSuperagentRuntime.js.map +1 -1
- package/lib/module/AgentSettingsPanel.js +157 -64
- package/lib/module/AgentSettingsPanel.js.map +1 -1
- package/lib/module/AgentSphereIcon.js +15 -118
- package/lib/module/AgentSphereIcon.js.map +1 -1
- package/lib/module/AttachmentPickerStatusModal.js +6 -5
- package/lib/module/AttachmentPickerStatusModal.js.map +1 -1
- package/lib/module/ChannelsPanel.js +67 -45
- package/lib/module/ChannelsPanel.js.map +1 -1
- package/lib/module/ConversationChat.js +38 -13
- package/lib/module/ConversationChat.js.map +1 -1
- package/lib/module/ConversationComposer.js +18 -13
- package/lib/module/ConversationComposer.js.map +1 -1
- package/lib/module/ConversationScreen.js +4 -0
- package/lib/module/ConversationScreen.js.map +1 -1
- package/lib/module/EditorDrawer.js +55 -25
- package/lib/module/EditorDrawer.js.map +1 -1
- package/lib/module/FilesPanel.js +56 -20
- package/lib/module/FilesPanel.js.map +1 -1
- package/lib/module/MarkdownText.js +1 -1
- package/lib/module/MarkdownText.js.map +1 -1
- package/lib/module/MessageActionBar.js +10 -3
- package/lib/module/MessageActionBar.js.map +1 -1
- package/lib/module/RenameAgentModal.js +2 -1
- package/lib/module/RenameAgentModal.js.map +1 -1
- package/lib/module/ShareAgentModal.js +11 -10
- package/lib/module/ShareAgentModal.js.map +1 -1
- package/lib/module/ShareAgentModal.styles.js +2 -2
- package/lib/module/ShareAgentModal.styles.js.map +1 -1
- package/lib/module/SuperagentHomeScreen.js +45 -13
- package/lib/module/SuperagentHomeScreen.js.map +1 -1
- package/lib/module/ToolApprovalCard.js +73 -15
- package/lib/module/ToolApprovalCard.js.map +1 -1
- package/lib/module/ToolCallSummary.js +19 -10
- package/lib/module/ToolCallSummary.js.map +1 -1
- package/lib/module/agentSphereAssets.js +323 -0
- package/lib/module/agentSphereAssets.js.map +1 -0
- package/lib/module/agentSphereStyles.js +3 -3
- package/lib/module/agentSphereStyles.js.map +1 -1
- package/lib/module/apiClient.js +7 -0
- package/lib/module/apiClient.js.map +1 -1
- package/lib/module/attachmentUpload.js +2 -1
- package/lib/module/attachmentUpload.js.map +1 -1
- package/lib/module/composerStyles.js +2 -2
- package/lib/module/composerStyles.js.map +1 -1
- package/lib/module/connectorBrandIcons.generated.js +621 -0
- package/lib/module/connectorBrandIcons.generated.js.map +1 -0
- package/lib/module/connectorBrandIcons.js +1 -53
- package/lib/module/connectorBrandIcons.js.map +1 -1
- package/lib/module/connectorCatalog.js +17 -0
- package/lib/module/connectorCatalog.js.map +1 -1
- package/lib/module/conversationParts.js +5 -4
- package/lib/module/conversationParts.js.map +1 -1
- package/lib/module/conversationRuntime.js +149 -9
- package/lib/module/conversationRuntime.js.map +1 -1
- package/lib/module/conversationStyles.js +3 -2
- package/lib/module/conversationStyles.js.map +1 -1
- package/lib/module/editorShellStyles.js +6 -2
- package/lib/module/editorShellStyles.js.map +1 -1
- package/lib/module/fileTreeUtils.js +6 -0
- package/lib/module/fileTreeUtils.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/markdownStyles.js +2 -2
- package/lib/module/markdownStyles.js.map +1 -1
- package/lib/module/messageActionStyles.js +2 -2
- package/lib/module/messageActionStyles.js.map +1 -1
- package/lib/module/realtimeClient.js +4 -1
- package/lib/module/realtimeClient.js.map +1 -1
- package/lib/module/renameAgentModalStyles.js +2 -2
- package/lib/module/renameAgentModalStyles.js.map +1 -1
- package/lib/module/screenParts.js +25 -42
- package/lib/module/screenParts.js.map +1 -1
- package/lib/module/styles.js +32 -21
- package/lib/module/styles.js.map +1 -1
- package/lib/module/superagentApiClient.js +63 -18
- package/lib/module/superagentApiClient.js.map +1 -1
- package/lib/module/theme.js +239 -0
- package/lib/module/theme.js.map +1 -0
- package/lib/module/useSuperagentConversation.js +242 -46
- package/lib/module/useSuperagentConversation.js.map +1 -1
- package/lib/module/useSuperagentRuntime.js +246 -106
- package/lib/module/useSuperagentRuntime.js.map +1 -1
- package/lib/typescript/commonjs/AgentSettingsPanel.d.ts.map +1 -1
- package/lib/typescript/commonjs/AgentSphereIcon.d.ts.map +1 -1
- package/lib/typescript/commonjs/AttachmentPickerStatusModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/ChannelsPanel.d.ts.map +1 -1
- package/lib/typescript/commonjs/ConversationChat.d.ts +1 -1
- package/lib/typescript/commonjs/ConversationChat.d.ts.map +1 -1
- package/lib/typescript/commonjs/ConversationComposer.d.ts.map +1 -1
- package/lib/typescript/commonjs/ConversationMessageList.d.ts +1 -1
- package/lib/typescript/commonjs/ConversationMessageList.d.ts.map +1 -1
- package/lib/typescript/commonjs/ConversationScreen.d.ts +2 -1
- package/lib/typescript/commonjs/ConversationScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/EditorDrawer.d.ts +1 -1
- package/lib/typescript/commonjs/EditorDrawer.d.ts.map +1 -1
- package/lib/typescript/commonjs/FilesPanel.d.ts.map +1 -1
- package/lib/typescript/commonjs/RenameAgentModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/ShareAgentModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/ShareAgentModal.styles.d.ts.map +1 -1
- package/lib/typescript/commonjs/SuperagentHomeScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ToolApprovalCard.d.ts +3 -3
- package/lib/typescript/commonjs/ToolApprovalCard.d.ts.map +1 -1
- package/lib/typescript/commonjs/ToolCallSummary.d.ts +1 -1
- package/lib/typescript/commonjs/ToolCallSummary.d.ts.map +1 -1
- package/lib/typescript/commonjs/agentSphereAssets.d.ts +2 -0
- package/lib/typescript/commonjs/agentSphereAssets.d.ts.map +1 -0
- package/lib/typescript/commonjs/agentSphereStyles.d.ts.map +1 -1
- package/lib/typescript/commonjs/apiClient.d.ts.map +1 -1
- package/lib/typescript/commonjs/composerStyles.d.ts.map +1 -1
- package/lib/typescript/commonjs/connectorBrandIcons.d.ts.map +1 -1
- package/lib/typescript/commonjs/connectorBrandIcons.generated.d.ts +2 -0
- package/lib/typescript/commonjs/connectorBrandIcons.generated.d.ts.map +1 -0
- package/lib/typescript/commonjs/connectorCatalog.d.ts +2 -0
- package/lib/typescript/commonjs/connectorCatalog.d.ts.map +1 -1
- package/lib/typescript/commonjs/conversationParts.d.ts +1 -1
- package/lib/typescript/commonjs/conversationParts.d.ts.map +1 -1
- package/lib/typescript/commonjs/conversationRuntime.d.ts +9 -3
- package/lib/typescript/commonjs/conversationRuntime.d.ts.map +1 -1
- package/lib/typescript/commonjs/conversationStyles.d.ts.map +1 -1
- package/lib/typescript/commonjs/editorShellStyles.d.ts +4 -0
- package/lib/typescript/commonjs/editorShellStyles.d.ts.map +1 -1
- package/lib/typescript/commonjs/fileTreeUtils.d.ts +1 -0
- package/lib/typescript/commonjs/fileTreeUtils.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +2 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/markdownStyles.d.ts.map +1 -1
- package/lib/typescript/commonjs/messageActionStyles.d.ts.map +1 -1
- package/lib/typescript/commonjs/realtimeClient.d.ts.map +1 -1
- package/lib/typescript/commonjs/renameAgentModalStyles.d.ts.map +1 -1
- package/lib/typescript/commonjs/screenParts.d.ts +1 -1
- package/lib/typescript/commonjs/screenParts.d.ts.map +1 -1
- package/lib/typescript/commonjs/styles.d.ts +20 -11
- package/lib/typescript/commonjs/styles.d.ts.map +1 -1
- package/lib/typescript/commonjs/superagentApiClient.d.ts +2 -1
- package/lib/typescript/commonjs/superagentApiClient.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme.d.ts +36 -0
- package/lib/typescript/commonjs/theme.d.ts.map +1 -0
- package/lib/typescript/commonjs/types.d.ts +17 -2
- package/lib/typescript/commonjs/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/useSuperagentConversation.d.ts +3 -2
- package/lib/typescript/commonjs/useSuperagentConversation.d.ts.map +1 -1
- package/lib/typescript/commonjs/useSuperagentRuntime.d.ts +5 -2
- package/lib/typescript/commonjs/useSuperagentRuntime.d.ts.map +1 -1
- package/lib/typescript/module/AgentSettingsPanel.d.ts.map +1 -1
- package/lib/typescript/module/AgentSphereIcon.d.ts.map +1 -1
- package/lib/typescript/module/AttachmentPickerStatusModal.d.ts.map +1 -1
- package/lib/typescript/module/ChannelsPanel.d.ts.map +1 -1
- package/lib/typescript/module/ConversationChat.d.ts +1 -1
- package/lib/typescript/module/ConversationChat.d.ts.map +1 -1
- package/lib/typescript/module/ConversationComposer.d.ts.map +1 -1
- package/lib/typescript/module/ConversationMessageList.d.ts +1 -1
- package/lib/typescript/module/ConversationMessageList.d.ts.map +1 -1
- package/lib/typescript/module/ConversationScreen.d.ts +2 -1
- package/lib/typescript/module/ConversationScreen.d.ts.map +1 -1
- package/lib/typescript/module/EditorDrawer.d.ts +1 -1
- package/lib/typescript/module/EditorDrawer.d.ts.map +1 -1
- package/lib/typescript/module/FilesPanel.d.ts.map +1 -1
- package/lib/typescript/module/RenameAgentModal.d.ts.map +1 -1
- package/lib/typescript/module/ShareAgentModal.d.ts.map +1 -1
- package/lib/typescript/module/ShareAgentModal.styles.d.ts.map +1 -1
- package/lib/typescript/module/SuperagentHomeScreen.d.ts.map +1 -1
- package/lib/typescript/module/ToolApprovalCard.d.ts +3 -3
- package/lib/typescript/module/ToolApprovalCard.d.ts.map +1 -1
- package/lib/typescript/module/ToolCallSummary.d.ts +1 -1
- package/lib/typescript/module/ToolCallSummary.d.ts.map +1 -1
- package/lib/typescript/module/agentSphereAssets.d.ts +2 -0
- package/lib/typescript/module/agentSphereAssets.d.ts.map +1 -0
- package/lib/typescript/module/agentSphereStyles.d.ts.map +1 -1
- package/lib/typescript/module/apiClient.d.ts.map +1 -1
- package/lib/typescript/module/composerStyles.d.ts.map +1 -1
- package/lib/typescript/module/connectorBrandIcons.d.ts.map +1 -1
- package/lib/typescript/module/connectorBrandIcons.generated.d.ts +2 -0
- package/lib/typescript/module/connectorBrandIcons.generated.d.ts.map +1 -0
- package/lib/typescript/module/connectorCatalog.d.ts +2 -0
- package/lib/typescript/module/connectorCatalog.d.ts.map +1 -1
- package/lib/typescript/module/conversationParts.d.ts +1 -1
- package/lib/typescript/module/conversationParts.d.ts.map +1 -1
- package/lib/typescript/module/conversationRuntime.d.ts +9 -3
- package/lib/typescript/module/conversationRuntime.d.ts.map +1 -1
- package/lib/typescript/module/conversationStyles.d.ts.map +1 -1
- package/lib/typescript/module/editorShellStyles.d.ts +4 -0
- package/lib/typescript/module/editorShellStyles.d.ts.map +1 -1
- package/lib/typescript/module/fileTreeUtils.d.ts +1 -0
- package/lib/typescript/module/fileTreeUtils.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +2 -0
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/markdownStyles.d.ts.map +1 -1
- package/lib/typescript/module/messageActionStyles.d.ts.map +1 -1
- package/lib/typescript/module/realtimeClient.d.ts.map +1 -1
- package/lib/typescript/module/renameAgentModalStyles.d.ts.map +1 -1
- package/lib/typescript/module/screenParts.d.ts +1 -1
- package/lib/typescript/module/screenParts.d.ts.map +1 -1
- package/lib/typescript/module/styles.d.ts +20 -11
- package/lib/typescript/module/styles.d.ts.map +1 -1
- package/lib/typescript/module/superagentApiClient.d.ts +2 -1
- package/lib/typescript/module/superagentApiClient.d.ts.map +1 -1
- package/lib/typescript/module/theme.d.ts +36 -0
- package/lib/typescript/module/theme.d.ts.map +1 -0
- package/lib/typescript/module/types.d.ts +17 -2
- package/lib/typescript/module/types.d.ts.map +1 -1
- package/lib/typescript/module/useSuperagentConversation.d.ts +3 -2
- package/lib/typescript/module/useSuperagentConversation.d.ts.map +1 -1
- package/lib/typescript/module/useSuperagentRuntime.d.ts +5 -2
- package/lib/typescript/module/useSuperagentRuntime.d.ts.map +1 -1
- package/package.json +13 -11
- package/src/AgentSettingsPanel.tsx +146 -58
- package/src/AgentSphereIcon.tsx +11 -62
- package/src/AttachmentPickerStatusModal.tsx +6 -5
- package/src/ChannelsPanel.tsx +59 -39
- package/src/ConversationChat.tsx +49 -12
- package/src/ConversationComposer.tsx +18 -12
- package/src/ConversationMessageList.tsx +1 -1
- package/src/ConversationScreen.tsx +5 -0
- package/src/EditorDrawer.tsx +66 -41
- package/src/FilesPanel.tsx +48 -20
- package/src/MarkdownText.tsx +1 -1
- package/src/MessageActionBar.tsx +9 -3
- package/src/RenameAgentModal.tsx +2 -1
- package/src/ShareAgentModal.styles.ts +2 -1
- package/src/ShareAgentModal.tsx +9 -8
- package/src/SuperagentHomeScreen.tsx +45 -10
- package/src/ToolApprovalCard.tsx +83 -15
- package/src/ToolCallSummary.tsx +22 -13
- package/src/agentSphereAssets.ts +325 -0
- package/src/agentSphereStyles.ts +3 -2
- package/src/apiClient.ts +7 -0
- package/src/attachmentUpload.ts +2 -1
- package/src/composerStyles.ts +2 -1
- package/src/connectorBrandIcons.generated.ts +618 -0
- package/src/connectorBrandIcons.tsx +1 -53
- package/src/connectorCatalog.ts +24 -0
- package/src/conversationParts.tsx +6 -5
- package/src/conversationRuntime.ts +166 -11
- package/src/conversationStyles.ts +2 -1
- package/src/editorShellStyles.ts +6 -1
- package/src/fileTreeUtils.ts +13 -0
- package/src/index.ts +2 -0
- package/src/markdownStyles.ts +2 -1
- package/src/messageActionStyles.ts +2 -1
- package/src/realtimeClient.ts +7 -1
- package/src/renameAgentModalStyles.ts +2 -1
- package/src/screenParts.tsx +17 -29
- package/src/styles.ts +25 -16
- package/src/superagentApiClient.ts +68 -18
- package/src/theme.ts +254 -0
- package/src/types.ts +22 -2
- package/src/useSuperagentConversation.ts +247 -45
- package/src/useSuperagentRuntime.ts +244 -107
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.useSuperagentRuntime = useSuperagentRuntime;
|
|
7
7
|
var _react = require("react");
|
|
8
|
+
var _reactNative = require("react-native");
|
|
8
9
|
var _apiClient = require("./apiClient.js");
|
|
9
10
|
var _fileTreeUtils = require("./fileTreeUtils.js");
|
|
10
11
|
var _realtimeClient = require("./realtimeClient.js");
|
|
@@ -22,6 +23,10 @@ function useSuperagentRuntime({
|
|
|
22
23
|
}), [config.baseUrl, config.currentUserId, config.getAccessToken, config.getHeaders]);
|
|
23
24
|
const [agents, setAgents] = (0, _react.useState)([]);
|
|
24
25
|
const [activeAgentId, setActiveAgentId] = (0, _react.useState)(initialAgentId ?? null);
|
|
26
|
+
// Always-latest active agent id, so a slow load for a previous agent can detect
|
|
27
|
+
// that the user has since switched and skip applying its (now stale) result.
|
|
28
|
+
const activeAgentIdRef = (0, _react.useRef)(activeAgentId);
|
|
29
|
+
activeAgentIdRef.current = activeAgentId;
|
|
25
30
|
const [currentRoute, setCurrentRoute] = (0, _react.useState)(initialAgentId ? {
|
|
26
31
|
name: 'agent',
|
|
27
32
|
agentId: initialAgentId
|
|
@@ -48,6 +53,11 @@ function useSuperagentRuntime({
|
|
|
48
53
|
const [isLoading, setIsLoading] = (0, _react.useState)(true);
|
|
49
54
|
const [loadError, setLoadError] = (0, _react.useState)(null);
|
|
50
55
|
const [runtimeAuthToken, setRuntimeAuthToken] = (0, _react.useState)(null);
|
|
56
|
+
// Caches the resolved runtime token keyed by the agent it belongs to. The
|
|
57
|
+
// runtimeAuthToken state lags an agent switch (it's cleared in a later effect),
|
|
58
|
+
// so resolveRuntimeToken must not trust it as a cache — this ref can never hand
|
|
59
|
+
// back a different agent's token.
|
|
60
|
+
const runtimeTokenRef = (0, _react.useRef)(null);
|
|
51
61
|
const [realtimeClient, setRealtimeClient] = (0, _react.useState)();
|
|
52
62
|
const [secrets, setSecrets] = (0, _react.useState)([]);
|
|
53
63
|
const connectorFlowRef = (0, _react.useRef)(null);
|
|
@@ -82,31 +92,37 @@ function useSuperagentRuntime({
|
|
|
82
92
|
setIsLoadingConnectors(true);
|
|
83
93
|
try {
|
|
84
94
|
const connectors = await superagentService.listConnectors(agentId);
|
|
95
|
+
if (activeAgentIdRef.current !== agentId) return;
|
|
85
96
|
setAvailableConnectors(connectors.availableConnectors);
|
|
86
97
|
setConnectedConnectors(connectors.connectedConnectors);
|
|
87
98
|
} catch {
|
|
99
|
+
if (activeAgentIdRef.current !== agentId) return;
|
|
88
100
|
setAvailableConnectors([]);
|
|
89
101
|
setConnectedConnectors([]);
|
|
90
102
|
} finally {
|
|
91
|
-
setIsLoadingConnectors(false);
|
|
103
|
+
if (activeAgentIdRef.current === agentId) setIsLoadingConnectors(false);
|
|
92
104
|
}
|
|
93
105
|
}, [superagentService]);
|
|
94
106
|
const loadAutomations = (0, _react.useCallback)(async agentId => {
|
|
95
107
|
setIsLoadingAutomations(true);
|
|
96
108
|
try {
|
|
97
109
|
const loadedAutomations = await superagentService.listAutomations(agentId);
|
|
110
|
+
if (activeAgentIdRef.current !== agentId) return;
|
|
98
111
|
setAutomations(loadedAutomations);
|
|
99
112
|
} catch {
|
|
113
|
+
if (activeAgentIdRef.current !== agentId) return;
|
|
100
114
|
setAutomations([]);
|
|
101
115
|
} finally {
|
|
102
|
-
setIsLoadingAutomations(false);
|
|
116
|
+
if (activeAgentIdRef.current === agentId) setIsLoadingAutomations(false);
|
|
103
117
|
}
|
|
104
118
|
}, [superagentService]);
|
|
105
119
|
const loadAutomationCredits = (0, _react.useCallback)(async agentId => {
|
|
106
120
|
try {
|
|
107
121
|
const loadedCredits = await superagentService.listAutomationCredits(agentId);
|
|
122
|
+
if (activeAgentIdRef.current !== agentId) return;
|
|
108
123
|
setAutomationCredits(loadedCredits);
|
|
109
124
|
} catch {
|
|
125
|
+
if (activeAgentIdRef.current !== agentId) return;
|
|
110
126
|
setAutomationCredits({});
|
|
111
127
|
}
|
|
112
128
|
}, [superagentService]);
|
|
@@ -114,55 +130,74 @@ function useSuperagentRuntime({
|
|
|
114
130
|
setIsLoadingFiles(true);
|
|
115
131
|
try {
|
|
116
132
|
const loadedFilePaths = await superagentService.listSandboxFiles(agentId);
|
|
133
|
+
if (activeAgentIdRef.current !== agentId) return;
|
|
117
134
|
const normalizedFilePaths = (0, _fileTreeUtils.normalizeFilePaths)(loadedFilePaths);
|
|
118
135
|
setFilePaths(normalizedFilePaths.length > 0 ? normalizedFilePaths : _fileTreeUtils.DEFAULT_SANDBOX_FILE_PATHS);
|
|
119
136
|
setFileLoadError(null);
|
|
120
137
|
setFileLoadFailed(false);
|
|
121
138
|
} catch (error) {
|
|
139
|
+
if (activeAgentIdRef.current !== agentId) return;
|
|
122
140
|
setFilePaths(_fileTreeUtils.DEFAULT_SANDBOX_FILE_PATHS);
|
|
123
141
|
setFileLoadError(getErrorMessage(error));
|
|
124
142
|
setFileLoadFailed(true);
|
|
125
143
|
} finally {
|
|
126
|
-
setIsLoadingFiles(false);
|
|
144
|
+
if (activeAgentIdRef.current === agentId) setIsLoadingFiles(false);
|
|
127
145
|
}
|
|
128
146
|
}, [superagentService]);
|
|
129
147
|
const loadAgentSettings = (0, _react.useCallback)(async agentId => {
|
|
130
148
|
setIsLoadingAgentSettings(true);
|
|
131
149
|
try {
|
|
132
150
|
const loadedSecrets = await superagentService.listSecrets(agentId);
|
|
151
|
+
if (activeAgentIdRef.current !== agentId) return;
|
|
133
152
|
setSecrets(loadedSecrets);
|
|
134
153
|
} catch {
|
|
154
|
+
if (activeAgentIdRef.current !== agentId) return;
|
|
135
155
|
setSecrets([]);
|
|
136
156
|
} finally {
|
|
137
|
-
setIsLoadingAgentSettings(false);
|
|
157
|
+
if (activeAgentIdRef.current === agentId) setIsLoadingAgentSettings(false);
|
|
138
158
|
}
|
|
139
159
|
}, [superagentService]);
|
|
140
160
|
const loadCollaborators = (0, _react.useCallback)(async agentId => {
|
|
141
161
|
setIsLoadingCollaborators(true);
|
|
142
162
|
try {
|
|
143
163
|
const loadedCollaborators = await superagentService.listCollaborators(agentId);
|
|
164
|
+
if (activeAgentIdRef.current !== agentId) return;
|
|
144
165
|
setCollaborators(loadedCollaborators);
|
|
145
166
|
} catch {
|
|
167
|
+
if (activeAgentIdRef.current !== agentId) return;
|
|
146
168
|
setCollaborators([]);
|
|
147
169
|
} finally {
|
|
148
|
-
setIsLoadingCollaborators(false);
|
|
170
|
+
if (activeAgentIdRef.current === agentId) setIsLoadingCollaborators(false);
|
|
149
171
|
}
|
|
150
172
|
}, [superagentService]);
|
|
151
173
|
const resolveRuntimeToken = (0, _react.useCallback)(async agentId => {
|
|
152
|
-
|
|
153
|
-
|
|
174
|
+
// Use the agent-keyed ref, not the runtimeAuthToken state: the state still
|
|
175
|
+
// holds the previous agent's token during a switch (it's cleared in a later
|
|
176
|
+
// effect), so trusting it could return the wrong agent's token here.
|
|
177
|
+
const cached = runtimeTokenRef.current;
|
|
178
|
+
if (cached && cached.agentId === agentId) {
|
|
179
|
+
return cached.token;
|
|
154
180
|
}
|
|
155
181
|
const token = await superagentService.getRuntimeAuthToken(agentId);
|
|
156
|
-
|
|
182
|
+
runtimeTokenRef.current = {
|
|
183
|
+
agentId,
|
|
184
|
+
token
|
|
185
|
+
};
|
|
186
|
+
// Compare against the latest active agent (ref), not the closure-captured
|
|
187
|
+
// activeAgentId: the user may have switched agents while the fetch was in
|
|
188
|
+
// flight, and writing a stale agent's token into shared state would point
|
|
189
|
+
// realtime/channel calls at the wrong agent.
|
|
190
|
+
if (agentId === activeAgentIdRef.current) {
|
|
157
191
|
setRuntimeAuthToken(token);
|
|
158
192
|
}
|
|
159
193
|
return token;
|
|
160
|
-
}, [
|
|
194
|
+
}, [superagentService]);
|
|
161
195
|
const loadChannels = (0, _react.useCallback)(async agentId => {
|
|
162
196
|
setIsLoadingChannels(true);
|
|
163
197
|
try {
|
|
164
198
|
const token = await resolveRuntimeToken(agentId);
|
|
165
199
|
const status = await superagentService.getChannelStatus(agentId, token);
|
|
200
|
+
if (activeAgentIdRef.current !== agentId) return;
|
|
166
201
|
setChannelStatus(current => ({
|
|
167
202
|
...status,
|
|
168
203
|
imessage: {
|
|
@@ -175,25 +210,33 @@ function useSuperagentRuntime({
|
|
|
175
210
|
}
|
|
176
211
|
}));
|
|
177
212
|
} catch {
|
|
213
|
+
if (activeAgentIdRef.current !== agentId) return;
|
|
178
214
|
setChannelStatus({});
|
|
179
215
|
} finally {
|
|
180
|
-
setIsLoadingChannels(false);
|
|
216
|
+
if (activeAgentIdRef.current === agentId) setIsLoadingChannels(false);
|
|
181
217
|
}
|
|
182
218
|
}, [resolveRuntimeToken, superagentService]);
|
|
183
219
|
const refreshAutomations = (0, _react.useCallback)(async agentId => {
|
|
184
220
|
await Promise.all([loadAutomations(agentId), loadAutomationCredits(agentId)]);
|
|
185
221
|
}, [loadAutomationCredits, loadAutomations]);
|
|
186
222
|
(0, _react.useEffect)(() => {
|
|
223
|
+
// Reset per-agent state on every active-agent change (not just when it goes
|
|
224
|
+
// null) so the drawer never shows the previous agent's secrets/connectors/
|
|
225
|
+
// files/collaborators/automations during the new agent's load window — which
|
|
226
|
+
// could otherwise let a destructive action target the wrong agent.
|
|
227
|
+
setAvailableConnectors([]);
|
|
228
|
+
setAutomationCredits({});
|
|
229
|
+
setAutomations([]);
|
|
230
|
+
setChannelStatus({});
|
|
231
|
+
setCollaborators([]);
|
|
232
|
+
setConnectingChannelId(null);
|
|
233
|
+
setConnectingConnectorId(null);
|
|
234
|
+
setConnectedConnectors([]);
|
|
235
|
+
setFilePaths([]);
|
|
236
|
+
setFileLoadError(null);
|
|
237
|
+
setFileLoadFailed(false);
|
|
238
|
+
setSecrets([]);
|
|
187
239
|
if (!activeAgentId) {
|
|
188
|
-
setAvailableConnectors([]);
|
|
189
|
-
setAutomationCredits({});
|
|
190
|
-
setAutomations([]);
|
|
191
|
-
setChannelStatus({});
|
|
192
|
-
setCollaborators([]);
|
|
193
|
-
setConnectingChannelId(null);
|
|
194
|
-
setConnectedConnectors([]);
|
|
195
|
-
setFilePaths([]);
|
|
196
|
-
setSecrets([]);
|
|
197
240
|
return;
|
|
198
241
|
}
|
|
199
242
|
loadAgentSettings(activeAgentId);
|
|
@@ -231,23 +274,17 @@ function useSuperagentRuntime({
|
|
|
231
274
|
if (!flow || flow.cancelled) {
|
|
232
275
|
return;
|
|
233
276
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
if (event.status === 'error') {
|
|
242
|
-
flow.cancelled = true;
|
|
243
|
-
connectorFlowRef.current = null;
|
|
244
|
-
setConnectingConnectorId(null);
|
|
277
|
+
|
|
278
|
+
// The callback event carries no connection/connector identifier, so it can't
|
|
279
|
+
// be reliably attributed to this flow — a late callback from a superseded
|
|
280
|
+
// connect could otherwise mark the wrong flow. Don't mutate flow state here;
|
|
281
|
+
// waitForConnectorAuthorization polls the authoritative per-connection status
|
|
282
|
+
// (it detects ACTIVE/FAILED on its own). Just refresh the connector list so
|
|
283
|
+
// the UI reflects the latest state.
|
|
284
|
+
if (event.status === 'success' || event.status === 'error') {
|
|
245
285
|
await loadConnectors(flow.agentId);
|
|
246
|
-
showAlert(nativeAdapters, 'Connector failed', 'OAuth authorization did not complete. Please try connecting again.');
|
|
247
|
-
return;
|
|
248
286
|
}
|
|
249
|
-
|
|
250
|
-
}, [loadConnectors, nativeAdapters]);
|
|
287
|
+
}, [loadConnectors]);
|
|
251
288
|
(0, _react.useEffect)(() => {
|
|
252
289
|
return nativeAdapters.subscribeToExternalAuthCallbacks?.(completePendingConnectorFromCallback);
|
|
253
290
|
}, [completePendingConnectorFromCallback, nativeAdapters]);
|
|
@@ -374,6 +411,9 @@ function useSuperagentRuntime({
|
|
|
374
411
|
} : agent));
|
|
375
412
|
} catch (error) {
|
|
376
413
|
showAlert(nativeAdapters, 'Permissions update failed', getErrorMessage(error));
|
|
414
|
+
// Rethrow so optimistic callers (the permission toggle) can revert; the
|
|
415
|
+
// guard-config caller wraps this in try/catch since the alert already fired.
|
|
416
|
+
throw error;
|
|
377
417
|
}
|
|
378
418
|
}, [nativeAdapters, superagentService]);
|
|
379
419
|
const onSaveSecret = (0, _react.useCallback)(async ({
|
|
@@ -386,6 +426,9 @@ function useSuperagentRuntime({
|
|
|
386
426
|
await loadAgentSettings(agentId);
|
|
387
427
|
} catch (error) {
|
|
388
428
|
showAlert(nativeAdapters, 'Secret save failed', getErrorMessage(error));
|
|
429
|
+
// Rethrow so the form keeps the user's input instead of clearing on a
|
|
430
|
+
// failed save.
|
|
431
|
+
throw error;
|
|
389
432
|
}
|
|
390
433
|
}, [loadAgentSettings, nativeAdapters, superagentService]);
|
|
391
434
|
const onDeleteSecret = (0, _react.useCallback)(async ({
|
|
@@ -448,7 +491,10 @@ function useSuperagentRuntime({
|
|
|
448
491
|
const onCloneAgent = (0, _react.useCallback)(({
|
|
449
492
|
agentId
|
|
450
493
|
}) => {
|
|
451
|
-
|
|
494
|
+
// Use the Superagent clone route — /remix-app is an app route that the web
|
|
495
|
+
// builder redirects back to /superagent/:id for user_agent apps (reopening the
|
|
496
|
+
// original instead of cloning). /clone-superagent/:id is the agent clone flow.
|
|
497
|
+
nativeAdapters.openWebUrl?.(buildWebUrl(config.webUrl ?? config.baseUrl, `/clone-superagent/${encodeURIComponent(agentId)}`));
|
|
452
498
|
}, [config.baseUrl, config.webUrl, nativeAdapters]);
|
|
453
499
|
const onDeleteAgent = (0, _react.useCallback)(async ({
|
|
454
500
|
agentId
|
|
@@ -571,7 +617,7 @@ function useSuperagentRuntime({
|
|
|
571
617
|
agentId,
|
|
572
618
|
path
|
|
573
619
|
}) => {
|
|
574
|
-
return superagentService.readSandboxFile(agentId, path);
|
|
620
|
+
return superagentService.readSandboxFile(agentId, (0, _fileTreeUtils.sanitizeSandboxFilePath)(path));
|
|
575
621
|
}, [superagentService]);
|
|
576
622
|
const onSaveSandboxFile = (0, _react.useCallback)(async ({
|
|
577
623
|
agentId,
|
|
@@ -579,7 +625,7 @@ function useSuperagentRuntime({
|
|
|
579
625
|
path
|
|
580
626
|
}) => {
|
|
581
627
|
try {
|
|
582
|
-
await superagentService.writeSandboxFile(agentId, path, content);
|
|
628
|
+
await superagentService.writeSandboxFile(agentId, (0, _fileTreeUtils.sanitizeSandboxFilePath)(path), content);
|
|
583
629
|
await loadFiles(agentId);
|
|
584
630
|
} catch (error) {
|
|
585
631
|
showAlert(nativeAdapters, 'Save failed', getErrorMessage(error));
|
|
@@ -594,12 +640,18 @@ function useSuperagentRuntime({
|
|
|
594
640
|
if (!files?.length) {
|
|
595
641
|
return [];
|
|
596
642
|
}
|
|
643
|
+
const writtenPaths = [];
|
|
597
644
|
for (const file of files) {
|
|
598
|
-
|
|
645
|
+
const safeName = (0, _fileTreeUtils.sanitizeSandboxFilePath)(file.name) || 'upload';
|
|
646
|
+
// Stage uploads under a dedicated folder so a picked file named like a
|
|
647
|
+
// generated-app file (package.json, README.md, ...) can't overwrite it.
|
|
648
|
+
const safePath = `incoming_files/${safeName}`;
|
|
649
|
+
await superagentService.writeSandboxFile(agentId, safePath, file.content);
|
|
650
|
+
writtenPaths.push(safePath);
|
|
599
651
|
}
|
|
600
652
|
await loadFiles(agentId);
|
|
601
|
-
return
|
|
602
|
-
path
|
|
653
|
+
return writtenPaths.map(path => ({
|
|
654
|
+
path
|
|
603
655
|
}));
|
|
604
656
|
} catch (error) {
|
|
605
657
|
if (nativeAdapters.isAttachmentPickerCancel?.(error)) {
|
|
@@ -629,19 +681,31 @@ function useSuperagentRuntime({
|
|
|
629
681
|
setConnectingChannelId('whatsapp');
|
|
630
682
|
try {
|
|
631
683
|
const token = await resolveRuntimeToken(agentId);
|
|
684
|
+
// Editor gate: the connect redirect only authenticates the app-user token and
|
|
685
|
+
// does not re-check live editor access, so a downgraded viewer could otherwise
|
|
686
|
+
// open it. /whatsapp/status enforces the two-layer editor check and throws
|
|
687
|
+
// (403) for viewers — require it to pass before opening the setup page.
|
|
688
|
+
await superagentService.getWhatsAppStatus(agentId, token);
|
|
632
689
|
const connectUrl = superagentService.getWhatsAppConnectUrl(agentId, token);
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
690
|
+
if (activeAgentIdRef.current === agentId) {
|
|
691
|
+
setChannelStatus(current => ({
|
|
692
|
+
...current,
|
|
693
|
+
whatsapp: {
|
|
694
|
+
...current.whatsapp,
|
|
695
|
+
connectUrl
|
|
696
|
+
}
|
|
697
|
+
}));
|
|
698
|
+
}
|
|
699
|
+
if (!nativeAdapters.openUrl) {
|
|
700
|
+
// Without a URL opener the setup page never launches; surface an error
|
|
701
|
+
// instead of completing silently (mirrors the connector OAuth flow).
|
|
702
|
+
throw new Error('This app cannot open the WhatsApp setup page. Connect WhatsApp from the web app.');
|
|
703
|
+
}
|
|
704
|
+
await nativeAdapters.openUrl(connectUrl);
|
|
641
705
|
} catch (error) {
|
|
642
706
|
showAlert(nativeAdapters, 'WhatsApp setup failed', getErrorMessage(error));
|
|
643
707
|
} finally {
|
|
644
|
-
setConnectingChannelId(null);
|
|
708
|
+
if (activeAgentIdRef.current === agentId) setConnectingChannelId(null);
|
|
645
709
|
}
|
|
646
710
|
}, [nativeAdapters, resolveRuntimeToken, superagentService]);
|
|
647
711
|
const onSetupTelegram = (0, _react.useCallback)(async ({
|
|
@@ -652,12 +716,14 @@ function useSuperagentRuntime({
|
|
|
652
716
|
try {
|
|
653
717
|
const runtimeToken = await resolveRuntimeToken(agentId);
|
|
654
718
|
const telegram = await superagentService.setupTelegram(agentId, runtimeToken, token);
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
719
|
+
if (activeAgentIdRef.current === agentId) {
|
|
720
|
+
setChannelStatus(current => ({
|
|
721
|
+
...current,
|
|
722
|
+
telegram
|
|
723
|
+
}));
|
|
724
|
+
}
|
|
659
725
|
} finally {
|
|
660
|
-
setConnectingChannelId(null);
|
|
726
|
+
if (activeAgentIdRef.current === agentId) setConnectingChannelId(null);
|
|
661
727
|
}
|
|
662
728
|
}, [resolveRuntimeToken, superagentService]);
|
|
663
729
|
const onDisconnectTelegram = (0, _react.useCallback)(async ({
|
|
@@ -676,16 +742,18 @@ function useSuperagentRuntime({
|
|
|
676
742
|
try {
|
|
677
743
|
const token = await resolveRuntimeToken(agentId);
|
|
678
744
|
await superagentService.disconnectTelegram(agentId, token);
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
745
|
+
if (activeAgentIdRef.current === agentId) {
|
|
746
|
+
setChannelStatus(current => ({
|
|
747
|
+
...current,
|
|
748
|
+
telegram: {
|
|
749
|
+
connected: false
|
|
750
|
+
}
|
|
751
|
+
}));
|
|
752
|
+
}
|
|
685
753
|
} catch (error) {
|
|
686
754
|
showAlert(nativeAdapters, 'Telegram disconnect failed', getErrorMessage(error));
|
|
687
755
|
} finally {
|
|
688
|
-
setConnectingChannelId(null);
|
|
756
|
+
if (activeAgentIdRef.current === agentId) setConnectingChannelId(null);
|
|
689
757
|
}
|
|
690
758
|
}, [nativeAdapters, resolveRuntimeToken, superagentService]);
|
|
691
759
|
const onGenerateLineCode = (0, _react.useCallback)(async ({
|
|
@@ -695,18 +763,20 @@ function useSuperagentRuntime({
|
|
|
695
763
|
try {
|
|
696
764
|
const token = await resolveRuntimeToken(agentId);
|
|
697
765
|
const activation = await superagentService.generateLineCode(agentId, token);
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
766
|
+
if (activeAgentIdRef.current === agentId) {
|
|
767
|
+
setChannelStatus(current => ({
|
|
768
|
+
...current,
|
|
769
|
+
line: {
|
|
770
|
+
...current.line,
|
|
771
|
+
activation,
|
|
772
|
+
connected: false
|
|
773
|
+
}
|
|
774
|
+
}));
|
|
775
|
+
}
|
|
706
776
|
} catch (error) {
|
|
707
777
|
showAlert(nativeAdapters, 'LINE setup failed', getErrorMessage(error));
|
|
708
778
|
} finally {
|
|
709
|
-
setConnectingChannelId(null);
|
|
779
|
+
if (activeAgentIdRef.current === agentId) setConnectingChannelId(null);
|
|
710
780
|
}
|
|
711
781
|
}, [nativeAdapters, resolveRuntimeToken, superagentService]);
|
|
712
782
|
const onGenerateIMessageCode = (0, _react.useCallback)(async ({
|
|
@@ -716,20 +786,22 @@ function useSuperagentRuntime({
|
|
|
716
786
|
try {
|
|
717
787
|
const token = await resolveRuntimeToken(agentId);
|
|
718
788
|
const activation = await superagentService.generateIMessageCode(agentId, token);
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
789
|
+
if (activeAgentIdRef.current === agentId) {
|
|
790
|
+
setChannelStatus(current => ({
|
|
791
|
+
...current,
|
|
792
|
+
imessage: {
|
|
793
|
+
...current.imessage,
|
|
794
|
+
activation,
|
|
795
|
+
connected: current.imessage?.connected ?? false
|
|
796
|
+
}
|
|
797
|
+
}));
|
|
798
|
+
}
|
|
727
799
|
return activation;
|
|
728
800
|
} catch (error) {
|
|
729
801
|
showAlert(nativeAdapters, 'iMessage setup failed', getErrorMessage(error));
|
|
730
802
|
throw error;
|
|
731
803
|
} finally {
|
|
732
|
-
setConnectingChannelId(null);
|
|
804
|
+
if (activeAgentIdRef.current === agentId) setConnectingChannelId(null);
|
|
733
805
|
}
|
|
734
806
|
}, [nativeAdapters, resolveRuntimeToken, superagentService]);
|
|
735
807
|
const onDisconnectIMessage = (0, _react.useCallback)(async ({
|
|
@@ -748,14 +820,16 @@ function useSuperagentRuntime({
|
|
|
748
820
|
try {
|
|
749
821
|
const token = await resolveRuntimeToken(agentId);
|
|
750
822
|
const imessage = await superagentService.disconnectIMessage(agentId, token);
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
823
|
+
if (activeAgentIdRef.current === agentId) {
|
|
824
|
+
setChannelStatus(current => ({
|
|
825
|
+
...current,
|
|
826
|
+
imessage
|
|
827
|
+
}));
|
|
828
|
+
}
|
|
755
829
|
} catch (error) {
|
|
756
830
|
showAlert(nativeAdapters, 'iMessage disconnect failed', getErrorMessage(error));
|
|
757
831
|
} finally {
|
|
758
|
-
setConnectingChannelId(null);
|
|
832
|
+
if (activeAgentIdRef.current === agentId) setConnectingChannelId(null);
|
|
759
833
|
}
|
|
760
834
|
}, [nativeAdapters, resolveRuntimeToken, superagentService]);
|
|
761
835
|
const onOpenIMessage = (0, _react.useCallback)(async ({
|
|
@@ -763,7 +837,10 @@ function useSuperagentRuntime({
|
|
|
763
837
|
phoneNumber
|
|
764
838
|
}) => {
|
|
765
839
|
try {
|
|
766
|
-
|
|
840
|
+
if (!nativeAdapters.openUrl) {
|
|
841
|
+
throw new Error('This app cannot open Messages. Use the web app to share the iMessage code.');
|
|
842
|
+
}
|
|
843
|
+
await nativeAdapters.openUrl(buildIMessageUrl(phoneNumber, code));
|
|
767
844
|
} catch (error) {
|
|
768
845
|
showAlert(nativeAdapters, 'iMessage link unavailable', getErrorMessage(error));
|
|
769
846
|
}
|
|
@@ -782,7 +859,11 @@ function useSuperagentRuntime({
|
|
|
782
859
|
addFriendUrl,
|
|
783
860
|
code
|
|
784
861
|
}) => {
|
|
785
|
-
|
|
862
|
+
if (!nativeAdapters.share) {
|
|
863
|
+
showAlert(nativeAdapters, 'Sharing unavailable', 'This app cannot share the activation code. Copy it manually instead.');
|
|
864
|
+
return;
|
|
865
|
+
}
|
|
866
|
+
await nativeAdapters.share({
|
|
786
867
|
message: `LINE activation code: ${code}\n${addFriendUrl}`,
|
|
787
868
|
title: 'LINE activation code',
|
|
788
869
|
url: addFriendUrl
|
|
@@ -792,7 +873,11 @@ function useSuperagentRuntime({
|
|
|
792
873
|
code,
|
|
793
874
|
phoneNumber
|
|
794
875
|
}) => {
|
|
795
|
-
|
|
876
|
+
if (!nativeAdapters.share) {
|
|
877
|
+
showAlert(nativeAdapters, 'Sharing unavailable', 'This app cannot share the activation code. Copy it manually instead.');
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
await nativeAdapters.share({
|
|
796
881
|
message: `Text ${code} to ${phoneNumber} to connect this Superagent on iMessage.`,
|
|
797
882
|
title: 'iMessage activation code',
|
|
798
883
|
url: buildIMessageUrl(phoneNumber, code)
|
|
@@ -828,22 +913,35 @@ function useSuperagentRuntime({
|
|
|
828
913
|
connectorFlowRef.current = null;
|
|
829
914
|
setConnectingConnectorId(null);
|
|
830
915
|
await loadConnectors(agentId);
|
|
831
|
-
|
|
916
|
+
// Return the connection_id (string) so the connector tool-approval can
|
|
917
|
+
// submit it; fall back to `true` when the backend omits it.
|
|
918
|
+
return connection.connection_id ?? true;
|
|
832
919
|
}
|
|
833
920
|
if (!connection.redirect_url || !connection.connection_id) {
|
|
834
921
|
throw new Error('The backend did not return an authorization URL for this connector.');
|
|
835
922
|
}
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
923
|
+
if (!nativeAdapters.openUrl) {
|
|
924
|
+
// Without a URL opener the browser never launches, so polling would just
|
|
925
|
+
// time out after ~2 minutes. Fail immediately with an actionable error.
|
|
926
|
+
throw new Error('This app cannot open the authorization page. Connect this integration from the web app.');
|
|
927
|
+
}
|
|
928
|
+
await nativeAdapters.openUrl(connection.redirect_url);
|
|
929
|
+
const connected = await waitForConnectorAuthorization(superagentService, agentId, connectorId, connection.connection_id, flow);
|
|
930
|
+
|
|
931
|
+
// Only clear shared state if this flow is still the active one — a newer
|
|
932
|
+
// connect may have superseded it (and owns connectorFlowRef now).
|
|
933
|
+
if (connectorFlowRef.current === flow) {
|
|
839
934
|
connectorFlowRef.current = null;
|
|
840
935
|
setConnectingConnectorId(null);
|
|
936
|
+
}
|
|
937
|
+
if (connected) {
|
|
841
938
|
await loadConnectors(agentId);
|
|
842
|
-
return true;
|
|
843
939
|
}
|
|
844
|
-
return
|
|
940
|
+
// On success return the connection_id so the connector tool-approval can
|
|
941
|
+
// submit it for backend verification; `false` on failure.
|
|
942
|
+
return connected ? connection.connection_id : false;
|
|
845
943
|
} catch (error) {
|
|
846
|
-
if (
|
|
944
|
+
if (connectorFlowRef.current === flow) {
|
|
847
945
|
connectorFlowRef.current = null;
|
|
848
946
|
setConnectingConnectorId(null);
|
|
849
947
|
showAlert(nativeAdapters, 'Connector failed', getErrorMessage(error));
|
|
@@ -905,6 +1003,7 @@ function useSuperagentRuntime({
|
|
|
905
1003
|
}
|
|
906
1004
|
}, [loadConnectors, nativeAdapters, superagentService]);
|
|
907
1005
|
return {
|
|
1006
|
+
activeAgentId,
|
|
908
1007
|
agents,
|
|
909
1008
|
apiClient,
|
|
910
1009
|
availableConnectors,
|
|
@@ -916,7 +1015,12 @@ function useSuperagentRuntime({
|
|
|
916
1015
|
connectingConnectorId,
|
|
917
1016
|
connectedConnectors,
|
|
918
1017
|
currentRoute,
|
|
1018
|
+
// Also expose as initialRoute, the prop SuperagentHomeScreen actually consumes,
|
|
1019
|
+
// so spreading the runtime opens on the deep-linked agent (initialAgentId)
|
|
1020
|
+
// instead of defaulting to the home route.
|
|
1021
|
+
initialRoute: currentRoute,
|
|
919
1022
|
currentUserAvatarUrl: config.currentUserAvatarUrl,
|
|
1023
|
+
currentUserId: config.currentUserId,
|
|
920
1024
|
currentUserName: config.currentUserName,
|
|
921
1025
|
fileLoadError,
|
|
922
1026
|
fileLoadFailed,
|
|
@@ -969,7 +1073,10 @@ function useSuperagentRuntime({
|
|
|
969
1073
|
onShareAgentLink,
|
|
970
1074
|
onShareIMessageCode,
|
|
971
1075
|
onShareLineCode,
|
|
972
|
-
|
|
1076
|
+
// Only expose Live Voice when the native audio adapter is actually installed;
|
|
1077
|
+
// otherwise the composer would prefer it and fail on tap ("audio callbacks are
|
|
1078
|
+
// not installed") instead of falling back to onStartVoiceInput.
|
|
1079
|
+
onStartLiveVoice: nativeAdapters.liveVoiceAudio?.startAudioCapture ? onStartLiveVoice : undefined,
|
|
973
1080
|
onSetupTelegram,
|
|
974
1081
|
onToggleAutomation,
|
|
975
1082
|
onUpdateAgentModel,
|
|
@@ -980,22 +1087,27 @@ function useSuperagentRuntime({
|
|
|
980
1087
|
};
|
|
981
1088
|
}
|
|
982
1089
|
async function waitForConnectorAuthorization(superagentService, agentId, connectorId, connectionId, flow) {
|
|
1090
|
+
// The connection status (scoped to this flow's connectionId) is the
|
|
1091
|
+
// authoritative source of truth — not a global callback flag, which can't be
|
|
1092
|
+
// attributed to a specific flow. Returns whether the connector ended up ACTIVE.
|
|
1093
|
+
const isActive = async () => (await superagentService.getConnectorConnectionStatus(agentId, connectorId, connectionId)) === 'ACTIVE';
|
|
983
1094
|
const maxAttempts = 40;
|
|
984
1095
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
985
1096
|
if (flow.cancelled) {
|
|
986
|
-
|
|
1097
|
+
// Cancelled — but OAuth may have already completed; confirm with the
|
|
1098
|
+
// authoritative status before reporting not-connected.
|
|
1099
|
+
return isActive().catch(() => false);
|
|
987
1100
|
}
|
|
988
1101
|
await delay(3000);
|
|
989
|
-
if (flow.cancelled) {
|
|
990
|
-
return;
|
|
991
|
-
}
|
|
992
1102
|
const status = await superagentService.getConnectorConnectionStatus(agentId, connectorId, connectionId);
|
|
993
1103
|
if (status === 'ACTIVE') {
|
|
994
|
-
return;
|
|
1104
|
+
return true;
|
|
995
1105
|
}
|
|
996
1106
|
if (status === 'FAILED') {
|
|
997
1107
|
throw new Error('OAuth connection failed.');
|
|
998
1108
|
}
|
|
1109
|
+
// If the user cancelled during the delay, the next iteration's top-of-loop
|
|
1110
|
+
// check re-confirms via the authoritative status before returning.
|
|
999
1111
|
}
|
|
1000
1112
|
throw new Error('Connection timed out after 2 minutes.');
|
|
1001
1113
|
}
|
|
@@ -1004,20 +1116,48 @@ async function openAllowedExternalUrl(nativeAdapters, url, allowedHosts, fallbac
|
|
|
1004
1116
|
showAlert(nativeAdapters, fallbackMessage, 'The backend returned a channel link that cannot be opened safely.');
|
|
1005
1117
|
return;
|
|
1006
1118
|
}
|
|
1119
|
+
if (!nativeAdapters.openUrl) {
|
|
1120
|
+
// No URL opener: surface it instead of passing the host check and then
|
|
1121
|
+
// silently doing nothing.
|
|
1122
|
+
showAlert(nativeAdapters, fallbackMessage, 'This app cannot open external links. Use the web app instead.');
|
|
1123
|
+
return;
|
|
1124
|
+
}
|
|
1007
1125
|
try {
|
|
1008
|
-
await nativeAdapters.openUrl
|
|
1126
|
+
await nativeAdapters.openUrl(url);
|
|
1009
1127
|
} catch (error) {
|
|
1010
1128
|
showAlert(nativeAdapters, fallbackMessage, getErrorMessage(error));
|
|
1011
1129
|
}
|
|
1012
1130
|
}
|
|
1013
1131
|
function showAlert(nativeAdapters, title, message) {
|
|
1014
|
-
nativeAdapters.alert
|
|
1132
|
+
if (nativeAdapters.alert) {
|
|
1133
|
+
nativeAdapters.alert(title, message);
|
|
1134
|
+
return;
|
|
1135
|
+
}
|
|
1136
|
+
// No host alert adapter — fall back to React Native's Alert (as confirmAction
|
|
1137
|
+
// does) so connector/channel/file/model errors aren't silently swallowed.
|
|
1138
|
+
_reactNative.Alert.alert(title, message);
|
|
1015
1139
|
}
|
|
1016
1140
|
async function confirmAction(nativeAdapters, input) {
|
|
1017
|
-
if (
|
|
1018
|
-
return
|
|
1141
|
+
if (nativeAdapters.confirm) {
|
|
1142
|
+
return nativeAdapters.confirm(input);
|
|
1019
1143
|
}
|
|
1020
|
-
|
|
1144
|
+
|
|
1145
|
+
// No host confirm adapter — fall back to a native prompt so destructive actions
|
|
1146
|
+
// still require explicit confirmation instead of silently proceeding.
|
|
1147
|
+
return new Promise(resolve => {
|
|
1148
|
+
_reactNative.Alert.alert(input.title, input.message, [{
|
|
1149
|
+
onPress: () => resolve(false),
|
|
1150
|
+
style: 'cancel',
|
|
1151
|
+
text: 'Cancel'
|
|
1152
|
+
}, {
|
|
1153
|
+
onPress: () => resolve(true),
|
|
1154
|
+
style: input.destructive ? 'destructive' : 'default',
|
|
1155
|
+
text: input.confirmText ?? 'Confirm'
|
|
1156
|
+
}], {
|
|
1157
|
+
cancelable: true,
|
|
1158
|
+
onDismiss: () => resolve(false)
|
|
1159
|
+
});
|
|
1160
|
+
});
|
|
1021
1161
|
}
|
|
1022
1162
|
function buildWebUrl(baseUrl, path) {
|
|
1023
1163
|
return `${normalizeBaseUrl(baseUrl)}${path.startsWith('/') ? path : `/${path}`}`;
|