Files
DemonGatanjieu-Anomalous_Mo…/web/modules/prompt_language.js
T
DemonGatanjieuandClaude Fable 5.2 d6c2edb1a1 Offer only the bases to pick from, stop an AI's run with no prompt, ask before swapping a named model
Found in a Gemini Flash exam (recorded in tool-exam.md):
- A later step's mask preview (only the character redrawn) was taken for a base;
  picked, the rest enlarged the mask. A base is the decoded picture itself.
- Flash tries run_workflow with no arguments: on a blueprint just built that drew
  three bases of nothing and spent the three to pick from. A run that draws from
  an empty latent with every positive prompt empty is refused once.
- A Tile refused for not fitting: when the user named the model, the AI is told
  to ask before changing it.
- A decision's rejected option given as a sentence stays one option.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-10 21:13:34 +08:00

67 lines
3.8 KiB
JavaScript

/**
* Before a run: is a prompt in a language the canvas's drawing model cannot read (api/prompt_language.py)?
* The model files come from the loaders' model boxes (ui_node_model_picker.js), the prompts from what the run
* sends: the canvas's positive prompt boxes (prompt_boxes.js), or a job sheet's rows. Asked by the AI's
* run_workflow (mcp_bridge.js) and job sheet (job_sheet_run.js), and the job sheet's Start (ui_job_sheet.js).
* What was asked about once is let through the next time (`heard`, kept apart for the AI and the user: the AI's
* refusal is no warning the user saw), so either can insist.
* And is there a prompt at all: an AI trying a tool out calls run_workflow with nothing, and on a picture
* Anomalous just built, its prompt box still empty, that drew pictures of nothing (the bases of a plan too).
* Such a run is refused once as well.
*/
import { promptBoxes, promptMissing } from './prompt_boxes.js';
import { modelComboWidgets } from './ui_node_model_picker.js';
const off = node => node.mode === 2 || node.mode === 4;
const heard = new Set();
function* nodesOf(graph) {
for (const node of graph?._nodes || []) {
yield node;
if (node.subgraph) yield* nodesOf(node.subgraph);
}
}
/** The text in `graph`'s positive prompt boxes. */
export const canvasPrompts = graph => [...nodesOf(graph)].filter(node => !off(node))
.flatMap(node => promptBoxes(node).filter(box => box.role === 'positive').map(box => String(box.widget?.value ?? '')));
/** {family, model} when a prompt of `texts` (default: the canvas's) is in a language `graph`'s model cannot read; else null. */
export async function languageProblem(graph, texts = canvasPrompts(graph)) {
const models = [...nodesOf(graph)].filter(node => !off(node)).flatMap(node => modelComboWidgets(node).map(widget => widget.value))
.filter(value => typeof value === 'string' && value && value !== 'None');
if (!models.length || !texts.some(Boolean)) return null;
try {
const response = await fetch('/anomalous/prompt_language', { method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ models: [...new Set(models)], texts }) });
const found = await response.json();
return found?.family ? found : null;
} catch {
return null; // the check only helps: a run is never stopped by it failing
}
}
/** Whether `graph` would draw from an empty latent with every positive prompt box (`texts`) empty, the first time the AI tries it on that canvas. */
export function noPrompt(graph, texts) {
return promptMissing([...nodesOf(graph)].filter(node => !off(node)), texts)
&& Boolean(firstTime({ model: `no prompt ${graph?.id ?? ''}` }, texts, 'ai'));
}
export const NO_PROMPT_WORDS = 'Nothing was run: the positive prompt is empty, so the pictures would follow nothing. Give it with the run: '
+ 'run_workflow(prompt=…, negative=…). If the user wants a run with no prompt, call again unchanged.';
/** The problem the first time `who` ('ai' or 'user') meets it; null when they met it before with the same model and prompts. */
export function firstTime(problem, texts, who) {
if (!problem) return null;
const key = `${who}\n${problem.model}\n${texts.join('\n')}`;
if (heard.has(key)) return null;
heard.add(key);
return problem;
}
/** What the AI is told: nothing ran, why, and how to go on. */
export const aiWords = problem => `Nothing was run: the canvas's model ${problem.model} (${problem.family}) reads English words and tags only, `
+ 'and the prompt is Chinese, Japanese or Korean, so the picture would not follow it and shows whatever the model leans to. '
+ 'Write the prompt in English for it (keep what the user asked for), then run again. If the user wants it run as written, call again unchanged.';