@gentbajko/slopify 3.10.3 → 3.11.1

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.
@@ -152,6 +152,11 @@ export function textRecipes(context) {
152
152
  recipes.push(recipe(context, "article:continuation", "article", llmInput(context, continuationMessages(messages, resolved.articleContinuation), false, documents), [article.key]));
153
153
  const endMatter = articleMarkdown === null ? null : splitEndMatter(articleMarkdown);
154
154
  const articleText = endMatter === null ? null : plainText(endMatter.body);
155
+ // The pictures, and an intro or outro written from the article, go on reading the article
156
+ // they were made from while the version keeps it (`picturesArticle`).
157
+ const pictureText = content.picturesArticle === undefined
158
+ ? articleText
159
+ : plainText(splitEndMatter(content.picturesArticle).body);
155
160
  let script;
156
161
  if (voices !== undefined && scriptCheck !== undefined) {
157
162
  if (writesScript)
@@ -209,7 +214,7 @@ export function textRecipes(context) {
209
214
  const key = `entry:${category}:text`;
210
215
  const input = choice.mode === "text"
211
216
  ? { kind: "local", version: 1, operation: "entry-text", values: prompt }
212
- : articleText === null
217
+ : pictureText === null
213
218
  ? {
214
219
  kind: "deferred",
215
220
  version: 1,
@@ -219,7 +224,7 @@ export function textRecipes(context) {
219
224
  article.fingerprint,
220
225
  ],
221
226
  }
222
- : llmInput(context, withLanguage(segmentMessages(prompt, config, articleText), config.language));
227
+ : llmInput(context, withLanguage(segmentMessages(prompt, config, pictureText), config.language));
223
228
  const value = recipe(context, key, "article", input, choice.mode === "llm" ? [article.key] : []);
224
229
  recipes.push(value);
225
230
  entries[category] = {
@@ -234,9 +239,9 @@ export function textRecipes(context) {
234
239
  title: subjectOf(config),
235
240
  values: config.values,
236
241
  format: config.format,
237
- article: articleText ?? "",
242
+ article: pictureText ?? "",
238
243
  });
239
- recipes.push(recipe(context, "thumbnail:prompt", "thumbnail", articleText === null
244
+ recipes.push(recipe(context, "thumbnail:prompt", "thumbnail", pictureText === null
240
245
  ? {
241
246
  kind: "deferred",
242
247
  version: 1,
@@ -248,6 +253,7 @@ export function textRecipes(context) {
248
253
  return {
249
254
  recipes,
250
255
  articleText,
256
+ pictureText,
251
257
  narrationText,
252
258
  descriptions,
253
259
  cards,
@@ -17,6 +17,15 @@ export async function runRevisionInvocation(deps, context, providers) {
17
17
  continue;
18
18
  if (piece.input.kind === "deferred")
19
19
  return "held";
20
+ // A step Slopify does itself (no provider call) records how long it ran, for the working
21
+ // time; a provider call records its own attempts.
22
+ const local = /^(subtitles|export|document|voices):/.test(piece.key) ||
23
+ /^shorts:\d+:render$/.test(piece.key) ||
24
+ (!/^(review|youtube|shorts|animate):/.test(piece.key) &&
25
+ piece.input.kind !== "llm" &&
26
+ piece.input.kind !== "tts" &&
27
+ piece.input.kind !== "image");
28
+ const timed = local ? startLocalTime(deps, context) : undefined;
20
29
  try {
21
30
  const outcome = piece.key.startsWith("subtitles:")
22
31
  ? await executeSubtitleRecipe(deps, context, piece)
@@ -57,9 +66,25 @@ export async function runRevisionInvocation(deps, context, providers) {
57
66
  }
58
67
  throw label === undefined ? error : new Error(`${label}: ${error.message}`, { cause: error });
59
68
  }
69
+ finally {
70
+ if (timed !== undefined)
71
+ endLocalTime(deps, timed);
72
+ }
60
73
  }
61
74
  deps.db
62
75
  .prepare("UPDATE revision_work_pieces SET state='done' WHERE work_id=? AND result_json IS NOT NULL")
63
76
  .run(context.work.workId);
64
77
  return "done";
65
78
  }
79
+ function startLocalTime(deps, context) {
80
+ const id = deps.ids.next();
81
+ deps.db
82
+ .prepare("INSERT INTO local_work_times(id,project_id,stage_id,revision_id,work_id,started_at) VALUES (?,?,?,?,?,?)")
83
+ .run(id, context.work.projectId, context.work.stageId, context.work.revisionId, context.work.workId, deps.clock.now().toISOString());
84
+ return id;
85
+ }
86
+ function endLocalTime(deps, id) {
87
+ deps.db
88
+ .prepare("UPDATE local_work_times SET ended_at=? WHERE id=?")
89
+ .run(deps.clock.now().toISOString(), id);
90
+ }
@@ -34,6 +34,9 @@ export const revisionContentSchema = z
34
34
  .object({
35
35
  articleMarkdown: z.string().max(500000).optional(),
36
36
  articleEdited: z.boolean().default(false),
37
+ // The article the pictures were drawn from, kept once the article is edited by hand so
38
+ // they are not drawn again (`rebuild/recipe-save.ts`).
39
+ picturesArticle: z.string().max(500000).optional(),
37
40
  provided: z
38
41
  .object({
39
42
  research: id.optional(),
@@ -31,8 +31,13 @@ export function projectTiming(db, projectId, now) {
31
31
  a.started_at AS started_at, a.ended_at AS ended_at, w.state AS work_state
32
32
  FROM attempts a JOIN stages s ON s.id = a.stage_id
33
33
  LEFT JOIN revision_work w ON w.id = a.work_id
34
- WHERE s.project_id = ?`)
35
- .all(projectId)
34
+ WHERE s.project_id = ?
35
+ UNION ALL
36
+ SELECT s.kind, t.revision_id, t.work_id, t.started_at, t.ended_at, w.state
37
+ FROM local_work_times t JOIN stages s ON s.id = t.stage_id
38
+ LEFT JOIN revision_work w ON w.id = t.work_id
39
+ WHERE t.project_id = ?`)
40
+ .all(projectId, projectId)
36
41
  .map((row) => attemptRow.parse(row));
37
42
  const head = currentRevisionId(db, projectId);
38
43
  // Work an edit carried over to the current revision is still its run's work: a video
@@ -35,6 +35,8 @@ export const projectTables = [
35
35
  "project_controls",
36
36
  "stages",
37
37
  "attempts",
38
+ // Since 3.11.1: how long each local step (a render, the levelling) ran.
39
+ "local_work_times",
38
40
  "stage_pieces",
39
41
  "outputs",
40
42
  "project_revisions",