langchain_agentx_stream_ui 0.7.9 → 0.8.2
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/dist/{chunk-AMUGAG7U.js → chunk-MI4NGIDF.js} +2 -2
- package/dist/{chunk-RWKNI52H.js → chunk-XEIQBTD2.js} +155 -71
- package/dist/chunk-XEIQBTD2.js.map +1 -0
- package/dist/default.css +396 -0
- package/dist/index.d.ts +94 -3
- package/dist/index.js +640 -6
- package/dist/index.js.map +1 -1
- package/dist/{multi-session-9LtrGlsm.d.ts → multi-session-BoyeyFv9.d.ts} +25 -0
- package/dist/multi-session.d.ts +1 -1
- package/dist/multi-session.js +2 -2
- package/dist/virtual.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-RWKNI52H.js.map +0 -1
- /package/dist/{chunk-AMUGAG7U.js.map → chunk-MI4NGIDF.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
fixDiagramSvg,
|
|
25
25
|
markEventIdSeen,
|
|
26
26
|
shouldSkipDuplicateEvent
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-MI4NGIDF.js";
|
|
28
28
|
import {
|
|
29
29
|
DefaultToolBody,
|
|
30
30
|
InteractionBusContext,
|
|
@@ -121,7 +121,7 @@ import {
|
|
|
121
121
|
useSessionStatus,
|
|
122
122
|
useSessionViewOptions,
|
|
123
123
|
useTimeline
|
|
124
|
-
} from "./chunk-
|
|
124
|
+
} from "./chunk-XEIQBTD2.js";
|
|
125
125
|
import {
|
|
126
126
|
AGENT_PROGRESS_GUTTER,
|
|
127
127
|
AGENT_PROGRESS_INDENT,
|
|
@@ -6134,6 +6134,639 @@ var DEMO_WORKFLOW_SCALE = {
|
|
|
6134
6134
|
evictCompletedLoops: true
|
|
6135
6135
|
};
|
|
6136
6136
|
|
|
6137
|
+
// src/view/mcp/McpPanel.tsx
|
|
6138
|
+
import {
|
|
6139
|
+
useCallback as useCallback6,
|
|
6140
|
+
useEffect as useEffect12,
|
|
6141
|
+
useRef as useRef6,
|
|
6142
|
+
useState as useState8
|
|
6143
|
+
} from "react";
|
|
6144
|
+
import { Fragment as Fragment5, jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
6145
|
+
var STATE_META = {
|
|
6146
|
+
connecting: { icon: "\u27F3", label: "\u8FDE\u63A5\u4E2D", tone: "running" },
|
|
6147
|
+
connected: { icon: "\u25CF", label: "\u5DF2\u8FDE\u63A5", tone: "success" },
|
|
6148
|
+
failed: { icon: "\u2717", label: "\u8FDE\u63A5\u5931\u8D25", tone: "error" },
|
|
6149
|
+
disconnected: { icon: "\u25CB", label: "\u672A\u8FDE\u63A5", tone: "muted" },
|
|
6150
|
+
reconnecting: { icon: "\u27F3", label: "\u91CD\u8FDE\u4E2D", tone: "running" },
|
|
6151
|
+
needs_auth: { icon: "\u26A0", label: "\u9700\u8981\u9274\u6743", tone: "warning" },
|
|
6152
|
+
disabled: { icon: "\u2298", label: "\u5DF2\u505C\u7528", tone: "muted" }
|
|
6153
|
+
};
|
|
6154
|
+
var ADJ_META = {
|
|
6155
|
+
allowed: { icon: "\u2713", label: "\u5C06\u8FDB\u6C60", cls: "lax-mcp-adj--allowed" },
|
|
6156
|
+
denied: { icon: "\u2717", label: "\u88AB deny \u5265\u79BB", cls: "lax-mcp-adj--denied" },
|
|
6157
|
+
uncovered: { icon: "\u26A0", label: "\u672A\u8986\u76D6 \u2192 \u4E0D\u8FDB\u6C60", cls: "lax-mcp-adj--uncovered" }
|
|
6158
|
+
};
|
|
6159
|
+
var EMPTY_FORM = {
|
|
6160
|
+
name: "",
|
|
6161
|
+
transport: "stdio",
|
|
6162
|
+
command: "",
|
|
6163
|
+
argsText: "",
|
|
6164
|
+
envText: "",
|
|
6165
|
+
cwd: "",
|
|
6166
|
+
url: "",
|
|
6167
|
+
headersText: ""
|
|
6168
|
+
};
|
|
6169
|
+
function errorMessage(err) {
|
|
6170
|
+
return err instanceof Error ? err.message : String(err);
|
|
6171
|
+
}
|
|
6172
|
+
function splitLines(text) {
|
|
6173
|
+
return text.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
|
|
6174
|
+
}
|
|
6175
|
+
function parseKeyValueLines(text) {
|
|
6176
|
+
const lines = splitLines(text);
|
|
6177
|
+
if (lines.length === 0) return void 0;
|
|
6178
|
+
const record = {};
|
|
6179
|
+
for (const line of lines) {
|
|
6180
|
+
const eq = line.indexOf("=");
|
|
6181
|
+
if (eq <= 0) continue;
|
|
6182
|
+
record[line.slice(0, eq).trim()] = line.slice(eq + 1).trim();
|
|
6183
|
+
}
|
|
6184
|
+
return Object.keys(record).length > 0 ? record : void 0;
|
|
6185
|
+
}
|
|
6186
|
+
function toSpec(status) {
|
|
6187
|
+
return {
|
|
6188
|
+
name: status.name,
|
|
6189
|
+
transport: status.transport,
|
|
6190
|
+
command: status.command,
|
|
6191
|
+
args: status.args,
|
|
6192
|
+
env: status.env,
|
|
6193
|
+
cwd: status.cwd,
|
|
6194
|
+
url: status.url,
|
|
6195
|
+
headers: status.headers,
|
|
6196
|
+
enabled: status.enabled
|
|
6197
|
+
};
|
|
6198
|
+
}
|
|
6199
|
+
function buildSpec(form) {
|
|
6200
|
+
const spec = { name: form.name.trim(), transport: form.transport, enabled: true };
|
|
6201
|
+
if (form.transport === "stdio") {
|
|
6202
|
+
spec.command = form.command.trim();
|
|
6203
|
+
const args = form.argsText.trim().split(/\s+/).filter(Boolean);
|
|
6204
|
+
if (args.length > 0) spec.args = args;
|
|
6205
|
+
const env = parseKeyValueLines(form.envText);
|
|
6206
|
+
if (env) spec.env = env;
|
|
6207
|
+
if (form.cwd.trim()) spec.cwd = form.cwd.trim();
|
|
6208
|
+
} else {
|
|
6209
|
+
spec.url = form.url.trim();
|
|
6210
|
+
const headers = parseKeyValueLines(form.headersText);
|
|
6211
|
+
if (headers) spec.headers = headers;
|
|
6212
|
+
}
|
|
6213
|
+
return spec;
|
|
6214
|
+
}
|
|
6215
|
+
function McpPanel({ isOpen, onClose, client, demoServerSpec }) {
|
|
6216
|
+
const panelRef = useRef6(null);
|
|
6217
|
+
const [loading, setLoading] = useState8(true);
|
|
6218
|
+
const [loadError, setLoadError] = useState8(null);
|
|
6219
|
+
const [servers, setServers] = useState8([]);
|
|
6220
|
+
const [summary, setSummary] = useState8(null);
|
|
6221
|
+
const [allowText, setAllowText] = useState8("");
|
|
6222
|
+
const [denyText, setDenyText] = useState8("");
|
|
6223
|
+
const [rulesSaving, setRulesSaving] = useState8(false);
|
|
6224
|
+
const [rulesError, setRulesError] = useState8(null);
|
|
6225
|
+
const [toolsLoads, setToolsLoads] = useState8({});
|
|
6226
|
+
const [expanded, setExpanded] = useState8({});
|
|
6227
|
+
const [busy, setBusy] = useState8(null);
|
|
6228
|
+
const [formOpen, setFormOpen] = useState8(false);
|
|
6229
|
+
const [form, setForm] = useState8(EMPTY_FORM);
|
|
6230
|
+
const [formError, setFormError] = useState8(null);
|
|
6231
|
+
const refresh = useCallback6(
|
|
6232
|
+
async (showLoading = false) => {
|
|
6233
|
+
if (showLoading) setLoading(true);
|
|
6234
|
+
try {
|
|
6235
|
+
const [serversRes, summaryRes, rulesRes] = await Promise.all([
|
|
6236
|
+
client.listServers(),
|
|
6237
|
+
client.getSummary(),
|
|
6238
|
+
client.getRules()
|
|
6239
|
+
]);
|
|
6240
|
+
setServers(serversRes.servers);
|
|
6241
|
+
setSummary(summaryRes);
|
|
6242
|
+
setAllowText(rulesRes.allow.join("\n"));
|
|
6243
|
+
setDenyText(rulesRes.deny.join("\n"));
|
|
6244
|
+
setLoadError(null);
|
|
6245
|
+
} catch (err) {
|
|
6246
|
+
setLoadError(errorMessage(err));
|
|
6247
|
+
} finally {
|
|
6248
|
+
if (showLoading) setLoading(false);
|
|
6249
|
+
}
|
|
6250
|
+
},
|
|
6251
|
+
[client]
|
|
6252
|
+
);
|
|
6253
|
+
const loadTools = useCallback6(
|
|
6254
|
+
async (name) => {
|
|
6255
|
+
setToolsLoads((prev) => ({ ...prev, [name]: { status: "loading", tools: [] } }));
|
|
6256
|
+
try {
|
|
6257
|
+
const res = await client.listTools(name);
|
|
6258
|
+
setToolsLoads((prev) => ({ ...prev, [name]: { status: "ok", tools: res.tools } }));
|
|
6259
|
+
} catch (err) {
|
|
6260
|
+
setToolsLoads((prev) => ({
|
|
6261
|
+
...prev,
|
|
6262
|
+
[name]: { status: "error", error: errorMessage(err), tools: [] }
|
|
6263
|
+
}));
|
|
6264
|
+
}
|
|
6265
|
+
},
|
|
6266
|
+
[client]
|
|
6267
|
+
);
|
|
6268
|
+
useEffect12(() => {
|
|
6269
|
+
if (!isOpen) return;
|
|
6270
|
+
void refresh(true);
|
|
6271
|
+
const onKeyDown = (event) => {
|
|
6272
|
+
if (event.key === "Escape") onClose();
|
|
6273
|
+
};
|
|
6274
|
+
const prevOverflow = document.body.style.overflow;
|
|
6275
|
+
document.body.style.overflow = "hidden";
|
|
6276
|
+
window.addEventListener("keydown", onKeyDown);
|
|
6277
|
+
panelRef.current?.focus();
|
|
6278
|
+
return () => {
|
|
6279
|
+
window.removeEventListener("keydown", onKeyDown);
|
|
6280
|
+
document.body.style.overflow = prevOverflow;
|
|
6281
|
+
};
|
|
6282
|
+
}, [isOpen, refresh, onClose]);
|
|
6283
|
+
const trapTabFocus = (event) => {
|
|
6284
|
+
if (event.key !== "Tab" || panelRef.current === null) return;
|
|
6285
|
+
const focusables = Array.from(
|
|
6286
|
+
panelRef.current.querySelectorAll(
|
|
6287
|
+
"button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), a[href]"
|
|
6288
|
+
)
|
|
6289
|
+
).filter((el) => el.offsetParent !== null);
|
|
6290
|
+
if (focusables.length === 0) return;
|
|
6291
|
+
const first = focusables[0];
|
|
6292
|
+
const last = focusables[focusables.length - 1];
|
|
6293
|
+
const active = document.activeElement;
|
|
6294
|
+
if (event.shiftKey && active === first) {
|
|
6295
|
+
event.preventDefault();
|
|
6296
|
+
last.focus();
|
|
6297
|
+
} else if (!event.shiftKey && active === last) {
|
|
6298
|
+
event.preventDefault();
|
|
6299
|
+
first.focus();
|
|
6300
|
+
}
|
|
6301
|
+
};
|
|
6302
|
+
const runAction = async (key, fn) => {
|
|
6303
|
+
if (busy !== null) return;
|
|
6304
|
+
setBusy(key);
|
|
6305
|
+
try {
|
|
6306
|
+
await fn();
|
|
6307
|
+
} catch (err) {
|
|
6308
|
+
setLoadError(errorMessage(err));
|
|
6309
|
+
} finally {
|
|
6310
|
+
setBusy(null);
|
|
6311
|
+
}
|
|
6312
|
+
};
|
|
6313
|
+
const saveServerList = (next, after) => runAction("put-servers", async () => {
|
|
6314
|
+
await client.putServers(next);
|
|
6315
|
+
after?.();
|
|
6316
|
+
await refresh();
|
|
6317
|
+
});
|
|
6318
|
+
const submitForm = () => {
|
|
6319
|
+
const spec = buildSpec(form);
|
|
6320
|
+
if (spec.name === "") {
|
|
6321
|
+
setFormError("name \u4E0D\u80FD\u4E3A\u7A7A");
|
|
6322
|
+
return;
|
|
6323
|
+
}
|
|
6324
|
+
if (servers.some((s) => s.name === spec.name)) {
|
|
6325
|
+
setFormError(`server "${spec.name}" \u5DF2\u5B58\u5728`);
|
|
6326
|
+
return;
|
|
6327
|
+
}
|
|
6328
|
+
if (spec.transport === "stdio" && !spec.command) {
|
|
6329
|
+
setFormError("stdio server \u9700\u8981 command");
|
|
6330
|
+
return;
|
|
6331
|
+
}
|
|
6332
|
+
if (spec.transport !== "stdio" && !spec.url) {
|
|
6333
|
+
setFormError(`${spec.transport} server \u9700\u8981 url`);
|
|
6334
|
+
return;
|
|
6335
|
+
}
|
|
6336
|
+
setFormError(null);
|
|
6337
|
+
void saveServerList([...servers.map(toSpec), spec], () => {
|
|
6338
|
+
setFormOpen(false);
|
|
6339
|
+
setForm(EMPTY_FORM);
|
|
6340
|
+
});
|
|
6341
|
+
};
|
|
6342
|
+
const deleteServer = (name) => saveServerList(
|
|
6343
|
+
servers.filter((s) => s.name !== name).map(toSpec)
|
|
6344
|
+
);
|
|
6345
|
+
const toggleEnabled = (server) => runAction(`toggle:${server.name}`, async () => {
|
|
6346
|
+
if (server.enabled) await client.disconnectServer(server.name);
|
|
6347
|
+
else await client.connectServer(server.name);
|
|
6348
|
+
await refresh();
|
|
6349
|
+
});
|
|
6350
|
+
const reconnectServer = (name) => runAction(`reconnect:${name}`, async () => {
|
|
6351
|
+
await client.reconnectServer(name);
|
|
6352
|
+
await refresh();
|
|
6353
|
+
});
|
|
6354
|
+
const toggleTools = (name) => {
|
|
6355
|
+
const next = !expanded[name];
|
|
6356
|
+
setExpanded((prev) => ({ ...prev, [name]: next }));
|
|
6357
|
+
if (next && !toolsLoads[name]) void loadTools(name);
|
|
6358
|
+
};
|
|
6359
|
+
const saveRules = async () => {
|
|
6360
|
+
if (rulesSaving) return;
|
|
6361
|
+
setRulesSaving(true);
|
|
6362
|
+
setRulesError(null);
|
|
6363
|
+
try {
|
|
6364
|
+
const res = await client.putRules({ allow: splitLines(allowText), deny: splitLines(denyText) });
|
|
6365
|
+
setAllowText(res.allow.join("\n"));
|
|
6366
|
+
setDenyText(res.deny.join("\n"));
|
|
6367
|
+
setToolsLoads({});
|
|
6368
|
+
for (const name of Object.keys(expanded)) {
|
|
6369
|
+
if (expanded[name]) void loadTools(name);
|
|
6370
|
+
}
|
|
6371
|
+
await refresh();
|
|
6372
|
+
} catch (err) {
|
|
6373
|
+
setRulesError(errorMessage(err));
|
|
6374
|
+
} finally {
|
|
6375
|
+
setRulesSaving(false);
|
|
6376
|
+
}
|
|
6377
|
+
};
|
|
6378
|
+
if (!isOpen) return null;
|
|
6379
|
+
const toolsInPool = summary !== null ? summary.tools_total - summary.tools_blocked : null;
|
|
6380
|
+
return /* @__PURE__ */ jsx20(
|
|
6381
|
+
"div",
|
|
6382
|
+
{
|
|
6383
|
+
className: "lax-mcp-overlay",
|
|
6384
|
+
role: "dialog",
|
|
6385
|
+
"aria-modal": "true",
|
|
6386
|
+
"aria-label": "MCP Servers",
|
|
6387
|
+
"data-testid": "lax-mcp-overlay",
|
|
6388
|
+
onClick: (event) => {
|
|
6389
|
+
if (event.target === event.currentTarget) onClose();
|
|
6390
|
+
},
|
|
6391
|
+
children: /* @__PURE__ */ jsxs17(
|
|
6392
|
+
"div",
|
|
6393
|
+
{
|
|
6394
|
+
className: "lax-mcp-panel",
|
|
6395
|
+
ref: panelRef,
|
|
6396
|
+
tabIndex: -1,
|
|
6397
|
+
"data-testid": "lax-mcp-panel",
|
|
6398
|
+
onKeyDown: trapTabFocus,
|
|
6399
|
+
onClick: (event) => event.stopPropagation(),
|
|
6400
|
+
children: [
|
|
6401
|
+
/* @__PURE__ */ jsxs17("header", { className: "lax-mcp-header", children: [
|
|
6402
|
+
/* @__PURE__ */ jsx20("span", { className: "lax-mcp-title", children: "MCP Servers" }),
|
|
6403
|
+
/* @__PURE__ */ jsx20(
|
|
6404
|
+
"span",
|
|
6405
|
+
{
|
|
6406
|
+
className: `lax-mcp-ready${summary?.ready ? " is-ready" : " is-not-ready"}`,
|
|
6407
|
+
"aria-live": "polite",
|
|
6408
|
+
"data-testid": "lax-mcp-ready",
|
|
6409
|
+
children: summary?.ready ? "\u25CF \u5C31\u7EEA" : "\u26A0 \u672A\u5C31\u7EEA"
|
|
6410
|
+
}
|
|
6411
|
+
),
|
|
6412
|
+
/* @__PURE__ */ jsx20("button", { type: "button", className: "lax-mcp-close", "aria-label": "\u5173\u95ED", onClick: onClose, children: "\xD7" })
|
|
6413
|
+
] }),
|
|
6414
|
+
loadError !== null && /* @__PURE__ */ jsxs17("div", { className: "lax-mcp-error", role: "alert", "data-testid": "lax-mcp-error", children: [
|
|
6415
|
+
/* @__PURE__ */ jsx20("span", { className: "lax-mcp-error-text", children: loadError }),
|
|
6416
|
+
/* @__PURE__ */ jsx20("button", { type: "button", className: "lax-mcp-btn", onClick: () => void refresh(true), children: "\u91CD\u8BD5" })
|
|
6417
|
+
] }),
|
|
6418
|
+
/* @__PURE__ */ jsx20("div", { className: "lax-mcp-body", children: loading ? /* @__PURE__ */ jsx20("div", { className: "lax-mcp-loading", "data-testid": "lax-mcp-loading", children: "\u52A0\u8F7D\u4E2D\u2026" }) : /* @__PURE__ */ jsxs17(Fragment5, { children: [
|
|
6419
|
+
/* @__PURE__ */ jsxs17("section", { className: "lax-mcp-section", "aria-label": "server \u914D\u7F6E", children: [
|
|
6420
|
+
/* @__PURE__ */ jsx20("div", { className: "lax-mcp-section-title", children: "\u2460 Server \u914D\u7F6E" }),
|
|
6421
|
+
/* @__PURE__ */ jsxs17("div", { className: "lax-mcp-config-actions", children: [
|
|
6422
|
+
/* @__PURE__ */ jsx20(
|
|
6423
|
+
"button",
|
|
6424
|
+
{
|
|
6425
|
+
type: "button",
|
|
6426
|
+
className: "lax-mcp-btn",
|
|
6427
|
+
onClick: () => {
|
|
6428
|
+
setFormOpen((v) => !v);
|
|
6429
|
+
setFormError(null);
|
|
6430
|
+
},
|
|
6431
|
+
children: "\uFF0B \u6DFB\u52A0 server"
|
|
6432
|
+
}
|
|
6433
|
+
),
|
|
6434
|
+
demoServerSpec !== void 0 && /* @__PURE__ */ jsxs17(
|
|
6435
|
+
"button",
|
|
6436
|
+
{
|
|
6437
|
+
type: "button",
|
|
6438
|
+
className: "lax-mcp-btn",
|
|
6439
|
+
disabled: servers.some((s) => s.name === demoServerSpec.name),
|
|
6440
|
+
onClick: () => void saveServerList([...servers.map(toSpec), demoServerSpec]),
|
|
6441
|
+
children: [
|
|
6442
|
+
"\u26A1 \u6DFB\u52A0\u6F14\u793A server\uFF08",
|
|
6443
|
+
demoServerSpec.name,
|
|
6444
|
+
"\uFF09"
|
|
6445
|
+
]
|
|
6446
|
+
}
|
|
6447
|
+
)
|
|
6448
|
+
] }),
|
|
6449
|
+
formOpen && /* @__PURE__ */ jsx20(
|
|
6450
|
+
ServerForm,
|
|
6451
|
+
{
|
|
6452
|
+
form,
|
|
6453
|
+
setForm,
|
|
6454
|
+
error: formError,
|
|
6455
|
+
busy: busy !== null,
|
|
6456
|
+
onSubmit: submitForm,
|
|
6457
|
+
onCancel: () => {
|
|
6458
|
+
setFormOpen(false);
|
|
6459
|
+
setFormError(null);
|
|
6460
|
+
}
|
|
6461
|
+
}
|
|
6462
|
+
)
|
|
6463
|
+
] }),
|
|
6464
|
+
/* @__PURE__ */ jsxs17("section", { className: "lax-mcp-section", "aria-label": "\u8FDE\u63A5\u72B6\u6001\u4E0E\u5DE5\u5177\u6E05\u5355", children: [
|
|
6465
|
+
/* @__PURE__ */ jsx20("div", { className: "lax-mcp-section-title", children: "\u2461 \u8FDE\u63A5\u72B6\u6001 / \u2462 \u5DE5\u5177\u6E05\u5355" }),
|
|
6466
|
+
servers.length === 0 ? /* @__PURE__ */ jsx20("div", { className: "lax-mcp-empty", "data-testid": "lax-mcp-empty", children: "\u5C1A\u672A\u914D\u7F6E MCP server" }) : servers.map((server) => /* @__PURE__ */ jsxs17("div", { className: "lax-mcp-server", "data-server": server.name, children: [
|
|
6467
|
+
/* @__PURE__ */ jsx20(
|
|
6468
|
+
McpServerRow,
|
|
6469
|
+
{
|
|
6470
|
+
server,
|
|
6471
|
+
busy: busy !== null,
|
|
6472
|
+
expanded: expanded[server.name] === true,
|
|
6473
|
+
onReconnect: () => reconnectServer(server.name),
|
|
6474
|
+
onToggleEnabled: () => toggleEnabled(server),
|
|
6475
|
+
onDelete: () => deleteServer(server.name),
|
|
6476
|
+
onToggleTools: () => toggleTools(server.name)
|
|
6477
|
+
}
|
|
6478
|
+
),
|
|
6479
|
+
expanded[server.name] === true && /* @__PURE__ */ jsx20(ToolsGroup, { load: toolsLoads[server.name] })
|
|
6480
|
+
] }, server.name))
|
|
6481
|
+
] }),
|
|
6482
|
+
/* @__PURE__ */ jsxs17("section", { className: "lax-mcp-section", "aria-label": "\u89C4\u5219\u88C1\u51B3", children: [
|
|
6483
|
+
/* @__PURE__ */ jsx20("div", { className: "lax-mcp-section-title", children: "\u2463 \u89C4\u5219\u88C1\u51B3" }),
|
|
6484
|
+
/* @__PURE__ */ jsx20(
|
|
6485
|
+
McpRuleEditor,
|
|
6486
|
+
{
|
|
6487
|
+
allowText,
|
|
6488
|
+
denyText,
|
|
6489
|
+
onAllowChange: setAllowText,
|
|
6490
|
+
onDenyChange: setDenyText,
|
|
6491
|
+
saving: rulesSaving,
|
|
6492
|
+
error: rulesError,
|
|
6493
|
+
disabled: servers.length === 0,
|
|
6494
|
+
inPool: toolsInPool,
|
|
6495
|
+
total: summary?.tools_total ?? null,
|
|
6496
|
+
blocked: summary?.tools_blocked ?? null,
|
|
6497
|
+
onSave: () => void saveRules()
|
|
6498
|
+
}
|
|
6499
|
+
)
|
|
6500
|
+
] })
|
|
6501
|
+
] }) })
|
|
6502
|
+
]
|
|
6503
|
+
}
|
|
6504
|
+
)
|
|
6505
|
+
}
|
|
6506
|
+
);
|
|
6507
|
+
}
|
|
6508
|
+
function McpServerRow(props) {
|
|
6509
|
+
const { server, busy, expanded, onReconnect, onToggleEnabled, onDelete, onToggleTools } = props;
|
|
6510
|
+
const meta = STATE_META[server.state];
|
|
6511
|
+
const rowBusy = server.state === "connecting" || server.state === "reconnecting";
|
|
6512
|
+
return /* @__PURE__ */ jsxs17("div", { className: `lax-mcp-server-row lax-mcp-server-row--${server.state}`, children: [
|
|
6513
|
+
/* @__PURE__ */ jsx20("span", { className: `lax-mcp-state-icon tone-${meta.tone}`, role: "img", "aria-label": meta.label, children: meta.icon }),
|
|
6514
|
+
/* @__PURE__ */ jsx20("span", { className: "lax-mcp-server-name", children: server.name }),
|
|
6515
|
+
/* @__PURE__ */ jsx20("span", { className: "lax-mcp-server-meta", children: server.transport }),
|
|
6516
|
+
/* @__PURE__ */ jsx20("span", { className: "lax-mcp-server-meta", children: server.state === "connected" ? server.tool_count === 0 ? "\u5DF2\u8FDE\u63A5 \xB7 \u672A\u66B4\u9732\u5DE5\u5177" : `${server.tool_count ?? "\u2013"} tool` : null }),
|
|
6517
|
+
/* @__PURE__ */ jsxs17("span", { className: "lax-mcp-server-actions", children: [
|
|
6518
|
+
/* @__PURE__ */ jsx20(
|
|
6519
|
+
"button",
|
|
6520
|
+
{
|
|
6521
|
+
type: "button",
|
|
6522
|
+
className: "lax-mcp-btn",
|
|
6523
|
+
disabled: busy || server.state !== "connected",
|
|
6524
|
+
"aria-expanded": expanded,
|
|
6525
|
+
onClick: onToggleTools,
|
|
6526
|
+
children: expanded ? "\u25BE \u5DE5\u5177" : "\u25B8 \u5DE5\u5177"
|
|
6527
|
+
}
|
|
6528
|
+
),
|
|
6529
|
+
/* @__PURE__ */ jsx20("button", { type: "button", className: "lax-mcp-btn", disabled: busy || rowBusy, onClick: onReconnect, children: "\u21BB \u91CD\u8FDE" }),
|
|
6530
|
+
/* @__PURE__ */ jsx20(
|
|
6531
|
+
"button",
|
|
6532
|
+
{
|
|
6533
|
+
type: "button",
|
|
6534
|
+
className: "lax-mcp-btn",
|
|
6535
|
+
disabled: busy || rowBusy,
|
|
6536
|
+
onClick: onToggleEnabled,
|
|
6537
|
+
children: server.enabled ? "\u23FB \u505C\u7528" : "\u23FB \u542F\u7528"
|
|
6538
|
+
}
|
|
6539
|
+
),
|
|
6540
|
+
/* @__PURE__ */ jsx20("button", { type: "button", className: "lax-mcp-btn", disabled: busy, onClick: onDelete, children: "\u{1F5D1} \u5220\u9664" }),
|
|
6541
|
+
server.state === "needs_auth" && /* @__PURE__ */ jsx20(
|
|
6542
|
+
"button",
|
|
6543
|
+
{
|
|
6544
|
+
type: "button",
|
|
6545
|
+
className: "lax-mcp-btn",
|
|
6546
|
+
disabled: true,
|
|
6547
|
+
title: "OAuth \u767B\u5F55\uFF08\u9884\u7559\uFF0C\u672A\u5B9E\u73B0\uFF09",
|
|
6548
|
+
children: "\u{1F511} OAuth \u767B\u5F55"
|
|
6549
|
+
}
|
|
6550
|
+
)
|
|
6551
|
+
] }),
|
|
6552
|
+
server.state === "failed" && server.error != null && server.error !== "" && /* @__PURE__ */ jsx20("div", { className: "lax-mcp-server-error", children: server.error })
|
|
6553
|
+
] });
|
|
6554
|
+
}
|
|
6555
|
+
function ToolsGroup({ load }) {
|
|
6556
|
+
if (load === void 0 || load.status === "loading") {
|
|
6557
|
+
return /* @__PURE__ */ jsx20("div", { className: "lax-mcp-tools lax-mcp-tools--loading", "data-testid": "lax-mcp-tools-loading", children: "\u6E05\u5355\u62C9\u53D6\u4E2D\u2026" });
|
|
6558
|
+
}
|
|
6559
|
+
if (load.status === "error") {
|
|
6560
|
+
return /* @__PURE__ */ jsxs17("div", { className: "lax-mcp-tools lax-mcp-tools--error", role: "alert", children: [
|
|
6561
|
+
"\u53D1\u73B0\u5931\u8D25\uFF1A",
|
|
6562
|
+
load.error
|
|
6563
|
+
] });
|
|
6564
|
+
}
|
|
6565
|
+
if (load.tools.length === 0) {
|
|
6566
|
+
return /* @__PURE__ */ jsx20("div", { className: "lax-mcp-tools", children: "\u5DF2\u8FDE\u63A5\uFF0C\u4F46\u8BE5 server \u672A\u66B4\u9732\u5DE5\u5177" });
|
|
6567
|
+
}
|
|
6568
|
+
return /* @__PURE__ */ jsx20("div", { className: "lax-mcp-tools", children: load.tools.map((tool) => /* @__PURE__ */ jsx20(McpToolRow, { tool }, tool.model_name)) });
|
|
6569
|
+
}
|
|
6570
|
+
function McpToolRow({ tool }) {
|
|
6571
|
+
const adj = ADJ_META[tool.adjudication];
|
|
6572
|
+
return /* @__PURE__ */ jsxs17("div", { className: "lax-mcp-tool-row", "data-adjudication": tool.adjudication, children: [
|
|
6573
|
+
/* @__PURE__ */ jsx20("span", { className: "lax-mcp-tool-name", children: tool.model_name }),
|
|
6574
|
+
tool.destructive_hint === true ? /* @__PURE__ */ jsx20("span", { className: "lax-mcp-tool-hint tone-error", children: "\u5199\u64CD\u4F5C" }) : tool.read_only_hint === true ? /* @__PURE__ */ jsx20("span", { className: "lax-mcp-tool-hint tone-success", children: "readOnly" }) : null,
|
|
6575
|
+
/* @__PURE__ */ jsxs17("span", { className: `lax-mcp-adj ${adj.cls}`, children: [
|
|
6576
|
+
adj.icon,
|
|
6577
|
+
" ",
|
|
6578
|
+
adj.label
|
|
6579
|
+
] })
|
|
6580
|
+
] });
|
|
6581
|
+
}
|
|
6582
|
+
function McpRuleEditor(props) {
|
|
6583
|
+
const {
|
|
6584
|
+
allowText,
|
|
6585
|
+
denyText,
|
|
6586
|
+
onAllowChange,
|
|
6587
|
+
onDenyChange,
|
|
6588
|
+
saving,
|
|
6589
|
+
error,
|
|
6590
|
+
disabled,
|
|
6591
|
+
inPool,
|
|
6592
|
+
total,
|
|
6593
|
+
blocked,
|
|
6594
|
+
onSave
|
|
6595
|
+
} = props;
|
|
6596
|
+
return /* @__PURE__ */ jsxs17("div", { className: "lax-mcp-rules", "data-testid": "lax-mcp-rules", children: [
|
|
6597
|
+
/* @__PURE__ */ jsxs17("div", { className: "lax-mcp-rules-grid", children: [
|
|
6598
|
+
/* @__PURE__ */ jsxs17("label", { className: "lax-mcp-field", children: [
|
|
6599
|
+
/* @__PURE__ */ jsx20("span", { children: "allow\uFF08\u6BCF\u884C\u4E00\u4E2A\u5DE5\u5177\u540D\uFF09" }),
|
|
6600
|
+
/* @__PURE__ */ jsx20(
|
|
6601
|
+
"textarea",
|
|
6602
|
+
{
|
|
6603
|
+
className: "lax-mcp-textarea",
|
|
6604
|
+
value: allowText,
|
|
6605
|
+
onChange: (event) => onAllowChange(event.target.value),
|
|
6606
|
+
placeholder: "mcp__demo__echo"
|
|
6607
|
+
}
|
|
6608
|
+
)
|
|
6609
|
+
] }),
|
|
6610
|
+
/* @__PURE__ */ jsxs17("label", { className: "lax-mcp-field", children: [
|
|
6611
|
+
/* @__PURE__ */ jsx20("span", { children: "deny\uFF08\u6BCF\u884C\u4E00\u4E2A\u5DE5\u5177\u540D\uFF09" }),
|
|
6612
|
+
/* @__PURE__ */ jsx20(
|
|
6613
|
+
"textarea",
|
|
6614
|
+
{
|
|
6615
|
+
className: "lax-mcp-textarea",
|
|
6616
|
+
value: denyText,
|
|
6617
|
+
onChange: (event) => onDenyChange(event.target.value),
|
|
6618
|
+
placeholder: "mcp__demo__write"
|
|
6619
|
+
}
|
|
6620
|
+
)
|
|
6621
|
+
] })
|
|
6622
|
+
] }),
|
|
6623
|
+
/* @__PURE__ */ jsx20("div", { className: "lax-mcp-hint", children: "\u9ED8\u8BA4\u5168 deny\uFF08fail closed\uFF09\uFF1A\u672A\u8986\u76D6\u89C4\u5219\u7684\u5DE5\u5177\u4E0D\u4F1A\u8FDB\u5165\u4F1A\u8BDD\u3002\u89C4\u5219\u53D8\u66F4\u5BF9\u65B0\u4F1A\u8BDD\u751F\u6548\u3002" }),
|
|
6624
|
+
/* @__PURE__ */ jsxs17("div", { className: "lax-mcp-rules-preview", "data-testid": "lax-mcp-rules-preview", children: [
|
|
6625
|
+
"\u88C1\u51B3\u9884\u89C8\uFF1A",
|
|
6626
|
+
inPool !== null && total !== null ? `${inPool}/${total} \u8FDB\u6C60` : "\u2013",
|
|
6627
|
+
blocked !== null ? ` \xB7 ${blocked} \u88AB\u62E6\u622A\uFF08deny / \u672A\u8986\u76D6\uFF09` : ""
|
|
6628
|
+
] }),
|
|
6629
|
+
error !== null && /* @__PURE__ */ jsxs17("div", { className: "lax-mcp-inline-error", role: "alert", children: [
|
|
6630
|
+
"\u4FDD\u5B58\u5931\u8D25\uFF1A",
|
|
6631
|
+
error
|
|
6632
|
+
] }),
|
|
6633
|
+
/* @__PURE__ */ jsx20(
|
|
6634
|
+
"button",
|
|
6635
|
+
{
|
|
6636
|
+
type: "button",
|
|
6637
|
+
className: "lax-mcp-btn lax-mcp-btn--primary",
|
|
6638
|
+
disabled: disabled || saving,
|
|
6639
|
+
onClick: onSave,
|
|
6640
|
+
children: saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58\u89C4\u5219"
|
|
6641
|
+
}
|
|
6642
|
+
)
|
|
6643
|
+
] });
|
|
6644
|
+
}
|
|
6645
|
+
function ServerForm(props) {
|
|
6646
|
+
const { form, setForm, error, busy, onSubmit, onCancel } = props;
|
|
6647
|
+
const set = (patch) => setForm((prev) => ({ ...prev, ...patch }));
|
|
6648
|
+
const isStdio = form.transport === "stdio";
|
|
6649
|
+
return /* @__PURE__ */ jsxs17(
|
|
6650
|
+
"form",
|
|
6651
|
+
{
|
|
6652
|
+
className: "lax-mcp-form",
|
|
6653
|
+
onSubmit: (event) => {
|
|
6654
|
+
event.preventDefault();
|
|
6655
|
+
onSubmit();
|
|
6656
|
+
},
|
|
6657
|
+
children: [
|
|
6658
|
+
/* @__PURE__ */ jsxs17("div", { className: "lax-mcp-form-row", children: [
|
|
6659
|
+
/* @__PURE__ */ jsxs17("label", { className: "lax-mcp-field", children: [
|
|
6660
|
+
/* @__PURE__ */ jsx20("span", { children: "name" }),
|
|
6661
|
+
/* @__PURE__ */ jsx20(
|
|
6662
|
+
"input",
|
|
6663
|
+
{
|
|
6664
|
+
className: "lax-mcp-input",
|
|
6665
|
+
value: form.name,
|
|
6666
|
+
onChange: (event) => set({ name: event.target.value }),
|
|
6667
|
+
placeholder: "demo"
|
|
6668
|
+
}
|
|
6669
|
+
)
|
|
6670
|
+
] }),
|
|
6671
|
+
/* @__PURE__ */ jsxs17("label", { className: "lax-mcp-field", children: [
|
|
6672
|
+
/* @__PURE__ */ jsx20("span", { children: "transport" }),
|
|
6673
|
+
/* @__PURE__ */ jsxs17(
|
|
6674
|
+
"select",
|
|
6675
|
+
{
|
|
6676
|
+
className: "lax-mcp-select",
|
|
6677
|
+
value: form.transport,
|
|
6678
|
+
onChange: (event) => set({ transport: event.target.value }),
|
|
6679
|
+
children: [
|
|
6680
|
+
/* @__PURE__ */ jsx20("option", { value: "stdio", children: "stdio" }),
|
|
6681
|
+
/* @__PURE__ */ jsx20("option", { value: "sse", children: "sse" }),
|
|
6682
|
+
/* @__PURE__ */ jsx20("option", { value: "http", children: "http" })
|
|
6683
|
+
]
|
|
6684
|
+
}
|
|
6685
|
+
)
|
|
6686
|
+
] })
|
|
6687
|
+
] }),
|
|
6688
|
+
isStdio ? /* @__PURE__ */ jsxs17(Fragment5, { children: [
|
|
6689
|
+
/* @__PURE__ */ jsxs17("label", { className: "lax-mcp-field", children: [
|
|
6690
|
+
/* @__PURE__ */ jsx20("span", { children: "command" }),
|
|
6691
|
+
/* @__PURE__ */ jsx20(
|
|
6692
|
+
"input",
|
|
6693
|
+
{
|
|
6694
|
+
className: "lax-mcp-input",
|
|
6695
|
+
value: form.command,
|
|
6696
|
+
onChange: (event) => set({ command: event.target.value }),
|
|
6697
|
+
placeholder: "python"
|
|
6698
|
+
}
|
|
6699
|
+
)
|
|
6700
|
+
] }),
|
|
6701
|
+
/* @__PURE__ */ jsxs17("label", { className: "lax-mcp-field", children: [
|
|
6702
|
+
/* @__PURE__ */ jsx20("span", { children: "args\uFF08\u7A7A\u683C\u5206\u9694\uFF09" }),
|
|
6703
|
+
/* @__PURE__ */ jsx20(
|
|
6704
|
+
"input",
|
|
6705
|
+
{
|
|
6706
|
+
className: "lax-mcp-input",
|
|
6707
|
+
value: form.argsText,
|
|
6708
|
+
onChange: (event) => set({ argsText: event.target.value }),
|
|
6709
|
+
placeholder: "-u echo_server.py"
|
|
6710
|
+
}
|
|
6711
|
+
)
|
|
6712
|
+
] }),
|
|
6713
|
+
/* @__PURE__ */ jsxs17("label", { className: "lax-mcp-field", children: [
|
|
6714
|
+
/* @__PURE__ */ jsx20("span", { children: "env\uFF08\u6BCF\u884C KEY=VALUE\uFF09" }),
|
|
6715
|
+
/* @__PURE__ */ jsx20(
|
|
6716
|
+
"textarea",
|
|
6717
|
+
{
|
|
6718
|
+
className: "lax-mcp-textarea",
|
|
6719
|
+
value: form.envText,
|
|
6720
|
+
onChange: (event) => set({ envText: event.target.value })
|
|
6721
|
+
}
|
|
6722
|
+
)
|
|
6723
|
+
] }),
|
|
6724
|
+
/* @__PURE__ */ jsxs17("label", { className: "lax-mcp-field", children: [
|
|
6725
|
+
/* @__PURE__ */ jsx20("span", { children: "cwd" }),
|
|
6726
|
+
/* @__PURE__ */ jsx20(
|
|
6727
|
+
"input",
|
|
6728
|
+
{
|
|
6729
|
+
className: "lax-mcp-input",
|
|
6730
|
+
value: form.cwd,
|
|
6731
|
+
onChange: (event) => set({ cwd: event.target.value })
|
|
6732
|
+
}
|
|
6733
|
+
)
|
|
6734
|
+
] })
|
|
6735
|
+
] }) : /* @__PURE__ */ jsxs17(Fragment5, { children: [
|
|
6736
|
+
/* @__PURE__ */ jsxs17("label", { className: "lax-mcp-field", children: [
|
|
6737
|
+
/* @__PURE__ */ jsx20("span", { children: "url" }),
|
|
6738
|
+
/* @__PURE__ */ jsx20(
|
|
6739
|
+
"input",
|
|
6740
|
+
{
|
|
6741
|
+
className: "lax-mcp-input",
|
|
6742
|
+
value: form.url,
|
|
6743
|
+
onChange: (event) => set({ url: event.target.value }),
|
|
6744
|
+
placeholder: "http://localhost:9000/sse"
|
|
6745
|
+
}
|
|
6746
|
+
)
|
|
6747
|
+
] }),
|
|
6748
|
+
/* @__PURE__ */ jsxs17("label", { className: "lax-mcp-field", children: [
|
|
6749
|
+
/* @__PURE__ */ jsx20("span", { children: "headers\uFF08\u6BCF\u884C KEY=VALUE\uFF09" }),
|
|
6750
|
+
/* @__PURE__ */ jsx20(
|
|
6751
|
+
"textarea",
|
|
6752
|
+
{
|
|
6753
|
+
className: "lax-mcp-textarea",
|
|
6754
|
+
value: form.headersText,
|
|
6755
|
+
onChange: (event) => set({ headersText: event.target.value })
|
|
6756
|
+
}
|
|
6757
|
+
)
|
|
6758
|
+
] })
|
|
6759
|
+
] }),
|
|
6760
|
+
error !== null && /* @__PURE__ */ jsx20("div", { className: "lax-mcp-inline-error", role: "alert", children: error }),
|
|
6761
|
+
/* @__PURE__ */ jsxs17("div", { className: "lax-mcp-form-row", children: [
|
|
6762
|
+
/* @__PURE__ */ jsx20("button", { type: "submit", className: "lax-mcp-btn lax-mcp-btn--primary", disabled: busy, children: "\u4FDD\u5B58" }),
|
|
6763
|
+
/* @__PURE__ */ jsx20("button", { type: "button", className: "lax-mcp-btn", onClick: onCancel, children: "\u53D6\u6D88" })
|
|
6764
|
+
] })
|
|
6765
|
+
]
|
|
6766
|
+
}
|
|
6767
|
+
);
|
|
6768
|
+
}
|
|
6769
|
+
|
|
6137
6770
|
// src/view/tools/groupParallelTools.ts
|
|
6138
6771
|
function buildTimelineEntries(rootIds, byId, options = {}) {
|
|
6139
6772
|
const filtered = options.hideStandalonePermissions ? rootIds.filter((id) => byId[id]?.kind !== "permission") : [...rootIds];
|
|
@@ -6171,18 +6804,18 @@ function buildTimelineEntries(rootIds, byId, options = {}) {
|
|
|
6171
6804
|
}
|
|
6172
6805
|
|
|
6173
6806
|
// src/view/nodes/SubAgentNode.tsx
|
|
6174
|
-
import { jsx as
|
|
6807
|
+
import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
6175
6808
|
function SubAgentBlock({ nodeId }) {
|
|
6176
6809
|
const node = useNodeTyped(nodeId, "subagent");
|
|
6177
6810
|
const childIds = useChildren(nodeId);
|
|
6178
6811
|
const registry = useNodeRegistry();
|
|
6179
6812
|
if (!node) return null;
|
|
6180
|
-
return /* @__PURE__ */
|
|
6181
|
-
/* @__PURE__ */
|
|
6813
|
+
return /* @__PURE__ */ jsxs18("div", { className: "lax-subagent-block", "data-status": node.status, children: [
|
|
6814
|
+
/* @__PURE__ */ jsxs18("div", { className: "lax-subagent-block__header", children: [
|
|
6182
6815
|
"SubAgent: ",
|
|
6183
6816
|
node.subagentId
|
|
6184
6817
|
] }),
|
|
6185
|
-
/* @__PURE__ */
|
|
6818
|
+
/* @__PURE__ */ jsx21("div", { className: "lax-subagent-block__children", children: childIds.map((childId) => /* @__PURE__ */ jsx21(TimelineItem, { nodeId: childId, registry }, childId)) })
|
|
6186
6819
|
] });
|
|
6187
6820
|
}
|
|
6188
6821
|
|
|
@@ -6256,6 +6889,7 @@ export {
|
|
|
6256
6889
|
MAX_PREVIEW_LINES,
|
|
6257
6890
|
MIN_HINT_DISPLAY_MS,
|
|
6258
6891
|
MarkdownBlock,
|
|
6892
|
+
McpPanel,
|
|
6259
6893
|
MermaidDiagram,
|
|
6260
6894
|
MissingApplicationKindError,
|
|
6261
6895
|
MultiAgentSession,
|