@elizaos/ui 2.0.3-beta.6 → 2.0.3-beta.7
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/App.d.ts.map +1 -1
- package/App.js +30 -4
- package/api/app-shell-capabilities.d.ts +9 -0
- package/api/app-shell-capabilities.d.ts.map +1 -0
- package/api/app-shell-capabilities.js +39 -0
- package/api/auth-client.d.ts.map +1 -1
- package/api/auth-client.js +4 -1
- package/api/client-agent.d.ts.map +1 -1
- package/api/client-agent.js +35 -24
- package/api/client-base.d.ts +36 -0
- package/api/client-base.d.ts.map +1 -1
- package/api/client-base.js +79 -0
- package/api/client-chat.d.ts.map +1 -1
- package/api/client-chat.js +14 -5
- package/api/client-cloud.d.ts +49 -0
- package/api/client-cloud.d.ts.map +1 -1
- package/api/client-cloud.js +73 -6
- package/api/client-local-inference.d.ts.map +1 -1
- package/api/client-local-inference.js +5 -1
- package/api/desktop-external-api-base.d.ts +4 -0
- package/api/desktop-external-api-base.d.ts.map +1 -0
- package/api/desktop-external-api-base.js +43 -0
- package/api/desktop-http-transport.d.ts.map +1 -1
- package/api/desktop-http-transport.js +2 -28
- package/api/i18n-locale-client.d.ts.map +1 -1
- package/api/i18n-locale-client.js +12 -0
- package/cloud/billing/components/billing-tab.d.ts.map +1 -1
- package/cloud/billing/components/billing-tab.js +11 -14
- package/cloud/connectors/discord-gateway-connection.d.ts.map +1 -1
- package/cloud/connectors/discord-gateway-connection.js +39 -5
- package/cloud/connectors/index.d.ts +9 -0
- package/cloud/connectors/index.d.ts.map +1 -1
- package/cloud/connectors/index.js +14 -1
- package/cloud/handoff/run-cloud-agent-handoff.d.ts +10 -1
- package/cloud/handoff/run-cloud-agent-handoff.d.ts.map +1 -1
- package/cloud/handoff/run-cloud-agent-handoff.js +43 -7
- package/cloud/handoff/silent-repoint.d.ts +33 -0
- package/cloud/handoff/silent-repoint.d.ts.map +1 -0
- package/cloud/handoff/silent-repoint.js +55 -0
- package/cloud/instances/AgentDetailPage.d.ts.map +1 -1
- package/cloud/instances/AgentDetailPage.js +2 -2
- package/cloud/instances/components/agent-actions.d.ts.map +1 -1
- package/cloud/instances/components/agent-actions.js +1 -4
- package/cloud/instances/components/eliza-agents-table.d.ts.map +1 -1
- package/cloud/instances/components/eliza-agents-table.js +1 -10
- package/cloud/instances/index.d.ts +2 -5
- package/cloud/instances/index.d.ts.map +1 -1
- package/cloud/instances/index.js +2 -12
- package/cloud/organization/invite-member-dialog.d.ts.map +1 -1
- package/cloud/organization/invite-member-dialog.js +2 -5
- package/cloud/organization/members-tab.d.ts.map +1 -1
- package/cloud/organization/members-tab.js +4 -7
- package/cloud/public-pages/pages/app-auth/app-authorize-page.d.ts +9 -0
- package/cloud/public-pages/pages/app-auth/app-authorize-page.d.ts.map +1 -1
- package/cloud/public-pages/pages/app-auth/app-authorize-page.js +11 -1
- package/cloud/register-all.d.ts +0 -1
- package/cloud/register-all.d.ts.map +1 -1
- package/cloud/register-all.js +3 -7
- package/cloud/settings/index.d.ts +5 -6
- package/cloud/settings/index.d.ts.map +1 -1
- package/cloud/settings/index.js +5 -6
- package/cloud/settings/register-cloud-settings.d.ts +2 -2
- package/cloud/settings/register-cloud-settings.d.ts.map +1 -1
- package/cloud/settings/register-cloud-settings.js +127 -121
- package/cloud/shell/CloudRouterShell.d.ts.map +1 -1
- package/cloud/shell/CloudRouterShell.js +5 -0
- package/cloud-ui/components/drawer.d.ts.map +1 -1
- package/cloud-ui/components/drawer.js +1 -1
- package/cloud-ui/index.d.ts +0 -1
- package/cloud-ui/index.d.ts.map +1 -1
- package/cloud-ui/index.js +0 -1
- package/components/apps/app-identity.helpers.d.ts.map +1 -1
- package/components/apps/app-identity.helpers.js +8 -0
- package/components/chat/widgets/inbox-unread.d.ts.map +1 -1
- package/components/chat/widgets/inbox-unread.js +8 -1
- package/components/chat/widgets/needs-attention.d.ts.map +1 -1
- package/components/chat/widgets/needs-attention.js +18 -2
- package/components/chat/widgets/relationships-attention.d.ts.map +1 -1
- package/components/chat/widgets/relationships-attention.js +5 -0
- package/components/composites/chat/chat-composer.js +15 -15
- package/components/config-ui/ui-renderer.d.ts.map +1 -1
- package/components/config-ui/ui-renderer.js +1 -1
- package/components/local-inference/useHomeModelStatus.d.ts.map +1 -1
- package/components/local-inference/useHomeModelStatus.js +31 -1
- package/components/pages/SettingsView.d.ts.map +1 -1
- package/components/pages/SettingsView.js +1 -4
- package/components/pages/Springboard.d.ts.map +1 -1
- package/components/pages/Springboard.js +17 -1
- package/components/pages/SpringboardSurface.d.ts.map +1 -1
- package/components/pages/SpringboardSurface.js +14 -3
- package/components/settings/CloudAgentsSection.d.ts.map +1 -1
- package/components/settings/CloudAgentsSection.js +6 -8
- package/components/settings/CloudOverviewSection.d.ts +2 -0
- package/components/settings/CloudOverviewSection.d.ts.map +1 -0
- package/components/settings/CloudOverviewSection.js +81 -0
- package/components/settings/ConnectorsSection.d.ts +19 -0
- package/components/settings/ConnectorsSection.d.ts.map +1 -1
- package/components/settings/ConnectorsSection.js +72 -27
- package/components/settings/settings-sections.d.ts.map +1 -1
- package/components/settings/settings-sections.js +26 -4
- package/components/shell/ComputerUseApprovalOverlay.d.ts.map +1 -1
- package/components/shell/ComputerUseApprovalOverlay.js +12 -2
- package/components/shell/ContinuousChatOverlay.d.ts.map +1 -1
- package/components/shell/ContinuousChatOverlay.js +41 -8
- package/components/shell/ShellHeaderControls.d.ts.map +1 -1
- package/components/shell/ShellHeaderControls.js +1 -1
- package/components/shell/StartupFailureView.d.ts.map +1 -1
- package/components/shell/StartupFailureView.js +4 -2
- package/components/shell/__e2e__/home-screen-fixture.catalog-stub.d.ts +2 -0
- package/components/shell/__e2e__/home-screen-fixture.catalog-stub.d.ts.map +1 -1
- package/components/shell/__e2e__/home-screen-fixture.catalog-stub.js +8 -0
- package/components/views/ViewTileImage.d.ts +4 -4
- package/components/views/ViewTileImage.d.ts.map +1 -1
- package/components/views/ViewTileImage.js +26 -9
- package/config/boot-config-store.d.ts +10 -0
- package/config/boot-config-store.d.ts.map +1 -1
- package/first-run/CompactOnboarding.d.ts.map +1 -1
- package/first-run/CompactOnboarding.js +4 -2
- package/first-run/use-first-run-controller.d.ts +1 -0
- package/first-run/use-first-run-controller.d.ts.map +1 -1
- package/first-run/use-first-run-controller.js +133 -56
- package/hooks/useAvailableViews.d.ts +11 -2
- package/hooks/useAvailableViews.d.ts.map +1 -1
- package/hooks/useAvailableViews.js +49 -7
- package/hooks/useHorizontalPager.d.ts.map +1 -1
- package/hooks/useHorizontalPager.js +11 -4
- package/hooks/useViewCatalog.d.ts.map +1 -1
- package/hooks/useViewCatalog.js +5 -2
- package/hooks/view-catalog.d.ts +2 -0
- package/hooks/view-catalog.d.ts.map +1 -1
- package/hooks/view-catalog.js +1 -0
- package/index.d.ts +0 -1
- package/index.d.ts.map +1 -1
- package/index.js +0 -1
- package/layouts/content-layout/content-layout.d.ts.map +1 -1
- package/layouts/content-layout/content-layout.js +2 -1
- package/package.json +10 -10
- package/platform/browser-launch.d.ts.map +1 -1
- package/platform/browser-launch.js +2 -0
- package/state/AppContext.js +6 -4
- package/state/startup-coordinator.d.ts +2 -0
- package/state/startup-coordinator.d.ts.map +1 -1
- package/state/startup-coordinator.js +8 -0
- package/state/startup-first-run-options.d.ts +4 -0
- package/state/startup-first-run-options.d.ts.map +1 -0
- package/state/startup-first-run-options.js +18 -0
- package/state/startup-phase-hydrate.d.ts.map +1 -1
- package/state/startup-phase-hydrate.js +25 -14
- package/state/startup-phase-poll.d.ts.map +1 -1
- package/state/startup-phase-poll.js +60 -0
- package/state/startup-phase-restore.d.ts.map +1 -1
- package/state/startup-phase-restore.js +6 -19
- package/state/types.d.ts +0 -17
- package/state/types.d.ts.map +1 -1
- package/state/types.js +0 -13
- package/state/use-startup-shell-controller.d.ts.map +1 -1
- package/state/use-startup-shell-controller.js +3 -2
- package/state/useAppShellState.d.ts +5 -1
- package/state/useAppShellState.d.ts.map +1 -1
- package/state/useAppShellState.js +11 -3
- package/state/useChatCallbacks.d.ts +1 -0
- package/state/useChatCallbacks.d.ts.map +1 -1
- package/state/useChatCallbacks.js +53 -8
- package/state/useChatLifecycle.d.ts +1 -0
- package/state/useChatLifecycle.d.ts.map +1 -1
- package/state/useChatLifecycle.js +2 -2
- package/state/useChatSend.d.ts.map +1 -1
- package/state/useChatSend.js +72 -8
- package/state/useCloudState.d.ts.map +1 -1
- package/state/useCloudState.js +29 -1
- package/state/useDataLoaders.d.ts.map +1 -1
- package/state/useDataLoaders.js +9 -0
- package/state/useFirstRunCallbacks.d.ts.map +1 -1
- package/state/useFirstRunCallbacks.js +5 -0
- package/state/useLifecycleState.d.ts +0 -7
- package/state/useLifecycleState.d.ts.map +1 -1
- package/state/useLifecycleState.js +0 -24
- package/state/usePluginsSkillsState.d.ts +2 -2
- package/state/useWalletState.d.ts +3 -1
- package/state/useWalletState.d.ts.map +1 -1
- package/state/useWalletState.js +4 -2
- package/storybook/mock-providers.d.ts.map +1 -1
- package/storybook/mock-providers.js +2 -0
- package/styles/electrobun-mac-window-drag.css +7 -0
- package/widgets/WidgetHost.d.ts.map +1 -1
- package/widgets/WidgetHost.js +21 -3
- package/cloud/documents/DocumentsRoute.d.ts +0 -21
- package/cloud/documents/DocumentsRoute.d.ts.map +0 -1
- package/cloud/documents/DocumentsRoute.js +0 -45
- package/cloud/documents/DocumentsSection.d.ts +0 -15
- package/cloud/documents/DocumentsSection.d.ts.map +0 -1
- package/cloud/documents/DocumentsSection.js +0 -18
- package/cloud/documents/components/document-list.d.ts +0 -19
- package/cloud/documents/components/document-list.d.ts.map +0 -1
- package/cloud/documents/components/document-list.js +0 -75
- package/cloud/documents/components/document-query.d.ts +0 -15
- package/cloud/documents/components/document-query.d.ts.map +0 -1
- package/cloud/documents/components/document-query.js +0 -92
- package/cloud/documents/components/document-upload.d.ts +0 -16
- package/cloud/documents/components/document-upload.d.ts.map +0 -1
- package/cloud/documents/components/document-upload.js +0 -180
- package/cloud/documents/components/documents-page-client.d.ts +0 -20
- package/cloud/documents/components/documents-page-client.d.ts.map +0 -1
- package/cloud/documents/components/documents-page-client.js +0 -80
- package/cloud/documents/index.d.ts +0 -37
- package/cloud/documents/index.d.ts.map +0 -1
- package/cloud/documents/index.js +0 -45
- package/cloud/documents/lib/agents.d.ts +0 -23
- package/cloud/documents/lib/agents.d.ts.map +0 -1
- package/cloud/documents/lib/agents.js +0 -26
- package/cloud/documents/lib/documents.d.ts +0 -54
- package/cloud/documents/lib/documents.d.ts.map +0 -1
- package/cloud/documents/lib/documents.js +0 -118
- package/cloud/instances/AgentChatPage.d.ts +0 -13
- package/cloud/instances/AgentChatPage.d.ts.map +0 -1
- package/cloud/instances/AgentChatPage.js +0 -217
- package/cloud-ui/components/image-gen/empty-state.d.ts +0 -3
- package/cloud-ui/components/image-gen/empty-state.d.ts.map +0 -1
- package/cloud-ui/components/image-gen/empty-state.js +0 -12
- package/cloud-ui/components/image-gen/enhanced-loading.d.ts +0 -14
- package/cloud-ui/components/image-gen/enhanced-loading.d.ts.map +0 -1
- package/cloud-ui/components/image-gen/enhanced-loading.js +0 -23
- package/cloud-ui/components/image-gen/index.d.ts +0 -5
- package/cloud-ui/components/image-gen/index.d.ts.map +0 -1
- package/cloud-ui/components/image-gen/index.js +0 -4
- package/cloud-ui/components/image-gen/loading-state.d.ts +0 -2
- package/cloud-ui/components/image-gen/loading-state.d.ts.map +0 -1
- package/cloud-ui/components/image-gen/loading-state.js +0 -11
- package/cloud-ui/components/image-gen/prompt-input.d.ts +0 -32
- package/cloud-ui/components/image-gen/prompt-input.d.ts.map +0 -1
- package/cloud-ui/components/image-gen/prompt-input.js +0 -24
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isLoopbackBindHost, isWildcardBindHost } from "@elizaos/shared";
|
|
2
2
|
import { getElectrobunRendererRpc } from "../bridge/electrobun-rpc.js";
|
|
3
3
|
import { isElectrobunRuntime } from "../bridge/electrobun-runtime.js";
|
|
4
|
+
import { isDesktopExternalHttpApiBaseUrl } from "./desktop-external-api-base.js";
|
|
4
5
|
import { bodyToString, fetchAgentTransport, headersToRecord, methodAllowsBody, } from "./transport.js";
|
|
5
6
|
function isExternalPlainHttpUrl(url) {
|
|
6
7
|
try {
|
|
@@ -13,33 +14,6 @@ function isExternalPlainHttpUrl(url) {
|
|
|
13
14
|
return false;
|
|
14
15
|
}
|
|
15
16
|
}
|
|
16
|
-
function getConfiguredExternalApiBaseOrigin() {
|
|
17
|
-
if (typeof window === "undefined")
|
|
18
|
-
return null;
|
|
19
|
-
const value = window
|
|
20
|
-
.__ELIZA_DESKTOP_EXTERNAL_API_BASE__;
|
|
21
|
-
if (typeof value !== "string" || !value.trim())
|
|
22
|
-
return null;
|
|
23
|
-
try {
|
|
24
|
-
const parsed = new URL(value);
|
|
25
|
-
return parsed.protocol === "http:" ? parsed.origin : null;
|
|
26
|
-
}
|
|
27
|
-
catch {
|
|
28
|
-
return null;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
function isConfiguredExternalApiBaseUrl(url) {
|
|
32
|
-
const allowedOrigin = getConfiguredExternalApiBaseOrigin();
|
|
33
|
-
if (!allowedOrigin)
|
|
34
|
-
return false;
|
|
35
|
-
try {
|
|
36
|
-
const parsed = new URL(url);
|
|
37
|
-
return parsed.protocol === "http:" && parsed.origin === allowedOrigin;
|
|
38
|
-
}
|
|
39
|
-
catch {
|
|
40
|
-
return false;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
17
|
const desktopHttpTransport = {
|
|
44
18
|
async request(url, init, context) {
|
|
45
19
|
const rpc = getElectrobunRendererRpc();
|
|
@@ -70,7 +44,7 @@ const desktopHttpTransport = {
|
|
|
70
44
|
};
|
|
71
45
|
export function desktopHttpTransportForUrl(url) {
|
|
72
46
|
return isElectrobunRuntime() &&
|
|
73
|
-
(isExternalPlainHttpUrl(url) ||
|
|
47
|
+
(isExternalPlainHttpUrl(url) || isDesktopExternalHttpApiBaseUrl(url))
|
|
74
48
|
? desktopHttpTransport
|
|
75
49
|
: null;
|
|
76
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n-locale-client.d.ts","sourceRoot":"","sources":["../../../../../src/api/i18n-locale-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAqB,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"i18n-locale-client.d.ts","sourceRoot":"","sources":["../../../../../src/api/i18n-locale-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAqB,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAkB7D;;;GAGG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAczE"}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { getBootConfig } from "../config/boot-config.js";
|
|
10
10
|
import { normalizeLanguage } from "../i18n/index.js";
|
|
11
|
+
import { supportsFullAppShellRoutes } from "./app-shell-capabilities.js";
|
|
11
12
|
import { fetchWithCsrf } from "./csrf-client.js";
|
|
12
13
|
function localeBase() {
|
|
13
14
|
if (typeof window === "undefined")
|
|
@@ -15,11 +16,22 @@ function localeBase() {
|
|
|
15
16
|
const apiBase = getBootConfig().apiBase;
|
|
16
17
|
return apiBase ? apiBase.replace(/\/$/, "") : window.location.origin;
|
|
17
18
|
}
|
|
19
|
+
function shouldFetchSuggestedLanguage() {
|
|
20
|
+
if (typeof window === "undefined")
|
|
21
|
+
return false;
|
|
22
|
+
const apiBase = getBootConfig().apiBase;
|
|
23
|
+
if (apiBase)
|
|
24
|
+
return supportsFullAppShellRoutes(apiBase);
|
|
25
|
+
const host = window.location.hostname.toLowerCase();
|
|
26
|
+
return host !== "localhost" && host !== "127.0.0.1" && host !== "::1";
|
|
27
|
+
}
|
|
18
28
|
/**
|
|
19
29
|
* Fetch the server's suggested UI language. Returns `null` when the endpoint
|
|
20
30
|
* is unreachable or the server has no confident suggestion (advisory only).
|
|
21
31
|
*/
|
|
22
32
|
export async function fetchSuggestedLanguage() {
|
|
33
|
+
if (!shouldFetchSuggestedLanguage())
|
|
34
|
+
return null;
|
|
23
35
|
let res;
|
|
24
36
|
try {
|
|
25
37
|
res = await fetchWithCsrf(`${localeBase()}/api/i18n/locale`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"billing-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/cloud/billing/components/billing-tab.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"billing-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/cloud/billing/components/billing-tab.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAuBH,OAAO,KAAK,EACV,WAAW,EAIZ,MAAM,UAAU,CAAC;AAiBlB,UAAU,eAAe;IACvB,IAAI,EAAE,WAAW,CAAC;CACnB;AASD,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,EAAE,eAAe,2CA2cnD;AAED,YAAY,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
"use client";
|
|
13
13
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
14
|
-
import { BrandCard, CornerBrackets, Input } from "@elizaos/ui/cloud-ui";
|
|
14
|
+
import { BrandButton, BrandCard, CornerBrackets, Input, Label, } from "@elizaos/ui/cloud-ui";
|
|
15
15
|
import { AlertCircle, CheckCircle, CreditCard, Loader2, Wallet, } from "lucide-react";
|
|
16
16
|
import { lazy, Suspense, useCallback, useEffect, useState } from "react";
|
|
17
17
|
import { useNavigate } from "react-router-dom";
|
|
@@ -181,19 +181,16 @@ export function BillingTab({ user }) {
|
|
|
181
181
|
? "bg-[#FF5800] border-[#FF5800] text-white"
|
|
182
182
|
: "bg-transparent border-[rgba(255,255,255,0.2)] text-white/60 hover:border-[rgba(255,255,255,0.4)]"}`, children: [_jsx(CreditCard, { className: "h-4 w-4" }), t("cloud.billingTab.card", { defaultValue: "Card" })] }), _jsxs("button", { type: "button", onClick: () => setPaymentMethod("crypto"), className: `flex items-center gap-2 px-4 py-2 font-mono text-sm border transition-colors ${paymentMethod === "crypto"
|
|
183
183
|
? "bg-[#FF5800] border-[#FF5800] text-white"
|
|
184
|
-
: "bg-transparent border-[rgba(255,255,255,0.2)] text-white/60 hover:border-[rgba(255,255,255,0.4)]"}`, children: [_jsx(Wallet, { className: "h-4 w-4" }), t("cloud.billingTab.crypto", { defaultValue: "Crypto" })] })] })), _jsxs("div", { className: "flex flex-col sm:flex-row items-stretch gap-4", children: [_jsxs("div", { className: "
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
: t("cloud.billingTab.buyCredits", {
|
|
195
|
-
defaultValue: "Buy credits",
|
|
196
|
-
}) }))] }))] }), purchaseAmount && !isValidAmount && (_jsxs("div", { className: "flex items-center gap-2 text-sm text-red-400", children: [_jsx(AlertCircle, { className: "h-4 w-4" }), _jsx("span", { className: "font-mono", children: amountValue === null || amountValue < AMOUNT_LIMITS.MIN
|
|
184
|
+
: "bg-transparent border-[rgba(255,255,255,0.2)] text-white/60 hover:border-[rgba(255,255,255,0.4)]"}`, children: [_jsx(Wallet, { className: "h-4 w-4" }), t("cloud.billingTab.crypto", { defaultValue: "Crypto" })] })] })), _jsxs("div", { className: "flex flex-col sm:flex-row items-stretch sm:items-end gap-4", children: [_jsxs("div", { className: "flex-1 max-w-xs", children: [_jsx(Label, { htmlFor: "purchase-amount", className: "mb-1.5 block text-white/60 font-mono text-xs", children: t("cloud.billingTab.amountLabel", {
|
|
185
|
+
defaultValue: "Amount (USD)",
|
|
186
|
+
}) }), _jsxs("div", { className: "relative", children: [_jsx("span", { className: "absolute left-3 top-1/2 -translate-y-1/2 text-[#717171] font-mono z-10 pointer-events-none", children: "$" }), _jsx(Input, { id: "purchase-amount", type: "number", step: "1", min: AMOUNT_LIMITS.MIN, max: AMOUNT_LIMITS.MAX, value: purchaseAmount, onChange: (e) => setPurchaseAmount(e.target.value), className: "pl-7 bg-[rgba(29,29,29,0.3)] border border-[rgba(255,255,255,0.15)] text-[#e1e1e1] h-11 font-mono", placeholder: "0.00", disabled: isProcessingCheckout })] })] }), (paymentMethod !== "crypto" ||
|
|
187
|
+
!cryptoStatus?.directWallet?.enabled) && (_jsx(BrandButton, { type: "button", variant: "primary", onClick: handleBuyCredits, disabled: !isValidAmount || isProcessingCheckout, className: "h-11 px-6 w-full sm:w-auto flex-shrink-0 font-mono text-base whitespace-nowrap", children: isProcessingCheckout ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), t("cloud.billingTab.redirecting", {
|
|
188
|
+
defaultValue: "Redirecting...",
|
|
189
|
+
})] })) : paymentMethod === "crypto" ? (t("cloud.billingTab.payWithCrypto", {
|
|
190
|
+
defaultValue: "Pay with Crypto",
|
|
191
|
+
})) : (t("cloud.billingTab.buyCredits", {
|
|
192
|
+
defaultValue: "Buy credits",
|
|
193
|
+
})) }))] }), purchaseAmount && !isValidAmount && (_jsxs("div", { className: "flex items-center gap-2 text-sm text-red-400", children: [_jsx(AlertCircle, { className: "h-4 w-4" }), _jsx("span", { className: "font-mono", children: amountValue === null || amountValue < AMOUNT_LIMITS.MIN
|
|
197
194
|
? t("cloud.billingTab.minAmount", {
|
|
198
195
|
min: AMOUNT_LIMITS.MIN,
|
|
199
196
|
defaultValue: "Minimum amount is $" + "{{min}}",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discord-gateway-connection.d.ts","sourceRoot":"","sources":["../../../../../../src/cloud/connectors/discord-gateway-connection.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"discord-gateway-connection.d.ts","sourceRoot":"","sources":["../../../../../../src/cloud/connectors/discord-gateway-connection.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgKH,wBAAgB,wBAAwB,4CA6lCvC"}
|
|
@@ -22,6 +22,24 @@ import { Label } from "../../components/ui/label.js";
|
|
|
22
22
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "../../components/ui/select.js";
|
|
23
23
|
import { ApiError, api, apiFetch } from "../lib/api-client.js";
|
|
24
24
|
import { useCloudT } from "../shell/CloudI18nProvider.js";
|
|
25
|
+
function normalizeCharacters(agents) {
|
|
26
|
+
return (agents ?? []).flatMap((agent) => {
|
|
27
|
+
if (typeof agent.id !== "string" || agent.id.length === 0)
|
|
28
|
+
return [];
|
|
29
|
+
return [
|
|
30
|
+
{
|
|
31
|
+
id: agent.id,
|
|
32
|
+
name: typeof agent.name === "string" && agent.name.length > 0
|
|
33
|
+
? agent.name
|
|
34
|
+
: agent.id,
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
async function fetchRuntimeCharacters(signal) {
|
|
40
|
+
const data = await api("/api/agents", { signal, skipAuth: true });
|
|
41
|
+
return normalizeCharacters(data.agents);
|
|
42
|
+
}
|
|
25
43
|
function apiErrorMessage(error, fallback) {
|
|
26
44
|
if (error instanceof ApiError) {
|
|
27
45
|
const body = error.body;
|
|
@@ -89,14 +107,30 @@ export function DiscordGatewayConnection() {
|
|
|
89
107
|
try {
|
|
90
108
|
const data = await api("/api/v1/dashboard", { signal });
|
|
91
109
|
if (!signal?.aborted) {
|
|
92
|
-
|
|
110
|
+
const nextCharacters = normalizeCharacters(data.agents);
|
|
111
|
+
const fallbackCharacters = nextCharacters.length > 0
|
|
112
|
+
? nextCharacters
|
|
113
|
+
: await fetchRuntimeCharacters(signal);
|
|
114
|
+
if (!signal?.aborted) {
|
|
115
|
+
setCharacters(fallbackCharacters);
|
|
116
|
+
setCharacterId((current) => current || fallbackCharacters[0]?.id || "");
|
|
117
|
+
}
|
|
93
118
|
}
|
|
94
119
|
}
|
|
95
120
|
catch {
|
|
96
121
|
if (!signal?.aborted) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
122
|
+
try {
|
|
123
|
+
const fallbackCharacters = await fetchRuntimeCharacters(signal);
|
|
124
|
+
if (!signal?.aborted) {
|
|
125
|
+
setCharacters(fallbackCharacters);
|
|
126
|
+
setCharacterId((current) => current || fallbackCharacters[0]?.id || "");
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
toast.error(t("cloud.discord.fetchCharactersFailed", {
|
|
131
|
+
defaultValue: "Failed to fetch characters",
|
|
132
|
+
}));
|
|
133
|
+
}
|
|
100
134
|
}
|
|
101
135
|
}
|
|
102
136
|
finally {
|
|
@@ -454,7 +488,7 @@ export function DiscordGatewayConnection() {
|
|
|
454
488
|
defaultValue: "Select a character...",
|
|
455
489
|
}) }) }), _jsx(SelectContent, { children: characters.length === 0 ? (_jsx(SelectItem, { value: "none", disabled: true, children: t("cloud.discord.noCharactersAvailable", {
|
|
456
490
|
defaultValue: "No characters available",
|
|
457
|
-
}) })) : (characters.map((char) => (_jsx(SelectItem, { value: char.id, children: char.name }, char.id)))) })] }), _jsx(Button, { variant: "outline", size: "icon", onClick: handleRefreshCharacters, disabled: isLoadingCharacters, title: t("cloud.discord.refreshCharacters", {
|
|
491
|
+
}) })) : (characters.map((char) => (_jsx(SelectItem, { value: char.id, children: char.name }, char.id)))) })] }, characterId || "discord-gateway-character-unselected"), _jsx(Button, { variant: "outline", size: "icon", onClick: handleRefreshCharacters, disabled: isLoadingCharacters, title: t("cloud.discord.refreshCharacters", {
|
|
458
492
|
defaultValue: "Refresh characters",
|
|
459
493
|
}), children: _jsx(RefreshCw, { className: `h-4 w-4 ${isLoadingCharacters ? "animate-spin" : ""}` }) })] }), _jsx("p", { className: "text-xs text-muted-foreground", children: t("cloud.discord.characterHint", {
|
|
460
494
|
defaultValue: "The AI character that will respond to messages",
|
|
@@ -40,6 +40,15 @@ export { WhatsAppConnection } from "./whatsapp-connection.js";
|
|
|
40
40
|
* planned active-server-kind branch unifies them.
|
|
41
41
|
*/
|
|
42
42
|
export declare const CLOUD_CONNECTORS_SECTION_ID = "cloud-connectors";
|
|
43
|
+
/**
|
|
44
|
+
* Settings-section adapter for the cloud connectors surface.
|
|
45
|
+
*
|
|
46
|
+
* The standalone cloud route is already rendered under CloudRouterShell, which
|
|
47
|
+
* supplies query/i18n/auth providers. Settings sections render inside the
|
|
48
|
+
* app-shell settings registry instead, so this adapter provides the cloud stack
|
|
49
|
+
* before mounting the canonical connectors body.
|
|
50
|
+
*/
|
|
51
|
+
export declare function CloudConnectorsSettingsSection(): React.JSX.Element;
|
|
43
52
|
/**
|
|
44
53
|
* Register the cloud connectors surface as a Settings section under the "agent"
|
|
45
54
|
* group. Idempotent (the registry replaces by id). Call from the host's cloud
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/cloud/connectors/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/cloud/connectors/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AASH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,qBAAqB,CAAC;AAE9D;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAMlE;AAED;;;;;GAKG;AACH,wBAAgB,sCAAsC,IAAI,IAAI,CAa7D"}
|
|
@@ -25,7 +25,9 @@
|
|
|
25
25
|
* - Discord: `GET/POST /api/v1/discord/connections`, `PATCH/DELETE /api/v1/discord/connections/:id`, `GET /api/v1/dashboard` (character list)
|
|
26
26
|
*/
|
|
27
27
|
import { Plug } from "lucide-react";
|
|
28
|
+
import { createElement } from "react";
|
|
28
29
|
import { registerSettingsSection } from "../../components/settings/settings-section-registry.js";
|
|
30
|
+
import { CloudSettingsSectionShell } from "../settings/CloudSettingsSectionShell.js";
|
|
29
31
|
import { registerCloudRoute } from "../shell/cloud-route-registry.js";
|
|
30
32
|
import { CloudConnectorsSection } from "./CloudConnectorsSection.js";
|
|
31
33
|
export { BlooioConnection } from "./blooio-connection.js";
|
|
@@ -44,6 +46,17 @@ export { WhatsAppConnection } from "./whatsapp-connection.js";
|
|
|
44
46
|
* planned active-server-kind branch unifies them.
|
|
45
47
|
*/
|
|
46
48
|
export const CLOUD_CONNECTORS_SECTION_ID = "cloud-connectors";
|
|
49
|
+
/**
|
|
50
|
+
* Settings-section adapter for the cloud connectors surface.
|
|
51
|
+
*
|
|
52
|
+
* The standalone cloud route is already rendered under CloudRouterShell, which
|
|
53
|
+
* supplies query/i18n/auth providers. Settings sections render inside the
|
|
54
|
+
* app-shell settings registry instead, so this adapter provides the cloud stack
|
|
55
|
+
* before mounting the canonical connectors body.
|
|
56
|
+
*/
|
|
57
|
+
export function CloudConnectorsSettingsSection() {
|
|
58
|
+
return createElement(CloudSettingsSectionShell, null, createElement(CloudConnectorsSection));
|
|
59
|
+
}
|
|
47
60
|
/**
|
|
48
61
|
* Register the cloud connectors surface as a Settings section under the "agent"
|
|
49
62
|
* group. Idempotent (the registry replaces by id). Call from the host's cloud
|
|
@@ -61,7 +74,7 @@ export function registerCloudConnectorsSettingsSection() {
|
|
|
61
74
|
group: "agent",
|
|
62
75
|
titleKey: "settings.sections.cloudConnectors.title",
|
|
63
76
|
defaultTitle: "Cloud Connectors",
|
|
64
|
-
Component:
|
|
77
|
+
Component: CloudConnectorsSettingsSection,
|
|
65
78
|
});
|
|
66
79
|
}
|
|
67
80
|
// Register the standalone cloud route at import time. The cloud-frontend OAuth
|
|
@@ -13,6 +13,15 @@ import type { ConversationHandoffResult } from "./conversation-handoff.js";
|
|
|
13
13
|
*
|
|
14
14
|
* `start` is a thunk so the caller owns the supervisor args (agent id, bases,
|
|
15
15
|
* token, `onSwitch` rebind) and this module stays decoupled + unit-testable.
|
|
16
|
+
*
|
|
17
|
+
* `onSwitchSucceeded` is the gated success hook (PR4): it fires ONLY on a
|
|
18
|
+
* terminal `switched`/`switched-empty` — i.e. the dedicated is confirmed live
|
|
19
|
+
* and the transcript was copied + the client repointed onto it. It is the ONLY
|
|
20
|
+
* safe moment to delete the transient shared bridge; on `timed-out`/`failed`
|
|
21
|
+
* (or a thrown supervisor) the user is STILL on the shared adapter, so the hook
|
|
22
|
+
* is deliberately NOT called and the shared bridge is kept. Best-effort: a
|
|
23
|
+
* throw here is swallowed (a failed shared-delete just leaks a row — never
|
|
24
|
+
* un-switches the user).
|
|
16
25
|
*/
|
|
17
|
-
export declare function runCloudAgentHandoff(agentId: string, start: () => Promise<ConversationHandoffResult>): void;
|
|
26
|
+
export declare function runCloudAgentHandoff(agentId: string, start: () => Promise<ConversationHandoffResult>, onSwitchSucceeded?: () => void | Promise<void>): void;
|
|
18
27
|
//# sourceMappingURL=run-cloud-agent-handoff.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-cloud-agent-handoff.d.ts","sourceRoot":"","sources":["../../../../../../src/cloud/handoff/run-cloud-agent-handoff.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAExE
|
|
1
|
+
{"version":3,"file":"run-cloud-agent-handoff.d.ts","sourceRoot":"","sources":["../../../../../../src/cloud/handoff/run-cloud-agent-handoff.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAExE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,OAAO,CAAC,yBAAyB,CAAC,EAC/C,iBAAiB,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC7C,IAAI,CA8BN"}
|
|
@@ -13,8 +13,17 @@ import { CLOUD_HANDOFF_RETRY_EVENT, dispatchCloudHandoffPhase, } from "../../eve
|
|
|
13
13
|
*
|
|
14
14
|
* `start` is a thunk so the caller owns the supervisor args (agent id, bases,
|
|
15
15
|
* token, `onSwitch` rebind) and this module stays decoupled + unit-testable.
|
|
16
|
+
*
|
|
17
|
+
* `onSwitchSucceeded` is the gated success hook (PR4): it fires ONLY on a
|
|
18
|
+
* terminal `switched`/`switched-empty` — i.e. the dedicated is confirmed live
|
|
19
|
+
* and the transcript was copied + the client repointed onto it. It is the ONLY
|
|
20
|
+
* safe moment to delete the transient shared bridge; on `timed-out`/`failed`
|
|
21
|
+
* (or a thrown supervisor) the user is STILL on the shared adapter, so the hook
|
|
22
|
+
* is deliberately NOT called and the shared bridge is kept. Best-effort: a
|
|
23
|
+
* throw here is swallowed (a failed shared-delete just leaks a row — never
|
|
24
|
+
* un-switches the user).
|
|
16
25
|
*/
|
|
17
|
-
export function runCloudAgentHandoff(agentId, start) {
|
|
26
|
+
export function runCloudAgentHandoff(agentId, start, onSwitchSucceeded) {
|
|
18
27
|
dispatchCloudHandoffPhase({ agentId, phase: "migrating" });
|
|
19
28
|
start()
|
|
20
29
|
.then((result) => {
|
|
@@ -25,8 +34,16 @@ export function runCloudAgentHandoff(agentId, start) {
|
|
|
25
34
|
...(result.error ? { error: result.error } : {}),
|
|
26
35
|
});
|
|
27
36
|
if (result.status === "timed-out" || result.status === "failed") {
|
|
28
|
-
armRetry(agentId, start);
|
|
37
|
+
armRetry(agentId, start, onSwitchSucceeded);
|
|
38
|
+
return;
|
|
29
39
|
}
|
|
40
|
+
// Terminal SUCCESS (`switched`/`switched-empty`): the dedicated is live,
|
|
41
|
+
// the transcript is on it, and the client already repointed. Now — and
|
|
42
|
+
// ONLY now — is the shared bridge safe to delete.
|
|
43
|
+
void Promise.resolve(onSwitchSucceeded?.()).catch(() => {
|
|
44
|
+
// Fire-and-forget: a failed shared-delete leaks a row, never strands
|
|
45
|
+
// the (already switched) user. The supervisor logs the detail.
|
|
46
|
+
});
|
|
30
47
|
})
|
|
31
48
|
.catch((err) => {
|
|
32
49
|
dispatchCloudHandoffPhase({
|
|
@@ -34,18 +51,37 @@ export function runCloudAgentHandoff(agentId, start) {
|
|
|
34
51
|
phase: "failed",
|
|
35
52
|
error: err instanceof Error ? err.message : String(err),
|
|
36
53
|
});
|
|
37
|
-
armRetry(agentId, start);
|
|
54
|
+
armRetry(agentId, start, onSwitchSucceeded);
|
|
38
55
|
});
|
|
39
56
|
}
|
|
40
|
-
|
|
57
|
+
/**
|
|
58
|
+
* How long an armed retry listener stays live before it self-cleans. A handoff
|
|
59
|
+
* that fails and is never retried would otherwise leak its
|
|
60
|
+
* {@link CLOUD_HANDOFF_RETRY_EVENT} listener for the page lifetime; a flapping
|
|
61
|
+
* one would stack a new listener per failure. The TTL bounds both: the user has
|
|
62
|
+
* a generous window to hit retry, after which the listener is dropped.
|
|
63
|
+
*/
|
|
64
|
+
const RETRY_ARM_TTL_MS = 10 * 60_000;
|
|
65
|
+
function armRetry(agentId, start, onSwitchSucceeded) {
|
|
41
66
|
if (typeof window === "undefined")
|
|
42
67
|
return;
|
|
68
|
+
// Bind the listener to an AbortController so it's removable two ways: when the
|
|
69
|
+
// retry actually fires (one-shot), AND on a TTL timeout if it never does. The
|
|
70
|
+
// `{ signal }` option means a single abort() detaches the listener — no need
|
|
71
|
+
// to hold the handler ref for removeEventListener.
|
|
72
|
+
const ac = new AbortController();
|
|
73
|
+
const ttl = setTimeout(() => ac.abort(), RETRY_ARM_TTL_MS);
|
|
43
74
|
const onRetry = (event) => {
|
|
44
75
|
const detail = event.detail;
|
|
45
76
|
if (detail?.agentId !== agentId)
|
|
46
77
|
return;
|
|
47
|
-
|
|
48
|
-
|
|
78
|
+
clearTimeout(ttl);
|
|
79
|
+
ac.abort();
|
|
80
|
+
// Thread the gated delete through the retry: a handoff that fails first and
|
|
81
|
+
// succeeds on retry must still delete the shared bridge on the success leg.
|
|
82
|
+
runCloudAgentHandoff(agentId, start, onSwitchSucceeded);
|
|
49
83
|
};
|
|
50
|
-
window.addEventListener(CLOUD_HANDOFF_RETRY_EVENT, onRetry
|
|
84
|
+
window.addEventListener(CLOUD_HANDOFF_RETRY_EVENT, onRetry, {
|
|
85
|
+
signal: ac.signal,
|
|
86
|
+
});
|
|
51
87
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Silently re-point the live client from the shared bridge to the dedicated
|
|
3
|
+
* agent — the handoff's "invisible switch".
|
|
4
|
+
*
|
|
5
|
+
* This is the handoff-ONLY alternative to `switchAgentProfile`. The global
|
|
6
|
+
* profile switch (`AppContext.tsx`) intentionally:
|
|
7
|
+
* - `clearAllChatDrafts()` — wipes the composer (conversation ids are
|
|
8
|
+
* per-account, so a manual account switch can't carry a draft over), and
|
|
9
|
+
* - dispatches `SWITCH_AGENT` — which re-enters the startup coordinator
|
|
10
|
+
* (`ready → polling-backend`), a phase that is NOT shell-paintable, so
|
|
11
|
+
* `App.tsx` swaps the whole shell for `<StartupScreen/>` (the full-screen
|
|
12
|
+
* flash).
|
|
13
|
+
* Both are correct for a manual switch but WRONG for the handoff: the dedicated
|
|
14
|
+
* agent already holds the copied transcript on the SAME conversation id, the
|
|
15
|
+
* user is mid-conversation, and the composer may hold an unsent draft. So the
|
|
16
|
+
* handoff re-points in place instead:
|
|
17
|
+
* - persist the dedicated as the active server + profile (so a reboot restores
|
|
18
|
+
* the dedicated, not the shared bridge),
|
|
19
|
+
* - re-point the API/WS base seamlessly via `client.repointBaseUrl` (which
|
|
20
|
+
* reconnects the WS in place — no visible drop, no coordinator re-entry),
|
|
21
|
+
* - set the bearer token,
|
|
22
|
+
* and DELIBERATELY does NOT clear drafts and does NOT dispatch `SWITCH_AGENT`.
|
|
23
|
+
* The chat surface stays mounted on the same conversation id throughout.
|
|
24
|
+
*/
|
|
25
|
+
export declare function silentlyRepointToDedicated(opts: {
|
|
26
|
+
/** The dedicated agent's container base (REST + WS host). */
|
|
27
|
+
containerBase: string;
|
|
28
|
+
/** Bearer token (Steward JWT) — same one the shared bridge used. */
|
|
29
|
+
authToken: string;
|
|
30
|
+
/** The dedicated agent id — persisted so a reboot restores the dedicated. */
|
|
31
|
+
dedicatedAgentId: string;
|
|
32
|
+
}): void;
|
|
33
|
+
//# sourceMappingURL=silent-repoint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"silent-repoint.d.ts","sourceRoot":"","sources":["../../../../../../src/cloud/handoff/silent-repoint.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAC/C,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,gBAAgB,EAAE,MAAM,CAAC;CAC1B,GAAG,IAAI,CA+BP"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { client } from "../../api/index.js";
|
|
2
|
+
import { addAgentProfile, createPersistedActiveServer, savePersistedActiveServer, } from "../../state/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Silently re-point the live client from the shared bridge to the dedicated
|
|
5
|
+
* agent — the handoff's "invisible switch".
|
|
6
|
+
*
|
|
7
|
+
* This is the handoff-ONLY alternative to `switchAgentProfile`. The global
|
|
8
|
+
* profile switch (`AppContext.tsx`) intentionally:
|
|
9
|
+
* - `clearAllChatDrafts()` — wipes the composer (conversation ids are
|
|
10
|
+
* per-account, so a manual account switch can't carry a draft over), and
|
|
11
|
+
* - dispatches `SWITCH_AGENT` — which re-enters the startup coordinator
|
|
12
|
+
* (`ready → polling-backend`), a phase that is NOT shell-paintable, so
|
|
13
|
+
* `App.tsx` swaps the whole shell for `<StartupScreen/>` (the full-screen
|
|
14
|
+
* flash).
|
|
15
|
+
* Both are correct for a manual switch but WRONG for the handoff: the dedicated
|
|
16
|
+
* agent already holds the copied transcript on the SAME conversation id, the
|
|
17
|
+
* user is mid-conversation, and the composer may hold an unsent draft. So the
|
|
18
|
+
* handoff re-points in place instead:
|
|
19
|
+
* - persist the dedicated as the active server + profile (so a reboot restores
|
|
20
|
+
* the dedicated, not the shared bridge),
|
|
21
|
+
* - re-point the API/WS base seamlessly via `client.repointBaseUrl` (which
|
|
22
|
+
* reconnects the WS in place — no visible drop, no coordinator re-entry),
|
|
23
|
+
* - set the bearer token,
|
|
24
|
+
* and DELIBERATELY does NOT clear drafts and does NOT dispatch `SWITCH_AGENT`.
|
|
25
|
+
* The chat surface stays mounted on the same conversation id throughout.
|
|
26
|
+
*/
|
|
27
|
+
export function silentlyRepointToDedicated(opts) {
|
|
28
|
+
const { containerBase, authToken, dedicatedAgentId } = opts;
|
|
29
|
+
// Persist the dedicated as the restorable active server. Keyed by the
|
|
30
|
+
// dedicated id so a re-boot restores the dedicated agent, not the now-stale
|
|
31
|
+
// shared bridge.
|
|
32
|
+
const server = createPersistedActiveServer({
|
|
33
|
+
kind: "cloud",
|
|
34
|
+
id: `cloud:${dedicatedAgentId}`,
|
|
35
|
+
apiBase: containerBase,
|
|
36
|
+
accessToken: authToken,
|
|
37
|
+
});
|
|
38
|
+
savePersistedActiveServer(server);
|
|
39
|
+
// Register + activate the dedicated profile WITHOUT going through
|
|
40
|
+
// switchAgentProfile (which would clear drafts + dispatch SWITCH_AGENT).
|
|
41
|
+
// addAgentProfile sets it active in the registry and persists before
|
|
42
|
+
// returning, so no separate activation step is needed.
|
|
43
|
+
addAgentProfile({
|
|
44
|
+
kind: "cloud",
|
|
45
|
+
label: server.label,
|
|
46
|
+
apiBase: containerBase,
|
|
47
|
+
accessToken: authToken,
|
|
48
|
+
});
|
|
49
|
+
// Seamless in-place base swap: re-point the REST base AND reconnect the WS to
|
|
50
|
+
// the dedicated host without a visible disconnect. The transcript was already
|
|
51
|
+
// copied to the dedicated agent by the handoff supervisor, so the live chat
|
|
52
|
+
// surface stays mounted on the same conversation id with no reload.
|
|
53
|
+
client.setToken(authToken);
|
|
54
|
+
client.repointBaseUrl(containerBase);
|
|
55
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentDetailPage.d.ts","sourceRoot":"","sources":["../../../../../../src/cloud/instances/AgentDetailPage.tsx"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"AgentDetailPage.d.ts","sourceRoot":"","sources":["../../../../../../src/cloud/instances/AgentDetailPage.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AA2EH,MAAM,CAAC,OAAO,UAAU,eAAe,4CAoatC"}
|
|
@@ -6,7 +6,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
6
6
|
import { AGENT_PRICING } from "@elizaos/cloud-shared/lib/constants/agent-pricing";
|
|
7
7
|
import { formatHourlyRate, formatMonthlyEstimate, } from "@elizaos/cloud-shared/lib/constants/agent-pricing-display";
|
|
8
8
|
import { Badge, DashboardErrorState, DashboardLoadingState, } from "@elizaos/ui/cloud-ui";
|
|
9
|
-
import { AlertCircle, ArrowLeft, Cloud, ExternalLink,
|
|
9
|
+
import { AlertCircle, ArrowLeft, Cloud, ExternalLink, Server, Terminal, } from "lucide-react";
|
|
10
10
|
import { Link, Navigate, useParams } from "react-router-dom";
|
|
11
11
|
import { ApiError } from "../lib/api-client.js";
|
|
12
12
|
import { useDocumentTitle } from "../lib/use-document-title.js";
|
|
@@ -97,7 +97,7 @@ export default function AgentDetailPage() {
|
|
|
97
97
|
const showConnect = !!agent.webUiUrl && agent.status === "running";
|
|
98
98
|
return (_jsxs("div", { className: "max-w-5xl mx-auto space-y-6", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs(Link, { to: "/dashboard/agents", className: "group flex items-center gap-2 text-sm text-white/50 hover:text-white transition-colors", children: [_jsx("div", { className: "flex items-center justify-center w-7 h-7 bg-black/40 group-hover:bg-white/10 transition-colors", children: _jsx(ArrowLeft, { className: "h-3.5 w-3.5" }) }), _jsx("span", { children: t("cloud.agents.detail.backToInstances", {
|
|
99
99
|
defaultValue: "Instances",
|
|
100
|
-
}) })] }),
|
|
100
|
+
}) })] }), _jsx("div", { className: "flex items-center gap-2", children: showConnect && _jsx(ElizaConnectButton, { agentId: agent.id }) })] }), _jsx("div", { className: "space-y-4", children: _jsxs("div", { className: "flex items-start gap-4", children: [_jsx("div", { className: "flex items-center justify-center w-12 h-12 border border-[var(--brand-orange)]/25 bg-[var(--brand-orange)]/10 shrink-0", children: isDockerBacked ? (_jsx(Server, { className: "h-6 w-6 text-[var(--brand-orange)]" })) : (_jsx(Cloud, { className: "h-6 w-6 text-[var(--brand-orange)]" })) }), _jsxs("div", { className: "min-w-0 space-y-1.5", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2.5", children: [_jsx("h1", { className: "text-2xl font-semibold text-white truncate", style: { fontFamily: "var(--font-roboto-mono)" }, children: agent.agentName ??
|
|
101
101
|
t("cloud.agents.detail.unnamedAgent", {
|
|
102
102
|
defaultValue: "Unnamed Agent",
|
|
103
103
|
}) }), _jsxs(Badge, { variant: "outline", className: `${badgeColor} text-xs font-medium px-2 py-0.5`, children: [_jsx("span", { className: `inline-block size-1.5 rounded-full mr-1.5 ${dotColor}` }), agent.status] })] }), _jsx("div", { className: "flex items-center gap-3 text-xs text-white/35", children: _jsx("span", { className: "font-mono tabular-nums", children: agent.id }) })] })] }) }), _jsxs("div", { className: "grid grid-cols-2 lg:grid-cols-5 gap-px bg-white/5 border border-white/10", children: [_jsxs("div", { className: "bg-black/60 p-4 space-y-1", children: [_jsx("p", { className: "text-[11px] uppercase tracking-[0.2em] text-white/35", children: t("cloud.agents.detail.statusLabel", { defaultValue: "Status" }) }), _jsx("p", { className: "text-lg font-medium text-white capitalize tabular-nums", style: { fontFamily: "var(--font-roboto-mono)" }, children: agent.status })] }), _jsxs("div", { className: "bg-black/60 p-4 space-y-1", children: [_jsx("p", { className: "text-[11px] uppercase tracking-[0.2em] text-white/35", children: t("cloud.agents.detail.databaseLabel", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-actions.d.ts","sourceRoot":"","sources":["../../../../../../../src/cloud/instances/components/agent-actions.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-actions.d.ts","sourceRoot":"","sources":["../../../../../../../src/cloud/instances/components/agent-actions.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAC;AAmBpF,UAAU,sBAAsB;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,kBAAkB,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,aAAa,EACb,MAAM,EACN,QAAQ,GACT,EAAE,sBAAsB,2CAwZxB"}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"use client";
|
|
14
14
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
15
15
|
import { BrandButton, BrandCard } from "@elizaos/ui/cloud-ui";
|
|
16
|
-
import { Camera, ExternalLink, Loader2,
|
|
16
|
+
import { Camera, ExternalLink, Loader2, Moon, Pause, Play, Sun, Trash2, } from "lucide-react";
|
|
17
17
|
import { useRef, useState } from "react";
|
|
18
18
|
import { useNavigate } from "react-router-dom";
|
|
19
19
|
import { toast } from "sonner";
|
|
@@ -61,7 +61,6 @@ export function ElizaAgentActions({ agentId, executionTier, status, webUiUrl, })
|
|
|
61
61
|
const isSleeping = effectiveStatus === "sleeping";
|
|
62
62
|
const isDedicated = executionTier !== "shared";
|
|
63
63
|
const hasStandaloneWebUi = isRunning && isDedicated && Boolean(webUiUrl);
|
|
64
|
-
const hasDashboardChat = isRunning;
|
|
65
64
|
// Sleep (deep cold suspend) only applies to dedicated agents with their own
|
|
66
65
|
// compute slot — shared-runtime agents have nothing to free.
|
|
67
66
|
const canSleep = isRunning && isDedicated;
|
|
@@ -197,8 +196,6 @@ export function ElizaAgentActions({ agentId, executionTier, status, webUiUrl, })
|
|
|
197
196
|
defaultValue: "Agent Actions",
|
|
198
197
|
}) })] }), _jsxs("div", { className: "flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between", children: [_jsxs("div", { className: "flex flex-wrap gap-3", children: [hasStandaloneWebUi && (_jsxs(BrandButton, { variant: "primary", size: "sm", onClick: () => void openWebUIWithPairing(agentId), children: [_jsx(ExternalLink, { className: "h-4 w-4" }), t("cloud.containers.agentActions.openWebUi", {
|
|
199
198
|
defaultValue: "Open Web UI",
|
|
200
|
-
})] })), hasDashboardChat && (_jsxs(BrandButton, { variant: "primary", size: "sm", onClick: () => navigate(`/dashboard/agents/${agentId}/chat`), children: [_jsx(MessageCircle, { className: "h-4 w-4" }), t("cloud.containers.agentActions.chat", {
|
|
201
|
-
defaultValue: "Chat",
|
|
202
199
|
})] })), isStopped && (_jsxs(BrandButton, { variant: "primary", size: "sm", onClick: () => doAction("resume"), disabled: !!loading || isBusy, children: [loading === "resume" ? (_jsx(Loader2, { className: "h-4 w-4 animate-spin" })) : (_jsx(Play, { className: "h-4 w-4" })), t("cloud.containers.agentActions.resume", {
|
|
203
200
|
defaultValue: "Resume Agent",
|
|
204
201
|
})] })), canWake && (_jsxs(BrandButton, { variant: "primary", size: "sm", onClick: () => doAction("wake"), disabled: !!loading || isBusy, children: [loading === "wake" ? (_jsx(Loader2, { className: "h-4 w-4 animate-spin" })) : (_jsx(Sun, { className: "h-4 w-4" })), t("cloud.containers.agentActions.wake", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eliza-agents-table.d.ts","sourceRoot":"","sources":["../../../../../../../src/cloud/instances/components/eliza-agents-table.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"eliza-agents-table.d.ts","sourceRoot":"","sources":["../../../../../../../src/cloud/instances/components/eliza-agents-table.tsx"],"names":[],"mappings":"AAuEA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,CAAC,EAAE,QAAQ,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,QAAQ,CAAC;IAC7E,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,iBAAiB,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;IACxC,UAAU,EAAE,IAAI,GAAG,MAAM,CAAC;IAC1B,UAAU,EAAE,IAAI,GAAG,MAAM,CAAC;CAC3B;AAED,UAAU,qBAAqB;IAC7B,SAAS,EAAE,aAAa,EAAE,CAAC;CAC5B;AAuGD,wBAAgB,gBAAgB,CAAC,EAC/B,SAAS,EAAE,gBAAgB,GAC5B,EAAE,qBAAqB,2CAk/BvB"}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"use client";
|
|
9
9
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
10
|
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, Badge, DashboardDataList, DashboardDataListDesktop, DashboardDataListFilteredCount, DashboardDataListMobile, DataListEmptyState, Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@elizaos/ui/cloud-ui";
|
|
11
|
-
import { ArrowUpDown, Boxes, Cloud, ExternalLink, FileText, Loader2,
|
|
11
|
+
import { ArrowUpDown, Boxes, Cloud, ExternalLink, FileText, Loader2, Pause, Play, Search, Server, Trash2, } from "lucide-react";
|
|
12
12
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
13
13
|
import { toast } from "sonner";
|
|
14
14
|
import { useT } from "../lib/i18n.js";
|
|
@@ -425,7 +425,6 @@ export function ElizaAgentsTable({ sandboxes: initialSandboxes, }) {
|
|
|
425
425
|
const hasStandaloneWebUi = displayStatus === "running" &&
|
|
426
426
|
sb.execution_tier !== "shared" &&
|
|
427
427
|
Boolean(sb.canonical_web_ui_url);
|
|
428
|
-
const hasDashboardChat = displayStatus === "running";
|
|
429
428
|
return (_jsxs(TableRow, { className: "hover:bg-white/[0.03] transition-colors border-b border-white/5", children: [_jsx(TableCell, { children: _jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsx("a", { href: `/dashboard/agents/${sb.id}`, className: "font-medium text-white hover:opacity-75 transition-opacity", children: sb.agent_name ??
|
|
430
429
|
t("cloud.elizaAgentsTable.unnamedAgent", {
|
|
431
430
|
defaultValue: "Unnamed Agent",
|
|
@@ -455,9 +454,6 @@ export function ElizaAgentsTable({ sandboxes: initialSandboxes, }) {
|
|
|
455
454
|
defaultValue: "Not provisioned",
|
|
456
455
|
}) }) }), _jsx(TableCell, { children: hasStandaloneWebUi ? (_jsxs("button", { type: "button", onClick: () => openWebUIWithPairing(sb.id), className: "inline-flex items-center gap-1 text-xs text-white/60 hover:text-white transition-colors bg-transparent border-0 p-0", children: [_jsx(ExternalLink, { className: "h-3 w-3" }), t("cloud.elizaAgentsTable.open", {
|
|
457
456
|
defaultValue: "Open",
|
|
458
|
-
})] })) : hasDashboardChat &&
|
|
459
|
-
sb.execution_tier === "shared" ? (_jsxs("a", { href: `/dashboard/agents/${sb.id}/chat`, className: "inline-flex items-center gap-1 text-xs text-white/60 hover:text-white transition-colors", children: [_jsx(MessageCircle, { className: "h-3 w-3" }), t("cloud.elizaAgentsTable.chat", {
|
|
460
|
-
defaultValue: "Chat",
|
|
461
457
|
})] })) : (_jsx("span", { className: "text-xs text-white/20", children: displayStatus === "running" &&
|
|
462
458
|
sb.execution_tier !== "shared"
|
|
463
459
|
? t("cloud.elizaAgentsTable.unavailable", {
|
|
@@ -470,8 +466,6 @@ export function ElizaAgentsTable({ sandboxes: initialSandboxes, }) {
|
|
|
470
466
|
defaultValue: "View details",
|
|
471
467
|
}) })] }), hasStandaloneWebUi && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => openWebUIWithPairing(sb.id), className: "p-2 text-white/30 hover:text-white hover:bg-white/10 transition-colors", children: _jsx(ExternalLink, { className: "h-4 w-4" }) }) }), _jsx(TooltipContent, { className: "bg-neutral-900 border-white/10", children: t("cloud.elizaAgentsTable.openWebUi", {
|
|
472
468
|
defaultValue: "Open Web UI",
|
|
473
|
-
}) })] })), hasDashboardChat && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("a", { href: `/dashboard/agents/${sb.id}/chat`, className: "p-2 text-white/30 hover:text-white hover:bg-white/10 transition-colors", children: _jsx(MessageCircle, { className: "h-4 w-4" }) }) }), _jsx(TooltipContent, { className: "bg-neutral-900 border-white/10", children: t("cloud.elizaAgentsTable.openChat", {
|
|
474
|
-
defaultValue: "Open chat",
|
|
475
469
|
}) })] })), canStart && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => handleProvision(sb.id), disabled: busy, className: "p-2 text-white/30 hover:text-green-400 hover:bg-green-500/10 transition-colors disabled:opacity-30", children: _jsx(Play, { className: "h-4 w-4" }) }) }), _jsx(TooltipContent, { className: "bg-neutral-900 border-white/10", children: t("cloud.elizaAgentsTable.resumeAgent", {
|
|
476
470
|
defaultValue: "Resume agent",
|
|
477
471
|
}) })] })), canStop && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: () => handleSuspend(sb.id), disabled: busy, className: "p-2 text-white/30 hover:text-white hover:bg-white/10 transition-colors disabled:opacity-30", children: _jsx(Pause, { className: "h-4 w-4" }) }) }), _jsx(TooltipContent, { className: "bg-neutral-900 border-white/10", children: t("cloud.elizaAgentsTable.suspendAgent", {
|
|
@@ -494,7 +488,6 @@ export function ElizaAgentsTable({ sandboxes: initialSandboxes, }) {
|
|
|
494
488
|
const hasStandaloneWebUi = displayStatus === "running" &&
|
|
495
489
|
sb.execution_tier !== "shared" &&
|
|
496
490
|
Boolean(sb.canonical_web_ui_url);
|
|
497
|
-
const hasDashboardChat = displayStatus === "running";
|
|
498
491
|
return (_jsxs("div", { className: "border border-white/10 bg-black/40 p-4 space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0 space-y-1", children: [_jsx("a", { href: `/dashboard/agents/${sb.id}`, className: "font-medium text-white hover:opacity-75 transition-opacity block truncate", children: sb.agent_name ??
|
|
499
492
|
t("cloud.elizaAgentsTable.unnamedAgent", {
|
|
500
493
|
defaultValue: "Unnamed Agent",
|
|
@@ -515,8 +508,6 @@ export function ElizaAgentsTable({ sandboxes: initialSandboxes, }) {
|
|
|
515
508
|
defaultValue: "Details",
|
|
516
509
|
})] }), hasStandaloneWebUi && (_jsxs("button", { type: "button", onClick: () => openWebUIWithPairing(sb.id), className: "flex-1 flex items-center justify-center gap-1.5 py-2 text-xs text-[var(--brand-orange)] hover:bg-white/5 transition-colors", children: [_jsx(ExternalLink, { className: "h-3.5 w-3.5" }), t("cloud.elizaAgentsTable.webUi", {
|
|
517
510
|
defaultValue: "Web UI",
|
|
518
|
-
})] })), hasDashboardChat && (_jsxs("a", { href: `/dashboard/agents/${sb.id}/chat`, className: "flex-1 flex items-center justify-center gap-1.5 py-2 text-xs text-[var(--brand-orange)] hover:bg-white/5 transition-colors", children: [_jsx(MessageCircle, { className: "h-3.5 w-3.5" }), t("cloud.elizaAgentsTable.chat", {
|
|
519
|
-
defaultValue: "Chat",
|
|
520
511
|
})] })), canStart && (_jsx("button", { type: "button", onClick: () => handleProvision(sb.id), disabled: busy, className: "py-2 px-3 text-green-400 hover:bg-green-500/10 transition-colors disabled:opacity-30", children: _jsx(Play, { className: "h-3.5 w-3.5" }) })), canStop && (_jsx("button", { type: "button", onClick: () => handleSuspend(sb.id), disabled: busy, className: "py-2 px-3 text-orange-400 hover:bg-white/5 transition-colors disabled:opacity-30", children: _jsx(Pause, { className: "h-3.5 w-3.5" }) })), _jsx("button", { type: "button", onClick: () => !busy && setDeleteId(sb.id), disabled: isDeleting || busy, className: "py-2 px-3 text-white/30 hover:text-red-400 hover:bg-red-500/10 transition-colors disabled:opacity-30", children: _jsx(Trash2, { className: "h-3.5 w-3.5" }) })] })] }, sb.id));
|
|
521
512
|
})) })] }), _jsx(AlertDialog, { open: deleteId !== null, onOpenChange: () => setDeleteId(null), children: _jsxs(AlertDialogContent, { className: "bg-neutral-900 border-white/10", children: [_jsxs(AlertDialogHeader, { children: [_jsx(AlertDialogTitle, { className: "text-white", children: t("cloud.elizaAgentsTable.deleteAgentTitle", {
|
|
522
513
|
defaultValue: "Delete Agent",
|