@gui-chat-plugin/sequence 0.6.3 → 0.7.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 CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.7.1
4
+
5
+ - **A web page's address shows the page's preview picture.** In MulmoChat, the model had only
6
+ pages' addresses from its searches and browsing (neither returns image files'), and gave one as
7
+ `imageUrl`. A page's `og:image` (else `twitter:image`) is now fetched in its place, under the
8
+ same checks; one that is a page in turn isn't followed. Tried on Car and Driver's and Wired's
9
+ articles about the Tesla Roadster: each slide showed the article's photo.
10
+ - **An `imageUrl` that isn't used is said so.** The same model put the address on an HTML slide
11
+ without `{{image}}`; it was left out without a word. The result now says the picture isn't
12
+ shown and why, and the tool's description says the slide must have `{{image}}`.
13
+
14
+ ## 0.7.0
15
+
16
+ - **A slide's picture can come from the web (`imageUrl`).** The slides' policy lets an image come
17
+ only from a `data:` URL, so a picture the model found in a search couldn't be shown. `imageUrl`
18
+ is an image file's address: `execute()` fetches it, shows it as a `data:` URL (the policy is
19
+ unchanged) and saves it under `artifacts/images/` like a generated picture. It works on a picture
20
+ slide and at an HTML or Markdown slide's `{{image}}`. Only `https` addresses of named sites are
21
+ fetched, redirects are checked the same way, and only a PNG, JPEG, GIF or WebP picture of at
22
+ most 5 MB is shown. One that can't be fetched is drawn from `imagePrompt` (or the alt text)
23
+ instead, and the model is told; with nothing to draw, the slide isn't shown and the model is
24
+ told why. The result and the record keep the address in `imageUrl`.
25
+
3
26
  ## 0.6.3
4
27
 
5
28
  - **`& % #` inside `\text{}` are escaped before KaTeX reads the math.** In MulmoChat, a model wrote
package/README.md CHANGED
@@ -25,14 +25,14 @@ The core entry (`@gui-chat-plugin/sequence`) has the same tools without Views, f
25
25
 
26
26
  ### What `execute()` needs from its context
27
27
 
28
- | | Used for | Without it |
29
- | ------------------------------------ | ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
30
- | `app.generateImage(prompt)` | every picture | "image generation isn't available" |
31
- | `app.editImages(prompt, imagePaths)` | a panel drawn from its characters' sheets, a guide step drawn from the step before | drawn from the prompt alone |
32
- | `files.artifacts` (`FileOps`) | the records, and checking that a reference picture is still there | records are kept in memory only (the results say they weren't saved); no references |
33
- | `userSpokeAt` | holding a guide's next step, or a story's next panel after a choice, until the user has spoken | nothing is held |
34
- | `conversationId` | keeping each conversation's slideshows, holds and repeats apart | one conversation |
35
- | `currentResult` | telling "show step 2 again" (it isn't on the screen) from a repeated call (it is) | a step asked for again is shown again |
28
+ | | Used for | Without it |
29
+ | ------------------------------------ | ------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
30
+ | `app.generateImage(prompt)` | every picture | "image generation isn't available" |
31
+ | `app.editImages(prompt, imagePaths)` | a panel drawn from its characters' sheets, a guide step drawn from the step before | drawn from the prompt alone |
32
+ | `files.artifacts` (`FileOps`) | the records, saving a picture from the web, and checking that a reference picture is still there | records are kept in memory only (the results say they weren't saved); a picture from the web is shown but not saved; no references |
33
+ | `userSpokeAt` | holding a guide's next step, or a story's next panel after a choice, until the user has spoken | nothing is held |
34
+ | `conversationId` | keeping each conversation's slideshows, holds and repeats apart | one conversation |
35
+ | `currentResult` | telling "show step 2 again" (it isn't on the screen) from a repeated call (it is) | a step asked for again is shown again |
36
36
 
37
37
  `generateImage` and `editImages` are gui-chat-protocol's `context.app` conventions: they save each
38
38
  picture as `artifacts/images/…` and return its path in `data.imagePath`. `currentResult` is compared
@@ -67,8 +67,8 @@ it is drawn.
67
67
 
68
68
  ## Slides that aren't pictures
69
69
 
70
- A slide is a generated picture (`imagePrompt`), a chart (`chart`), Markdown (`markdown`) or HTML
71
- (`html`), the model's choice per slide: a picture for a scene or an object; a chart for numbers to
70
+ A slide is a generated picture (`imagePrompt`), a picture from the web (`imageUrl`, below), a chart
71
+ (`chart`), Markdown (`markdown`) or HTML (`html`), the model's choice per slide: a picture for a scene or an object; a chart for numbers to
72
72
  compare, a trend or proportions; Markdown for equations (TeX math), definitions, short lists and
73
73
  small tables; HTML for designed layouts, comparisons, timelines and diagrams. Picture models draw
74
74
  words, numbers and math badly. A slide sent with more than one is one kind: `html` first, then
@@ -89,6 +89,35 @@ Without `{{image}}`, an `imagePrompt` sent with `html` or `markdown` is left out
89
89
  without `imagePrompt` is drawn from the picture's alt text, or the slide's title when it has none. When the picture can't be drawn, the slide is shown without it
90
90
  and the model is told.
91
91
 
92
+ ### A picture from the web
93
+
94
+ `imageUrl` is the address of an image file the model found (in a search, or from the user), or of
95
+ a web page about the thing (an article from a search), whose preview picture (`og:image`, else
96
+ `twitter:image`) is shown: models have pages' addresses far more often than image files'. It is
97
+ shown instead of a generated picture: on a picture slide, or at an HTML or Markdown slide's `{{image}}`
98
+ in place of the one `imagePrompt` would draw. `execute()` fetches it and returns it as a `data:`
99
+ URL (`imageData`), so the slides' policy (`img-src data: blob:`) is unchanged and a slide still
100
+ can't send anything out in an image URL. It is saved as the hosts save their own pictures,
101
+ `artifacts/images/<YYYY>/<MM>/<id>.<ext>` (`imagePath`), so a movie of the slideshow, or the next
102
+ step of a guide drawn from it, can use it; the result and the record keep the address in
103
+ `imageUrl`.
104
+
105
+ Since MulmoChat fetches it on its server, from an address the model chose: only `https`, no IP
106
+ addresses and no local names (`localhost`, `*.local`, a name without a dot…), every redirect (at
107
+ most 3) and a page's preview picture checked the same way (a preview that is a page in turn isn't
108
+ followed), 10 seconds and 5 MB at most, and only bytes that are a PNG, JPEG, GIF
109
+ or WebP picture, whatever the server says its type is. A public name that resolves to a private
110
+ address isn't caught: that needs a DNS lookup, which a page can't make; what comes back is shown
111
+ only if it is a picture. MulmoChat's server runs on the user's machine, so it reaches what their
112
+ browser reaches; a host whose server runs elsewhere should fetch on a network that has nothing to
113
+ reach. MulmoGlass fetches it in the page, where a site that doesn't allow CORS
114
+ can't be read.
115
+
116
+ An `imageUrl` on a slide with no place for a picture (an HTML slide without `{{image}}`, a chart)
117
+ isn't fetched, and the model is told. A picture that can't be fetched is drawn instead, from `imagePrompt` (an HTML or Markdown slide's
118
+ from its alt text or title, as without `imageUrl`), and the model is told; a picture slide with no
119
+ `imagePrompt` isn't shown, and the model is told why, so it can give another address.
120
+
92
121
  ### Markdown slides
93
122
 
94
123
  `markdown` is GitHub-flavored Markdown with TeX math between `$…$` (inline) or `$$…$$` (a
@@ -150,7 +179,7 @@ that an HTML step is on the screen; a guide step asked for again is then shown a
150
179
 
151
180
  Saved through `files.artifacts`, with their pictures' paths:
152
181
 
153
- - `slideshows/<id>.json`: `{ id, title, mode, totalSlides, slides: { "1": { title, imagePrompt, imagePath } } }`; a slide that isn't a picture has `html` (an HTML slide), `html` and `markdown` (a Markdown slide) or `chart` (a chart slide), and an `imagePrompt` of `""` and no `imagePath` unless its `html` places a picture at `{{image}}`
182
+ - `slideshows/<id>.json`: `{ id, title, mode, totalSlides, slides: { "1": { title, imagePrompt, imagePath, imageUrl } } }` (`imageUrl` for a picture from the web); a slide that isn't a picture has `html` (an HTML slide), `html` and `markdown` (a Markdown slide) or `chart` (a chart slide), and an `imagePrompt` of `""` and no `imagePath` unless its `html` places a picture at `{{image}}`
154
183
  - `storyboards/<id>.json`: `{ id, title, style, totalPanels, interactive, characters: [{ name, description, imagePath }], panels: { "1": { caption, characters, imagePrompt, imagePath, choices } } }`
155
184
 
156
185
  IDs are 12 hex digits. The results name them, so a later tool call can refer to a slideshow or a
@@ -17,6 +17,12 @@ export interface SlideArgs {
17
17
  /** The picture's prompt: a picture slide's, or the picture an HTML or
18
18
  * Markdown slide places at {{image}}; "" for a slide without one. */
19
19
  imagePrompt: string;
20
+ /** A picture from the web, shown instead of a drawn one: a picture
21
+ * slide's, or the one an HTML or Markdown slide places at {{image}}. */
22
+ imageUrl?: string;
23
+ /** An imageUrl sent for a slide with no place for a picture (an HTML slide
24
+ * without {{image}}, a chart): not shown, and the model is told. */
25
+ unplacedImageUrl?: string;
20
26
  /** An HTML slide's body. */
21
27
  html?: string;
22
28
  /** A Markdown slide's text, with TeX math. */
@@ -25,7 +31,7 @@ export interface SlideArgs {
25
31
  chart?: SlideChart;
26
32
  mode: SlideMode;
27
33
  }
28
- export declare const SLIDE_ARGS_ERROR = "presentSlide needs slide and totalSlides (whole numbers, slide from 1 to totalSlides), and one of imagePrompt, html, markdown or chart";
34
+ export declare const SLIDE_ARGS_ERROR = "presentSlide needs slide and totalSlides (whole numbers, slide from 1 to totalSlides), and one of imagePrompt, imageUrl, html, markdown or chart";
29
35
  export declare const SLIDE_HTML_TOO_LONG = "presentSlide's slide is too long: keep its html, markdown or chart under 60000 characters";
30
36
  export declare const SLIDE_CHART_INVALID: string;
31
37
  /** The slide arguments, or what is wrong with them (said to the model). A
@@ -48,6 +54,8 @@ export interface Slideshow {
48
54
  /** A picture slide's picture, or the one an HTML or Markdown slide
49
55
  * places at {{image}} (withSlideImage). */
50
56
  imagePath?: string;
57
+ /** Where that picture came from, when it is from the web. */
58
+ imageUrl?: string;
51
59
  /** An HTML slide's body (slideHtmlDocument makes it a page); for a
52
60
  * Markdown slide, the HTML made of it. Keeps {{image}}. */
53
61
  html?: string;
@@ -62,6 +70,8 @@ export interface Slideshow {
62
70
  export interface SlideData {
63
71
  imageData?: string;
64
72
  imagePath?: string;
73
+ /** Where the picture came from, when it is from the web. */
74
+ imageUrl?: string;
65
75
  html?: string;
66
76
  markdown?: string;
67
77
  chart?: SlideChart;
@@ -0,0 +1,26 @@
1
+ import type { FileOps } from "gui-chat-protocol";
2
+ export declare const WEB_IMAGE_TIMEOUT_MS = 10000;
3
+ export declare const MAX_WEB_IMAGE_BYTES: number;
4
+ /** Why a URL isn't one to fetch, or null when it is. */
5
+ export declare function webImageUrlProblem(url: URL): string | null;
6
+ /** The picture's type and file extension from its first bytes: the server's
7
+ * Content-Type isn't trusted. */
8
+ export declare function webImageType(bytes: Uint8Array): {
9
+ mime: string;
10
+ extension: string;
11
+ } | null;
12
+ /** The address of a page's preview picture (og:image, twitter:image), from
13
+ * its <meta> tags, or null. Read as text: no DOM where execute() runs on a
14
+ * server. */
15
+ export declare function pagePreviewImage(html: string, pageUrl: string): string | null;
16
+ /** A picture from the web, saved under artifacts/images/ when the host has
17
+ * files, or why it couldn't be fetched. A page's address gives its preview
18
+ * picture, whose address is `source`; a page's preview that is a page
19
+ * isn't followed. */
20
+ export declare function fetchWebImage(address: string, artifacts: FileOps | undefined, fromPage?: boolean): Promise<{
21
+ imageData: string;
22
+ imagePath?: string;
23
+ source?: string;
24
+ } | {
25
+ error: string;
26
+ }>;