@gui-chat-plugin/sequence 0.2.0 → 0.3.0

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.
@@ -1,17 +1,59 @@
1
1
  import { createSerialLock as e } from "gui-chat-protocol";
2
+ //#region src/core/slideHtml.ts
3
+ var t = 1280, n = 720, r = 6e4, i = "https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.3.3/dist/index.global.js", a = "sha384-2ql948lIdLcGEE0/qxNiudyTjgauA3RDJERu5xW75kFCvSl5a9odyQYCb6tEjnmB", o = [
4
+ "fade-in",
5
+ "fade-up",
6
+ "fade-down",
7
+ "slide-in-left",
8
+ "slide-in-right",
9
+ "zoom-in",
10
+ "pop",
11
+ "draw"
12
+ ], s = "\n@theme {\n --animate-fade-in: fade-in 0.8s ease-out both;\n --animate-fade-up: fade-up 0.8s ease-out both;\n --animate-fade-down: fade-down 0.8s ease-out both;\n --animate-slide-in-left: slide-in-left 0.8s ease-out both;\n --animate-slide-in-right: slide-in-right 0.8s ease-out both;\n --animate-zoom-in: zoom-in 0.8s ease-out both;\n --animate-pop: pop 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) both;\n --animate-draw: draw 1.5s ease-in-out both;\n @keyframes fade-in { from { opacity: 0 } to { opacity: 1 } }\n @keyframes fade-up { from { opacity: 0; transform: translateY(40px) } to { opacity: 1; transform: none } }\n @keyframes fade-down { from { opacity: 0; transform: translateY(-40px) } to { opacity: 1; transform: none } }\n @keyframes slide-in-left { from { opacity: 0; transform: translateX(-80px) } to { opacity: 1; transform: none } }\n @keyframes slide-in-right { from { opacity: 0; transform: translateX(80px) } to { opacity: 1; transform: none } }\n @keyframes zoom-in { from { opacity: 0; transform: scale(0.8) } to { opacity: 1; transform: none } }\n @keyframes pop { from { opacity: 0; transform: scale(0.5) } to { opacity: 1; transform: none } }\n @keyframes draw { from { stroke-dashoffset: var(--draw-length, 1000) } to { stroke-dashoffset: 0 } }\n}", c = "\n(() => {\n const show = () => document.documentElement.classList.add(\"ready\");\n const ready = () => requestAnimationFrame(() => requestAnimationFrame(show));\n const check = () =>\n document.querySelector(\"style:not([type]):not(#slide-base)\") ? ready() : setTimeout(check, 30);\n addEventListener(\"DOMContentLoaded\", check);\n setTimeout(show, 1000);\n addEventListener(\"click\", (event) => {\n if (event.target instanceof Element && event.target.closest(\"a, area\")) event.preventDefault();\n }, true);\n})();", l = [
13
+ "default-src 'none'",
14
+ `script-src 'sha256-MZyL5rvWmIVxl3WUuDU5BqzPJGR2/fV/YPh01MNyUoM=' ${i}`,
15
+ "style-src 'unsafe-inline' https://fonts.googleapis.com",
16
+ "font-src https://fonts.gstatic.com data:",
17
+ "img-src data: blob:",
18
+ "media-src data: blob:",
19
+ "connect-src 'none'",
20
+ "form-action 'none'",
21
+ "base-uri 'none'"
22
+ ].join("; "), u = (e) => e.replace(/<(?=(meta|base|link)\b)/gi, "&lt;").replace(/shadowroot/gi, "data-no-shadow-root"), d = `
23
+ html, body { margin: 0; width: ${t}px; height: 720px; overflow: hidden; }
24
+ html:not(.ready) body { visibility: hidden; }
25
+ html:not(.ready) body * { animation-play-state: paused !important; }`;
26
+ function f(e) {
27
+ return `<!doctype html>
28
+ <html lang="en">
29
+ <head>
30
+ <meta charset="utf-8">
31
+ <meta http-equiv="Content-Security-Policy" content="${l}">
32
+ <style id="slide-base">${d}</style>
33
+ <script>${c}<\/script>
34
+ <script defer src="${i}" integrity="${a}" crossorigin="anonymous"><\/script>
35
+ <style type="text/tailwindcss">${s}</style>
36
+ </head>
37
+ <body class="bg-white text-slate-900 font-sans antialiased">
38
+ ${u(e)}
39
+ </body>
40
+ </html>`;
41
+ }
42
+ //#endregion
2
43
  //#region src/core/definitions.ts
3
- var t = "presentSlide", n = "defineStoryboard", r = "presentPanel", i = 4, a = 12, o = 3, s = /^[0-9a-f]{12}$/, c = (e) => typeof e == "object" && !!e && !Array.isArray(e), l = (e) => typeof e == "string" ? e.trim() : "", u = (e, t) => e.toLowerCase() === t.toLowerCase(), d = (e) => typeof e == "number" && Number.isInteger(e), f = "presentSlide needs slide and totalSlides (whole numbers, slide from 1 to totalSlides) and an imagePrompt";
4
- function p(e) {
5
- let { slide: t, totalSlides: n, title: r, imagePrompt: i } = e;
6
- return !d(t) || !d(n) || t < 1 || n < t || typeof i != "string" || !i.trim() ? null : {
44
+ var p = "presentSlide", m = "defineStoryboard", h = "presentPanel", ee = 4, te = 12, ne = 3, g = /^[0-9a-f]{12}$/, _ = (e) => typeof e == "object" && !!e && !Array.isArray(e), v = (e) => typeof e == "string" ? e.trim() : "", y = (e, t) => e.toLowerCase() === t.toLowerCase(), b = (e) => typeof e == "number" && Number.isInteger(e), x = "presentSlide needs slide and totalSlides (whole numbers, slide from 1 to totalSlides), and either an imagePrompt or html", re = `presentSlide's html is too long: keep a slide under ${r} characters`;
45
+ function ie(e) {
46
+ let { slide: t, totalSlides: n, title: r, imagePrompt: i } = e, a = v(e.html);
47
+ return !b(t) || !b(n) || t < 1 || n < t || !a && !v(i) ? x : a.length > 6e4 ? re : {
7
48
  slide: t,
8
49
  totalSlides: n,
9
50
  title: typeof r == "string" ? r : "",
10
- imagePrompt: i,
51
+ imagePrompt: a ? "" : String(i),
52
+ ...a && { html: a },
11
53
  mode: e.mode === "steps" ? "steps" : "presentation"
12
54
  };
13
55
  }
14
- var m = ({ slide: e, totalSlides: t, title: n, mode: r }) => {
56
+ var S = ({ slide: e, totalSlides: t, title: n, mode: r }) => {
15
57
  let i = n ? ` ("${n}")` : "";
16
58
  if (r === "steps") {
17
59
  let n = `Step ${e} of ${t}${i}`;
@@ -19,11 +61,11 @@ var m = ({ slide: e, totalSlides: t, title: n, mode: r }) => {
19
61
  }
20
62
  let a = `Slide ${e} of ${t}${i}`;
21
63
  return e < t ? `${a} is now on the screen. Explain it, then, in this same reply and without waiting for the user, call presentSlide for slide ${e + 1}. If the user has asked you to stop, or asked something else, since the slideshow began, answer them instead of going on.` : `${a}, the last one, is now on the screen. Explain it, then wrap up the slideshow.`;
22
- }, h = "When the user asks for a slideshow (or to explain something with slides), plan four to six slides, then show them one at a time with presentSlide: slide 1 first, and each next slide only after you have explained the one on the screen. Go on to the last slide without asking whether to continue. When the user wants to be shown how to do something they will do along with you (cooking, folding, fixing, an exercise), make it a step-by-step guide instead: mode \"steps\", one slide per step, and after each step wait for the user to say they are ready. Use generateImage for a single picture, not for slides.", g = {
64
+ }, ae = [`For an HTML slide, instead of imagePrompt: the slide's content, the inside of <body> only (no <html>, <head> or <body> tags), for a ${t}x720 px canvas, which it should fill (start with a <div class="w-full h-full ...">). Style it with Tailwind CSS v4 classes, which are loaded for you: a clear layout, a large title (text-6xl or so), few words in large type, a color scheme, and inline SVG or emoji for icons and diagrams. There is no network: no <img> from URLs, no links to follow.`, `Animate it so it builds up as you explain it: these classes are defined, ${o.map((e) => `animate-${e}`).join(", ")} (an SVG path drawing itself: set stroke-dasharray and --draw-length to its length), plus Tailwind's animate-pulse, animate-bounce, animate-spin and animate-ping, and transitions. Stagger the parts with a delay, [animation-delay:600ms], so they appear one after another over a few seconds. A <style> with your own @keyframes is allowed too (and Google Fonts by @import). Scripts don't run: animate with CSS only.`].join(" "), C = "When the user asks for a slideshow (or to explain something with slides), plan four to six slides, then show them one at a time with presentSlide: slide 1 first, and each next slide only after you have explained the one on the screen. Go on to the last slide without asking whether to continue. A slide is a generated picture (imagePrompt) or a designed slide in HTML (html): use a picture for a scene, an object or a place, and HTML for words, numbers, lists, comparisons, timelines and diagrams, which a picture model draws badly; a slideshow can mix them. When the user wants to be shown how to do something they will do along with you (cooking, folding, fixing, an exercise), make it a step-by-step guide instead: mode \"steps\", one slide per step, and after each step wait for the user to say they are ready. Use generateImage for a single picture, not for slides.", w = {
23
65
  type: "function",
24
- name: t,
25
- prompt: h,
26
- description: "Show one slide of a slideshow: a picture generated from imagePrompt, full screen. Call it once per slide, in order, starting with slide 1. With mode \"steps\" it is a step-by-step guide: one slide per step, and the next step waits for the user.",
66
+ name: p,
67
+ prompt: C,
68
+ description: "Show one slide of a slideshow, full screen: a picture generated from imagePrompt, or a slide written in HTML (html). Call it once per slide, in order, starting with slide 1. With mode \"steps\" it is a step-by-step guide: one slide per step, and the next step waits for the user.",
27
69
  parameters: {
28
70
  type: "object",
29
71
  properties: {
@@ -41,7 +83,11 @@ var m = ({ slide: e, totalSlides: t, title: n, mode: r }) => {
41
83
  },
42
84
  imagePrompt: {
43
85
  type: "string",
44
- description: "The picture for this slide: a clear illustration or diagram of its point, with the title as its only large text. Be concrete. For a step, show the action: hands, tools and the object."
86
+ description: "For a picture slide: the picture, a clear illustration of its point, with the title as its only large text. Be concrete. For a step, show the action: hands, tools and the object. Leave it out for an HTML slide."
87
+ },
88
+ html: {
89
+ type: "string",
90
+ description: ae
45
91
  },
46
92
  mode: {
47
93
  type: "string",
@@ -52,54 +98,53 @@ var m = ({ slide: e, totalSlides: t, title: n, mode: r }) => {
52
98
  required: [
53
99
  "slide",
54
100
  "totalSlides",
55
- "title",
56
- "imagePrompt"
101
+ "title"
57
102
  ]
58
103
  }
59
104
  };
60
- function _(e) {
105
+ function T(e) {
61
106
  let { totalPanels: t } = e;
62
- if (!d(t) || t < 1 || t > 12) return "totalPanels must be a whole number from 1 to 12";
107
+ if (!b(t) || t < 1 || t > 12) return "totalPanels must be a whole number from 1 to 12";
63
108
  let n = [];
64
109
  for (let t of Array.isArray(e.characters) ? e.characters : []) {
65
- let e = c(t) ? l(t.name) : "", r = c(t) ? l(t.description) : "";
110
+ let e = _(t) ? v(t.name) : "", r = _(t) ? v(t.description) : "";
66
111
  if (!e || !r) return "every character needs a name and a description";
67
- if (n.some((t) => u(t.name, e))) return `two characters are named ${e}`;
112
+ if (n.some((t) => y(t.name, e))) return `two characters are named ${e}`;
68
113
  n.push({
69
114
  name: e,
70
115
  description: r
71
116
  });
72
117
  }
73
118
  return n.length < 1 || n.length > 4 ? "a storyboard has 1 to 4 characters" : {
74
- title: l(e.title),
75
- style: l(e.style),
119
+ title: v(e.title),
120
+ style: v(e.style),
76
121
  totalPanels: t,
77
122
  characters: n,
78
123
  interactive: e.interactive === !0
79
124
  };
80
125
  }
81
- var v = ({ title: e, id: t }) => `The cast of "${e}" is now on the screen. Introduce the characters briefly, then, in this same reply and without waiting for the user, call presentPanel for panel 1 with storyboardId "${t}". If the user has asked you to stop, or asked something else, answer them instead of going on.`, y = "presentPanel needs a storyboardId, a panel number (from 1) and an imagePrompt";
82
- function b(e) {
83
- let { panel: t } = e, n = l(e.storyboardId), r = l(e.imagePrompt);
84
- if (!n || !r || !d(t) || t < 1) return null;
85
- let i = (e) => (Array.isArray(e) ? e : []).map(l).filter(Boolean);
126
+ var E = ({ title: e, id: t }) => `The cast of "${e}" is now on the screen. Introduce the characters briefly, then, in this same reply and without waiting for the user, call presentPanel for panel 1 with storyboardId "${t}". If the user has asked you to stop, or asked something else, answer them instead of going on.`, D = "presentPanel needs a storyboardId, a panel number (from 1) and an imagePrompt";
127
+ function O(e) {
128
+ let { panel: t } = e, n = v(e.storyboardId), r = v(e.imagePrompt);
129
+ if (!n || !r || !b(t) || t < 1) return null;
130
+ let i = (e) => (Array.isArray(e) ? e : []).map(v).filter(Boolean);
86
131
  return {
87
132
  storyboardId: n,
88
133
  panel: t,
89
134
  characters: i(e.characters),
90
135
  imagePrompt: r,
91
- caption: l(e.caption),
136
+ caption: v(e.caption),
92
137
  choices: i(e.choices).slice(0, 3)
93
138
  };
94
139
  }
95
- function x(e, t, n) {
140
+ function k(e, t, n) {
96
141
  let { id: r, totalPanels: i } = e;
97
142
  return n.length ? `Panel ${t} of ${i} is now on the screen, with the user's choices: ${n.map((e, t) => `${t + 1}. ${e}`).join(" ")} Tell this part of the story, then read the choices out and ask the user which one they pick, and wait for their answer. Then call presentPanel for panel ${t + 1} with storyboardId "${r}", going on the way they chose.` : t < i ? `Panel ${t} of ${i} is now on the screen. Tell this part of the story, then, in this same reply and without waiting for the user, call presentPanel for panel ${t + 1} with storyboardId "${r}". If the user has asked you to stop, or asked something else, since the story began, answer them instead of going on.` : `Panel ${t} of ${i}, the last one, is now on the screen. Tell this part of the story, then bring it to an end.`;
98
143
  }
99
- var S = "When the user asks for a story, a picture book, a comic or a storyboard, tell it in pictures: first call defineStoryboard with the art style and the characters who appear more than once (it draws a reference sheet for each, so they look the same in every panel), then show the panels one at a time with presentPanel, naming the characters in each, and tell each part of the story when its panel appears. Go on to the last panel without asking whether to continue, unless the story is interactive. When the user wants to decide what happens (an adventure, a story for a child who wants to choose), set interactive, and give two or three choices on two or three of the panels: the story waits there for the user's pick and goes on their way; it still ends at the last panel whichever way it goes. Use presentSlide to explain a topic, not to tell a story.", C = {
144
+ var A = "When the user asks for a story, a picture book, a comic or a storyboard, tell it in pictures: first call defineStoryboard with the art style and the characters who appear more than once (it draws a reference sheet for each, so they look the same in every panel), then show the panels one at a time with presentPanel, naming the characters in each, and tell each part of the story when its panel appears. Go on to the last panel without asking whether to continue, unless the story is interactive. When the user wants to decide what happens (an adventure, a story for a child who wants to choose), set interactive, and give two or three choices on two or three of the panels: the story waits there for the user's pick and goes on their way; it still ends at the last panel whichever way it goes. Use presentSlide to explain a topic, not to tell a story.", j = {
100
145
  type: "function",
101
- name: n,
102
- prompt: S,
146
+ name: m,
147
+ prompt: A,
103
148
  description: "Start a story told in pictures: set its art style and draw a reference sheet for each recurring character, shown as the cast. Then call presentPanel for each panel, in order.",
104
149
  parameters: {
105
150
  type: "object",
@@ -146,9 +191,9 @@ var S = "When the user asks for a story, a picture book, a comic or a storyboard
146
191
  "characters"
147
192
  ]
148
193
  }
149
- }, w = {
194
+ }, M = {
150
195
  type: "function",
151
- name: r,
196
+ name: h,
152
197
  description: "Show one panel of a storyboard made with defineStoryboard: a picture of the scene with its characters drawn as in their reference sheets, and a caption. Call it once per panel, in order, starting with panel 1.",
153
198
  parameters: {
154
199
  type: "object",
@@ -187,46 +232,54 @@ var S = "When the user asks for a story, a picture book, a comic or a storyboard
187
232
  "imagePrompt"
188
233
  ]
189
234
  }
190
- }, T = (e) => typeof e == "object" && !!e && !Array.isArray(e), ee = (e) => T(e) && typeof e.message == "string";
191
- function E(e) {
192
- let t = T(e?.data) ? e.data : {};
235
+ }, N = (e) => typeof e == "object" && !!e && !Array.isArray(e), oe = (e) => N(e) && typeof e.message == "string";
236
+ function P(e) {
237
+ let t = N(e?.data) ? e.data : {};
193
238
  return {
194
239
  ...typeof t.imageData == "string" && { imageData: t.imageData },
195
240
  ...typeof t.imagePath == "string" && { imagePath: t.imagePath }
196
241
  };
197
242
  }
198
- function te(e, t) {
199
- let n = E(e), r = E(t);
200
- return n.imagePath && r.imagePath ? n.imagePath === r.imagePath : !!n.imageData && n.imageData === r.imageData;
243
+ function F(e) {
244
+ let t = N(e?.data) ? e.data : {};
245
+ return typeof t.html == "string" ? t.html : "";
201
246
  }
202
- var D = (e, t) => e.userSpokeAt === void 0 || e.userSpokeAt > t, O = () => crypto.randomUUID().replace(/-/g, "").slice(0, 12), k = "artifacts/";
203
- async function A(e, t) {
247
+ var se = (e) => !!P(e).imageData || !!F(e);
248
+ function ce(e, t) {
249
+ let n = P(e), r = P(t);
250
+ if (n.imagePath && r.imagePath) return n.imagePath === r.imagePath;
251
+ if (n.imageData) return n.imageData === r.imageData;
252
+ let i = F(e);
253
+ return !!i && i === F(t);
254
+ }
255
+ var I = (e, t) => e.userSpokeAt === void 0 || e.userSpokeAt > t, L = () => crypto.randomUUID().replace(/-/g, "").slice(0, 12), le = "artifacts/";
256
+ async function R(e, t) {
204
257
  let n = e.files?.artifacts;
205
258
  if (!e.app?.editImages || !n) return [];
206
259
  let r = [];
207
- for (let e of t) if (e.startsWith(k)) try {
260
+ for (let e of t) if (e.startsWith(le)) try {
208
261
  await n.exists(e.slice(10)) && r.push(e);
209
262
  } catch {}
210
263
  return r;
211
264
  }
212
- async function j(e, t, n = []) {
265
+ async function z(e, t, n = []) {
213
266
  let r = e.app, i = r?.editImages, a = r?.generateImage;
214
267
  try {
215
268
  let e;
216
269
  if (n.length && i) e = await i(t, [...n]);
217
270
  else if (a) e = await a(t);
218
271
  else return { message: "image generation isn't available" };
219
- return ee(e) ? e : { message: "image generation returned an unrecognized result" };
272
+ return oe(e) ? e : { message: "image generation returned an unrecognized result" };
220
273
  } catch (e) {
221
274
  return { message: `image generation failed: ${e instanceof Error ? e.message : String(e)}` };
222
275
  }
223
276
  }
224
- var M = 50;
225
- function N(e) {
277
+ var ue = 50;
278
+ function B(e) {
226
279
  let t = /* @__PURE__ */ new Map();
227
280
  return (n) => {
228
281
  let r = n.conversationId ?? "", i = t.get(r);
229
- if (i === void 0 ? i = e() : t.delete(r), t.set(r, i), t.size > M) {
282
+ if (i === void 0 ? i = e() : t.delete(r), t.set(r, i), t.size > ue) {
230
283
  let e = t.keys().next().value;
231
284
  e !== void 0 && t.delete(e);
232
285
  }
@@ -235,20 +288,20 @@ function N(e) {
235
288
  }
236
289
  //#endregion
237
290
  //#region src/core/records.ts
238
- var P = "slideshows", F = "storyboards", I = {}, L = /* @__PURE__ */ new WeakMap(), R = /* @__PURE__ */ new WeakMap();
239
- function z(e) {
240
- let t = L.get(e);
241
- return t || L.set(e, t = /* @__PURE__ */ new Map()), t;
291
+ var V = "slideshows", H = "storyboards", U = {}, W = /* @__PURE__ */ new WeakMap(), G = /* @__PURE__ */ new WeakMap();
292
+ function K(e) {
293
+ let t = W.get(e);
294
+ return t || W.set(e, t = /* @__PURE__ */ new Map()), t;
242
295
  }
243
- function ne(t, n) {
244
- let r = R.get(t);
245
- r || R.set(t, r = /* @__PURE__ */ new Map());
296
+ function de(t, n) {
297
+ let r = G.get(t);
298
+ r || G.set(t, r = /* @__PURE__ */ new Map());
246
299
  let i = r.get(n);
247
300
  return i || r.set(n, i = e()), i;
248
301
  }
249
- var B = (e, t) => `${e}/${t}.json`;
250
- async function V(e, t) {
251
- let n = z(e ?? I), r = n.get(t);
302
+ var q = (e, t) => `${e}/${t}.json`;
303
+ async function J(e, t) {
304
+ let n = K(e ?? U), r = n.get(t);
252
305
  if (r) return r;
253
306
  if (!e) return null;
254
307
  try {
@@ -258,14 +311,14 @@ async function V(e, t) {
258
311
  return null;
259
312
  }
260
313
  }
261
- async function H(e, t, n) {
262
- return s.test(n) ? V(e, B(t, n)) : null;
314
+ async function Y(e, t, n) {
315
+ return g.test(n) ? J(e, q(t, n)) : null;
263
316
  }
264
- async function U(e, t, n, r) {
265
- let i = B(t, n), a = e ?? I;
266
- return ne(a, i)(async () => {
267
- let t = r(await V(e, i));
268
- if (z(a).set(i, t), !e) return !1;
317
+ async function X(e, t, n, r) {
318
+ let i = q(t, n), a = e ?? U;
319
+ return de(a, i)(async () => {
320
+ let t = r(await J(e, i));
321
+ if (K(a).set(i, t), !e) return !1;
269
322
  try {
270
323
  return await e.write(i, JSON.stringify(t, null, 2)), !0;
271
324
  } catch (e) {
@@ -273,12 +326,12 @@ async function U(e, t, n, r) {
273
326
  }
274
327
  });
275
328
  }
276
- var W = (e) => `the ${e} could not be saved, so it lasts only until the app or server restarts`, re = 6e4;
277
- function G() {
329
+ var Z = (e) => `the ${e} could not be saved, so it lasts only until the app or server restarts`, fe = 6e4;
330
+ function pe() {
278
331
  let e = /* @__PURE__ */ new Map();
279
332
  return { claim: (t) => {
280
333
  let n = Date.now();
281
- for (let [t, r] of e) n - r.at > re && e.delete(t);
334
+ for (let [t, r] of e) n - r.at > fe && e.delete(t);
282
335
  let r = e.get(t);
283
336
  if (r) return { earlier: r.shown };
284
337
  let i = () => void 0, a = new Promise((e) => i = e);
@@ -292,7 +345,7 @@ function G() {
292
345
  }
293
346
  //#endregion
294
347
  //#region src/core/presentSlide.ts
295
- function K({ slide: e, totalSlides: t, mode: n }) {
348
+ function me({ slide: e, totalSlides: t, mode: n }) {
296
349
  return n === "steps" ? {
297
350
  step: e,
298
351
  total: t,
@@ -310,25 +363,26 @@ function K({ slide: e, totalSlides: t, mode: n }) {
310
363
  nextCall: `call presentSlide for slide ${e + 1} of ${t}`
311
364
  };
312
365
  }
313
- var q = (e, { slide: t, totalSlides: n, title: r, imagePrompt: i }) => JSON.stringify([
366
+ var he = (e, { slide: t, totalSlides: n, title: r, imagePrompt: i, html: a }) => JSON.stringify([
314
367
  e,
315
368
  t,
316
369
  n,
317
370
  r,
318
- i
319
- ]), J = N(() => ({
371
+ i,
372
+ a
373
+ ]), ge = B(() => ({
320
374
  latest: {
321
375
  presentation: null,
322
376
  steps: null
323
377
  },
324
378
  lastShown: null,
325
- repeats: G()
379
+ repeats: pe()
326
380
  }));
327
- function Y(e, t) {
381
+ function _e(e, t) {
328
382
  let n = e.latest[t.mode], r = n?.totalSlides === t.totalSlides && (t.slide !== 1 || n.firstTitle === t.title);
329
383
  if (n && r) return n;
330
384
  let i = {
331
- id: O(),
385
+ id: L(),
332
386
  mode: t.mode,
333
387
  totalSlides: t.totalSlides,
334
388
  firstTitle: t.slide === 1 ? t.title : "",
@@ -338,18 +392,18 @@ function Y(e, t) {
338
392
  };
339
393
  return e.latest[t.mode] = i, i;
340
394
  }
341
- function X(e, t, n, r) {
395
+ function ve(e, t, n, r) {
342
396
  t.current = n.slide, t.shownAt = Date.now(), e.lastShown = t;
343
397
  let i = n.mode === "steps" ? "step" : "slide", { uuid: a, ...o } = r;
344
398
  return {
345
399
  ...o,
346
400
  message: `${i} ${n.slide} of ${n.totalSlides} is on the screen again, as it was`,
347
- instructions: m(n),
401
+ instructions: S(n),
348
402
  instructionsRequired: !0,
349
- sequence: K(n)
403
+ sequence: me(n)
350
404
  };
351
405
  }
352
- function ie(e, t) {
406
+ function ye(e, t) {
353
407
  if (e.mode !== "steps") return e.title ? `A presentation slide titled "${e.title}". ${e.imagePrompt}` : e.imagePrompt;
354
408
  let n = e.title ? `, "${e.title}"` : "";
355
409
  return [
@@ -358,15 +412,27 @@ function ie(e, t) {
358
412
  "Show the action clearly, with little or no text."
359
413
  ].filter(Boolean).join(" ");
360
414
  }
361
- async function ae(e, t, n) {
362
- let r = t.slides.get(n.slide - 1), i = n.mode === "steps" ? E(r).imagePath : void 0, a = i ? await A(e, [i]) : [], o = ie(n, a.length > 0), s = await j(e, o, a), { imageData: c, imagePath: l } = E(s);
363
- if (!c) return {
415
+ async function be(e, t, n) {
416
+ if (n.html) return {
417
+ html: n.html,
418
+ prompt: ""
419
+ };
420
+ let r = t.slides.get(n.slide - 1), i = n.mode === "steps" ? P(r).imagePath : void 0, a = i ? await R(e, [i]) : [], o = ye(n, a.length > 0), s = await z(e, o, a), { imageData: c, imagePath: l } = P(s);
421
+ return c ? {
422
+ imageData: c,
423
+ ...l && { imagePath: l },
424
+ prompt: o
425
+ } : { failed: {
364
426
  ...s,
365
427
  sequence: null
366
- };
367
- let u = t.id, d = await U(e.files?.artifacts, P, u, (e) => {
428
+ } };
429
+ }
430
+ async function xe(e, t, n) {
431
+ let r = await be(e, t, n);
432
+ if ("failed" in r) return r.failed;
433
+ let { imageData: i, imagePath: a, html: o, prompt: s } = r, c = t.id, l = await X(e.files?.artifacts, V, c, (e) => {
368
434
  let t = e ?? {
369
- id: u,
435
+ id: c,
370
436
  title: "",
371
437
  mode: n.mode,
372
438
  totalSlides: n.totalSlides,
@@ -375,39 +441,41 @@ async function ae(e, t, n) {
375
441
  return n.slide === 1 && (t.title = n.title), t.slides[String(n.slide)] = {
376
442
  title: n.title,
377
443
  imagePrompt: n.imagePrompt,
378
- ...l && { imagePath: l }
444
+ ...a && { imagePath: a },
445
+ ...o && { html: o }
379
446
  }, t;
380
- }), f = {
381
- imageData: c,
382
- ...l && { imagePath: l },
383
- prompt: o,
384
- slideshowId: u,
447
+ }), u = {
448
+ ...i && { imageData: i },
449
+ ...a && { imagePath: a },
450
+ ...o && { html: o },
451
+ prompt: s,
452
+ slideshowId: c,
385
453
  slide: n.slide,
386
454
  totalSlides: n.totalSlides,
387
455
  title: n.title,
388
456
  mode: n.mode
389
- }, p = n.mode === "steps" ? "step" : "slide";
457
+ }, d = n.mode === "steps" ? "step" : "slide";
390
458
  return {
391
- data: f,
459
+ data: u,
392
460
  title: n.title || `Slide ${n.slide}`,
393
461
  message: [
394
- `${p} ${n.slide} of ${n.totalSlides} of slideshow "${u}" is on the screen`,
395
- l ? `saved to ${l}` : "",
396
- d ? "" : W("slideshow")
462
+ `${d} ${n.slide} of ${n.totalSlides} of slideshow "${c}" is on the screen`,
463
+ a ? `saved to ${a}` : "",
464
+ l ? "" : Z("slideshow")
397
465
  ].filter(Boolean).join("; "),
398
- instructions: m(n),
466
+ instructions: S(n),
399
467
  instructionsRequired: !0,
400
- sequence: K(n)
468
+ sequence: me(n)
401
469
  };
402
470
  }
403
- async function Z(e, t) {
404
- let n = p(t);
405
- if (!n) return {
406
- message: f,
471
+ async function Q(e, t) {
472
+ let n = ie(t);
473
+ if (typeof n == "string") return {
474
+ message: n,
407
475
  sequence: null
408
476
  };
409
- let r = J(e), i = Y(r, n), a = n.mode === "steps";
410
- if (a && n.slide > i.current && i.current > 0 && !D(e, i.shownAt)) {
477
+ let r = ge(e), i = _e(r, n), a = n.mode === "steps";
478
+ if (a && n.slide > i.current && i.current > 0 && !I(e, i.shownAt)) {
411
479
  console.info(`[sequence] holding step ${n.slide} for the user`);
412
480
  let e = i.shownAt === Infinity ? "is still being drawn" : "is still on the screen";
413
481
  return {
@@ -416,15 +484,15 @@ async function Z(e, t) {
416
484
  };
417
485
  }
418
486
  let o = a ? i.slides.get(n.slide) : void 0;
419
- if (o) return te(e.currentResult, o) ? {
487
+ if (o) return ce(e.currentResult, o) ? {
420
488
  message: `step ${n.slide} of ${n.totalSlides} is already on the screen`,
421
489
  cancelled: !0
422
- } : X(r, i, n, o);
423
- let s = r.repeats.claim(q(i.id, n));
490
+ } : ve(r, i, n, o);
491
+ let s = r.repeats.claim(he(i.id, n));
424
492
  if ("earlier" in s) {
425
- if (!await s.earlier) return Z(e, t);
493
+ if (!await s.earlier) return Q(e, t);
426
494
  let a = i.slides.get(n.slide);
427
- return a && r.lastShown !== i ? X(r, i, n, a) : {
495
+ return a && r.lastShown !== i ? ve(r, i, n, a) : {
428
496
  message: `slide ${n.slide} of ${n.totalSlides} is already on the screen`,
429
497
  cancelled: !0
430
498
  };
@@ -436,22 +504,22 @@ async function Z(e, t) {
436
504
  i.current = n.slide, i.shownAt = Infinity;
437
505
  let u = !1;
438
506
  try {
439
- let t = await ae(e, i, n);
440
- return u = !!E(t).imageData, u && (i.slides.set(n.slide, t), i.current = n.slide, i.shownAt = Date.now(), r.lastShown = i), t;
507
+ let t = await xe(e, i, n);
508
+ return u = se(t), u && (i.slides.set(n.slide, t), i.current = n.slide, i.shownAt = Date.now(), r.lastShown = i), t;
441
509
  } finally {
442
510
  c(u), !u && i.current === n.slide && (i.current = l.current, i.shownAt = l.shownAt);
443
511
  }
444
512
  }
445
513
  //#endregion
446
514
  //#region src/core/storyboard.ts
447
- var oe = ({ id: e, title: t, totalPanels: n }) => ({
515
+ var Se = ({ id: e, title: t, totalPanels: n }) => ({
448
516
  step: 0,
449
517
  total: n,
450
518
  kind: "story",
451
519
  label: `The cast of "${t}"`,
452
520
  onShown: "introduce the characters",
453
521
  nextCall: `call presentPanel for panel 1 of ${n} with storyboardId "${e}"`
454
- }), se = ({ id: e, totalPanels: t }, n, r) => ({
522
+ }), Ce = ({ id: e, totalPanels: t }, n, r) => ({
455
523
  step: n,
456
524
  total: t,
457
525
  kind: "story",
@@ -459,21 +527,21 @@ var oe = ({ id: e, title: t, totalPanels: n }) => ({
459
527
  onShown: "tell that part of the story",
460
528
  nextCall: `call presentPanel for panel ${n + 1} of ${t} with storyboardId "${e}"`,
461
529
  ...r.length > 0 && { waitsForUser: !0 }
462
- }), Q = (e, t) => e ? `${e}. ${t}` : t, ce = (e, { name: t, description: n }) => Q(e, `Character reference sheet of ${t}: ${n}. Full body, front, side and back views, on a plain white background. No text or labels.`);
463
- async function le(e, t) {
464
- let n = _(t);
530
+ }), we = (e, t) => e ? `${e}. ${t}` : t, Te = (e, { name: t, description: n }) => we(e, `Character reference sheet of ${t}: ${n}. Full body, front, side and back views, on a plain white background. No text or labels.`);
531
+ async function Ee(e, t) {
532
+ let n = T(t);
465
533
  if (typeof n == "string") return {
466
534
  message: n,
467
535
  sequence: null
468
536
  };
469
- let r = await Promise.all(n.characters.map((t) => j(e, ce(n.style, t)))), i = r.map(E), a = r.find((e, t) => !i[t]?.imageData);
537
+ let r = await Promise.all(n.characters.map((t) => z(e, Te(n.style, t)))), i = r.map(P), a = r.find((e, t) => !i[t]?.imageData);
470
538
  if (i.every(({ imageData: e }) => !e) && a) return {
471
539
  ...a,
472
540
  message: `the character sheets couldn't be made: ${a.message}`,
473
541
  sequence: null
474
542
  };
475
543
  let o = {
476
- id: O(),
544
+ id: L(),
477
545
  ...n,
478
546
  characters: n.characters.map((e, t) => {
479
547
  let n = i[t]?.imagePath;
@@ -483,7 +551,7 @@ async function le(e, t) {
483
551
  };
484
552
  }),
485
553
  panels: {}
486
- }, s = await U(e.files?.artifacts, F, o.id, () => o), c = o.characters.filter((e) => e.imagePath).map((e) => `${e.name}: ${e.imagePath}`), l = n.characters.map(({ name: e }, t) => i[t]?.imageData ? null : `${e} (${r[t]?.message ?? ""})`).filter((e) => !!e), u = i.find((e) => e.imageData)?.imageData;
554
+ }, s = await X(e.files?.artifacts, H, o.id, () => o), c = o.characters.filter((e) => e.imagePath).map((e) => `${e.name}: ${e.imagePath}`), l = n.characters.map(({ name: e }, t) => i[t]?.imageData ? null : `${e} (${r[t]?.message ?? ""})`).filter((e) => !!e), u = i.find((e) => e.imageData)?.imageData;
487
555
  return {
488
556
  data: {
489
557
  storyboardId: o.id,
@@ -504,46 +572,46 @@ async function le(e, t) {
504
572
  `storyboard "${o.id}" is ready with ${o.totalPanels} panels; the cast is on the screen`,
505
573
  c.length ? `character sheets saved to ${c.join(", ")}` : "",
506
574
  l.length ? `no sheet for ${l.join("; ")}: they will be drawn from their description` : "",
507
- s ? "" : W("storyboard")
575
+ s ? "" : Z("storyboard")
508
576
  ].filter(Boolean).join("; "),
509
- instructions: v(o),
577
+ instructions: E(o),
510
578
  instructionsRequired: !0,
511
- sequence: oe(o)
579
+ sequence: Se(o)
512
580
  };
513
581
  }
514
- function ue(e, t, n) {
515
- let r = [Q(e.style, `Panel ${t.panel} of ${e.totalPanels} of the illustrated story "${e.title}". ${t.imagePrompt}`)], i = 0, a = n.map(({ character: e, hasSheet: t }) => t ? `${e.name} is the character in reference image ${++i}` : `${e.name}: ${e.description}`);
582
+ function De(e, t, n) {
583
+ let r = [we(e.style, `Panel ${t.panel} of ${e.totalPanels} of the illustrated story "${e.title}". ${t.imagePrompt}`)], i = 0, a = n.map(({ character: e, hasSheet: t }) => t ? `${e.name} is the character in reference image ${++i}` : `${e.name}: ${e.description}`);
516
584
  return a.length && r.push(`${a.join(". ")}.`), i && r.push("Draw each character exactly as in their reference image: the same face, hair, clothes and colors. Use the reference images only for how the characters look, not for their pose or the background."), r.push("No captions, speech bubbles or other text in the picture."), r.join(" ");
517
585
  }
518
- async function de(e, t, n) {
586
+ async function Oe(e, t, n) {
519
587
  let r = [], i = [];
520
588
  for (let a of n.characters) {
521
- let n = t.characters.find((e) => u(e.name, a));
589
+ let n = t.characters.find((e) => y(e.name, a));
522
590
  if (!n) r.push(a);
523
591
  else if (!i.some((e) => e.character === n)) {
524
- let [t] = n.imagePath ? await A(e, [n.imagePath]) : [];
592
+ let [t] = n.imagePath ? await R(e, [n.imagePath]) : [];
525
593
  i.push({
526
594
  character: n,
527
595
  sheet: t ?? null
528
596
  });
529
597
  }
530
598
  }
531
- let a = i.map(({ sheet: e }) => e).filter((e) => !!e), o = ue(t, n, i.map(({ character: e, sheet: t }) => ({
599
+ let a = i.map(({ sheet: e }) => e).filter((e) => !!e), o = De(t, n, i.map(({ character: e, sheet: t }) => ({
532
600
  character: e,
533
601
  hasSheet: !!t
534
- }))), s = await j(e, o, a), { imageData: c, imagePath: l } = E(s);
602
+ }))), s = await z(e, o, a), { imageData: c, imagePath: l } = P(s);
535
603
  if (!c) return {
536
604
  ...s,
537
605
  sequence: null
538
606
  };
539
- let d = n.panel < t.totalPanels && n.choices.length >= 2 ? n.choices : [], f = await U(e.files?.artifacts, F, t.id, (e) => {
607
+ let u = n.panel < t.totalPanels && n.choices.length >= 2 ? n.choices : [], d = await X(e.files?.artifacts, H, t.id, (e) => {
540
608
  let r = e ?? t;
541
- return d.length && (r.interactive = !0), r.panels[String(n.panel)] = {
609
+ return u.length && (r.interactive = !0), r.panels[String(n.panel)] = {
542
610
  caption: n.caption,
543
611
  characters: i.map(({ character: e }) => e.name),
544
612
  imagePrompt: n.imagePrompt,
545
613
  ...l && { imagePath: l },
546
- ...d.length && { choices: d }
614
+ ...u.length && { choices: u }
547
615
  }, r;
548
616
  });
549
617
  return {
@@ -555,32 +623,32 @@ async function de(e, t, n) {
555
623
  panel: n.panel,
556
624
  totalPanels: t.totalPanels,
557
625
  caption: n.caption,
558
- ...d.length && { choices: d }
626
+ ...u.length && { choices: u }
559
627
  },
560
628
  title: n.caption || `Panel ${n.panel}`,
561
629
  message: [
562
630
  `panel ${n.panel} of ${t.totalPanels} is on the screen`,
563
631
  l ? `saved to ${l}` : "",
564
632
  r.length ? `not in the cast, so drawn from the prompt alone: ${r.join(", ")}` : "",
565
- f ? "" : W("storyboard")
633
+ d ? "" : Z("storyboard")
566
634
  ].filter(Boolean).join("; "),
567
- instructions: x(t, n.panel, d),
635
+ instructions: k(t, n.panel, u),
568
636
  instructionsRequired: !0,
569
- sequence: se(t, n.panel, d)
637
+ sequence: Ce(t, n.panel, u)
570
638
  };
571
639
  }
572
- var fe = N(() => ({
573
- repeats: G(),
640
+ var ke = B(() => ({
641
+ repeats: pe(),
574
642
  awaitingChoice: /* @__PURE__ */ new Map()
575
643
  }));
576
644
  async function $(e, t) {
577
- let n = b(t);
645
+ let n = O(t);
578
646
  if (!n) return {
579
- message: y,
647
+ message: D,
580
648
  sequence: null
581
649
  };
582
- let { storyboardId: r, panel: i } = n, { repeats: a, awaitingChoice: o } = fe(e), s = o.get(r);
583
- if (s && i > s.panel && !D(e, s.shownAt)) return console.info(`[sequence] holding panel ${i} for the user`), {
650
+ let { storyboardId: r, panel: i } = n, { repeats: a, awaitingChoice: o } = ke(e), s = o.get(r);
651
+ if (s && i > s.panel && !I(e, s.shownAt)) return console.info(`[sequence] holding panel ${i} for the user`), {
584
652
  message: s.shownAt === Infinity ? `panel ${i} was not shown: panel ${s.panel} is still being drawn. Wait for it before going on.` : `panel ${i} was not shown: the user hasn't picked a choice yet, and panel ${s.panel} is still on the screen. Wait for their answer.`,
585
653
  cancelled: !0
586
654
  };
@@ -596,7 +664,7 @@ async function $(e, t) {
596
664
  o.set(r, u);
597
665
  let f = () => o.get(r) === u, p = !1;
598
666
  try {
599
- let t = await H(e.files?.artifacts, F, r);
667
+ let t = await Y(e.files?.artifacts, H, r);
600
668
  if (!t) return {
601
669
  message: `there is no storyboard "${r}"; call defineStoryboard first`,
602
670
  sequence: null
@@ -605,8 +673,8 @@ async function $(e, t) {
605
673
  message: `storyboard "${t.id}" has ${t.totalPanels} panels`,
606
674
  sequence: null
607
675
  };
608
- let a = await de(e, t, n);
609
- p = !!E(a).imageData;
676
+ let a = await Oe(e, t, n);
677
+ p = !!P(a).imageData;
610
678
  let s = a.data;
611
679
  return p && f() && (s?.choices?.length ? o.set(r, {
612
680
  panel: i,
@@ -618,21 +686,21 @@ async function $(e, t) {
618
686
  }
619
687
  //#endregion
620
688
  //#region src/core/index.ts
621
- var pe = {
622
- toolDefinition: g,
689
+ var Ae = {
690
+ toolDefinition: w,
623
691
  generatingMessage: "Making the slide...",
624
692
  isEnabled: () => !0,
625
- execute: (e, t) => Z(e, t)
626
- }, me = {
627
- toolDefinition: C,
693
+ execute: (e, t) => Q(e, t)
694
+ }, je = {
695
+ toolDefinition: j,
628
696
  generatingMessage: "Drawing the characters...",
629
697
  isEnabled: () => !0,
630
- execute: (e, t) => le(e, t)
631
- }, he = {
632
- toolDefinition: w,
698
+ execute: (e, t) => Ee(e, t)
699
+ }, Me = {
700
+ toolDefinition: M,
633
701
  generatingMessage: "Drawing the panel...",
634
702
  isEnabled: () => !0,
635
703
  execute: (e, t) => $(e, t)
636
704
  };
637
705
  //#endregion
638
- export { b as C, m as D, u as E, x as S, _ as T, h as _, F as a, S as b, C as c, a as d, y as f, g, t as h, P as i, i as l, w as m, he as n, H as o, r as p, pe as r, n as s, me as t, o as u, s as v, p as w, v as x, f as y };
706
+ export { o as A, k as C, y as D, T as E, t as M, f as N, S as O, E as S, ie as T, C as _, H as a, re as b, j as c, te as d, D as f, w as g, p as h, V as i, n as j, r as k, ee as l, M as m, Me as n, Y as o, h as p, Ae as r, m as s, je as t, ne as u, g as v, O as w, A as x, x as y };