comfyui-mcp 0.52.75 → 0.52.77
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/orchestrator/panel-arg-aliases.js +1 -0
- package/dist/orchestrator/panel-arg-aliases.js.map +1 -1
- package/dist/orchestrator/panel-tools.js +417 -24
- package/dist/orchestrator/panel-tools.js.map +1 -1
- package/dist/services/ui-bridge.js +38 -0
- package/dist/services/ui-bridge.js.map +1 -1
- package/package.json +1 -1
- package/scripts/codex-knowledge-parity-smoke.mjs +2 -1
|
@@ -31,6 +31,7 @@ import { describeReceived } from "./node-id.js";
|
|
|
31
31
|
* …" about one the caller is looking at. Coerced here instead. */
|
|
32
32
|
export const GROUP_ID_PATTERN = /^-?\d+$/;
|
|
33
33
|
export const GROUP_ID_MESSAGE = "a group id must be an integer (e.g. 2) — panel_query_graph's groups[] and panel_create_group both return it";
|
|
34
|
+
export const GROUP_REF_MESSAGE = "a group reference must be an integer id (e.g. 2) or a non-empty group title (e.g. 'Notes')";
|
|
34
35
|
/**
|
|
35
36
|
* Normalize an accepted group id to the NUMBER the wire has always carried.
|
|
36
37
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"panel-arg-aliases.js","sourceRoot":"","sources":["../../src/orchestrator/panel-arg-aliases.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"panel-arg-aliases.js","sourceRoot":"","sources":["../../src/orchestrator/panel-arg-aliases.ts"],"names":[],"mappings":"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"}
|
|
@@ -48,7 +48,7 @@ import { peekResolvedPanelBase, primePanelBase, verifiedPanelDiskVersion, } from
|
|
|
48
48
|
import { conversationOfScopeAddress, isScopeAddress, shortTabId } from "../services/session-scope.js";
|
|
49
49
|
import { NODE_ID_MESSAGE, NODE_ID_PATTERN, normalizeNodeId, PLAIN_NODE_ID_PATTERN, unionErrorFor, } from "./node-id.js";
|
|
50
50
|
import { unrecognizedKeysError } from "./unrecognized-keys.js";
|
|
51
|
-
import { FIND_NODES_DEFAULT_FIELDS, FIND_NODES_FIELDS, GROUP_ID_MESSAGE, GROUP_ID_PATTERN, normalizeGroupId, normalizeShowMediaItem, normalizeTodoItemKeys, pickAlias, projectFindNodesPayload, } from "./panel-arg-aliases.js";
|
|
51
|
+
import { FIND_NODES_DEFAULT_FIELDS, FIND_NODES_FIELDS, GROUP_ID_MESSAGE, GROUP_ID_PATTERN, GROUP_REF_MESSAGE, normalizeGroupId, normalizeShowMediaItem, normalizeTodoItemKeys, pickAlias, projectFindNodesPayload, } from "./panel-arg-aliases.js";
|
|
52
52
|
import { addressedNodeMatchesPersistRemedy, parseAmbiguousPromotedWidgetRefusal, parseContradictoryPromotedWidgetRefusal, parseSubgraphScopeRefusal, parseUnpromotedControlPersistRemedy, resolveInnerPromotedTarget, } from "./promoted-widget.js";
|
|
53
53
|
import { includeRequestedCreateGroupMembers } from "./create-group-membership.js";
|
|
54
54
|
import { sizeForUncollapse } from "./edit-node-uncollapse.js";
|
|
@@ -4297,6 +4297,8 @@ const ANIMA_REGIONAL_WIRED_PROMPT_INPUT = {
|
|
|
4297
4297
|
scene_prompt: "scene_prompt_in",
|
|
4298
4298
|
negative_prompt: "negative_prompt_in",
|
|
4299
4299
|
};
|
|
4300
|
+
const DASIWA_STACK_WIDGET = "stack_data";
|
|
4301
|
+
const DASIWA_LTX2_LORA_LOADER = "DaSiWa_LTX2LoraLoader";
|
|
4300
4302
|
function isAnimaRegionalPromptWidget(widget) {
|
|
4301
4303
|
return ANIMA_REGIONAL_PROMPT_WIDGETS.has(widget);
|
|
4302
4304
|
}
|
|
@@ -4338,6 +4340,101 @@ function parseQueriedNodeType(payload) {
|
|
|
4338
4340
|
}
|
|
4339
4341
|
return null;
|
|
4340
4342
|
}
|
|
4343
|
+
function canonicalQueriedNodeId(value) {
|
|
4344
|
+
if (typeof value === "number") {
|
|
4345
|
+
return Number.isSafeInteger(value) ? String(value) : null;
|
|
4346
|
+
}
|
|
4347
|
+
if (typeof value !== "string" || !NODE_ID_PATTERN.test(value))
|
|
4348
|
+
return null;
|
|
4349
|
+
const normalized = normalizeNodeId(value);
|
|
4350
|
+
return typeof normalized === "number" && !Number.isSafeInteger(normalized)
|
|
4351
|
+
? null
|
|
4352
|
+
: String(normalized);
|
|
4353
|
+
}
|
|
4354
|
+
function parseQueriedNodeIdentityRow(row) {
|
|
4355
|
+
if (!row || typeof row !== "object" || Array.isArray(row))
|
|
4356
|
+
return null;
|
|
4357
|
+
const record = row;
|
|
4358
|
+
const id = canonicalQueriedNodeId(record.id);
|
|
4359
|
+
if (!id)
|
|
4360
|
+
return null;
|
|
4361
|
+
const type = record.type;
|
|
4362
|
+
const classType = record.class_type;
|
|
4363
|
+
if (type !== undefined && typeof type !== "string")
|
|
4364
|
+
return null;
|
|
4365
|
+
if (classType !== undefined && typeof classType !== "string")
|
|
4366
|
+
return null;
|
|
4367
|
+
if (typeof type === "string" && typeof classType === "string" && type !== classType) {
|
|
4368
|
+
return null;
|
|
4369
|
+
}
|
|
4370
|
+
const resolvedType = typeof type === "string" ? type : classType;
|
|
4371
|
+
return resolvedType ? { id, type: resolvedType } : null;
|
|
4372
|
+
}
|
|
4373
|
+
/** Strict identity parser for the DaSiWa refusal gate. Unlike the older type-only
|
|
4374
|
+
* parser above, this accepts exactly one non-truncated row and authenticates its id. */
|
|
4375
|
+
function parseVerifiedQueriedNodeIdentity(payload) {
|
|
4376
|
+
if (!payload)
|
|
4377
|
+
return null;
|
|
4378
|
+
if (Object.prototype.hasOwnProperty.call(payload, "truncated") &&
|
|
4379
|
+
payload.truncated !== false) {
|
|
4380
|
+
return null;
|
|
4381
|
+
}
|
|
4382
|
+
if (Object.prototype.hasOwnProperty.call(payload, "nodes")) {
|
|
4383
|
+
return Array.isArray(payload.nodes) && payload.nodes.length === 1
|
|
4384
|
+
? parseQueriedNodeIdentityRow(payload.nodes[0])
|
|
4385
|
+
: null;
|
|
4386
|
+
}
|
|
4387
|
+
if (typeof payload.text !== "string")
|
|
4388
|
+
return null;
|
|
4389
|
+
const rows = [];
|
|
4390
|
+
const lines = payload.text.split(/\r?\n/);
|
|
4391
|
+
for (const [index, line] of lines.entries()) {
|
|
4392
|
+
const trimmed = line.trim();
|
|
4393
|
+
if (!trimmed)
|
|
4394
|
+
continue;
|
|
4395
|
+
// The live compact projection always prefixes its rows with this bounded summary.
|
|
4396
|
+
// Keep the grammar narrow so arbitrary prose cannot make an unverified row usable,
|
|
4397
|
+
// while accepting the documented header that older tests and panels may omit.
|
|
4398
|
+
if (index === 0 &&
|
|
4399
|
+
/^\d+ match\(es\) of \d+ in scope \(viewing: \d+ nodes\)(?: · traversal depth≤-?\d+)?$/.test(trimmed)) {
|
|
4400
|
+
continue;
|
|
4401
|
+
}
|
|
4402
|
+
// A compact row may be followed by one of the panel's bounded clipping notes or
|
|
4403
|
+
// truncation remedies. They do not identify nodes and are ignored only after a row
|
|
4404
|
+
// has been authenticated below.
|
|
4405
|
+
if (rows.length > 0 &&
|
|
4406
|
+
(/^\(\d+ widget value\(s\) clipped to \d+ chars/.test(trimmed) ||
|
|
4407
|
+
/^… truncated at \d+ of \d+/.test(trimmed))) {
|
|
4408
|
+
continue;
|
|
4409
|
+
}
|
|
4410
|
+
if (trimmed.startsWith("#")) {
|
|
4411
|
+
const compact = trimmed.match(/^#(\S+)\s+(\S+)(?:\s|$)/);
|
|
4412
|
+
if (!compact)
|
|
4413
|
+
return null;
|
|
4414
|
+
const id = canonicalQueriedNodeId(compact[1]);
|
|
4415
|
+
if (!id)
|
|
4416
|
+
return null;
|
|
4417
|
+
rows.push({ id, type: compact[2] });
|
|
4418
|
+
continue;
|
|
4419
|
+
}
|
|
4420
|
+
if (trimmed.startsWith("{")) {
|
|
4421
|
+
let row;
|
|
4422
|
+
try {
|
|
4423
|
+
row = JSON.parse(trimmed);
|
|
4424
|
+
}
|
|
4425
|
+
catch {
|
|
4426
|
+
return null;
|
|
4427
|
+
}
|
|
4428
|
+
const parsed = parseQueriedNodeIdentityRow(row);
|
|
4429
|
+
if (!parsed)
|
|
4430
|
+
return null;
|
|
4431
|
+
rows.push(parsed);
|
|
4432
|
+
continue;
|
|
4433
|
+
}
|
|
4434
|
+
return null;
|
|
4435
|
+
}
|
|
4436
|
+
return rows.length === 1 ? rows[0] : null;
|
|
4437
|
+
}
|
|
4341
4438
|
function animaRegionalPromptRefusal(type, widget) {
|
|
4342
4439
|
const wired = ANIMA_REGIONAL_WIRED_PROMPT_INPUT[widget];
|
|
4343
4440
|
const route = wired
|
|
@@ -4367,6 +4464,162 @@ async function refuseAnimaRegionalPromptWrite(ctx, nodeId, widget) {
|
|
|
4367
4464
|
return null;
|
|
4368
4465
|
return animaRegionalPromptRefusal(type, widget);
|
|
4369
4466
|
}
|
|
4467
|
+
function daSiWaStackRefusal(type) {
|
|
4468
|
+
return fail(`panel_set_widget cannot set "${DASIWA_STACK_WIDGET}" on ${type}. ` +
|
|
4469
|
+
`The node's custom multi-row widget owns the LoRA stack in its internal JS state and ` +
|
|
4470
|
+
`re-serializes that state over widget.value, so the normal graph_set_widget success ` +
|
|
4471
|
+
`echo would be a false success. Edit the stack rows in the node UI instead; do not retry ` +
|
|
4472
|
+
`panel_set_widget for this widget.`);
|
|
4473
|
+
}
|
|
4474
|
+
function daSiWaIdentityRefusal(reason) {
|
|
4475
|
+
return fail(`panel_set_widget refused "${DASIWA_STACK_WIDGET}" because the panel probe could not ` +
|
|
4476
|
+
`prove the requested node is the intended ${DASIWA_LTX2_LORA_LOADER} (${reason}). ` +
|
|
4477
|
+
`No graph_set_widget was dispatched. Edit the stack rows in the node UI instead; ` +
|
|
4478
|
+
`do not retry this write until the node identity can be read exactly.`);
|
|
4479
|
+
}
|
|
4480
|
+
function isUsablePanelConnectionIdentity(identity) {
|
|
4481
|
+
return (!!identity &&
|
|
4482
|
+
Number.isSafeInteger(identity.generation) &&
|
|
4483
|
+
typeof identity.tabSessionId === "string" &&
|
|
4484
|
+
identity.tabSessionId.length > 0);
|
|
4485
|
+
}
|
|
4486
|
+
function samePanelConnectionIdentity(left, right) {
|
|
4487
|
+
return left.generation === right.generation && left.tabSessionId === right.tabSessionId;
|
|
4488
|
+
}
|
|
4489
|
+
/** Refuse the DaSiWa stack widget whose custom UI deterministically overwrites a
|
|
4490
|
+
* graph_set_widget write after acknowledging it. This gate fails closed unless
|
|
4491
|
+
* the probe proves the requested node and remains bound to the same panel tab. */
|
|
4492
|
+
async function refuseDaSiWaStackWrite(ctx, nodeId, widget) {
|
|
4493
|
+
if (widget !== DASIWA_STACK_WIDGET)
|
|
4494
|
+
return null;
|
|
4495
|
+
try {
|
|
4496
|
+
if (ctx.tabExpectedNodeTypeFenceCapability?.() !== true) {
|
|
4497
|
+
return daSiWaIdentityRefusal("the bound panel does not advertise the atomic expected-node-type write fence; update the panel and hard-refresh");
|
|
4498
|
+
}
|
|
4499
|
+
}
|
|
4500
|
+
catch {
|
|
4501
|
+
return daSiWaIdentityRefusal("the panel expected-node-type write fence could not be verified");
|
|
4502
|
+
}
|
|
4503
|
+
const tabBefore = ctx.tabId;
|
|
4504
|
+
let identityBefore;
|
|
4505
|
+
try {
|
|
4506
|
+
identityBefore = ctx.panelConnectionIdentity?.();
|
|
4507
|
+
}
|
|
4508
|
+
catch {
|
|
4509
|
+
return daSiWaIdentityRefusal("the bound browser-tab identity was unreadable");
|
|
4510
|
+
}
|
|
4511
|
+
if (!isUsablePanelConnectionIdentity(identityBefore)) {
|
|
4512
|
+
return daSiWaIdentityRefusal("the bound browser-tab identity was unavailable");
|
|
4513
|
+
}
|
|
4514
|
+
let probe;
|
|
4515
|
+
try {
|
|
4516
|
+
probe = await ctx.call({
|
|
4517
|
+
cmd: "graph_query",
|
|
4518
|
+
ids: [nodeId],
|
|
4519
|
+
fields: "compact",
|
|
4520
|
+
limit: 1,
|
|
4521
|
+
});
|
|
4522
|
+
}
|
|
4523
|
+
catch {
|
|
4524
|
+
return daSiWaIdentityRefusal("the graph_query probe failed before identity could be verified");
|
|
4525
|
+
}
|
|
4526
|
+
if (ctx.tabId !== tabBefore) {
|
|
4527
|
+
return daSiWaIdentityRefusal("the probe was answered by a different panel tab");
|
|
4528
|
+
}
|
|
4529
|
+
let identityAfter;
|
|
4530
|
+
try {
|
|
4531
|
+
identityAfter = ctx.panelConnectionIdentity?.();
|
|
4532
|
+
}
|
|
4533
|
+
catch {
|
|
4534
|
+
return daSiWaIdentityRefusal("the panel-tab identity became unreadable after the probe");
|
|
4535
|
+
}
|
|
4536
|
+
if (!isUsablePanelConnectionIdentity(identityAfter)) {
|
|
4537
|
+
return daSiWaIdentityRefusal("the panel-tab identity became unavailable after the probe");
|
|
4538
|
+
}
|
|
4539
|
+
if (!samePanelConnectionIdentity(identityBefore, identityAfter)) {
|
|
4540
|
+
return daSiWaIdentityRefusal("the panel-tab connection changed during the probe");
|
|
4541
|
+
}
|
|
4542
|
+
if (probe.isError) {
|
|
4543
|
+
return daSiWaIdentityRefusal("the graph_query probe returned an error");
|
|
4544
|
+
}
|
|
4545
|
+
const identity = parseVerifiedQueriedNodeIdentity(parseToolResultJson(probe));
|
|
4546
|
+
const requestedId = canonicalQueriedNodeId(nodeId);
|
|
4547
|
+
if (!identity || !requestedId) {
|
|
4548
|
+
return daSiWaIdentityRefusal("the graph_query reply was malformed, truncated, or did not contain exactly one verifiable row");
|
|
4549
|
+
}
|
|
4550
|
+
if (identity.id !== requestedId) {
|
|
4551
|
+
return daSiWaIdentityRefusal("the graph_query row identified a different node_id");
|
|
4552
|
+
}
|
|
4553
|
+
if (identity.type !== DASIWA_LTX2_LORA_LOADER)
|
|
4554
|
+
return null;
|
|
4555
|
+
return daSiWaStackRefusal(identity.type);
|
|
4556
|
+
}
|
|
4557
|
+
/** Recheck the target immediately before a stack_data mutation. The first probe
|
|
4558
|
+
* prevents the known refusal from dispatching; this final fence catches a tab
|
|
4559
|
+
* reconnect or node replacement observed between that probe and graph_set_widget. */
|
|
4560
|
+
async function verifyDaSiWaStackWriteFence(ctx, nodeId) {
|
|
4561
|
+
try {
|
|
4562
|
+
if (ctx.tabExpectedNodeTypeFenceCapability?.() !== true) {
|
|
4563
|
+
return daSiWaIdentityRefusal("the bound panel does not advertise the atomic expected-node-type write fence; update the panel and hard-refresh");
|
|
4564
|
+
}
|
|
4565
|
+
}
|
|
4566
|
+
catch {
|
|
4567
|
+
return daSiWaIdentityRefusal("the panel expected-node-type write fence could not be verified");
|
|
4568
|
+
}
|
|
4569
|
+
const tabBefore = ctx.tabId;
|
|
4570
|
+
let identityBefore;
|
|
4571
|
+
try {
|
|
4572
|
+
identityBefore = ctx.panelConnectionIdentity?.();
|
|
4573
|
+
}
|
|
4574
|
+
catch {
|
|
4575
|
+
return daSiWaIdentityRefusal("the bound browser-tab identity was unreadable before dispatch");
|
|
4576
|
+
}
|
|
4577
|
+
if (!isUsablePanelConnectionIdentity(identityBefore)) {
|
|
4578
|
+
return daSiWaIdentityRefusal("the bound browser-tab identity was unavailable before dispatch");
|
|
4579
|
+
}
|
|
4580
|
+
let probe;
|
|
4581
|
+
try {
|
|
4582
|
+
probe = await ctx.call({
|
|
4583
|
+
cmd: "graph_query",
|
|
4584
|
+
ids: [nodeId],
|
|
4585
|
+
fields: "compact",
|
|
4586
|
+
limit: 1,
|
|
4587
|
+
});
|
|
4588
|
+
}
|
|
4589
|
+
catch {
|
|
4590
|
+
return daSiWaIdentityRefusal("the final graph_query fence failed before dispatch");
|
|
4591
|
+
}
|
|
4592
|
+
if (ctx.tabId !== tabBefore) {
|
|
4593
|
+
return daSiWaIdentityRefusal("the final fence was answered by a different panel tab");
|
|
4594
|
+
}
|
|
4595
|
+
let identityAfter;
|
|
4596
|
+
try {
|
|
4597
|
+
identityAfter = ctx.panelConnectionIdentity?.();
|
|
4598
|
+
}
|
|
4599
|
+
catch {
|
|
4600
|
+
return daSiWaIdentityRefusal("the panel-tab identity became unreadable before dispatch");
|
|
4601
|
+
}
|
|
4602
|
+
if (!isUsablePanelConnectionIdentity(identityAfter)) {
|
|
4603
|
+
return daSiWaIdentityRefusal("the panel-tab identity became unavailable before dispatch");
|
|
4604
|
+
}
|
|
4605
|
+
if (!samePanelConnectionIdentity(identityBefore, identityAfter)) {
|
|
4606
|
+
return daSiWaIdentityRefusal("the panel-tab connection changed before dispatch");
|
|
4607
|
+
}
|
|
4608
|
+
if (probe.isError) {
|
|
4609
|
+
return daSiWaIdentityRefusal("the final graph_query fence returned an error");
|
|
4610
|
+
}
|
|
4611
|
+
const identity = parseVerifiedQueriedNodeIdentity(parseToolResultJson(probe));
|
|
4612
|
+
const requestedId = canonicalQueriedNodeId(nodeId);
|
|
4613
|
+
if (!identity || !requestedId) {
|
|
4614
|
+
return daSiWaIdentityRefusal("the final graph_query fence was malformed, truncated, or did not contain exactly one verifiable row");
|
|
4615
|
+
}
|
|
4616
|
+
if (identity.id !== requestedId) {
|
|
4617
|
+
return daSiWaIdentityRefusal("the final graph_query fence identified a different node_id");
|
|
4618
|
+
}
|
|
4619
|
+
return identity.type === DASIWA_LTX2_LORA_LOADER
|
|
4620
|
+
? daSiWaStackRefusal(identity.type)
|
|
4621
|
+
: { expectedNodeType: identity.type };
|
|
4622
|
+
}
|
|
4370
4623
|
// ---- #809: turn the panel's silent `truncated: true` booleans into a remedy --------
|
|
4371
4624
|
//
|
|
4372
4625
|
// A bare boolean is the WORST truncation signal there is: it is a field, not prose, so
|
|
@@ -10216,6 +10469,7 @@ export function makePanelToolCtx(bridge, tabId, workflowTargets, onRunTicketOpen
|
|
|
10216
10469
|
ctx.panelConnectionIdentity = panelConnectionIdentity;
|
|
10217
10470
|
ctx.awaitPostRestartReachable = awaitPostRestartReachable;
|
|
10218
10471
|
ctx.tabCanMutateGraph = () => bridge.tabCanMutateGraph(ctx.tabId);
|
|
10472
|
+
ctx.tabExpectedNodeTypeFenceCapability = () => bridge.tabExpectedNodeTypeFenceCapability(ctx.tabId);
|
|
10219
10473
|
ctx.tabGraphMutationCapability = () => bridge.tabGraphMutationCapability(ctx.tabId);
|
|
10220
10474
|
return ctx;
|
|
10221
10475
|
}
|
|
@@ -11320,9 +11574,85 @@ const groupId = () => z
|
|
|
11320
11574
|
* undefined` at `group_id` puts both halves of the answer in front of the caller
|
|
11321
11575
|
* and makes them join it.
|
|
11322
11576
|
*/
|
|
11323
|
-
function
|
|
11577
|
+
function resolveGroupRefArg(tool, args) {
|
|
11324
11578
|
return pickAlias(tool, { name: "group_id", value: args.group_id }, { name: "group", value: args.group });
|
|
11325
11579
|
}
|
|
11580
|
+
/**
|
|
11581
|
+
* Resolve the title form of `group` before reaching the panel's ID-only group
|
|
11582
|
+
* mutators. The panel already exposes the complete group rider on graph_query,
|
|
11583
|
+
* and its subgraph-group resolver uses the same case-insensitive substring
|
|
11584
|
+
* semantics. Reuse that observation, but refuse when it cannot identify exactly
|
|
11585
|
+
* one current group rather than guessing which box to edit or remove.
|
|
11586
|
+
*/
|
|
11587
|
+
async function resolveGroupMutationTarget(ref, ctx) {
|
|
11588
|
+
if (typeof ref !== "string")
|
|
11589
|
+
return { ok: true, value: ref };
|
|
11590
|
+
const query = await ctx.call({ cmd: "graph_query", fields: "ids", limit: 1 }, 8000);
|
|
11591
|
+
if (query.isError)
|
|
11592
|
+
return { ok: false, result: query };
|
|
11593
|
+
const payload = parseToolResultJson(query);
|
|
11594
|
+
if (payload?.groups_truncated === true) {
|
|
11595
|
+
return {
|
|
11596
|
+
ok: false,
|
|
11597
|
+
result: fail(`Cannot safely resolve group title "${ref}": the live groups index was truncated, so another matching title may be hidden. ` +
|
|
11598
|
+
"Re-read with panel_graph_outline or use group_id with the exact id."),
|
|
11599
|
+
};
|
|
11600
|
+
}
|
|
11601
|
+
const groups = payload?.groups;
|
|
11602
|
+
if (!Array.isArray(groups)) {
|
|
11603
|
+
return {
|
|
11604
|
+
ok: false,
|
|
11605
|
+
result: fail(`Cannot resolve group title "${ref}": the live graph did not return its groups index. ` +
|
|
11606
|
+
"Re-read with panel_query_graph and retry with group_id."),
|
|
11607
|
+
};
|
|
11608
|
+
}
|
|
11609
|
+
const needle = ref.toLowerCase();
|
|
11610
|
+
const matches = groups.filter((group) => {
|
|
11611
|
+
if (!group || typeof group !== "object" || Array.isArray(group))
|
|
11612
|
+
return false;
|
|
11613
|
+
const title = group.title;
|
|
11614
|
+
return typeof title === "string" && title.toLowerCase().includes(needle);
|
|
11615
|
+
});
|
|
11616
|
+
if (matches.length === 0) {
|
|
11617
|
+
return {
|
|
11618
|
+
ok: false,
|
|
11619
|
+
result: fail(`No group title matching "${ref}" was found in the current graph. ` +
|
|
11620
|
+
"Use panel_query_graph to inspect groups[].title, or pass group_id."),
|
|
11621
|
+
};
|
|
11622
|
+
}
|
|
11623
|
+
if (matches.length > 1) {
|
|
11624
|
+
const candidates = matches
|
|
11625
|
+
.map((group) => {
|
|
11626
|
+
const id = group.id;
|
|
11627
|
+
const title = typeof group.title === "string" ? group.title : "?";
|
|
11628
|
+
return `${String(title)} (id ${String(id)})`;
|
|
11629
|
+
})
|
|
11630
|
+
.join(", ");
|
|
11631
|
+
return {
|
|
11632
|
+
ok: false,
|
|
11633
|
+
result: fail(`Group title "${ref}" is ambiguous: it matches ${candidates}. ` +
|
|
11634
|
+
"Use group_id with the exact id instead of guessing."),
|
|
11635
|
+
};
|
|
11636
|
+
}
|
|
11637
|
+
const match = matches[0];
|
|
11638
|
+
if (match.title_clipped === true) {
|
|
11639
|
+
return {
|
|
11640
|
+
ok: false,
|
|
11641
|
+
result: fail(`Cannot safely resolve group title "${ref}": the matching title was clipped in the live groups index. ` +
|
|
11642
|
+
"Re-read the graph and use group_id with the exact id."),
|
|
11643
|
+
};
|
|
11644
|
+
}
|
|
11645
|
+
const id = match.id;
|
|
11646
|
+
if (!((typeof id === "number" && Number.isSafeInteger(id)) ||
|
|
11647
|
+
(typeof id === "string" && id.length > 0))) {
|
|
11648
|
+
return {
|
|
11649
|
+
ok: false,
|
|
11650
|
+
result: fail(`Cannot safely resolve group title "${ref}": its live group entry has no usable id. ` +
|
|
11651
|
+
"Use panel_query_graph to inspect the current groups index."),
|
|
11652
|
+
};
|
|
11653
|
+
}
|
|
11654
|
+
return { ok: true, value: id };
|
|
11655
|
+
}
|
|
11326
11656
|
/**
|
|
11327
11657
|
* #1968 — apply `panel_find_nodes`' `fields` projection to the panel's reply.
|
|
11328
11658
|
*
|
|
@@ -11389,17 +11719,18 @@ const todoChecklist = () => z.array(z.object({
|
|
|
11389
11719
|
.describe("Step state (default 'pending'). Mark the one you're on 'active'."),
|
|
11390
11720
|
}));
|
|
11391
11721
|
/** The shared schema pair every group tool takes, so the three cannot drift into
|
|
11392
|
-
* disagreeing about which spellings they accept (#1968). Both are optional
|
|
11393
|
-
* the SHAPE and exactly one is required by `
|
|
11722
|
+
* disagreeing about which spellings they accept (#1968/#2108). Both are optional
|
|
11723
|
+
* in the SHAPE and exactly one is required by `resolveGroupRefArg` — a cross-field
|
|
11394
11724
|
* rule a flat ZodRawShape cannot express, handled the same way
|
|
11395
11725
|
* `validatePanelEditNodeArgs` handles node_id/node_ids. */
|
|
11396
11726
|
const GROUP_ID_ARGS = {
|
|
11397
11727
|
group_id: groupId()
|
|
11398
11728
|
.optional()
|
|
11399
11729
|
.describe("Group id from panel_query_graph's groups[] / panel_create_group."),
|
|
11400
|
-
group:
|
|
11730
|
+
group: z
|
|
11731
|
+
.union([groupId(), z.string().trim().min(1, GROUP_REF_MESSAGE)], { error: unionErrorFor(GROUP_REF_MESSAGE) })
|
|
11401
11732
|
.optional()
|
|
11402
|
-
.describe("
|
|
11733
|
+
.describe("Group title (case-insensitive substring) or numeric id; this is the title-aware alias for group_id."),
|
|
11403
11734
|
};
|
|
11404
11735
|
/**
|
|
11405
11736
|
* #1497 — the ONE node-id argument #845 never reached: panel_run's `to_node_id`.
|
|
@@ -12386,7 +12717,7 @@ export function buildPanelToolDefs() {
|
|
|
12386
12717
|
node_id: nodeId().describe("Node id whose input to disconnect."),
|
|
12387
12718
|
input: slotRef.optional().describe("Input slot name or index (default 0)."),
|
|
12388
12719
|
}, async (args, ctx) => ctx.call({ cmd: "graph_disconnect", node_id: args.node_id, input: args.input })),
|
|
12389
|
-
def("panel_set_widget", "Set a widget value on a node in the user's open graph (steps, cfg, seed, ckpt_name, text prompts, …). Returns the previous and new value (a string longer than 1000 chars is echoed as {chars, sha256, preview} so batched calls stay inside the outer tool-result budget — pass `echo: \"full\"` for the verbatim string). Undoable with Ctrl+Z. To CLEAR a text widget to an empty string, pass `clear: true` (some MCP clients drop an empty-string `value` from the serialized payload, so `value: \"\"` may not arrive — `clear: true` always works). For the LTXDirector timeline node (WhatDreamsCost CSGlide), set `timeline_data` with the FULL timeline JSON (segments + global_prompt) to drive its custom timeline UI — this re-syncs the editor and regenerates its derived `local_prompts`/`segment_lengths`/`guide_strength` widgets; setting those derived widgets directly is refused (they are silently reverted). For AnimaRegionalCanvasInline / Krea2RegionalCanvasInline (LC123), quality/scene/red/green/blue/negative prompt writes are refused: the custom textarea and node.properties.animaPrompts overwrite widget.value on APPLY. Drive quality/scene/negative via a PrimitiveStringMultiline wired into quality_prompt_in / scene_prompt_in / negative_prompt_in; red/green/blue have no socket.", {
|
|
12720
|
+
def("panel_set_widget", "Set a widget value on a node in the user's open graph (steps, cfg, seed, ckpt_name, text prompts, …). Returns the previous and new value (a string longer than 1000 chars is echoed as {chars, sha256, preview} so batched calls stay inside the outer tool-result budget — pass `echo: \"full\"` for the verbatim string). Undoable with Ctrl+Z. To CLEAR a text widget to an empty string, pass `clear: true` (some MCP clients drop an empty-string `value` from the serialized payload, so `value: \"\"` may not arrive — `clear: true` always works). For the LTXDirector timeline node (WhatDreamsCost CSGlide), set `timeline_data` with the FULL timeline JSON (segments + global_prompt) to drive its custom timeline UI — this re-syncs the editor and regenerates its derived `local_prompts`/`segment_lengths`/`guide_strength` widgets; setting those derived widgets directly is refused (they are silently reverted). For AnimaRegionalCanvasInline / Krea2RegionalCanvasInline (LC123), quality/scene/red/green/blue/negative prompt writes are refused: the custom textarea and node.properties.animaPrompts overwrite widget.value on APPLY. Drive quality/scene/negative via a PrimitiveStringMultiline wired into quality_prompt_in / scene_prompt_in / negative_prompt_in; red/green/blue have no socket. DaSiWa_LTX2LoraLoader's `stack_data` write is also refused: its custom multi-row widget reserializes its own JS state over `widget.value`, so the echoed write would be a false success; edit the stack rows in the node UI instead.", {
|
|
12390
12721
|
node_id: nodeId().describe("Node id from panel_graph_outline / panel_query_graph."),
|
|
12391
12722
|
widget: z.string().describe("Widget name (e.g. 'steps', 'cfg', 'text')."),
|
|
12392
12723
|
value: z
|
|
@@ -12417,6 +12748,16 @@ export function buildPanelToolDefs() {
|
|
|
12417
12748
|
const blocked = await refuseAnimaRegionalPromptWrite(ctx, args.node_id, args.widget);
|
|
12418
12749
|
if (blocked)
|
|
12419
12750
|
return blocked;
|
|
12751
|
+
const daSiWaBlocked = await refuseDaSiWaStackWrite(ctx, args.node_id, args.widget);
|
|
12752
|
+
if (daSiWaBlocked)
|
|
12753
|
+
return daSiWaBlocked;
|
|
12754
|
+
let expectedNodeType;
|
|
12755
|
+
if (args.widget === DASIWA_STACK_WIDGET) {
|
|
12756
|
+
const daSiWaFence = await verifyDaSiWaStackWriteFence(ctx, args.node_id);
|
|
12757
|
+
if (daSiWaFence && "content" in daSiWaFence)
|
|
12758
|
+
return daSiWaFence;
|
|
12759
|
+
expectedNodeType = daSiWaFence?.expectedNodeType;
|
|
12760
|
+
}
|
|
12420
12761
|
// #599: the frontend runs refresh-before-validate here (pulls a fresh
|
|
12421
12762
|
// /object_info so a just-staged/-downloaded/-installed value is accepted on
|
|
12422
12763
|
// a single revalidation, #338/#458) — that authoritative fetch can outlast
|
|
@@ -12429,7 +12770,19 @@ export function buildPanelToolDefs() {
|
|
|
12429
12770
|
// to the raw success reply so a later appendToolResultText disclosure
|
|
12430
12771
|
// (which makes the text no longer parse as JSON) cannot dodge it.
|
|
12431
12772
|
const echoFull = args.echo === "full";
|
|
12432
|
-
const write = async (nodeId, widget) => stripVerifiedLastObservedSchemaNote(summarizeSetWidgetEcho(await ctx.call({
|
|
12773
|
+
const write = async (nodeId, widget, targetExpectedNodeType = expectedNodeType) => stripVerifiedLastObservedSchemaNote(summarizeSetWidgetEcho(await ctx.call({
|
|
12774
|
+
cmd: "graph_set_widget",
|
|
12775
|
+
node_id: nodeId,
|
|
12776
|
+
widget,
|
|
12777
|
+
value,
|
|
12778
|
+
// The caller supplies the type proven for THIS addressed node.
|
|
12779
|
+
// The outer final fence is used for direct/re-mapped writes;
|
|
12780
|
+
// promoted recovery re-probes its inner node after entering
|
|
12781
|
+
// and supplies that node's own type.
|
|
12782
|
+
...(targetExpectedNodeType
|
|
12783
|
+
? { expected_node_type: targetExpectedNodeType }
|
|
12784
|
+
: {}),
|
|
12785
|
+
}, OBJECT_INFO_REFRESH_ACK_TIMEOUT_MS), echoFull));
|
|
12433
12786
|
let first = await write(args.node_id, args.widget);
|
|
12434
12787
|
if (!first.isError) {
|
|
12435
12788
|
markPanelSchemaReady(panelSchemaKey(ctx));
|
|
@@ -12527,7 +12880,38 @@ export function buildPanelToolDefs() {
|
|
|
12527
12880
|
`Resolved it to inner node ${inner.innerNodeId} but panel_enter_subgraph FAILED: ` +
|
|
12528
12881
|
`${textOfToolResult(entered)})`);
|
|
12529
12882
|
}
|
|
12530
|
-
|
|
12883
|
+
let innerExpectedNodeType;
|
|
12884
|
+
if (expectedNodeType !== undefined) {
|
|
12885
|
+
// The inner mapping was discovered before an awaited enter. Re-query
|
|
12886
|
+
// the addressed inner node after entering so the stack_data write gets
|
|
12887
|
+
// its OWN live type fence; carrying the outer wrapper's type would
|
|
12888
|
+
// reject a valid inner node, while omitting a fence would let a same-
|
|
12889
|
+
// type replacement mutate a detached object and report false success.
|
|
12890
|
+
const innerProbe = await ctx.call({ cmd: "graph_query", ids: [inner.innerNodeId], fields: "compact", limit: 1 }, OBJECT_INFO_REFRESH_ACK_TIMEOUT_MS);
|
|
12891
|
+
const innerIdentity = innerProbe.isError
|
|
12892
|
+
? null
|
|
12893
|
+
: parseVerifiedQueriedNodeIdentity(parseToolResultJson(innerProbe));
|
|
12894
|
+
const expectedInnerId = canonicalQueriedNodeId(inner.innerNodeId);
|
|
12895
|
+
if (!innerIdentity || !expectedInnerId || innerIdentity.id !== expectedInnerId) {
|
|
12896
|
+
const exited = await ctx.call({ cmd: "graph_exit_subgraph" }, 15000);
|
|
12897
|
+
return appendToolResultText(first, `\n\n(The panel listed "${refusal.widget}" as promoted and mapped it to inner node ` +
|
|
12898
|
+
`${inner.innerNodeId}, but the post-enter identity probe did not verify that ` +
|
|
12899
|
+
`exact live node${innerProbe.isError ? `: ${textOfToolResult(innerProbe)}` : "."} ` +
|
|
12900
|
+
`The write was not retried.${exited.isError
|
|
12901
|
+
? ` panel_exit_subgraph also FAILED: ${textOfToolResult(exited)}`
|
|
12902
|
+
: ""})`);
|
|
12903
|
+
}
|
|
12904
|
+
if (innerIdentity.type === DASIWA_LTX2_LORA_LOADER) {
|
|
12905
|
+
const exited = await ctx.call({ cmd: "graph_exit_subgraph" }, 15000);
|
|
12906
|
+
return appendToolResultText(first, `\n\n(The promoted inner node ${inner.innerNodeId} was identified as ` +
|
|
12907
|
+
`${DASIWA_LTX2_LORA_LOADER}; ${textOfToolResult(daSiWaStackRefusal(innerIdentity.type))} ` +
|
|
12908
|
+
`No inner graph_set_widget was dispatched.${exited.isError
|
|
12909
|
+
? ` panel_exit_subgraph also FAILED: ${textOfToolResult(exited)}`
|
|
12910
|
+
: ""})`);
|
|
12911
|
+
}
|
|
12912
|
+
innerExpectedNodeType = innerIdentity.type;
|
|
12913
|
+
}
|
|
12914
|
+
const written = await write(inner.innerNodeId, inner.widget, innerExpectedNodeType);
|
|
12531
12915
|
const exited = await ctx.call({ cmd: "graph_exit_subgraph" }, 15000);
|
|
12532
12916
|
if (!written.isError) {
|
|
12533
12917
|
const via = `\n\n(Applied via the inner widget this promotion lists: node ${inner.innerNodeId} ` +
|
|
@@ -14904,17 +15288,20 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
14904
15288
|
color: args.color,
|
|
14905
15289
|
font_size: args.font_size,
|
|
14906
15290
|
}, 15000), args.node_ids, (cmd, timeoutMs) => ctx.call(cmd, timeoutMs))),
|
|
14907
|
-
def("panel_move_group", "Move a group box to a new top-left [x, y] on the user's open graph. By default the nodes inside the group move with it (like dragging the group header); pass move_nodes:false to move only the box.
|
|
15291
|
+
def("panel_move_group", "Move a group box to a new top-left [x, y] on the user's open graph. By default the nodes inside the group move with it (like dragging the group header); pass move_nodes:false to move only the box. Identify it by numeric id from panel_query_graph / panel_create_group via `group_id`, or by case-insensitive group-title substring via `group`. Undoable.", {
|
|
14908
15292
|
...GROUP_ID_ARGS,
|
|
14909
15293
|
pos: xy().describe("New top-left [x, y] (two numbers)."),
|
|
14910
15294
|
move_nodes: z.boolean().optional().describe("Move the contained nodes too (default true)."),
|
|
14911
15295
|
}, async (args, ctx) => {
|
|
14912
|
-
const
|
|
14913
|
-
if (!
|
|
14914
|
-
return fail(
|
|
14915
|
-
|
|
15296
|
+
const ref = resolveGroupRefArg("panel_move_group", args);
|
|
15297
|
+
if (!ref.ok)
|
|
15298
|
+
return fail(ref.error);
|
|
15299
|
+
const target = await resolveGroupMutationTarget(ref.value, ctx);
|
|
15300
|
+
if (!target.ok)
|
|
15301
|
+
return target.result;
|
|
15302
|
+
return ctx.call({ cmd: "graph_move_group", group_id: target.value, pos: args.pos, move_nodes: args.move_nodes });
|
|
14916
15303
|
}),
|
|
14917
|
-
def("panel_edit_group", "Edit a group box: its title, color, font_size, and/or bounds [x, y, width, height]. Only the fields you pass are changed. Identify it
|
|
15304
|
+
def("panel_edit_group", "Edit a group box: its title, color, font_size, and/or bounds [x, y, width, height]. Only the fields you pass are changed. Identify it by numeric id via `group_id`, or by case-insensitive group-title substring via `group`. Undoable.", {
|
|
14918
15305
|
...GROUP_ID_ARGS,
|
|
14919
15306
|
title: z.string().optional().describe("New label."),
|
|
14920
15307
|
color: z.string().optional().describe("New box/header color, e.g. '#3f789e'."),
|
|
@@ -14923,23 +15310,29 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
14923
15310
|
.optional()
|
|
14924
15311
|
.describe("Resize/reposition the box: [x, y, width, height] (four numbers)."),
|
|
14925
15312
|
}, async (args, ctx) => {
|
|
14926
|
-
const
|
|
14927
|
-
if (!
|
|
14928
|
-
return fail(
|
|
15313
|
+
const ref = resolveGroupRefArg("panel_edit_group", args);
|
|
15314
|
+
if (!ref.ok)
|
|
15315
|
+
return fail(ref.error);
|
|
15316
|
+
const target = await resolveGroupMutationTarget(ref.value, ctx);
|
|
15317
|
+
if (!target.ok)
|
|
15318
|
+
return target.result;
|
|
14929
15319
|
return ctx.call({
|
|
14930
15320
|
cmd: "graph_edit_group",
|
|
14931
|
-
group_id:
|
|
15321
|
+
group_id: target.value,
|
|
14932
15322
|
title: args.title,
|
|
14933
15323
|
color: args.color,
|
|
14934
15324
|
font_size: args.font_size,
|
|
14935
15325
|
bounds: args.bounds,
|
|
14936
15326
|
}, 15000);
|
|
14937
15327
|
}),
|
|
14938
|
-
def("panel_remove_group", "Remove a group box from the user's open graph. The nodes inside the group are NOT deleted — only the box.
|
|
14939
|
-
const
|
|
14940
|
-
if (!
|
|
14941
|
-
return fail(
|
|
14942
|
-
|
|
15328
|
+
def("panel_remove_group", "Remove a group box from the user's open graph. The nodes inside the group are NOT deleted — only the box. Identify it by numeric id via `group_id`, or by case-insensitive group-title substring via `group`. Undoable.", { ...GROUP_ID_ARGS }, async (args, ctx) => {
|
|
15329
|
+
const ref = resolveGroupRefArg("panel_remove_group", args);
|
|
15330
|
+
if (!ref.ok)
|
|
15331
|
+
return fail(ref.error);
|
|
15332
|
+
const target = await resolveGroupMutationTarget(ref.value, ctx);
|
|
15333
|
+
if (!target.ok)
|
|
15334
|
+
return target.result;
|
|
15335
|
+
return ctx.call({ cmd: "graph_remove_group", group_id: target.value }, 15000);
|
|
14943
15336
|
}),
|
|
14944
15337
|
def("panel_set_node_title", "Compatibility wrapper for panel_edit_node(title).", { node_id: nodeId(), title: z.string() }, async (args, ctx) => ctx.call({ cmd: "graph_set_title", node_id: args.node_id, title: args.title }, 15000)),
|
|
14945
15338
|
def("panel_set_node_collapsed", "Compatibility wrapper for panel_edit_node(collapsed).", { node_id: nodeId(), collapsed: z.boolean().optional() }, async (args, ctx) => ctx.call({ cmd: "graph_set_node_collapsed", node_id: args.node_id, collapsed: args.collapsed ?? true })),
|