fix generate-all-steps: never overwrite existing content, right target per step
The previous version called target:'all' on every step unconditionally, which caused the AI to rewrite steps that already had good titles and descriptions — often making them worse or inaccurate. New behaviour: - Build a queue of only the steps that are actually missing content (placeholder title and/or empty description). - Determine target per step: 'title', 'description', or 'all' — only fill what is blank; leave existing user-written text completely alone. - If all steps already have titles and descriptions, show a toast and stop. - Call reload() once at the end instead of patching this.steps mid-loop, so the editor and step list both update atomically from the store. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
+31
-19
@@ -228,36 +228,48 @@ class GuideEditor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.pendingSave) await this.flushStep();
|
if (this.pendingSave) await this.flushStep();
|
||||||
|
|
||||||
|
// Only fill fields that are actually empty — never overwrite user-written content.
|
||||||
|
const PLACEHOLDER_TITLES = new Set([
|
||||||
|
'', 'screen capture', 'window capture', 'region capture', 'capture', 'untitled step',
|
||||||
|
]);
|
||||||
|
const isEmptyDesc = (html) => !(html || '').replace(/<[^>]*>/g, '').trim();
|
||||||
|
|
||||||
|
const queue = this.steps
|
||||||
|
.map((step) => {
|
||||||
|
const titleEmpty = !step.title || PLACEHOLDER_TITLES.has(step.title.toLowerCase());
|
||||||
|
const descEmpty = isEmptyDesc(step.descriptionHtml);
|
||||||
|
if (!titleEmpty && !descEmpty) return null;
|
||||||
|
const target = titleEmpty && descEmpty ? 'all' : titleEmpty ? 'title' : 'description';
|
||||||
|
return { stepId: step.stepId, target };
|
||||||
|
})
|
||||||
|
.filter(Boolean);
|
||||||
|
|
||||||
|
if (!queue.length) {
|
||||||
|
this.onToast('All steps already have titles and descriptions.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (button) setButtonLoading(button, true, 'Generating…');
|
if (button) setButtonLoading(button, true, 'Generating…');
|
||||||
let done = 0;
|
let done = 0;
|
||||||
let failed = 0;
|
let failed = 0;
|
||||||
const total = this.steps.length;
|
const total = queue.length;
|
||||||
try {
|
try {
|
||||||
for (const step of this.steps) {
|
for (const { stepId, target } of queue) {
|
||||||
this.onToast(`AI: filling step ${done + 1} of ${total}…`);
|
this.onToast(`AI: filling step ${done + failed + 1} of ${total}…`);
|
||||||
try {
|
try {
|
||||||
const result = await api.ai.fillStep({
|
const result = await api.ai.fillStep({ guideId: this.guideId, stepId, target });
|
||||||
guideId: this.guideId,
|
if (result?.ok) done++;
|
||||||
stepId: step.stepId,
|
else failed++;
|
||||||
target: 'all',
|
|
||||||
});
|
|
||||||
if (result?.ok) {
|
|
||||||
done++;
|
|
||||||
// Keep the in-memory steps list fresh so subsequent steps see updated guide context.
|
|
||||||
const idx = this.steps.findIndex((s) => s.stepId === step.stepId);
|
|
||||||
if (idx >= 0) this.steps[idx] = result.step;
|
|
||||||
} else {
|
|
||||||
failed++;
|
|
||||||
}
|
|
||||||
} catch {
|
} catch {
|
||||||
failed++;
|
failed++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Reload the currently-visible step so the editor reflects its new text.
|
// Reload re-fetches all steps from the store so the editor and list both reflect the new text.
|
||||||
if (this.selectedStepId) await this.reload(this.selectedStepId);
|
await this.reload(this.selectedStepId);
|
||||||
const msg = failed
|
const msg = failed
|
||||||
? `AI filled ${done} step${done === 1 ? '' : 's'} (${failed} failed).`
|
? `AI filled ${done} step${done === 1 ? '' : 's'} (${failed} failed).`
|
||||||
: `AI filled all ${done} step${done === 1 ? '' : 's'}.`;
|
: `AI filled ${done} step${done === 1 ? '' : 's'}.`;
|
||||||
this.onToast(msg, failed ? { error: true } : undefined);
|
this.onToast(msg, failed ? { error: true } : undefined);
|
||||||
} finally {
|
} finally {
|
||||||
if (button) setButtonLoading(button, false);
|
if (button) setButtonLoading(button, false);
|
||||||
|
|||||||
Reference in New Issue
Block a user