- The daily tool set now also offers tool_help and use_tool, and the
directory marks the tools reached that way; show_panel joins the daily
set. The "lazy" set is gone: a small model spent a third of its calls
looking tools up and never built what it planned.
- Gates window "Waiting for your answer" (1, 3 or 10 minutes): an open
question tells the AI to wait on with get_answers until then, and while
the user types (POST /anomalous/ai_tasks/{id}/typing) until a minute after
the last key. report and show_panel remind the AI to end each round with
ask_user; a question written in a note is pointed to ask_user.
- "Skip this one" is "Your call": the AI decides and does not ask again.
- ComfyUI's own `$$` widgets (the canvas image preview) are no longer
reported to the AI as the user's canvas change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
58 lines
3.3 KiB
JavaScript
58 lines
3.3 KiB
JavaScript
// node tests/activity_diff.mjs — canvas snapshots and their difference for the activity log.
|
|
import assert from 'node:assert/strict';
|
|
import { changeNodeId, diffSnapshots, snapshotGraph } from '../web/modules/activity_diff.js';
|
|
|
|
const graph = (nodes) => ({ _nodes: nodes });
|
|
const node = (id, title, widgets) => ({ id, type: title, title, widgets: Object.entries(widgets).map(([name, value]) => ({ name, value })) });
|
|
|
|
const before = snapshotGraph(graph([
|
|
node(3, 'KSampler', { steps: 20, cfg: 7, seed: 1 }),
|
|
node(4, 'CheckpointLoaderSimple', { ckpt_name: 'a.safetensors' }),
|
|
node(9, 'Note', { text: 'hello' }),
|
|
]));
|
|
const after = snapshotGraph(graph([
|
|
node(3, 'KSampler', { steps: 30, cfg: 7, seed: 1 }),
|
|
node(4, 'CheckpointLoaderSimple', { ckpt_name: 'b.safetensors' }),
|
|
node(12, 'LoraLoader', { lora_name: 'x.safetensors', strength_model: 1 }),
|
|
]));
|
|
|
|
assert.deepEqual(diffSnapshots(before, after).map(c => [c.kind, c.node, c.widget, c.before, c.after]), [
|
|
['changed', 'KSampler #3', 'steps', '20', '30'],
|
|
['changed', 'CheckpointLoaderSimple #4', 'ckpt_name', 'a.safetensors', 'b.safetensors'],
|
|
['added', 'LoraLoader #12', undefined, undefined, undefined],
|
|
['removed', 'Note #9', undefined, undefined, undefined],
|
|
]);
|
|
assert.deepEqual(diffSnapshots(before, before), []);
|
|
|
|
// Buttons, nameless widgets and ComfyUI's own preview hold no value.
|
|
const withButton = snapshotGraph(graph([{ id: 1, type: 'X', title: 'X', widgets: [{ name: 'run', type: 'button', value: 1 }, { value: 5 },
|
|
{ name: '$$canvas-image-preview', value: 'a.png' }] }]));
|
|
assert.deepEqual(withButton.get('1').widgets, {});
|
|
|
|
// Object values compare by content; a widget that appears counts as a change.
|
|
const a = snapshotGraph(graph([node(1, 'Img', { image: { name: 'a.png' } })]));
|
|
const b = snapshotGraph(graph([node(1, 'Img', { image: { name: 'a.png' }, extra: 2 })]));
|
|
assert.deepEqual(diffSnapshots(a, b).map(c => [c.widget, c.before, c.after]), [['extra', '', '2']]);
|
|
|
|
// Rewiring: what feeds an input, in words; not the inputs a removed node fed.
|
|
const wired = (links, extra = []) => {
|
|
const nodes = [
|
|
{ id: 1, type: 'CheckpointLoaderSimple', title: 'Load', outputs: [{ name: 'MODEL' }] },
|
|
{ id: 2, type: 'LoraLoader', title: 'LoRA', outputs: [{ name: 'MODEL' }] },
|
|
{ id: 3, type: 'KSampler', title: 'KSampler', inputs: [{ name: 'model', link: links.model ?? null }] },
|
|
...extra,
|
|
];
|
|
const table = new Map([[10, { origin_id: 1, origin_slot: 0 }], [11, { origin_id: 2, origin_slot: 0 }]]);
|
|
return snapshotGraph({ _nodes: nodes, links: table, getNodeById: id => nodes.find(n => n.id === id) });
|
|
};
|
|
assert.deepEqual(diffSnapshots(wired({}), wired({ model: 10 })).map(c => [c.kind, c.node, c.widget, c.before, c.after]),
|
|
[['wired', 'KSampler #3', 'model', '', 'Load #1 · MODEL']]);
|
|
assert.deepEqual(diffSnapshots(wired({ model: 10 }), wired({ model: 11 }))[0].after, 'LoRA #2 · MODEL');
|
|
const gone = snapshotGraph({ _nodes: [{ id: 3, type: 'KSampler', title: 'KSampler', inputs: [{ name: 'model', link: null }] }] });
|
|
assert.deepEqual(diffSnapshots(wired({ model: 10 }), gone).map(c => c.kind), ['removed', 'removed'], 'the removal says it');
|
|
|
|
assert.equal(changeNodeId({ node: 'KSampler #12' }), '12');
|
|
assert.equal(changeNodeId({ node: 'Title with # sign #7' }), '7');
|
|
assert.equal(changeNodeId({ node: 'no id' }), null);
|
|
console.log('activity_diff: ok');
|