@gui-chat-plugin/sequence 0.2.0 → 0.3.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.
- package/CHANGELOG.md +20 -0
- package/README.md +29 -6
- package/dist/core/definitions.d.ts +15 -5
- package/dist/core/host.d.ts +7 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/slideHtml.d.ts +23 -0
- package/dist/{core-qe3zK8TI.js → core-BJ7q9fgr.js} +219 -151
- package/dist/core-CPlicVIg.cjs +46 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +2 -2
- package/dist/style.css +1 -1
- package/dist/vue.cjs +1 -1
- package/dist/vue.js +91 -33
- package/package.json +1 -1
- package/dist/core-AQFO5Vcb.cjs +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.1
|
|
4
|
+
|
|
5
|
+
- **"HTML slides" go to presentSlide**: the prompt says that when the user asks for HTML slides,
|
|
6
|
+
presentSlide is the tool, one HTML slide per call, not one HTML page. OpenAI Realtime, asked to
|
|
7
|
+
"explain this article in HTML slides", wrote a single presentHtml page with its own slide
|
|
8
|
+
navigation (found in MulmoChat). With this and the hosts' presentHtml prompt, 6 of 6 runs in
|
|
9
|
+
MulmoChat and 3 of 3 in MulmoGlass made presentSlide HTML slides.
|
|
10
|
+
|
|
11
|
+
## 0.3.0
|
|
12
|
+
|
|
13
|
+
- **HTML slides**: `presentSlide` takes `html` instead of `imagePrompt` for a slide designed in HTML
|
|
14
|
+
(words, numbers, lists, comparisons, diagrams), styled with Tailwind CSS v4 and animated, so it
|
|
15
|
+
builds up while the model explains it. The model picks per slide; a slideshow can mix them. The
|
|
16
|
+
View shows it at 1280x720, scaled to fit, in a sandboxed iframe (`sandbox="allow-scripts"`, no
|
|
17
|
+
network: `connect-src 'none'`, images from `data:`/`blob:` only; the slide's own scripts, event
|
|
18
|
+
handlers, `<meta>` refreshes and links don't run, since they could navigate the frame to a URL
|
|
19
|
+
carrying the slide). Nothing is drawn, so it needs
|
|
20
|
+
no image backend. `slideHtmlDocument(html)` makes the page, for a host that shows one elsewhere.
|
|
21
|
+
Records and results carry `html`; `imagePrompt` is `""` and `imagePath` absent for these slides.
|
|
22
|
+
|
|
3
23
|
## 0.2.0
|
|
4
24
|
|
|
5
25
|
- **State per conversation**: the slideshow in progress, the steps and panels waiting for the
|
package/README.md
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
Tools that show things one step at a time, as pictures, for
|
|
4
4
|
[GUI Chat Protocol](https://github.com/receptron/gui-chat-protocol) hosts:
|
|
5
5
|
|
|
6
|
-
| Tool | Shows
|
|
7
|
-
| ------------------ |
|
|
8
|
-
| `presentSlide` | One slide of a spoken slideshow (mode `"presentation"`), or one step of a step-by-step guide the user follows along with (mode `"steps"`) |
|
|
9
|
-
| `defineStoryboard` | A story's cast: a reference sheet for each recurring character
|
|
10
|
-
| `presentPanel` | One panel of the story, with its characters drawn as in their sheets; an interactive story offers choices
|
|
6
|
+
| Tool | Shows |
|
|
7
|
+
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
8
|
+
| `presentSlide` | One slide of a spoken slideshow (mode `"presentation"`), or one step of a step-by-step guide the user follows along with (mode `"steps"`): a generated picture, or a slide in HTML |
|
|
9
|
+
| `defineStoryboard` | A story's cast: a reference sheet for each recurring character |
|
|
10
|
+
| `presentPanel` | One panel of the story, with its characters drawn as in their sheets; an interactive story offers choices |
|
|
11
11
|
|
|
12
12
|
From MulmoChat and MulmoGlass, tested there by voice on OpenAI Realtime, Gemini Live and Grok, and
|
|
13
13
|
in text chat.
|
|
@@ -60,11 +60,34 @@ overlap (a host that runs `execute()` on a server gets them as concurrent reques
|
|
|
60
60
|
claimed before anything is awaited, so an identical one waits for it and a later step is held while
|
|
61
61
|
it is drawn.
|
|
62
62
|
|
|
63
|
+
## HTML slides
|
|
64
|
+
|
|
65
|
+
A slide is a generated picture (`imagePrompt`) or HTML (`html`), the model's choice per slide: a
|
|
66
|
+
picture for a scene or an object, HTML for words, numbers, lists, comparisons and diagrams, which
|
|
67
|
+
picture models draw badly. The model writes the inside of `<body>` for a 1280x720 canvas, with
|
|
68
|
+
Tailwind CSS v4 classes and these entrance animations: `animate-fade-in`, `animate-fade-up`,
|
|
69
|
+
`animate-fade-down`, `animate-slide-in-left`, `animate-slide-in-right`, `animate-zoom-in`,
|
|
70
|
+
`animate-pop` and `animate-draw` (an SVG path drawing itself), staggered with
|
|
71
|
+
`[animation-delay:…]`. The slide's own scripts don't run: its animations are CSS.
|
|
72
|
+
|
|
73
|
+
`slideHtmlDocument(html)` (core entry) makes the page: Tailwind's browser build from jsDelivr (one
|
|
74
|
+
version, checked by its hash), the animations, and a Content Security Policy that lets it send
|
|
75
|
+
nothing out: `connect-src 'none'`; images, media and fonts only from `data:`/`blob:` URLs and
|
|
76
|
+
Google Fonts; and no script but the page's own and Tailwind's, so nothing can navigate the frame to
|
|
77
|
+
a URL carrying the page (a sandbox allows that, and CSP can't forbid it). The slide's `<meta>`,
|
|
78
|
+
`<base>` and `<link>` tags are made plain text (a refresh would navigate), and a link doesn't
|
|
79
|
+
navigate when clicked. The View shows it in an iframe with `sandbox="allow-scripts"` and no
|
|
80
|
+
`allow-same-origin`, so the page can't reach the host's pages, storage or cookies, scaled to fit. Tailwind is loaded from the network: offline, the slide
|
|
81
|
+
appears unstyled.
|
|
82
|
+
|
|
83
|
+
A host that sends `currentResult` by its saved picture's path only (as MulmoChat does) can't tell
|
|
84
|
+
that an HTML step is on the screen; a guide step asked for again is then shown again.
|
|
85
|
+
|
|
63
86
|
## Records
|
|
64
87
|
|
|
65
88
|
Saved through `files.artifacts`, with their pictures' paths:
|
|
66
89
|
|
|
67
|
-
- `slideshows/<id>.json`: `{ id, title, mode, totalSlides, slides: { "1": { title, imagePrompt, imagePath } } }`
|
|
90
|
+
- `slideshows/<id>.json`: `{ id, title, mode, totalSlides, slides: { "1": { title, imagePrompt, imagePath } } }`; an HTML slide has `html`, an `imagePrompt` of `""` and no `imagePath`
|
|
68
91
|
- `storyboards/<id>.json`: `{ id, title, style, totalPanels, interactive, characters: [{ name, description, imagePath }], panels: { "1": { caption, characters, imagePrompt, imagePath, choices } } }`
|
|
69
92
|
|
|
70
93
|
IDs are 12 hex digits. The results name them, so a later tool call can refer to a slideshow or a
|
|
@@ -13,12 +13,17 @@ export interface SlideArgs {
|
|
|
13
13
|
slide: number;
|
|
14
14
|
totalSlides: number;
|
|
15
15
|
title: string;
|
|
16
|
+
/** The picture's prompt; "" for an HTML slide. */
|
|
16
17
|
imagePrompt: string;
|
|
18
|
+
/** An HTML slide's body; absent for a picture. */
|
|
19
|
+
html?: string;
|
|
17
20
|
mode: SlideMode;
|
|
18
21
|
}
|
|
19
|
-
export declare const SLIDE_ARGS_ERROR = "presentSlide needs slide and totalSlides (whole numbers, slide from 1 to totalSlides) and an imagePrompt";
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
export declare const SLIDE_ARGS_ERROR = "presentSlide needs slide and totalSlides (whole numbers, slide from 1 to totalSlides), and either an imagePrompt or html";
|
|
23
|
+
export declare const SLIDE_HTML_TOO_LONG = "presentSlide's html is too long: keep a slide under 60000 characters";
|
|
24
|
+
/** The slide arguments, or what is wrong with them (said to the model). A
|
|
25
|
+
* slide with html is an HTML slide, whatever imagePrompt says. */
|
|
26
|
+
export declare function parseSlideArgs(args: Record<string, unknown>): SlideArgs | string;
|
|
22
27
|
/** What the model does once a slide is on the screen. */
|
|
23
28
|
export declare const slideShownInstructions: ({ slide, totalSlides, title, mode, }: SlideArgs) => string;
|
|
24
29
|
/** A slideshow as saved in artifacts/slideshows/<id>.json. */
|
|
@@ -30,14 +35,19 @@ export interface Slideshow {
|
|
|
30
35
|
totalSlides: number;
|
|
31
36
|
slides: Record<string, {
|
|
32
37
|
title: string;
|
|
38
|
+
/** "" for an HTML slide. */
|
|
33
39
|
imagePrompt: string;
|
|
34
40
|
imagePath?: string;
|
|
41
|
+
/** An HTML slide's body (slideHtmlDocument makes it a page). */
|
|
42
|
+
html?: string;
|
|
35
43
|
}>;
|
|
36
44
|
}
|
|
37
|
-
/** A shown slide's result data. */
|
|
45
|
+
/** A shown slide's result data: a picture, or an HTML slide's body. */
|
|
38
46
|
export interface SlideData {
|
|
39
|
-
imageData
|
|
47
|
+
imageData?: string;
|
|
40
48
|
imagePath?: string;
|
|
49
|
+
html?: string;
|
|
50
|
+
/** The picture's prompt; "" for an HTML slide. */
|
|
41
51
|
prompt: string;
|
|
42
52
|
slideshowId: string;
|
|
43
53
|
slide: number;
|
package/dist/core/host.d.ts
CHANGED
|
@@ -11,9 +11,15 @@ export declare function imageOf(result: ToolResult | null | undefined): {
|
|
|
11
11
|
imageData?: string;
|
|
12
12
|
imagePath?: string;
|
|
13
13
|
};
|
|
14
|
+
/** An HTML slide's body, when the result is one. */
|
|
15
|
+
export declare function htmlOf(result: ToolResult | null | undefined): string;
|
|
16
|
+
/** Whether a result shows something: a picture or an HTML slide. */
|
|
17
|
+
export declare const shownContent: (result: ToolResult) => boolean;
|
|
14
18
|
/** Whether two results show the same picture: by its saved path when both
|
|
15
19
|
* have one (a host may send the current result without its image data),
|
|
16
|
-
* else by the picture itself.
|
|
20
|
+
* else by the picture itself, or the same HTML slide. A host that sends the
|
|
21
|
+
* current result by its path only can't tell an HTML slide is on the
|
|
22
|
+
* screen: one asked for again is shown again. */
|
|
17
23
|
export declare function samePicture(a: ToolResult | null | undefined, b: ToolResult | null | undefined): boolean;
|
|
18
24
|
/** When the user spoke after `time` (ms since the epoch). A host that doesn't
|
|
19
25
|
* say when the user spoke holds nothing. */
|
package/dist/core/index.d.ts
CHANGED
|
@@ -4,5 +4,6 @@ export declare const presentSlidePluginCore: SequencePluginCore;
|
|
|
4
4
|
export declare const defineStoryboardPluginCore: SequencePluginCore;
|
|
5
5
|
export declare const presentPanelPluginCore: SequencePluginCore;
|
|
6
6
|
export * from "./definitions";
|
|
7
|
+
export { MAX_SLIDE_HTML, SLIDE_ANIMATIONS, SLIDE_HEIGHT, SLIDE_WIDTH, slideHtmlDocument, } from "./slideHtml";
|
|
7
8
|
export { SLIDESHOWS_DIR, STORYBOARDS_DIR, loadRecord } from "./records";
|
|
8
9
|
export type { SequenceContext } from "./host";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare const SLIDE_WIDTH = 1280;
|
|
2
|
+
export declare const SLIDE_HEIGHT = 720;
|
|
3
|
+
/** The most HTML a slide may have, in characters. */
|
|
4
|
+
export declare const MAX_SLIDE_HTML = 60000;
|
|
5
|
+
/** The animations every slide has, as `animate-<name>` classes. They keep
|
|
6
|
+
* their first frame while delayed (fill mode both), so an element with a
|
|
7
|
+
* delay stays hidden until its turn. */
|
|
8
|
+
export declare const SLIDE_ANIMATIONS: readonly ["fade-in", "fade-up", "fade-down", "slide-in-left", "slide-in-right", "zoom-in", "pop", "draw"];
|
|
9
|
+
/** PAGE_SCRIPT's hash, which the policy allows (checked by a test). */
|
|
10
|
+
export declare const PAGE_SCRIPT_HASH = "sha256-MZyL5rvWmIVxl3WUuDU5BqzPJGR2/fV/YPh01MNyUoM=";
|
|
11
|
+
/** The slide's HTML, made safe to show:
|
|
12
|
+
* - the tags that act on the page from outside the body are plain text:
|
|
13
|
+
* <meta> (a refresh navigates the frame, a policy of its own), <base> and
|
|
14
|
+
* <link> (prefetches). No tag can be rebuilt by the replacement, which only
|
|
15
|
+
* adds "<".
|
|
16
|
+
* - no declarative shadow root (<template shadowrootmode>, the only way to
|
|
17
|
+
* make one without a script): a click inside one reaches the page's link
|
|
18
|
+
* guard retargeted to its host, so a link there would navigate. Every
|
|
19
|
+
* "shadowroot" is renamed, which leaves no attribute that makes one.
|
|
20
|
+
* Everything stays in the light DOM, where the guard sees it. */
|
|
21
|
+
export declare const neutralizeSlideHtml: (html: string) => string;
|
|
22
|
+
/** The page an HTML slide is shown as. */
|
|
23
|
+
export declare function slideHtmlDocument(html: string): string;
|