@amd-gaia/agent-ui 0.25.4-rc.13 → 0.25.4-rc.15

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.
@@ -1 +1 @@
1
- import{K as e}from"./useT-TIhGZVZ6.js";var t={name:`message-square`,size:24,node:[[`path`,{d:`M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z`,key:`18887p`}]]};t.node;var n=e(t),r={name:`zap`,size:24,node:[[`path`,{d:`M15.914 4a1.5 1.5 0 00-2.474-1.561l-9 9A1.5 1.5 0 005.5 14h4.002a.5.5 0 01.471.666L8.086 20a1.5 1.5 0 002.475 1.56l9-9A1.5 1.5 0 0018.5 10h-3.997a.5.5 0 01-.472-.667z`,key:`1v7up4`}]]};r.node;var i=e(r);export{n,i as t};
1
+ import{q as e}from"./useT-c44fzppq.js";var t={name:`message-square`,size:24,node:[[`path`,{d:`M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z`,key:`18887p`}]]};t.node;var n=e(t),r={name:`zap`,size:24,node:[[`path`,{d:`M15.914 4a1.5 1.5 0 00-2.474-1.561l-9 9A1.5 1.5 0 005.5 14h4.002a.5.5 0 01.471.666L8.086 20a1.5 1.5 0 002.475 1.56l9-9A1.5 1.5 0 0018.5 10h-3.997a.5.5 0 01-.472-.667z`,key:`1v7up4`}]]};r.node;var i=e(r);export{n,i as t};
package/dist/index.html CHANGED
@@ -12,10 +12,10 @@
12
12
  <meta name="apple-mobile-web-app-capable" content="yes" />
13
13
  <meta name="apple-mobile-web-app-title" content="GAIA" />
14
14
  <title>GAIA Agent UI</title>
15
- <script type="module" crossorigin src="./assets/index-DsqWzb7b.js"></script>
15
+ <script type="module" crossorigin src="./assets/index-GK8rUlTc.js"></script>
16
16
  <link rel="modulepreload" crossorigin href="./assets/rolldown-runtime-XKyaHtl9.js">
17
- <link rel="modulepreload" crossorigin href="./assets/useT-TIhGZVZ6.js">
18
- <link rel="modulepreload" crossorigin href="./assets/api-CMkT9jku.js">
17
+ <link rel="modulepreload" crossorigin href="./assets/useT-c44fzppq.js">
18
+ <link rel="modulepreload" crossorigin href="./assets/api-UNqTRAb1.js">
19
19
  <link rel="stylesheet" crossorigin href="./assets/index-B7tI0eKR.css">
20
20
  </head>
21
21
  <body>
package/dist/sw.js CHANGED
@@ -9,7 +9,7 @@
9
9
  // never sees a stale UI or stale data.
10
10
 
11
11
  const CACHE_PREFIX = 'gaia-assets-';
12
- const CACHE_NAME = CACHE_PREFIX + '0.25.4rc13-d290fdd1dd302aec';
12
+ const CACHE_NAME = CACHE_PREFIX + '0.25.4rc15-aa5852539b09a5b3';
13
13
  const ASSETS_PATH = new URL('assets/', self.registration.scope).pathname;
14
14
 
15
15
  self.addEventListener('install', () => {
package/main.cjs CHANGED
@@ -102,6 +102,7 @@ const KeepAwake = require("./services/keep-awake.cjs");
102
102
  const PortManager = require("./services/port-manager.cjs");
103
103
  const { isGaiaBackendProcess } = require("./services/backend-orphan.cjs");
104
104
  const { showBackendCrashDialog } = require("./services/backend-crash-dialog.cjs");
105
+ const { createBackendSupervisor } = require("./services/backend-supervisor.cjs");
105
106
  const { buildIndexQuery, INSTALL_SCREEN_QUERY } = require("./services/index-query.cjs");
106
107
  const backendInstaller = require("./services/backend-installer.cjs");
107
108
  const { createEngineInstall } = require("./services/engine-install.cjs");
@@ -214,6 +215,8 @@ const APP_NAME = "GAIA";
214
215
  // from prior aborted sessions (issue #782 / T5).
215
216
  const DEFAULT_BACKEND_PORT = 4200;
216
217
  const STARTUP_TIMEOUT = 30000;
218
+ // A restart must answer within this, or it counts as a failed try.
219
+ const RESTART_TIMEOUT = 90000;
217
220
 
218
221
  // Parse CLI args (T11: --minimized flag for auto-start)
219
222
  const startMinimized = process.argv.includes("--minimized");
@@ -244,6 +247,8 @@ let backendProcess = null;
244
247
  let backendStarting = null;
245
248
  // Set as cleanup() begins; startup stops at its next step once it is.
246
249
  let shutdownStarted = false;
250
+ // Set once an update install starts quitting the app.
251
+ let updateQuitStarted = false;
247
252
  let backendPort = DEFAULT_BACKEND_PORT;
248
253
  let healthCheckUrl = `http://localhost:${backendPort}/api/health`;
249
254
  let backendStderrTail = [];
@@ -281,6 +286,11 @@ const portManager = new PortManager({
281
286
  */
282
287
  let isQuitting = false;
283
288
 
289
+ /** Any quit is under way, an update install's included: start no backend. */
290
+ function quitStarted() {
291
+ return shutdownStarted || isQuitting || updateQuitStarted;
292
+ }
293
+
284
294
  // ── Backend Process ────────────────────────────────────────────────────────
285
295
 
286
296
  /**
@@ -389,6 +399,8 @@ async function startBackend() {
389
399
  env: {
390
400
  ...process.env,
391
401
  GAIA_APP_PID: String(process.pid),
402
+ // Piped stdout is block-buffered: a dying backend's last lines would never arrive.
403
+ PYTHONUNBUFFERED: "1",
392
404
  ...(app.isPackaged && {
393
405
  GAIA_BUNDLED_LEMONADE_DIR: path.join(process.resourcesPath, "vendor", "lemonade"),
394
406
  }),
@@ -434,17 +446,16 @@ async function startBackend() {
434
446
  }
435
447
 
436
448
  child.on("exit", (code, signal) => {
437
- if (code !== 0 && code !== null) {
438
- console.error(`Backend exited with code ${code} (signal=${signal})`);
449
+ // Any exit we didn't ask for leaves the window without a backend, even code 0.
450
+ const crashed = !isIntentionalKill && !isQuitting;
451
+ if (crashed) {
452
+ console.error(`Backend exited with code ${code} (signal=${signal}, pid=${child.pid})`);
439
453
  }
440
- const crashed = !isIntentionalKill && code !== 0 && code !== null;
441
- backendProcess = null;
454
+ if (backendProcess === child) backendProcess = null;
442
455
  if (trayManager && !isQuitting) trayManager.setBackendAlive(false);
443
456
 
444
- if (crashed && !isQuitting) {
445
- // Fire-and-forget — don't block the event loop.
446
- void handleBackendCrash(code, signal);
447
- }
457
+ // Once restarts run out, the supervisor's onStopped shows the crash dialog.
458
+ if (crashed) backendSupervisor.crashed({ code, signal });
448
459
 
449
460
  // Remove pidfile on exit to avoid leaving stale PID behind.
450
461
  try {
@@ -461,12 +472,82 @@ async function startBackend() {
461
472
  }
462
473
  });
463
474
 
475
+ // "close" waits for stdio to drain, so the tail holds the backend's last words.
476
+ child.once("close", (code, signal) => {
477
+ if (isIntentionalKill || isQuitting) return;
478
+ const tail = backendStderrTail.length ? backendStderrTail.join("\n") : "(nothing on stderr)";
479
+ console.error(`[main] Backend pid ${child.pid} closed (code=${code}, signal=${signal}). Last stderr lines:\n${tail}`);
480
+ });
481
+
464
482
  return child;
465
483
  }
466
484
 
485
+ /**
486
+ * Start a new backend for the supervisor and resolve once it answers.
487
+ * Rejects when it exits first or never answers, so the supervisor retries.
488
+ */
489
+ async function restartBackend() {
490
+ backendStarting = startBackend();
491
+ const child = await backendStarting;
492
+ if (!child) {
493
+ throw new Error("GAIA's backend program is missing, so it can't restart. Reinstall GAIA.");
494
+ }
495
+ if (quitStarted()) {
496
+ isIntentionalKill = true;
497
+ await portManager.killBackend(child);
498
+ throw new Error("GAIA is quitting, so the restarted backend was stopped.");
499
+ }
500
+ backendProcess = child;
501
+ const alive = () => child.exitCode === null && child.signalCode === null;
502
+ const ready = await waitForBackend(RESTART_TIMEOUT, alive);
503
+ if (!ready) {
504
+ if (!alive()) {
505
+ throw new Error(`The backend exited (code ${child.exitCode}, signal ${child.signalCode}) before it answered.`);
506
+ }
507
+ isIntentionalKill = true;
508
+ await portManager.killBackend(child);
509
+ throw new Error(`The backend did not answer within ${RESTART_TIMEOUT / 1000} s.`);
510
+ }
511
+ console.log(`[main] Backend restarted on port ${backendPort} (pid=${child.pid})`);
512
+ if (trayManager) {
513
+ trayManager.setBackendPort(backendPort);
514
+ trayManager.setBackendAlive(true);
515
+ }
516
+ return { port: backendPort };
517
+ }
518
+
519
+ /** What the renderer needs: the supervisor's state plus the API base to use. */
520
+ function backendStateForRenderer(state) {
521
+ return { ...state, apiBase: state.port ? buildIndexQuery(state.port).api : null };
522
+ }
523
+
524
+ const backendSupervisor = createBackendSupervisor({
525
+ start: restartBackend,
526
+ onStopped: (state) => {
527
+ const { code = null, signal = null } = state.lastExit || {};
528
+ void handleBackendCrash(code, signal);
529
+ },
530
+ onState: (state) => {
531
+ console.log(
532
+ `[main] Backend ${state.status}` +
533
+ (state.status === "restarting" ? ` (try ${state.attempt} of ${state.maxRestarts})` : "") +
534
+ (state.lastError ? `: ${state.lastError}` : "")
535
+ );
536
+ if (mainWindow && !mainWindow.isDestroyed()) {
537
+ mainWindow.webContents.send("backend:state", backendStateForRenderer(state));
538
+ }
539
+ },
540
+ });
541
+
542
+ ipcMain.handle("backend:get-state", () => backendStateForRenderer(backendSupervisor.getState()));
543
+ ipcMain.handle("backend:restart", () => {
544
+ backendSupervisor.restartNow();
545
+ return backendStateForRenderer(backendSupervisor.getState());
546
+ });
547
+
467
548
  /**
468
549
  * Tell the user the backend stopped and offer Restart / Save diagnostics /
469
- * Quit. Invoked from child.on("exit") when the kill was NOT initiated by us.
550
+ * Quit. Invoked by the supervisor's onStopped once automatic restarts run out.
470
551
  */
471
552
  async function handleBackendCrash(code, signal) {
472
553
  autoUpdater.reportStartFailure();
@@ -488,11 +569,11 @@ async function handleBackendCrash(code, signal) {
488
569
  }
489
570
  }
490
571
 
491
- async function waitForBackend(timeoutMs) {
572
+ async function waitForBackend(timeoutMs, isAlive = () => true) {
492
573
  const start = Date.now();
493
574
  const http = require("http");
494
575
 
495
- while (Date.now() - start < timeoutMs) {
576
+ while (Date.now() - start < timeoutMs && isAlive()) {
496
577
  try {
497
578
  await new Promise((resolve, reject) => {
498
579
  const req = http.get(healthCheckUrl, (res) => {
@@ -1213,6 +1294,7 @@ app.whenReady().then(async () => {
1213
1294
  if (shutdownStarted) return;
1214
1295
  backendStarting = startBackend();
1215
1296
  backendProcess = await backendStarting;
1297
+ if (backendProcess) backendSupervisor.running(backendPort);
1216
1298
  if (shutdownStarted) {
1217
1299
  console.log("[main] Quit during startup — not opening the window");
1218
1300
  return;
@@ -1344,6 +1426,7 @@ const quitGuard = installQuitGuard({
1344
1426
  // Mark any subsequent backend exit as intentional so we don't pop the
1345
1427
  // crash dialog during normal shutdown.
1346
1428
  isIntentionalKill = true;
1429
+ backendSupervisor.stop();
1347
1430
  },
1348
1431
  onError: (err) => {
1349
1432
  console.error("[main] Quit check failed:", err);
@@ -1355,12 +1438,19 @@ const quitGuard = installQuitGuard({
1355
1438
  },
1356
1439
  });
1357
1440
 
1441
+ // The installer is already running: a restart now would hold its files open.
1442
+ electronAutoUpdater.on("before-quit-for-update", () => {
1443
+ updateQuitStarted = true;
1444
+ backendSupervisor.stop();
1445
+ });
1446
+
1358
1447
  quitOnTermSignal({ proc: process, app, guard: quitGuard });
1359
1448
 
1360
1449
  installQuitCleanup({ app, cleanup });
1361
1450
 
1362
1451
  async function cleanup() {
1363
1452
  shutdownStarted = true;
1453
+ backendSupervisor.stop();
1364
1454
  const installStopped = engineInstall ? engineInstall.stop() : null;
1365
1455
 
1366
1456
  // Phase F: tear down auto-updater timers and IPC handlers.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amd-gaia/agent-ui",
3
- "version": "0.25.4-rc.13",
3
+ "version": "0.25.4-rc.15",
4
4
  "type": "module",
5
5
  "productName": "GAIA Agent UI",
6
6
  "description": "Chat with the GAIA agent - local and private by default on AMD Ryzen AI, cloud models when you choose them",
package/preload.cjs CHANGED
@@ -16,6 +16,7 @@
16
16
  * system:* — System metrics for the observability dashboard (#2007)
17
17
  * power:* — Keep the PC awake while a chat turn runs (#5226)
18
18
  * dialog:* — The OS folder picker
19
+ * backend:* — Backend restarts after a crash (services/backend-supervisor.cjs)
19
20
  */
20
21
 
21
22
  const { contextBridge, ipcRenderer } = require("electron");
@@ -90,6 +91,13 @@ contextBridge.exposeInMainWorld("gaiaAPI", {
90
91
  dialog: {
91
92
  pickFolder: (defaultPath) => ipcRenderer.invoke("dialog:pick-folder", defaultPath),
92
93
  },
94
+
95
+ // ── GAIA's backend process: restarts after a crash, and its new port ──
96
+ backend: {
97
+ getState: () => ipcRenderer.invoke("backend:get-state"),
98
+ restart: () => ipcRenderer.invoke("backend:restart"),
99
+ onState: (cb) => onEvent("backend:state", cb),
100
+ },
93
101
  });
94
102
 
95
103
  // ── Window frame ─────────────────────────────────────────────────────────
@@ -0,0 +1,150 @@
1
+ // Copyright(C) 2026 Advanced Micro Devices, Inc. All rights reserved.
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ /**
5
+ * Restarts GAIA's backend when it exits on its own: after a growing wait,
6
+ * at most `maxRestarts` times in `windowMs`, then it stops and waits for the
7
+ * user's Restart GAIA (restartNow). No Electron imports, so it unit-tests.
8
+ *
9
+ * State, as sent to the renderer:
10
+ * status "running" | "restarting" | "stopped"
11
+ * port the backend's port once running
12
+ * since when this outage began (ms epoch), for the banner's timer
13
+ * attempt which try this outage is on
14
+ * nextAttemptAt when the next try starts, or null while one is starting
15
+ * lastExit { code, signal } of the last exit
16
+ * lastError why the last start failed, if it did
17
+ */
18
+
19
+ "use strict";
20
+
21
+ const DEFAULTS = Object.freeze({
22
+ maxRestarts: 3,
23
+ windowMs: 10 * 60_000,
24
+ backoffMs: [1000, 5000, 15000],
25
+ });
26
+
27
+ /**
28
+ * @param {object} deps
29
+ * @param {() => Promise<{port: number}>} deps.start spawns the backend and resolves once it answers
30
+ * @param {(state: object) => void} deps.onState called with every new state
31
+ * @param {(state: object) => void} [deps.onStopped] called once each time restarts run out
32
+ */
33
+ function createBackendSupervisor({
34
+ start,
35
+ onState,
36
+ onStopped = () => {},
37
+ maxRestarts = DEFAULTS.maxRestarts,
38
+ windowMs = DEFAULTS.windowMs,
39
+ backoffMs = DEFAULTS.backoffMs,
40
+ now = Date.now,
41
+ setTimer = setTimeout,
42
+ clearTimer = clearTimeout,
43
+ }) {
44
+ if (!Number.isInteger(maxRestarts) || maxRestarts < 1) {
45
+ throw new Error(`backend supervisor: maxRestarts must be a positive integer, got ${maxRestarts}`);
46
+ }
47
+ if (!Array.isArray(backoffMs) || backoffMs.length === 0) {
48
+ throw new Error("backend supervisor: backoffMs must list at least one delay");
49
+ }
50
+
51
+ // Automatic restarts in the window; a user's Restart GAIA isn't counted.
52
+ let history = [];
53
+ let timer = null;
54
+ let starting = false;
55
+ let stopped = false;
56
+ let state = { status: "running", port: null, since: null, attempt: 0, nextAttemptAt: null, lastExit: null, lastError: null };
57
+
58
+ function emit(next) {
59
+ state = { ...state, ...next, maxRestarts };
60
+ onState({ ...state });
61
+ }
62
+
63
+ function attemptStart() {
64
+ timer = null;
65
+ starting = true;
66
+ emit({ nextAttemptAt: null });
67
+ let started;
68
+ try {
69
+ started = Promise.resolve(start());
70
+ } catch (err) {
71
+ started = Promise.reject(err);
72
+ }
73
+ started.then(
74
+ ({ port }) => {
75
+ starting = false;
76
+ if (stopped) return;
77
+ emit({ status: "running", port, since: null, attempt: 0, lastError: null });
78
+ },
79
+ (err) => {
80
+ starting = false;
81
+ if (stopped) return;
82
+ schedule({ lastError: err && err.message ? err.message : String(err) });
83
+ }
84
+ );
85
+ }
86
+
87
+ function schedule(extra) {
88
+ const t = now();
89
+ history = history.filter((at) => t - at < windowMs);
90
+ const outage = state.status === "running" ? { since: t, attempt: 0 } : {};
91
+ if (history.length >= maxRestarts) {
92
+ const wasStopped = state.status === "stopped";
93
+ emit({ status: "stopped", nextAttemptAt: null, ...outage, ...extra });
94
+ if (!wasStopped) onStopped({ ...state });
95
+ return "stopped";
96
+ }
97
+ const delay = backoffMs[Math.min(history.length, backoffMs.length - 1)];
98
+ history.push(t + delay);
99
+ const attempt = (outage.attempt ?? state.attempt) + 1;
100
+ emit({ ...outage, status: "restarting", attempt, nextAttemptAt: t + delay, ...extra });
101
+ timer = setTimer(attemptStart, delay);
102
+ return "restarting";
103
+ }
104
+
105
+ return {
106
+ /** The backend is up on `port` (the first start, outside the supervisor). */
107
+ running(port) {
108
+ emit({ status: "running", port, since: null, attempt: 0, nextAttemptAt: null, lastError: null });
109
+ },
110
+
111
+ /** The backend exited on its own. Returns what happens next. */
112
+ crashed({ code = null, signal = null } = {}) {
113
+ if (stopped) return "stopped";
114
+ // An exit during a start is that start's failure, reported by start() itself;
115
+ // keep its exit so the crash dialog names the latest one.
116
+ if (starting) {
117
+ state = { ...state, lastExit: { code, signal } };
118
+ return state.status;
119
+ }
120
+ if (timer) return state.status;
121
+ return schedule({ lastExit: { code, signal } });
122
+ },
123
+
124
+ /** The user's Restart GAIA: start now, with a fresh budget. */
125
+ restartNow() {
126
+ if (stopped || starting) return;
127
+ if (timer) {
128
+ clearTimer(timer);
129
+ timer = null;
130
+ }
131
+ history = [];
132
+ if (state.status === "running") return;
133
+ emit({ status: "restarting", attempt: 1 });
134
+ attemptStart();
135
+ },
136
+
137
+ /** GAIA is quitting: no more restarts. */
138
+ stop() {
139
+ stopped = true;
140
+ if (timer) clearTimer(timer);
141
+ timer = null;
142
+ },
143
+
144
+ getState() {
145
+ return { ...state, maxRestarts };
146
+ },
147
+ };
148
+ }
149
+
150
+ module.exports = { createBackendSupervisor, DEFAULTS };
@@ -111,6 +111,9 @@ async function writeDiagnosticsBundle(destPath, logger) {
111
111
  "gaia.log",
112
112
  "electron-main.log",
113
113
  "electron-install-state.json",
114
+ // Fatal-crash stacks from the backend (src/gaia/ui/fault_log.py), and its rotated copy.
115
+ "logs/backend-faults.log",
116
+ "logs/backend-faults.log.1",
114
117
  ];
115
118
 
116
119
  const present = candidates.filter((rel) =>
@@ -1 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-XKyaHtl9.js";import{F as t,a as n,c as r,d as i,l as a,q as o,s}from"./useT-TIhGZVZ6.js";import{At as c,Bt as l,I as u,R as d,V as f,Y as p,jt as m,q as h,ut as g}from"./api-CMkT9jku.js";import{Ft as _,Lt as v,Vt as y,Z as b,a as x,c as S,d as C,et as w,f as T,l as E,o as D,r as O,s as k,vt as A}from"./index-DsqWzb7b.js";var j=e(o(),1);function M(){let e=n(),t=i(e=>e.runSetupAgain),o=i(e=>e.closeSettings),[l,d]=(0,j.useState)(null),[f,p]=(0,j.useState)(null),[m,h]=(0,j.useState)(``),[g,_]=(0,j.useState)(``),[y,b]=(0,j.useState)(!1),[x,S]=(0,j.useState)(null),[w,T]=(0,j.useState)(!1);(0,j.useEffect)(()=>{u().then(e=>{d(e),h(e.saved_base_url??e.base_url??``)}).catch(e=>p(e instanceof Error?e.message:String(e)))},[]);let E=(0,j.useCallback)(async e=>{b(!0),S(null);try{let n=await c(e);d(n),_(``),T(!1),n.mode===`gaia`&&!n.gaia_installed&&(o(),t(!0))}catch(e){T(C(e)),S(e instanceof Error?e.message:String(e))}finally{b(!1)}},[o,t]),D=()=>void E({mode:`external`,base_url:m.trim(),api_key:g.trim()||void 0});if(f)return a(`section`,{className:`settings-section`,children:[r(`h4`,{children:e(`settings.advanced.modelServer`)}),a(`div`,{className:`model-warning`,role:`alert`,children:[r(v,{size:14}),a(`div`,{className:`model-warning-content`,children:[r(`strong`,{children:e(`settings.server.readFailed`)}),r(`p`,{children:f})]})]})]});if(!l)return null;let O=l.mode===`external`,k=l.source===`env`;return a(`section`,{className:`settings-section`,"aria-label":e(`settings.advanced.modelServer`),children:[r(`h4`,{children:e(`settings.advanced.modelServer`)}),r(`p`,{className:`model-override-desc`,role:`status`,children:k?e(`settings.server.usesEnv`,{url:l.base_url??``}):O?e(`settings.server.usesYours`,{url:l.base_url??``}):e(`settings.server.usesOwn`)}),!k&&l.env_url_ignored&&r(`p`,{className:`model-status-hint`,children:e(`settings.server.envIgnored`,{url:l.env_url_ignored})}),k?r(`p`,{className:`model-status-hint`,children:e(`settings.server.envUseOwn`)}):a(s.Fragment,{children:[a(`p`,{className:`model-status-hint`,children:[e(`settings.server.useYours`),` `,r(`bdi`,{children:l.what_gaia_does})]}),a(`form`,{className:`model-input-row`,onSubmit:e=>{e.preventDefault(),D()},children:[r(`input`,{type:`text`,className:`model-input`,placeholder:`http://localhost:13305`,value:m,onChange:e=>{h(e.target.value),S(null)},disabled:y,spellCheck:!1,autoCapitalize:`off`,autoCorrect:`off`,"aria-label":e(`settings.server.address`)}),r(`input`,{type:`password`,className:`model-input`,autoComplete:`off`,placeholder:l.api_key_stored?e.bare(`settings.server.keySaved`):e.bare(`settings.server.keyOptional`),value:g,onChange:e=>_(e.target.value),disabled:y,"aria-label":e(`settings.server.key`)}),r(`div`,{className:`model-btn-group`,children:r(`button`,{type:`submit`,className:`btn-model-save`,disabled:y||!m.trim(),children:y?a(s.Fragment,{children:[r(A,{size:13,className:`btn-spinner`}),` `,e(`settings.server.checking`)]}):e(`settings.server.use`)})})]})]}),O&&r(`div`,{className:`setting-actions`,children:r(`button`,{type:`button`,className:`btn-secondary`,disabled:y,onClick:()=>void E({mode:`gaia`}),children:e(`settings.server.useOwn`)})}),x&&a(`div`,{className:`model-warning`,role:`alert`,children:[r(v,{size:14}),a(`div`,{className:`model-warning-content`,children:[r(`strong`,{children:e(w?`settings.server.needsKey`:`settings.server.notSwitched`)}),r(`p`,{children:x})]})]})]})}var N={vulkan:`Vulkan`,rocm:`ROCm`,metal:`Metal`,cpu:`CPU`,npu:`NPU`,remote:`Remote (cloud)`},P={gaia:`settings.server.ownerGaia`,user:`settings.server.ownerUser`,remote:`settings.server.ownerRemote`};function F(e){return e?N[e]??e:`unknown`}function I(e){if(!e)return`unknown`;let t=F(e.backend);return e.backend_source===`lemonade_default`?`${t} (Lemonade's default)`:t}function L(e){return e?`${Math.round(e/1024)}K tokens`:`unknown`}var R={asr:`settings.server.kind.speechRecognition`,embedding:`settings.server.kind.embedding`,image:`settings.server.kind.image`,llm:`settings.server.kind.language`,rerank:`settings.server.kind.reranker`,reranking:`settings.server.kind.reranker`,stt:`settings.server.kind.speechRecognition`,transcription:`settings.server.kind.speechRecognition`,tts:`settings.server.kind.speech`,vision:`settings.server.kind.vision`,"3d":`settings.server.kind.threeD`};function z(e,t){if(!e.model_type)return t(`settings.server.loadedModel`);let n=e.model_type.toLowerCase(),r=R[n];return r?t(r):t(`settings.server.kindOther`,{kind:`${n.charAt(0).toUpperCase()}${n.slice(1)}`})}function B(e,t){let n=[e.name?w(e.name):t.bare(`settings.server.unknownModel`),I(e)];return e.backend!==`remote`&&e.ctx_size&&n.push(L(e.ctx_size)),n.join(` · `)}function V({label:e,value:t,title:n}){return a(`div`,{className:`status-row`,children:[r(`span`,{className:`status-label`,children:e}),r(`span`,{className:`status-value model-server-value`,dir:`auto`,title:n??t,children:t})]})}function ee(){let e=n(),t=i(e=>e.openSettings),[o,c]=(0,j.useState)(null),[l,u]=(0,j.useState)(null),[d,p]=(0,j.useState)(null),[h,_]=(0,j.useState)(null),[v,y]=(0,j.useState)(!1);(0,j.useEffect)(()=>{f().then(c).catch(e=>u(e instanceof Error?e.message:String(e)))},[]);let b=(0,j.useCallback)(async t=>{p(t),_(null);try{let n=await m(t);c(n),_({ok:!0,text:e(`settings.server.savedBackend`)})}catch(e){_({ok:!1,text:e instanceof Error?e.message:String(e)})}finally{p(null)}},[e]),S=o?.chat_model??null,C=(0,j.useCallback)(async()=>{if(S?.name){y(!0);try{if(!await g(S.name,S.ctx_size??void 0))return;_({ok:!0,text:e(`settings.server.reloading`,{name:S.name})})}catch(e){_({ok:!1,text:e instanceof Error?e.message:String(e)})}finally{y(!1)}}},[S,e]),T=r(`button`,{type:`button`,className:`btn-secondary`,onClick:()=>t(`model`),children:e(`settings.server.changeModel`)});if(l)return a(`section`,{className:`settings-section`,"aria-label":e(`settings.advanced.modelServer`),children:[r(`h4`,{children:e(`settings.advanced.modelServer`)}),r(x,{message:l})]});if(!o)return a(`section`,{className:`settings-section`,"aria-label":e(`settings.advanced.modelServer`),children:[r(`h4`,{children:e(`settings.advanced.modelServer`)}),r(`p`,{className:`loading-text`,children:e(`settings.server.checkingServer`)})]});if(!o.reachable)return a(`section`,{className:`settings-section`,"aria-label":e(`settings.advanced.modelServer`),children:[r(`h4`,{children:e(`settings.advanced.modelServer`)}),r(x,{message:o.error??e(`settings.errors.serverDownTitle`)}),T]});let E=o.available_backends??[],D=o.preferred_backend??null,O=E.map(e=>e.name);D&&!O.includes(D)&&O.push(D);let k=D??o.default_backend??null,M=E.filter(e=>e.state===`installable`).map(e=>F(e.name)),N=!!S?.name&&S.recipe===`llamacpp`;return a(`section`,{className:`settings-section`,"aria-label":e(`settings.advanced.modelServer`),children:[r(`h4`,{children:e(`settings.advanced.modelServer`)}),a(`div`,{className:`status-grid`,children:[r(V,{label:e(`settings.server.server`),value:`${P[o.owner]?e(P[o.owner]):o.owner}${o.version?` v${o.version}`:``}`}),r(V,{label:e(`settings.server.addressShort`),value:o.base_url}),r(V,{label:e(`settings.server.chatModel`),value:S?.name?w(S.name):e(`settings.advanced.noneLoaded`),title:S?.name??void 0}),S&&r(V,{label:e(`settings.server.runsOn`),value:I(S)}),S&&S.backend!==`remote`&&r(V,{label:e(`settings.advanced.context`),value:L(S.ctx_size)}),r(V,{label:e(`settings.advanced.embedding`),value:o.embedding_model?.name?`${o.embedding_model.name} · ${I(o.embedding_model)}`:e(`settings.advanced.noneLoaded`)}),(o.loaded_models??[]).map((t,n)=>r(V,{label:z(t,e),value:B(t,e),title:t.name??void 0},`${t.name??`unknown`}-${n}`))]}),o.embedding_note&&r(`p`,{className:`settings-hint`,children:r(`bdi`,{children:o.embedding_note})}),o.system_info_error&&r(`p`,{className:`settings-hint`,children:r(`bdi`,{children:o.system_info_error})}),a(`div`,{className:`settings-field model-server-backend`,children:[r(`span`,{className:`settings-label`,children:e(`settings.server.backend`)}),E.length===0&&!D?r(`span`,{className:`settings-hint`,children:e(`settings.server.noBackends`)}):a(s.Fragment,{children:[r(`div`,{className:`segmented`,role:`radiogroup`,"aria-label":e(`settings.server.backendShort`),children:O.map(e=>a(`button`,{type:`button`,role:`radio`,"aria-checked":k===e,className:k===e?`is-active`:``,disabled:d!==null,onClick:()=>{e!==k&&b(e)},children:[d===e?r(A,{size:12,className:`spin`}):null,F(e)]},e))}),a(`span`,{className:`settings-hint`,children:[e(`settings.server.backendHint`),M.length>0&&` ${e(`settings.server.installable`,{names:M.join(`, `)})}`]})]}),h?.ok&&r(`p`,{className:`settings-ok`,role:`status`,children:h.text}),h&&!h.ok&&r(x,{message:h.text})]}),a(`div`,{className:`settings-row`,children:[T,N&&a(`button`,{type:`button`,className:`btn-secondary`,onClick:()=>void C(),disabled:v,children:[v?r(A,{size:13,className:`spin`}):null,e(`settings.server.reload`)]})]})]})}function H(){let e=n(),[i,o]=(0,j.useState)(null),[c,u]=(0,j.useState)(!0),[f,m]=(0,j.useState)([]),[g,C]=(0,j.useState)(``),[w,N]=(0,j.useState)(``),[P,F]=(0,j.useState)(!1),[I,L]=(0,j.useState)(!1),[R,z]=(0,j.useState)(null),[B,V]=(0,j.useState)(!1),H=(0,j.useRef)(null),[W,G]=(0,j.useState)(!1),[K,ne]=(0,j.useState)(!1),[q,re]=(0,j.useState)(!1),[ie,ae]=(0,j.useState)(null);(0,j.useEffect)(()=>{t.system.info(`Checking system status...`);let e=t.system.time();p().then(n=>{o(n),t.system.timed(`System status received`,e,{lemonade:n.lemonade_running?`running`:`stopped`,model:n.model_loaded||`none`,embedding:n.embedding_model_loaded?`yes`:`no`,disk:`${n.disk_space_gb}GB free`,memory:n.memory_available_gb==null?`unknown`:`${n.memory_available_gb}GB available`}),n.lemonade_running||t.system.warn(`Lemonade Server is NOT running.`)}).catch(e=>{t.system.error(`Failed to get system status`,e),o(null)}).finally(()=>u(!1)),d().then(e=>m(e.servers)).catch(()=>{}),h().then(e=>{let t=e.custom_model??``;C(t),N(t),G(e.dynamic_tools),ne(e.dynamic_tools_locked)}).catch(e=>{t.system.error(`Failed to load settings`,e)}).finally(()=>F(!0))},[]),(0,j.useEffect)(()=>()=>{H.current&&clearTimeout(H.current)},[]);let oe=(0,j.useCallback)(async()=>{let e=g.trim(),n=e.length>0?e:``;L(!0),z(null),V(!1);try{t.system.info(`Saving custom_model override`,{custom_model:n});let e=(await l({custom_model:n})).custom_model??``;C(e),N(e),V(!0),H.current&&clearTimeout(H.current),H.current=setTimeout(()=>V(!1),2200)}catch(e){let n=e instanceof Error?e.message:String(e);t.system.error(`Failed to save custom_model`,e),z(n)}finally{L(!1)}},[g]),se=(0,j.useCallback)(async()=>{if(K||q)return;let e=W,n=!e;G(n),re(!0),ae(null);try{t.system.info(`Saving dynamic_tools setting`,{dynamic_tools:n});let e=await l({dynamic_tools:n});G(e.dynamic_tools),ne(e.dynamic_tools_locked)}catch(n){let r=n instanceof Error?n.message:String(n);t.system.error(`Failed to save dynamic_tools`,n),G(e),ae(r)}finally{re(!1)}},[W,K,q]),ce=g.trim()!==w.trim(),J=i?i.default_model_name:b,{isLoadingModel:le,isDownloadingModel:Y,downloadError:X,loadModel:ue,downloadModel:de}=O(J??void 0),Z=!!i?.default_model_is_cloud,Q=!Z&&!!(i?.lemonade_running&&i.model_loaded&&i.expected_model_loaded===!1),fe=!Z&&!!(i?.lemonade_running&&i.model_loaded&&i.context_size_sufficient===!1),$=!Z&&!(!i?.lemonade_running||i.model_loaded||i.model_downloaded!==!1),pe=(Q||fe)&&J!==null,me=f.some(e=>!e.connected);return a(`div`,{className:`settings-pane`,children:[r(`h2`,{className:`settings-pane-title`,children:e(`settings.section.advanced`)}),r(`section`,{className:`settings-card`,"aria-label":e(`settings.advanced.status`),children:c?r(`p`,{className:`loading-text`,children:e(`settings.advanced.checking`)}):i?a(s.Fragment,{children:[a(`div`,{className:`status-grid`,children:[r(U,{label:e(`settings.advanced.modelServer`),value:i.lemonade_running?i.lemonade_version?e(`settings.advanced.runningAt`,{version:i.lemonade_version}):e(`settings.advanced.running`):S(i)?e(`settings.advanced.notInstalled`):i.lemonade_error?e(`settings.advanced.unavailable`):e(`settings.advanced.notRunning`),ok:i.lemonade_running,hint:i.lemonade_running?void 0:S(i)?e(`settings.advanced.notInstalledHint`):i.lemonade_error?e(`settings.advanced.queryFailed`,{reason:i.lemonade_error}):i.start_instruction&&!k(i.start_instruction)?i.start_instruction:e(`settings.advanced.notRunningHint`)}),S(i)&&r(D,{className:`btn-primary`}),r(U,{label:e(`settings.section.model`),value:i.model_loaded||e(`settings.advanced.noneLoaded`),ok:!!i.model_loaded&&(Z||i.expected_model_loaded!==!1),hint:i.model_loaded?!Z&&i.expected_model_loaded===!1?e(`settings.advanced.expected`,{name:J??``}):void 0:e(`settings.advanced.loadsFirst`)}),r(U,{label:e(`settings.advanced.disk`),value:a(`bdi`,{dir:`ltr`,children:[i.disk_space_gb,` GB`]}),ok:i.disk_space_gb>5,hint:!i.model_loaded&&i.disk_space_gb<30?e(`settings.advanced.diskLow`,{need:`6 GB`,size:`${i.disk_space_gb} GB`}):void 0})]}),$&&a(`div`,{className:`model-action-row model-action-row--download`,children:[a(`div`,{className:`model-action-info`,children:[r(`span`,{className:`model-action-label`,children:e(`settings.advanced.notDownloaded`)}),r(`span`,{className:`model-action-desc`,children:e(`settings.advanced.notDownloadedHint`,{name:J??``,need:`6 GB`})})]}),r(`button`,{className:`btn-model-action btn-model-action--download`,onClick:()=>de(!1),disabled:Y,children:Y?a(s.Fragment,{children:[r(A,{size:13,className:`btn-spinner`}),` `,e(`settings.advanced.downloading`)]}):e(`settings.model.download`)})]}),$&&X&&r(x,{message:X}),pe&&a(`div`,{className:`model-action-row model-action-row--load`,children:[a(`div`,{className:`model-action-info`,children:[r(`span`,{className:`model-action-label`,children:e(Q?`settings.advanced.wrongModel`:`settings.advanced.smallContext`)}),r(`span`,{className:`model-action-desc`,children:e(`settings.advanced.loadHint`,{name:J??``,size:`${32 .toFixed(0)}K`})})]}),r(`button`,{className:`btn-model-action btn-model-action--load`,onClick:()=>ue(),disabled:le,children:le?a(s.Fragment,{children:[r(A,{size:13,className:`btn-spinner`}),` `,e(`settings.advanced.loading`)]}):e(`settings.advanced.load`)})]}),a(`details`,{className:`settings-more`,children:[a(`summary`,{children:[r(y,{size:13,className:`settings-disclosure-chevron`,"aria-hidden":`true`}),` `,e(`settings.advanced.details`)]}),a(`div`,{className:`status-grid`,children:[i.model_size_gb!=null&&r(U,{label:e(`settings.advanced.modelSize`),value:a(`bdi`,{dir:`ltr`,children:[i.model_size_gb,` GB`]}),ok:!0}),i.model_device&&!Z&&r(U,{label:e(`settings.advanced.device`),value:i.model_device.toUpperCase(),ok:i.model_device!==`cpu`}),i.model_context_size!=null&&r(U,{label:e(`settings.advanced.context`),value:e(`settings.ctx.tokens`,{size:`${(i.model_context_size/1024).toFixed(0)}K`}),ok:i.context_size_sufficient}),i.model_labels&&i.model_labels.length>0&&r(U,{label:e(`settings.advanced.capabilities`),value:i.model_labels.join(`, `),ok:!0}),r(U,{label:e(`settings.advanced.embedding`),value:i.embedding_model_loaded?e(`settings.advanced.available`):e(`settings.advanced.notLoaded`),ok:i.embedding_model_loaded}),i.gpu_name&&r(U,{label:`GPU`,value:r(`bdi`,{children:`${i.gpu_name}${i.gpu_vram_gb?` (${T(i.gpu_vram_gb)})`:``}`}),ok:!0}),r(U,{label:e(`settings.advanced.memory`),value:i.memory_available_gb==null?e(`settings.advanced.unknown`):a(`bdi`,{dir:`ltr`,children:[i.memory_available_gb,` GB`]}),ok:i.memory_available_gb!=null&&i.memory_available_gb>2}),i.processor_name&&r(U,{label:e(`settings.advanced.processor`),value:r(`bdi`,{children:i.processor_name}),ok:!0})]}),i.lemonade_running&&J!==null&&!Z&&a(`div`,{className:`force-redownload-row`,children:[r(`span`,{className:`force-redownload-label`,children:e(`settings.advanced.corrupted`)}),r(`button`,{className:`btn-force-redownload`,onClick:()=>de(!0),disabled:Y,children:Y?a(s.Fragment,{children:[r(A,{size:12,className:`btn-spinner`}),` `,e(`settings.advanced.downloading`)]}):e(`settings.advanced.redownload`)})]}),!$&&X&&r(x,{message:X})]})]}):r(`div`,{className:`status-error`,children:r(`p`,{children:e(`settings.advanced.unreachable`)})})}),a(E,{title:e(`settings.advanced.serverTitle`),hint:e(`settings.advanced.serverHint`),children:[r(ee,{}),r(M,{})]}),a(E,{title:e(`settings.advanced.customTitle`),hint:w||e(`settings.advanced.customHint`),children:[r(`p`,{className:`model-override-desc`,children:e(`settings.advanced.customDesc`)}),a(`div`,{className:`model-input-row`,children:[r(`input`,{type:`text`,className:`model-input${w?` has-override`:``}`,placeholder:e.bare(`settings.advanced.customPlaceholder`),value:g,onChange:e=>{C(e.target.value),z(null),V(!1)},onKeyDown:e=>{e.key===`Enter`&&!I&&ce&&P&&(e.preventDefault(),oe())},disabled:!P||I,spellCheck:!1,autoCapitalize:`off`,autoCorrect:`off`,"aria-label":e(`settings.advanced.customAria`)}),r(`div`,{className:`model-btn-group`,children:r(`button`,{className:`btn-model-save${B?` saved`:``}`,onClick:()=>{oe()},disabled:!P||I||!ce&&!B,"aria-label":e(`settings.advanced.customSave`),children:I?a(s.Fragment,{children:[r(A,{size:13,className:`btn-spinner`}),` `,e(`settings.models.applying`)]}):B?a(s.Fragment,{children:[r(_,{size:13}),` `,e(`settings.advanced.saved`)]}):e(`settings.advanced.save`)})})]}),r(`p`,{className:`model-status-hint`,children:e(`settings.advanced.customIds`)}),R&&r(te,{message:R})]}),a(E,{title:e(`settings.advanced.dynamicTitle`),children:[r(`p`,{className:`model-override-desc`,children:e(`settings.advanced.dynamicDesc`)}),a(`label`,{className:`setting-row`,children:[r(`span`,{children:e(`settings.advanced.dynamicEnable`)}),a(`span`,{className:`toggle-switch`,children:[r(`input`,{type:`checkbox`,checked:W,onChange:()=>void se(),disabled:!P||q||K,"aria-label":e(W?`settings.advanced.dynamicOff`:`settings.advanced.dynamicOn`)}),r(`span`,{className:`toggle-track`})]})]}),K&&r(`p`,{className:`model-status-hint`,children:e(`settings.advanced.dynamicLocked`)}),ie&&r(te,{message:ie})]}),f.length>0&&r(E,{title:e(`settings.advanced.mcp`),count:f.length,defaultOpen:me,children:r(`div`,{className:`status-grid`,children:f.map(t=>a(`div`,{className:`status-row`,children:[r(`bdi`,{className:`status-label`,children:t.name}),r(`div`,{className:`status-value-wrap`,children:t.connected?a(`span`,{className:`status-value ok mcp-status-connected`,children:[r(_,{size:12}),e.plural(`settings.advanced.tools`,t.tool_count)]}):a(`span`,{className:`status-value warn mcp-status-failed`,title:t.error??void 0,children:[r(v,{size:12}),e(`settings.custom.failed`)]})})]},t.name))})}),a(`div`,{className:`about-info`,children:[a(`p`,{children:[a(`bdi`,{dir:`ltr`,children:[`GAIA v`,`0.25.4rc13`]}),` `,r(`span`,{className:`beta-badge`,children:`BETA`})]}),r(`p`,{className:`about-sub`,children:e(`settings.advanced.about`)})]})]})}function te({message:e}){let t=n();return a(`div`,{className:`model-warning`,role:`alert`,children:[r(v,{size:14}),a(`div`,{className:`model-warning-content`,children:[r(`strong`,{children:t(`settings.advanced.saveFailed`)}),r(`p`,{children:e})]})]})}function U({label:e,value:t,ok:n,hint:i}){return a(`div`,{className:`status-row${i?` status-row--has-hint`:``}`,children:[r(`span`,{className:`status-label`,children:e}),a(`div`,{className:`status-value-wrap`,children:[r(`span`,{className:`status-value ${n?`ok`:`warn`}`,children:t}),i&&r(`span`,{className:`status-hint`,children:i})]})]})}export{H as AdvancedSettings};
@@ -1 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-XKyaHtl9.js";import{F as t,a as n,c as r,d as i,l as a,o,q as s,s as c}from"./useT-TIhGZVZ6.js";import{_n as l,bn as u,cn as d,dn as f,fn as p,gn as m,hn as h,ln as g,mn as _,on as v,pn as y,sn as b,un as x,vn as S,yn as C}from"./api-CMkT9jku.js";import{Dt as w,Ft as T,Lt as E,Ot as D,Rt as O,Vt as k,l as A,nt as j,vt as M}from"./index-DsqWzb7b.js";var N=e(s(),1),P=t.api;function F(e){switch(e){case`connector.configured`:return`configured`;case`connector.disconnected`:return`disconnected`;case`connection.revoked`:return`disconnected`;case`connector.oauth.completed`:return`oauth_completed`;case`connection.connected`:return`oauth_completed`;case`connector.oauth.error`:return`oauth_error`;case`connector.tested`:return`tested`;case`connector.enabled`:return`enabled`;case`connector.disabled`:return`disabled`;case`connector.grant.changed`:return`grant_changed`;case`connector.activation.changed`:return`activation_changed`;default:return null}}function I(e){let t=(0,N.useRef)(e);(0,N.useEffect)(()=>{t.current=e},[e]),(0,N.useEffect)(()=>{let e=`${o()}/connectors/events`,n=null,r=1e3,i=null,a=!1,s=()=>{a||(n=new EventSource(e),n.onopen=()=>{r=1e3},n.onmessage=e=>{try{let n=JSON.parse(e.data),r=F(n.type);if(r===null){P.debug(`connectors-sse: ignoring event`,n.type);return}let i=n.payload??{},a=i.connector_id??i.provider??null;t.current({connectorId:a,reason:r,payload:i})}catch(e){P.warn(`connectors-sse: malformed event`,e)}},n.onerror=()=>{n?.close(),n=null,!a&&(i=setTimeout(s,r),r=Math.min(r*2,3e4))})};return s(),()=>{a=!0,i&&clearTimeout(i),n?.close()}},[])}function L(e){return e.type===`mcp_server`&&e.configured}function R({connector:e,onChanged:t}){let i=n(),[o,s]=(0,N.useState)(!1),[c,l]=(0,N.useState)(!1),[u,d]=(0,N.useState)(null),[m,h]=(0,N.useState)(null),g=(0,N.useRef)(null),_=(0,N.useRef)(null);(0,N.useEffect)(()=>{if(!o)return;let e=e=>{let t=e.target;g.current&&!g.current.contains(t)&&_.current&&!_.current.contains(t)&&s(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[o]);let v=(0,N.useCallback)(()=>s(!1),[]);if(j(o,v),(0,N.useEffect)(()=>{if(!o)return;let e=()=>{if(!g.current)return;let e=g.current.getBoundingClientRect();h({top:e.bottom+4,right:window.innerWidth-e.right})};return window.addEventListener(`resize`,e),window.addEventListener(`scroll`,e,!0),()=>{window.removeEventListener(`resize`,e),window.removeEventListener(`scroll`,e,!0)}},[o]),!L(e))return null;let b=e=>{e.stopPropagation(),e.preventDefault()},x=e=>{if(b(e),!o&&g.current){let e=g.current.getBoundingClientRect();h({top:e.bottom+4,right:window.innerWidth-e.right})}s(e=>!e)},S=async e=>{l(!0),d(null);try{await e(),s(!1),t()}catch(e){d(e instanceof Error?e.message:String(e))}finally{l(!1)}};return a(`div`,{className:`connector-tile-menu`,onClick:b,onKeyDown:b,children:[r(`button`,{ref:g,type:`button`,className:`connector-tile-menu-trigger`,"aria-haspopup":`menu`,"aria-expanded":o,"aria-label":i(`settings.connectors.actions`),onClick:x,disabled:c,children:r(D,{size:14})}),o&&m&&a(`div`,{ref:_,role:`menu`,className:`connector-tile-menu-popup`,style:{position:`fixed`,top:m.top,right:m.right},children:[e.enabled?r(`button`,{role:`menuitem`,type:`button`,className:`connector-tile-menu-item`,onClick:()=>void S(()=>f(e.id)),disabled:c,children:i(`settings.connectors.disable`)}):r(`button`,{role:`menuitem`,type:`button`,className:`connector-tile-menu-item`,onClick:()=>void S(()=>y(e.id)),disabled:c,children:i(`settings.connectors.enable`)}),r(`div`,{className:`connector-tile-menu-divider`}),r(`button`,{role:`menuitem`,type:`button`,className:`connector-tile-menu-item connector-tile-menu-item--danger`,onClick:()=>void S(()=>p(e.id)),disabled:c,children:i(`settings.connectors.disconnect`)}),u&&r(`div`,{className:`connector-tile-menu-error`,children:u})]})]})}var z={"https://www.googleapis.com/auth/gmail.readonly":`settings.connectors.scope.gmailRead`,"https://www.googleapis.com/auth/gmail.modify":`settings.connectors.scope.gmailModify`,"https://www.googleapis.com/auth/gmail.send":`settings.connectors.scope.gmailSend`,"https://www.googleapis.com/auth/gmail.compose":`settings.connectors.scope.gmailCompose`,"https://www.googleapis.com/auth/calendar.readonly":`settings.connectors.scope.calendarRead`,"https://www.googleapis.com/auth/calendar.events":`settings.connectors.scope.calendarEvents`,"https://www.googleapis.com/auth/drive.readonly":`settings.connectors.scope.driveRead`,"https://www.googleapis.com/auth/drive.file":`settings.connectors.scope.driveFile`,"https://www.googleapis.com/auth/spreadsheets.readonly":`settings.connectors.scope.sheetsRead`,"https://www.googleapis.com/auth/spreadsheets":`settings.connectors.scope.sheets`,openid:`settings.connectors.scope.openid`,"https://www.googleapis.com/auth/userinfo.email":`settings.connectors.scope.email`,email:`settings.connectors.scope.email`,profile:`settings.connectors.scope.profile`,"https://graph.microsoft.com/Mail.ReadWrite":`settings.connectors.scope.outlookMail`,"https://graph.microsoft.com/Mail.Send":`settings.connectors.scope.outlookSend`,"https://graph.microsoft.com/Calendars.ReadWrite":`settings.connectors.scope.outlookCalendar`,"https://graph.microsoft.com/Calendars.Read":`settings.connectors.scope.outlookCalendarRead`,"https://graph.microsoft.com/User.Read":`settings.connectors.scope.microsoftProfile`};function B(e,t){let n=z[e];return n?t(n):e.split(/[/.:]/).pop()??e}var V=6,H=[`use`];function U(e,t){return!(`revoke_supported`in e)||e.revoke_supported&&e.revoked_remotely?null:e.revoke_supported&&!e.revoked_remotely?t(`settings.connectors.notRevoked`,{reason:String(e.revoke_error??t.bare(`settings.advanced.unknown`))}):e.revoke_error?t(`settings.connectors.localOnly`,{reason:String(e.revoke_error)}):t(`settings.connectors.noRevokeApi`)}function W(){let e=n(),[t,i]=(0,N.useState)([]),[o,s]=(0,N.useState)([]),[l,u]=(0,N.useState)(!0),[d,f]=(0,N.useState)(null),[p,h]=(0,N.useState)(null),[g,v]=(0,N.useState)(null),[y,b]=(0,N.useState)(``),x=(0,N.useCallback)(async()=>{try{let[{connectors:e},{agent_mcps:t}]=await Promise.all([C(),m()]);i(e),s(t),f(null)}catch(e){f(e instanceof Error?e.message:String(e))}finally{u(!1)}},[]);(0,N.useEffect)(()=>{x()},[x]);let S=e=>v(t=>t===e?null:e),w=(0,N.useCallback)(async e=>{try{let t=await _(e);i(n=>n.map(n=>n.id===e?t:n))}catch{x()}},[x]);I((0,N.useCallback)(t=>{t.reason===`disconnected`&&h(U(t.payload,e)),t.connectorId?w(t.connectorId):x()},[w,x,e]));let T=y.trim().toLowerCase(),D=t.filter(e=>!T||e.display_name.toLowerCase().includes(T)||e.description.toLowerCase().includes(T)),O=D.filter(e=>e.configured),k=D.filter(e=>!e.configured&&e.type===`oauth_pkce`),j=D.filter(e=>!e.configured&&e.type!==`oauth_pkce`),P=!t.some(e=>e.configured),F=e=>r(`div`,{className:`connectors-list`,children:e.map(e=>r(G,{connector:e,expanded:g===e.id,onToggle:()=>S(e.id),onChanged:()=>void w(e.id)},e.id))});return a(`section`,{className:`connectors-section`,"aria-label":e(`settings.section.connectors`),children:[r(`p`,{className:`settings-pane-lede`,children:e(`settings.connectors.lede`)}),d&&a(`div`,{className:`error-banner`,children:[r(E,{size:14}),r(`span`,{children:d})]}),p&&a(`div`,{className:`error-banner`,role:`status`,onClick:()=>h(null),children:[r(E,{size:14}),r(`span`,{children:p})]}),l?r(`div`,{className:`connectors-loading`,children:r(M,{size:16,className:`spin`})}):a(c.Fragment,{children:[t.length>V&&r(`input`,{className:`settings-input`,type:`search`,value:y,onChange:e=>b(e.target.value),placeholder:e(`settings.connectors.search`),"aria-label":e(`settings.connectors.search`)}),t.length===0&&!d&&r(`p`,{className:`settings-hint`,children:e(`settings.connectors.none`)}),T&&D.length===0&&r(`p`,{className:`settings-hint`,children:e(`settings.connectors.noMatch`)}),O.length>0&&r(A,{title:e(`settings.connectors.connected`),count:O.length,defaultOpen:!0,forceOpen:!!T,children:F(O)}),k.length>0&&r(A,{title:e(`settings.connectors.accounts`),hint:e(`settings.connectors.accountsHint`),count:k.length,defaultOpen:P,forceOpen:!!T,children:F(k)}),j.length>0&&r(A,{title:e(`settings.connectors.servers`),hint:e(`settings.connectors.serversHint`),count:j.length,forceOpen:!!T,children:F(j)}),o.length>0&&!T&&r(A,{title:e(`settings.connectors.agentServers`),count:o.length,children:r(X,{servers:o,expanded:g,onToggle:S})})]})]})}function G({connector:e,expanded:t,onToggle:i,onChanged:o}){let s=n();return a(`div`,{className:`connector-tile${t?` connector-tile--open`:``}`,children:[a(`div`,{className:`connector-tile-row`,children:[a(`button`,{type:`button`,className:`connector-tile-header`,onClick:i,"aria-expanded":t,children:[r(`bdi`,{className:`connector-tile-name`,children:e.display_name}),e.configured&&r(`span`,{className:`connector-tile-type`,children:e.type===`oauth_pkce`?`OAuth`:`MCP`}),e.configured?e.type===`mcp_server`&&e.enabled===!1?r(`span`,{className:`connector-status disabled`,children:s(`settings.connectors.disabled`)}):a(`span`,{className:`connector-status ok`,children:[r(T,{size:12}),e.account_id?r(`bdi`,{dir:`ltr`,children:e.account_id}):s(`settings.connectors.configured`)]}):e.configurable===!1?r(`span`,{className:`connector-status idle`,children:s(`settings.connectors.setupRequired`)}):null,r(`span`,{className:`connector-tile-chevron`,children:r(t?O:k,{size:14})})]}),r(R,{connector:e,onChanged:o})]}),t&&a(`div`,{className:`connector-detail`,children:[e.type===`oauth_pkce`?r(K,{connector:e,onChanged:o}):r(J,{connector:e,onChanged:o}),e.configured&&r(Q,{connectorId:e.id,connectorType:e.type})]})]})}function K({connector:e,onChanged:t}){let o=n(),[s,l]=(0,N.useState)(!1),[u,f]=(0,N.useState)(null),[m,h]=(0,N.useState)({}),[_,v]=(0,N.useState)(null),{agents:y}=i(),x=y.filter(t=>t.namespaced_agent_id&&t.required_connections?.some(t=>t.connector_id===e.id)),S=x.map(e=>e.namespaced_agent_id).join(`,`),[C,T]=(0,N.useState)(()=>new Set);(0,N.useEffect)(()=>{T(new Set(x.map(e=>e.namespaced_agent_id)))},[S]);let D=e=>T(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n}),O=()=>[...C];(0,N.useEffect)(()=>{let e=()=>{t()};return window.addEventListener(`focus`,e),()=>window.removeEventListener(`focus`,e)},[t]);let k=e=>{let t=window;t.gaia?.openExternal?t.gaia.openExternal(e):window.open(e,`_blank`,`noopener`)},A=async()=>{l(!0),f(null);try{let t=await b(e.id,e.available_scopes?.length?e.available_scopes:e.default_scopes,O());k(t.authorization_url)}catch(e){f(e instanceof Error?e.message:String(e))}finally{l(!1)}},j=async()=>{l(!0),f(null),v(null);try{let t=await d(e.id,e.available_scopes?.length?e.available_scopes:e.default_scopes,O());v(t)}catch(e){f(e instanceof Error?e.message:String(e))}finally{l(!1)}};(0,N.useEffect)(()=>{e.configured&&v(null)},[e.configured]),I((0,N.useCallback)(t=>{t.connectorId===e.id&&(t.reason===`oauth_error`?(f(String(t.payload.error??o(`settings.connectors.deviceFailed`))),v(null)):t.reason===`oauth_completed`&&v(null))},[e.id,o]));let P=async()=>{l(!0),f(null);try{await p(e.id),t()}catch(e){f(e instanceof Error?e.message:String(e))}finally{l(!1)}},F=async()=>{let n=(e.oauth_setup_fields??[]).filter(e=>e.required!==!1&&!m[e.key]?.trim()).map(e=>e.label);if(n.length)f(o(`settings.connectors.required`,{fields:n.join(`, `)}));else{l(!0),f(null);try{let n=e.available_scopes?.length?e.available_scopes:e.default_scopes,r=await g(e.id,{...m,scopes:n,grant_agents:O()}),i=typeof r.authorization_url==`string`?r.authorization_url:null;i&&k(i),t()}catch(e){f(e instanceof Error?e.message:String(e))}finally{l(!1)}}},L=e.oauth_setup_fields??[],R=e.configurable===!1&&!e.configured&&L.length>0;return a(`div`,{className:`configure-body`,children:[e.description&&r(`p`,{className:`connector-desc`,children:r(`bdi`,{children:e.description})}),R&&a(`div`,{className:`oauth-setup-form`,children:[r(`p`,{className:`connector-desc`,children:o(`settings.connectors.firstSetup`)}),L.map(e=>a(`label`,{className:`oauth-setup-field`,children:[r(`span`,{className:`oauth-setup-label`,children:e.label}),r(`input`,{type:e.kind===`secret`?`password`:`text`,className:`oauth-setup-input`,placeholder:e.placeholder,value:m[e.key]??``,onChange:t=>h(n=>({...n,[e.key]:t.target.value})),autoComplete:`off`,spellCheck:!1}),e.help_md&&r(`span`,{className:`oauth-setup-help`,children:r(`bdi`,{children:e.help_md})})]},e.key))]}),!e.configured&&x.length>0&&a(`div`,{className:`oauth-grant-onconnect`,children:[r(`p`,{className:`oauth-grant-onconnect-label`,children:o(`settings.connectors.grantOnConnect`)}),x.map(e=>a(`label`,{className:`oauth-grant-onconnect-item`,children:[r(`input`,{type:`checkbox`,checked:C.has(e.namespaced_agent_id),onChange:()=>D(e.namespaced_agent_id)}),r(`span`,{children:e.name})]},e.namespaced_agent_id)),r(`p`,{className:`oauth-grant-onconnect-help`,children:o(`settings.connectors.grantLater`)})]}),!R&&r(q,{connector:e,onChanged:t}),u&&a(`div`,{className:`configure-error`,children:[r(E,{size:12}),` `,u]}),a(`div`,{className:`configure-actions`,children:[e.configured?r(`button`,{className:`btn-secondary`,disabled:s,onClick:()=>void P(),children:s?r(M,{size:12,className:`spin`}):o(`settings.connectors.disconnect`)}):R?r(`button`,{className:`btn-primary`,disabled:s,onClick:()=>void F(),children:s?r(M,{size:12,className:`spin`}):a(c.Fragment,{children:[r(w,{size:12}),` `,o(`settings.connectors.saveConnect`)]})}):e.configurable===!1?r(`span`,{className:`connector-setup-required`,title:e.config_error??void 0,children:o(`settings.connectors.setupRequired`)}):a(c.Fragment,{children:[r(`button`,{className:`btn-primary`,disabled:s||_!==null,onClick:()=>void A(),children:s?r(M,{size:12,className:`spin`}):a(c.Fragment,{children:[r(w,{size:12}),` `,o(`settings.key.connect`)]})}),e.supports_device_code&&r(`button`,{className:`btn-secondary`,disabled:s||_!==null,onClick:()=>void j(),title:o(`settings.connectors.codeTitle`),children:o(`settings.connectors.code`)})]}),(e.docs_url||e.product_url)&&a(`a`,{href:e.docs_url||e.product_url||`#`,target:`_blank`,rel:`noopener noreferrer`,className:`connector-product-link`,children:[o(`settings.connectors.learnMore`),` `,r(w,{size:11})]})]}),_&&!e.configured&&a(`div`,{className:`device-code-block`,children:[a(`p`,{className:`device-code-instructions`,children:[o(`settings.connectors.goTo`),` `,r(`a`,{href:_.verification_uri,target:`_blank`,rel:`noopener noreferrer`,onClick:e=>{e.preventDefault(),k(_.verification_uri)},children:_.verification_uri})]}),a(`div`,{className:`device-code-value`,children:[r(`code`,{children:_.user_code}),r(`button`,{type:`button`,className:`btn-secondary`,onClick:()=>void navigator.clipboard?.writeText(_.user_code),title:o(`settings.connectors.copyCode`),children:o(`gpu.copy`)})]}),a(`p`,{className:`device-code-waiting`,children:[r(M,{size:12,className:`spin`}),` `,o(`settings.connectors.waiting`)]}),r(`button`,{type:`button`,className:`btn-secondary`,onClick:()=>v(null),children:o(`settings.key.cancel`)})]})]})}function q({connector:e,onChanged:t}){let i=n(),[o,s]=(0,N.useState)(!1),[l,u]=(0,N.useState)({}),[d,f]=(0,N.useState)(!1),[p,m]=(0,N.useState)(!1),[h,_]=(0,N.useState)(null),v=e.oauth_setup_fields??[];if(v.length===0)return null;let y=e.oauth_client,b=y?.source===`keyring`?i(`settings.connectors.savedClient`,{id:y.client_id??``}):y?.source===`env`?i(`settings.connectors.envClient`,{id:y.client_id??``}):i(`settings.connectors.noClient`),x=async()=>{if(!l.client_id?.trim())_(i(`settings.connectors.clientRequired`));else{f(!0),_(null),m(!1);try{await g(e.id,{...Object.fromEntries(Object.entries(l).map(([e,t])=>[e,t.trim()])),save_only:!0}),m(!0),u({}),t(),setTimeout(()=>m(!1),2200)}catch(e){_(e instanceof Error?e.message:String(e))}finally{f(!1)}}};return a(`div`,{className:`oauth-client-editor`,children:[a(`button`,{type:`button`,className:`oauth-client-editor__toggle`,onClick:()=>s(e=>!e),"aria-expanded":o,children:[r(o?O:k,{size:12}),r(`span`,{children:i(`settings.connectors.client`)}),r(`span`,{className:`oauth-client-editor__status`,children:b})]}),o&&a(`div`,{className:`oauth-setup-form`,children:[r(`p`,{className:`connector-desc`,children:i(`settings.connectors.clientHelp`)}),v.map(e=>a(`label`,{className:`oauth-setup-field`,children:[r(`span`,{className:`oauth-setup-label`,children:e.label}),r(`input`,{type:e.kind===`secret`?`password`:`text`,className:`oauth-setup-input`,placeholder:e.kind===`secret`&&y?.source===`keyring`&&y.has_secret?`••••••••`:e.placeholder,value:l[e.key]??``,onChange:t=>u(n=>({...n,[e.key]:t.target.value})),autoComplete:`off`,spellCheck:!1}),e.help_md&&r(`span`,{className:`oauth-setup-help`,children:r(`bdi`,{children:e.help_md})})]},e.key)),h&&a(`div`,{className:`configure-error`,children:[r(E,{size:12}),` `,h]}),r(`div`,{className:`configure-actions`,children:r(`button`,{className:`btn-model-save${p?` saved`:``}`,disabled:d||!l.client_id?.trim(),onClick:()=>void x(),children:d?r(M,{size:12,className:`spin`}):p?a(c.Fragment,{children:[r(T,{size:12}),` `,i(`settings.advanced.saved`)]}):i(`settings.connectors.saveClient`)})})]})]})}function J({connector:e,onChanged:t}){let i=n(),[o,s]=(0,N.useState)(()=>Object.fromEntries(e.mcp_env_keys.map(e=>[e,``]))),[l,u]=(0,N.useState)(!1),[d,m]=(0,N.useState)(!1),[h,_]=(0,N.useState)(null);(0,N.useEffect)(()=>{s(Object.fromEntries(e.mcp_env_keys.map(e=>[e,``])))},[e.mcp_env_keys.join(`,`)]);let v=e.mcp_env_keys.length===0,b=Object.values(o).every(e=>e.trim()===``),x=async()=>{let n=Object.fromEntries(Object.entries(o).filter(([,e])=>e.trim()!==``));if(v||Object.keys(n).length!==0){u(!0),_(null),m(!1);try{await g(e.id,n),m(!0),t(),setTimeout(()=>m(!1),2200)}catch(e){_(e instanceof Error?e.message:String(e))}finally{u(!1)}}},S=async()=>{u(!0),_(null);try{await p(e.id),s(Object.fromEntries(e.mcp_env_keys.map(e=>[e,``]))),t()}catch(e){_(e instanceof Error?e.message:String(e))}finally{u(!1)}},C=async()=>{u(!0),_(null);try{e.enabled?await f(e.id):await y(e.id),t()}catch(e){_(e instanceof Error?e.message:String(e))}finally{u(!1)}};return a(`div`,{className:`configure-body`,children:[e.description&&r(`p`,{className:`connector-desc`,children:r(`bdi`,{children:e.description})}),h&&a(`div`,{className:`configure-error`,children:[r(E,{size:12}),` `,h]}),e.configured&&a(`div`,{className:`connector-toggle-row`,children:[r(`span`,{className:`connector-toggle-label`,children:i(`settings.connectors.active`)}),a(`span`,{className:`toggle-switch`,children:[r(`input`,{type:`checkbox`,checked:e.enabled!==!1,onChange:()=>void C(),disabled:l,"aria-label":e.enabled?i(`settings.connectors.disableServer`):i(`settings.connectors.enableServer`)}),r(`span`,{className:`toggle-track`})]})]}),e.configured&&e.enabled===!1&&r(`p`,{className:`connector-toggle-help`,children:i(`settings.connectors.disabledHelp`)}),e.mcp_env_keys.map(t=>a(`div`,{className:`mcp-key-row`,children:[r(`label`,{className:`mcp-key-label`,children:t}),r(`input`,{type:`password`,className:`mcp-key-input`,placeholder:e.configured?`••••••••`:i.bare(`settings.connectors.enterValue`),value:o[t]??``,onChange:e=>s(n=>({...n,[t]:e.target.value})),spellCheck:!1,autoComplete:`off`})]},t)),a(`div`,{className:`configure-actions`,children:[!(v&&e.configured)&&r(`button`,{className:`btn-model-save${d?` saved`:``}`,disabled:l||!v&&b,onClick:()=>void x(),children:l?r(M,{size:12,className:`spin`}):d?a(c.Fragment,{children:[r(T,{size:12}),` `,i(`settings.advanced.saved`)]}):i(v?`settings.key.connect`:`settings.advanced.save`)}),e.configured&&r(`button`,{className:`btn-secondary`,disabled:l,onClick:()=>void S(),children:i(`settings.connectors.disconnect`)}),e.product_url&&a(`a`,{href:e.product_url,target:`_blank`,rel:`noopener noreferrer`,className:`connector-product-link`,children:[i(`settings.connectors.docs`),` `,r(w,{size:11})]})]})]})}function Y({agent:e,connectorId:t,grantedScopes:i,onChanged:o}){let s=n(),c=e.required_connections?.find(e=>e.connector_id===t),l=e.namespaced_agent_id;if(!c||!l)return null;let[d,f]=(0,N.useState)(()=>new Set(i)),[p,m]=(0,N.useState)(null),[g,_]=(0,N.useState)(null);(0,N.useEffect)(()=>{f(new Set(i))},[i.join(`,`)]);let v=async e=>{if(p!==null)return;let n=new Set(d);n.has(e)?n.delete(e):n.add(e),f(n),m(e),_(null);try{n.size===0?await u(t,l):await h(t,l,[...n]),o()}catch(e){f(new Set(i)),_(e instanceof Error?e.message:String(e))}finally{m(null)}};return a(`div`,{className:`grant-agent-card`,children:[r(`bdi`,{className:`grant-agent-card-name`,children:e.name}),r(`div`,{className:`grant-scope-list`,children:c.scopes.map(e=>a(`label`,{className:`grant-scope-item`,children:[r(`span`,{className:`grant-scope-label`,children:B(e,s)}),a(`span`,{className:`toggle-switch`,children:[r(`input`,{type:`checkbox`,checked:d.has(e),onChange:()=>void v(e),disabled:p!==null}),r(`span`,{className:`toggle-track`})]})]},e))}),g&&a(`div`,{className:`grant-scope-warning grant-scope-warning--error`,children:[r(E,{size:11}),` `,g]})]})}function X({servers:e,expanded:t,onToggle:n}){return r(`div`,{className:`agent-mcps-section`,children:r(`div`,{className:`connectors-list`,children:e.map(e=>{let i=`${e.agent_id}::${e.server_name}`;return r(Z,{server:e,expanded:t===i,onToggle:()=>n(i)},i)})})})}function Z({server:e,expanded:t,onToggle:i}){let o=n(),s=[e.command,...e.args].join(` `);return a(`div`,{className:`agent-mcp-tile${t?` agent-mcp-tile--open`:``}`,children:[a(`button`,{type:`button`,className:`agent-mcp-tile-header`,onClick:i,"aria-expanded":t,children:[r(`span`,{className:`agent-mcp-server-name`,children:e.server_name}),r(`span`,{className:`agent-mcp-agent-label`,children:o(`settings.connectors.via`,{name:e.agent_name})}),e.disabled?r(`span`,{className:`agent-mcp-status disabled`,children:o(`settings.connectors.disabled`)}):a(`span`,{className:`agent-mcp-status enabled`,children:[r(T,{size:11}),` `,o(`settings.connectors.active`)]}),r(`span`,{className:`agent-mcp-readonly-badge`,children:o(`settings.connectors.readOnly`)}),r(`span`,{className:`agent-mcp-chevron`,children:r(t?O:k,{size:14})})]}),t&&a(`div`,{className:`agent-mcp-detail`,children:[s&&r(`bdi`,{dir:`ltr`,className:`agent-mcp-command-row`,children:s}),r(`bdi`,{dir:`ltr`,className:`agent-mcp-config-path`,children:e.config_path}),r(`div`,{className:`agent-mcp-config-hint`,children:o(`settings.connectors.editConfig`)})]})]})}function Q({connectorId:e,connectorType:t}){let o=n(),{agents:s}=i(),[u,d]=(0,N.useState)({}),[f,p]=(0,N.useState)({}),[m,h]=(0,N.useState)(!0),g=(0,N.useCallback)(async()=>{try{let[{grants:t},{activations:n}]=await Promise.all([S(e),l(e)]);d(t),p(n)}catch{d({}),p({})}finally{h(!1)}},[e]);if((0,N.useEffect)(()=>{g()},[g]),I((0,N.useCallback)(t=>{t.connectorId===e&&(t.reason===`grant_changed`||t.reason===`activation_changed`||t.reason===`disconnected`)&&g()},[e,g])),m)return null;let _=s.filter(t=>t.namespaced_agent_id&&t.required_connections?.some(t=>t.connector_id===e)),v=t===`mcp_server`?s.filter(t=>t.namespaced_agent_id&&(t.consumes_mcp_servers||t.required_connections?.some(t=>t.connector_id===e))):[];return a(`div`,{className:`connection-grants`,children:[r(`div`,{className:`grants-header`,children:o(`settings.connectors.grants`)}),_.length===0?r(`div`,{className:`grants-empty`,children:o(`settings.connectors.noGrants`)}):_.map(t=>r(Y,{agent:t,connectorId:e,grantedScopes:u[t.namespaced_agent_id]??[],onChanged:()=>void g()},t.namespaced_agent_id)),v.length>0&&a(c.Fragment,{children:[r(`div`,{className:`grants-header grants-header--activations`,children:o(`settings.connectors.activeFor`)}),r(`div`,{className:`grants-help`,children:o(`settings.connectors.activationHelp`)}),v.map(t=>r($,{agent:t,connectorId:e,active:!!f[t.namespaced_agent_id],grantedScopes:u[t.namespaced_agent_id]??[],onChanged:()=>void g()},`activation-${t.namespaced_agent_id}`))]})]})}function $({agent:e,connectorId:t,active:i,grantedScopes:o,onChanged:s}){let c=n(),l=e.required_connections?.find(e=>e.connector_id===t),u=e.namespaced_agent_id;if(!u)return null;let[d,f]=(0,N.useState)(i),[p,m]=(0,N.useState)(!1),[h,g]=(0,N.useState)(null);(0,N.useEffect)(()=>{f(i)},[i]);let _=async()=>{if(p)return;let e=!d;f(e),m(!0),g(null);try{if(e){let e=o.length===0?l?[...l.scopes]:[...H]:void 0;await v(t,u,e)}else await x(t,u);s()}catch(e){f(i),g(e instanceof Error?e.message:String(e))}finally{m(!1)}};return a(`div`,{className:`grant-agent-card`,children:[r(`bdi`,{className:`grant-agent-card-name`,children:e.name}),r(`div`,{className:`grant-scope-list`,children:a(`label`,{className:`grant-scope-item`,children:[r(`span`,{className:`grant-scope-label`,children:c(d?`settings.connectors.toolsVisible`:`settings.connectors.toolsHidden`)}),a(`span`,{className:`toggle-switch`,children:[r(`input`,{type:`checkbox`,checked:d,onChange:()=>void _(),disabled:p}),r(`span`,{className:`toggle-track`})]})]})}),h&&a(`div`,{className:`grant-scope-warning grant-scope-warning--error`,children:[r(E,{size:11}),` `,h]})]})}function ee(){let e=n();return a(`div`,{className:`settings-pane`,children:[r(`h2`,{className:`settings-pane-title`,children:e(`settings.section.connectors`)}),r(W,{})]})}export{ee as ConnectorsPane};