@gentbajko/slopify 3.2.2 → 3.2.3

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.
@@ -0,0 +1,21 @@
1
+ # Slopify 3.2.3
2
+
3
+ Released 1 October 2026.
4
+
5
+ 3.2.3 makes Soften and retry actually reword a short's refused picture, and shows a render's progress on Home.
6
+
7
+ ## Shorts
8
+
9
+ - **Soften and retry** on a short's picture now draws the reworded prompt. In 3.2.2 the button appeared, but the picture was asked for with its original wording again and was refused again.
10
+
11
+ ## Home
12
+
13
+ - **Running now** shows what a running step is doing and how far it is ("Rendering the video (45%)"), as the project page does, instead of a step count that stood still through the whole render.
14
+
15
+ ## Thumbnails
16
+
17
+ - Regenerating a thumbnail asks with its own sentence: it makes a new thumbnail and leaves the video and shorts alone. It used the image's wording, which said the video would be rendered again.
18
+
19
+ ## Upgrading from 3.2.2
20
+
21
+ - **Nothing becomes outdated.**
@@ -1,4 +1,10 @@
1
1
  [
2
+ {
3
+ "id": "3.2.3",
4
+ "title": "Slopify 3.2.3",
5
+ "version": "3.2.3",
6
+ "date": "2026-10-01"
7
+ },
2
8
  {
3
9
  "id": "3.2.2",
4
10
  "title": "Slopify 3.2.2",
@@ -171,7 +171,8 @@ export async function executeProviderRecipe(deps, context, providers, piece) {
171
171
  }
172
172
  // Soften and retry (`soften.ts`): the project's AI model rewords a refused image prompt
173
173
  // before the image is drawn again. Undefined when nobody asked, or the project has no model.
174
- async function softenIfAsked(deps, context, providers, piece, prompt, label) {
174
+ // A short's stills are drawn in `runtime-shorts.ts`, which asks the same way.
175
+ export async function softenIfAsked(deps, context, providers, piece, prompt, label) {
175
176
  if (!softeningRequested(deps.db, context.work.projectId, piece.key))
176
177
  return undefined;
177
178
  const llm = executionView(deps, context.work.projectId, context.work.revisionId)?.revision.config
@@ -21,8 +21,10 @@ import { figureShots } from "./runtime-export-edit.js";
21
21
  import { exportSnapshot, revisionAudio } from "./runtime-export-inputs.js";
22
22
  import { imageCall } from "./runtime-image.js";
23
23
  import { savedCatalogue } from "./runtime-plan.js";
24
+ import { softenIfAsked } from "./runtime-provider.js";
24
25
  import { preparedResult, preparedTexts, publishResult } from "./runtime-publication.js";
25
26
  import { wordsSchema } from "./runtime-subtitles.js";
27
+ import { clearSoftening } from "./soften.js";
26
28
  // The Shorts step's four kinds of work (`recipe-shorts.ts`): the pick, each clip's image
27
29
  // prompts, each image, and each clip's render. Each is one piece of its own, so a failure
28
30
  // names the clip it belongs to and Try again redoes only what did not finish.
@@ -173,9 +175,14 @@ async function image(deps, context, providers, piece, clip, index) {
173
175
  const input = piece.input;
174
176
  if (input.kind !== "image")
175
177
  throw setupError();
176
- const made = await providers
177
- .forPiece(piece.id)
178
- .image(imageCall(deps, context.work.projectId, input, `Short ${String(clip.number)} image ${String(index)}`));
178
+ const wrapped = providers.forPiece(piece.id);
179
+ const label = `Short ${String(clip.number)} image ${String(index)}`;
180
+ // Soften and retry reworded this still's refused prompt: draw that one instead.
181
+ const softened = await softenIfAsked(deps, context, wrapped, piece, input.prompt, label);
182
+ if (softened === "held")
183
+ return "held";
184
+ const prompt = softened ?? input.prompt;
185
+ const made = await wrapped.image(imageCall(deps, context.work.projectId, { ...input, prompt }, label));
179
186
  if (!made.ok)
180
187
  return "held";
181
188
  const asset = writeAsset(deps, context.work.projectId, made.value.mime === "image/jpeg" ? "short-image.jpg" : "short-image.png", made.value.bytes);
@@ -183,11 +190,13 @@ async function image(deps, context, providers, piece, clip, index) {
183
190
  short: clip.number,
184
191
  sentences: [clip.first, clip.last],
185
192
  index,
186
- prompt: input.prompt,
193
+ prompt,
187
194
  provider: input.provider,
188
195
  model: input.model,
189
196
  });
190
- await publishResult(deps, context, piece, [output], { prompt: input.prompt }, asset);
197
+ await publishResult(deps, context, piece, [output], { prompt }, asset);
198
+ if (softened !== undefined)
199
+ clearSoftening(deps.db, context.work.projectId, [piece.key]);
191
200
  return "done";
192
201
  }
193
202
  async function render(deps, context, piece, snapshot, clip) {