@elizaos/agent 2.0.0-alpha.429 → 2.0.0-alpha.430
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/package.json +4 -4
- package/packages/agent/src/api/accounts-routes.js +21 -6
- package/packages/app-core/src/components/accounts/AccountList.d.ts.map +1 -1
- package/packages/app-core/src/components/accounts/AccountList.js +25 -8
- package/packages/app-core/src/components/accounts/AddAccountDialog.d.ts.map +1 -1
- package/packages/app-core/src/components/accounts/AddAccountDialog.js +67 -1
- package/packages/app-core/src/components/settings/ProviderSwitcher.d.ts.map +1 -1
- package/packages/app-core/src/components/settings/ProviderSwitcher.js +11 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elizaos/agent",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.430",
|
|
4
4
|
"description": "Standalone elizaOS-based agent and backend server package.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -467,7 +467,7 @@
|
|
|
467
467
|
"@elizaos/app-steward": "^0.0.0",
|
|
468
468
|
"@elizaos/app-task-coordinator": "^0.0.0",
|
|
469
469
|
"@elizaos/app-training": "^0.0.1",
|
|
470
|
-
"@elizaos/core": "^2.0.0-alpha.
|
|
470
|
+
"@elizaos/core": "^2.0.0-alpha.430",
|
|
471
471
|
"@elizaos/plugin-agent-orchestrator": "^0.6.2-alpha.0",
|
|
472
472
|
"@elizaos/plugin-browser-bridge": "^0.1.0",
|
|
473
473
|
"@elizaos/plugin-local-embedding": "^2.0.0-alpha.12",
|
|
@@ -476,8 +476,8 @@
|
|
|
476
476
|
"@elizaos/plugin-solana": "^2.0.0-alpha.6",
|
|
477
477
|
"@elizaos/plugin-sql": "^2.0.0-alpha.19",
|
|
478
478
|
"@elizaos/plugin-wechat": "^0.1.0",
|
|
479
|
-
"@elizaos/shared": "^2.0.0-alpha.
|
|
480
|
-
"@elizaos/skills": "^2.0.0-alpha.
|
|
479
|
+
"@elizaos/shared": "^2.0.0-alpha.430",
|
|
480
|
+
"@elizaos/skills": "^2.0.0-alpha.430",
|
|
481
481
|
"@hapi/boom": "^10.0.1",
|
|
482
482
|
"@noble/curves": "^2.0.1",
|
|
483
483
|
"@solana/web3.js": "^1.98.4",
|
|
@@ -426,14 +426,29 @@ async function handleOAuthRoutes(ctx, providerId, rest) {
|
|
|
426
426
|
error(res, parsed.error.issues[0]?.message ?? "Invalid body", 400);
|
|
427
427
|
return true;
|
|
428
428
|
}
|
|
429
|
-
// Reserve an accountId
|
|
430
|
-
//
|
|
429
|
+
// Reserve an accountId up front so the OAuth flow can wire it
|
|
430
|
+
// into the credential record before any token exchange completes.
|
|
431
|
+
// Priority is computed AT SAVE TIME, not now: pre-allocating leaks
|
|
432
|
+
// a stale priority if two users start parallel OAuth flows before
|
|
433
|
+
// either completes (both would get the same number). Computing in
|
|
434
|
+
// the post-save hook is monotonic regardless of concurrency since
|
|
435
|
+
// the on-disk credential file appears strictly before the hook
|
|
436
|
+
// fires.
|
|
431
437
|
const accountId = nodeCrypto.randomUUID();
|
|
432
438
|
const pool = await getPool();
|
|
433
|
-
const
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
439
|
+
const onAccountSaved = async (record) => {
|
|
440
|
+
// Exclude the just-saved record from the priority calc — its
|
|
441
|
+
// credential file already exists on disk so `pool.list` would
|
|
442
|
+
// include it at a default priority (createdAt-sorted index),
|
|
443
|
+
// which would push the new max one too high.
|
|
444
|
+
const others = pool
|
|
445
|
+
.list(providerId)
|
|
446
|
+
.filter((a) => a.id !== record.id);
|
|
447
|
+
const livePriority = others.length === 0
|
|
448
|
+
? 0
|
|
449
|
+
: Math.max(...others.map((a) => a.priority)) + 1;
|
|
450
|
+
const linkedConfig = buildLinkedAccountConfigFromRecord(record, livePriority);
|
|
451
|
+
await pool.upsert(linkedConfig);
|
|
437
452
|
};
|
|
438
453
|
const startFlow = subscription === "anthropic-subscription"
|
|
439
454
|
? startAnthropicOAuthFlow
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccountList.d.ts","sourceRoot":"","sources":["../../../../../../../app-core/src/components/accounts/AccountList.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAU/D,UAAU,gBAAgB;IACxB,UAAU,EAAE,uBAAuB,CAAC;CACrC;AAOD,wBAAgB,WAAW,CAAC,EAAE,UAAU,EAAE,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"AccountList.d.ts","sourceRoot":"","sources":["../../../../../../../app-core/src/components/accounts/AccountList.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAU/D,UAAU,gBAAgB;IACxB,UAAU,EAAE,uBAAuB,CAAC;CACrC;AAOD,wBAAgB,WAAW,CAAC,EAAE,UAAU,EAAE,EAAE,gBAAgB,2CA6J3D"}
|
|
@@ -44,16 +44,33 @@ export function AccountList({ providerId }) {
|
|
|
44
44
|
const neighbour = sorted[neighbourIndex];
|
|
45
45
|
if (!self || !neighbour || self.priority === neighbour.priority)
|
|
46
46
|
return;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
//
|
|
50
|
-
//
|
|
47
|
+
const selfOriginal = self.priority;
|
|
48
|
+
const neighbourOriginal = neighbour.priority;
|
|
49
|
+
// Swap priorities via two sequential PATCHes. There's no atomic
|
|
50
|
+
// server-side swap, so on failure of the second call we roll the
|
|
51
|
+
// first one back so the user doesn't end up with two accounts at
|
|
52
|
+
// the same priority. Worst case a partial-failure leaves the
|
|
53
|
+
// original ordering with a flash; never a corrupted ordering.
|
|
51
54
|
await accounts.patch(providerId, self.id, {
|
|
52
|
-
priority:
|
|
53
|
-
});
|
|
54
|
-
await accounts.patch(providerId, neighbour.id, {
|
|
55
|
-
priority: self.priority,
|
|
55
|
+
priority: neighbourOriginal,
|
|
56
56
|
});
|
|
57
|
+
try {
|
|
58
|
+
await accounts.patch(providerId, neighbour.id, {
|
|
59
|
+
priority: selfOriginal,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
try {
|
|
64
|
+
await accounts.patch(providerId, self.id, {
|
|
65
|
+
priority: selfOriginal,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// Rollback failed — refresh will reconcile from server state.
|
|
70
|
+
void accounts.refresh();
|
|
71
|
+
}
|
|
72
|
+
throw err;
|
|
73
|
+
}
|
|
57
74
|
}, [accounts, providerId, sorted]);
|
|
58
75
|
if (accounts.loading && !accounts.data) {
|
|
59
76
|
return (_jsxs("div", { className: "mt-3 flex items-center gap-2 text-xs text-muted", children: [_jsx(Spinner, { className: "h-3 w-3" }), t("accounts.loading", { defaultValue: "Loading accounts…" })] }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AddAccountDialog.d.ts","sourceRoot":"","sources":["../../../../../../../app-core/src/components/accounts/AddAccountDialog.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAeH,OAAO,KAAK,EACV,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,iBAAiB,CAAC;AAYzB,UAAU,qBAAqB;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,uBAAuB,CAAC;IACpC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;CACnD;AAoDD,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,UAAU,EACV,OAAO,EACP,SAAS,GACV,EAAE,qBAAqB,
|
|
1
|
+
{"version":3,"file":"AddAccountDialog.d.ts","sourceRoot":"","sources":["../../../../../../../app-core/src/components/accounts/AddAccountDialog.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAeH,OAAO,KAAK,EACV,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,iBAAiB,CAAC;AAYzB,UAAU,qBAAqB;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,uBAAuB,CAAC;IACpC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;CACnD;AAoDD,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,UAAU,EACV,OAAO,EACP,SAAS,GACV,EAAE,qBAAqB,2CAwdvB"}
|
|
@@ -67,6 +67,14 @@ export function AddAccountDialog({ open, providerId, onClose, onCreated, }) {
|
|
|
67
67
|
const [sessionId, setSessionId] = useState(null);
|
|
68
68
|
const eventSourceRef = useRef(null);
|
|
69
69
|
const sessionIdRef = useRef(null);
|
|
70
|
+
// Mirrors the `open` prop in a ref so async paths (`startOAuth` mid-
|
|
71
|
+
// await) can detect that the dialog was closed before
|
|
72
|
+
// `client.startAccountOAuth` resolved and immediately cancel the
|
|
73
|
+
// freshly-created server-side flow.
|
|
74
|
+
const openRef = useRef(open);
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
openRef.current = open;
|
|
77
|
+
}, [open]);
|
|
70
78
|
const closeEventSource = useCallback(() => {
|
|
71
79
|
if (eventSourceRef.current) {
|
|
72
80
|
eventSourceRef.current.close();
|
|
@@ -114,10 +122,28 @@ export function AddAccountDialog({ open, providerId, onClose, onCreated, }) {
|
|
|
114
122
|
const url = `/api/accounts/${providerId}/oauth/status?sessionId=${encodeURIComponent(newSessionId)}`;
|
|
115
123
|
const source = new EventSource(url);
|
|
116
124
|
eventSourceRef.current = source;
|
|
125
|
+
// EventSource auto-reconnects on transient network blips, which
|
|
126
|
+
// is fine. But persistent failures (server gone, route 404) just
|
|
127
|
+
// toggle readyState=2 forever and the user is stuck on "Waiting
|
|
128
|
+
// for browser…". Surface that after a small grace period so the
|
|
129
|
+
// user can retry instead of staring at a spinner.
|
|
130
|
+
let connectedOnce = false;
|
|
131
|
+
let persistentErrorTimer = null;
|
|
132
|
+
const cancelPersistentErrorTimer = () => {
|
|
133
|
+
if (persistentErrorTimer) {
|
|
134
|
+
clearTimeout(persistentErrorTimer);
|
|
135
|
+
persistentErrorTimer = null;
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
source.onopen = () => {
|
|
139
|
+
connectedOnce = true;
|
|
140
|
+
cancelPersistentErrorTimer();
|
|
141
|
+
};
|
|
117
142
|
source.onmessage = (event) => {
|
|
118
143
|
try {
|
|
119
144
|
const data = JSON.parse(event.data);
|
|
120
145
|
if (data.status === "success" && data.account) {
|
|
146
|
+
cancelPersistentErrorTimer();
|
|
121
147
|
closeEventSource();
|
|
122
148
|
sessionIdRef.current = null;
|
|
123
149
|
onCreated(data.account);
|
|
@@ -126,6 +152,7 @@ export function AddAccountDialog({ open, providerId, onClose, onCreated, }) {
|
|
|
126
152
|
else if (data.status === "error" ||
|
|
127
153
|
data.status === "cancelled" ||
|
|
128
154
|
data.status === "timeout") {
|
|
155
|
+
cancelPersistentErrorTimer();
|
|
129
156
|
closeEventSource();
|
|
130
157
|
sessionIdRef.current = null;
|
|
131
158
|
setErrorMessage(data.error ??
|
|
@@ -144,7 +171,24 @@ export function AddAccountDialog({ open, providerId, onClose, onCreated, }) {
|
|
|
144
171
|
}
|
|
145
172
|
};
|
|
146
173
|
source.onerror = () => {
|
|
147
|
-
//
|
|
174
|
+
// EventSource readyState: 0=connecting, 1=open, 2=closed.
|
|
175
|
+
// If we're at 2 and never got an `onopen`, the route is
|
|
176
|
+
// unreachable. Give the browser ~5s to retry; if it can't
|
|
177
|
+
// recover, surface the error.
|
|
178
|
+
if (persistentErrorTimer)
|
|
179
|
+
return;
|
|
180
|
+
persistentErrorTimer = setTimeout(() => {
|
|
181
|
+
persistentErrorTimer = null;
|
|
182
|
+
if (!connectedOnce &&
|
|
183
|
+
eventSourceRef.current?.readyState === EventSource.CLOSED) {
|
|
184
|
+
closeEventSource();
|
|
185
|
+
sessionIdRef.current = null;
|
|
186
|
+
setErrorMessage(t("accounts.add.oauth.sseUnreachable", {
|
|
187
|
+
defaultValue: "Lost connection to the OAuth status stream. Try again.",
|
|
188
|
+
}));
|
|
189
|
+
setStep("error");
|
|
190
|
+
}
|
|
191
|
+
}, 5_000);
|
|
148
192
|
};
|
|
149
193
|
}, [closeEventSource, onClose, onCreated, providerId, t]);
|
|
150
194
|
const startOAuth = useCallback(async () => {
|
|
@@ -159,6 +203,28 @@ export function AddAccountDialog({ open, providerId, onClose, onCreated, }) {
|
|
|
159
203
|
const flow = await client.startAccountOAuth(providerId, {
|
|
160
204
|
label: label.trim(),
|
|
161
205
|
});
|
|
206
|
+
// The dialog might have been closed between user clicking "Sign
|
|
207
|
+
// in" and the server returning the flow handle. If so, the
|
|
208
|
+
// server-side OAuth listener is orphaned — cancel it explicitly
|
|
209
|
+
// so the loopback port releases immediately instead of timing
|
|
210
|
+
// out in 5 minutes.
|
|
211
|
+
if (!openRef.current) {
|
|
212
|
+
try {
|
|
213
|
+
await client.cancelAccountOAuth(providerId, {
|
|
214
|
+
sessionId: flow.sessionId,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
// Best-effort.
|
|
219
|
+
}
|
|
220
|
+
try {
|
|
221
|
+
win?.close();
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
// Cross-origin — ignore.
|
|
225
|
+
}
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
162
228
|
navigatePreOpenedWindow(win, flow.authUrl);
|
|
163
229
|
sessionIdRef.current = flow.sessionId;
|
|
164
230
|
setSessionId(flow.sessionId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProviderSwitcher.d.ts","sourceRoot":"","sources":["../../../../../../../app-core/src/components/settings/ProviderSwitcher.tsx"],"names":[],"mappings":"AAkCA,OAAO,EAAkC,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAahF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAqBhD,UAAU,UAAU;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CAC9C;AASD,UAAU,qBAAqB;IAC7B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,sBAAsB,CAAC,EAAE,CACvB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAwJD,wBAAgB,gBAAgB,CAAC,KAAK,GAAE,qBAA0B,
|
|
1
|
+
{"version":3,"file":"ProviderSwitcher.d.ts","sourceRoot":"","sources":["../../../../../../../app-core/src/components/settings/ProviderSwitcher.tsx"],"names":[],"mappings":"AAkCA,OAAO,EAAkC,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAahF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAqBhD,UAAU,UAAU;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CAC9C;AASD,UAAU,qBAAqB;IAC7B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,sBAAsB,CAAC,EAAE,CACvB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAwJD,wBAAgB,gBAAgB,CAAC,KAAK,GAAE,qBAA0B,2CAg8BjE"}
|
|
@@ -568,6 +568,16 @@ export function ProviderSwitcher(props = {}) {
|
|
|
568
568
|
(largeModelOptions.length > 0 || cloudModelSchema) ? (_jsxs("div", { className: "border-border/40 border-t px-4 py-4 sm:px-5", children: [largeModelOptions.length > 0 ? (_jsxs("div", { children: [_jsx("label", { htmlFor: "provider-switcher-primary-model", className: "mb-1.5 block text-muted text-xs font-medium uppercase tracking-wider", children: t("providerswitcher.model", { defaultValue: "Model" }) }), _jsxs(Select, { value: currentLargeModel || "", onValueChange: (v) => handleModelFieldChange("large", v), children: [_jsx(SelectTrigger, { id: "provider-switcher-primary-model", className: "h-9 w-full max-w-sm rounded-lg border border-border bg-card text-sm", children: _jsx(SelectValue, { placeholder: t("providerswitcher.chooseModel", {
|
|
569
569
|
defaultValue: "Choose a model",
|
|
570
570
|
}) }) }), _jsx(SelectContent, { className: "max-h-64", children: largeModelOptions.map((model) => (_jsx(SelectItem, { value: model.id, children: model.name }, model.id))) })] })] })) : null, cloudModelSchema ? (_jsx(AdvancedSettingsDisclosure, { title: "Model overrides", className: "mt-4", children: _jsx(ConfigRenderer, { schema: cloudModelSchema.schema, hints: cloudModelSchema.hints, values: modelValues.values, setKeys: modelValues.setKeys, registry: defaultRegistry, onChange: handleModelFieldChange }) })) : null, _jsxs("div", { className: "mt-2 flex items-center justify-between gap-2", children: [_jsx("p", { className: "text-muted text-xs-tight", children: t("providerswitcher.restartRequiredHint", appNameInterpolationVars(branding)) }), _jsxs("div", { className: "flex items-center gap-2", children: [modelSaving && (_jsx("span", { className: "inline-flex items-center text-muted", title: t("providerswitcher.savingRestarting"), role: "status", "aria-label": t("providerswitcher.savingRestarting"), children: _jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" }) })), modelSaveSuccess && (_jsx("span", { className: "inline-flex items-center text-ok", title: t("providerswitcher.savedRestartingAgent"), role: "status", "aria-label": t("providerswitcher.savedRestartingAgent"), children: _jsx(CheckCircle2, { className: "h-3.5 w-3.5" }) }))] })] })] })) : null] })) : null, isSubscriptionProviderSelectionId(visibleProviderPanelId) ? (_jsxs("div", { className: "min-w-0", children: [_jsx(ProviderPanelHeader, { icon: KeyRound, title: getSubscriptionProviderLabel(SUBSCRIPTION_PROVIDER_SELECTIONS.find((provider) => provider.id === visibleProviderPanelId) ?? SUBSCRIPTION_PROVIDER_SELECTIONS[0], t), description: "Connect subscription-backed access for models and task agents.", children: cloudCallsDisabled ||
|
|
571
|
-
resolvedSelectedId !== visibleProviderPanelId ? (_jsx(Button, { type: "button", variant: "outline", className: "h-8 rounded-lg px-2.5 text-xs", onClick: () => void handleSelectSubscription(visibleProviderPanelId), children: "Use subscription" })) : null }), _jsxs("div", { className: "px-3 py-3 sm:px-4", children: [cloudCallsDisabled ? (_jsx("div", { className: "mb-3 rounded-lg border border-warn/30 bg-warn/5 px-3 py-2 text-warn text-xs-tight", children: "Local-only active. Remote subscription routing is paused." })) : null, _jsx(SubscriptionStatus, { resolvedSelectedId: visibleProviderPanelId, subscriptionStatus: subscriptionStatus, anthropicConnected: anthropicConnected, setAnthropicConnected: setAnthropicConnected, anthropicCliDetected: anthropicCliDetected, openaiConnected: openaiConnected, setOpenaiConnected: setOpenaiConnected, handleSelectSubscription: handleSelectSubscription, loadSubscriptionStatus: loadSubscriptionStatus }),
|
|
571
|
+
resolvedSelectedId !== visibleProviderPanelId ? (_jsx(Button, { type: "button", variant: "outline", className: "h-8 rounded-lg px-2.5 text-xs", onClick: () => void handleSelectSubscription(visibleProviderPanelId), children: "Use subscription" })) : null }), _jsxs("div", { className: "px-3 py-3 sm:px-4", children: [cloudCallsDisabled ? (_jsx("div", { className: "mb-3 rounded-lg border border-warn/30 bg-warn/5 px-3 py-2 text-warn text-xs-tight", children: "Local-only active. Remote subscription routing is paused." })) : null, _jsx(SubscriptionStatus, { resolvedSelectedId: visibleProviderPanelId, subscriptionStatus: subscriptionStatus, anthropicConnected: anthropicConnected, setAnthropicConnected: setAnthropicConnected, anthropicCliDetected: anthropicCliDetected, openaiConnected: openaiConnected, setOpenaiConnected: setOpenaiConnected, handleSelectSubscription: handleSelectSubscription, loadSubscriptionStatus: loadSubscriptionStatus }), (() => {
|
|
572
|
+
const selection = SUBSCRIPTION_PROVIDER_SELECTIONS.find((p) => p.id === visibleProviderPanelId);
|
|
573
|
+
// The outer `isSubscriptionProviderSelectionId` guard
|
|
574
|
+
// makes this lookup non-null in practice; the explicit
|
|
575
|
+
// null check is defensive against future panel ids
|
|
576
|
+
// that pass the guard but aren't in the selections
|
|
577
|
+
// table (e.g. a renamed enum left half-migrated).
|
|
578
|
+
if (!selection)
|
|
579
|
+
return null;
|
|
580
|
+
return _jsx(AccountList, { providerId: selection.storedProvider });
|
|
581
|
+
})()] })] })) : null, selectedPanelProvider ? (_jsxs("div", { className: "min-w-0", children: [_jsx(ProviderPanelHeader, { icon: KeyRound, title: apiProviderChoices.find((choice) => choice.id === visibleProviderPanelId)?.label ?? selectedPanelProvider.name, description: "Use your own provider API key and model routing.", children: cloudCallsDisabled ||
|
|
572
582
|
resolvedSelectedId !== visibleProviderPanelId ? (_jsx(Button, { type: "button", variant: "outline", className: "h-8 rounded-lg px-2.5 text-xs", onClick: () => void handleSwitchProvider(visibleProviderPanelId), children: "Use provider" })) : null }), _jsxs("div", { className: "px-3 py-3 sm:px-4", children: [cloudCallsDisabled ? (_jsx("div", { className: "mb-3 rounded-lg border border-warn/30 bg-warn/5 px-3 py-2 text-warn text-xs-tight", children: "Local-only active. Remote API routing is paused." })) : null, _jsx(ApiKeyConfig, { selectedProvider: selectedPanelProvider, pluginSaving: pluginSaving, pluginSaveSuccess: pluginSaveSuccess, handlePluginConfigSave: handlePluginConfigSave, loadPlugins: loadPlugins })] })] })) : null] })] }));
|
|
573
583
|
}
|