@hanzo/ui 8.27.3 → 8.27.4
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/dist/backdrop/Backdrop.cjs +420 -0
- package/dist/backdrop/Backdrop.d.ts +53 -0
- package/dist/backdrop/Backdrop.d.ts.map +1 -0
- package/dist/backdrop/Backdrop.js +418 -0
- package/dist/backdrop/Backdrop.js.map +1 -0
- package/dist/backdrop/index.cjs +50 -0
- package/dist/backdrop/index.d.ts +29 -0
- package/dist/backdrop/index.d.ts.map +1 -0
- package/dist/backdrop/index.js +29 -0
- package/dist/backdrop/index.js.map +1 -0
- package/dist/backdrop/scene.cjs +439 -0
- package/dist/backdrop/scene.d.ts +235 -0
- package/dist/backdrop/scene.d.ts.map +1 -0
- package/dist/backdrop/scene.js +423 -0
- package/dist/backdrop/scene.js.map +1 -0
- package/dist/chat/Chat.cjs +23 -1
- package/dist/chat/Chat.d.ts +6 -3
- package/dist/chat/Chat.d.ts.map +1 -1
- package/dist/chat/Chat.js +23 -1
- package/dist/chat/Chat.js.map +1 -1
- package/dist/chat/Inspector.cjs +51 -0
- package/dist/chat/Inspector.d.ts +49 -0
- package/dist/chat/Inspector.d.ts.map +1 -0
- package/dist/chat/Inspector.js +49 -0
- package/dist/chat/Inspector.js.map +1 -0
- package/dist/chat/Message.cjs +3 -1
- package/dist/chat/Message.d.ts +3 -1
- package/dist/chat/Message.d.ts.map +1 -1
- package/dist/chat/Message.js +3 -1
- package/dist/chat/Message.js.map +1 -1
- package/dist/chat/Parts.cjs +159 -0
- package/dist/chat/Parts.d.ts +186 -0
- package/dist/chat/Parts.d.ts.map +1 -0
- package/dist/chat/Parts.js +153 -0
- package/dist/chat/Parts.js.map +1 -0
- package/dist/chat/Persona.cjs +34 -0
- package/dist/chat/Persona.d.ts +37 -0
- package/dist/chat/Persona.d.ts.map +1 -0
- package/dist/chat/Persona.js +30 -0
- package/dist/chat/Persona.js.map +1 -0
- package/dist/chat/Preview.cjs +42 -0
- package/dist/chat/Preview.d.ts +36 -0
- package/dist/chat/Preview.d.ts.map +1 -0
- package/dist/chat/Preview.js +40 -0
- package/dist/chat/Preview.js.map +1 -0
- package/dist/chat/directive.cjs +272 -0
- package/dist/chat/directive.d.ts +167 -0
- package/dist/chat/directive.d.ts.map +1 -0
- package/dist/chat/directive.js +266 -0
- package/dist/chat/directive.js.map +1 -0
- package/dist/chat/index.cjs +59 -4
- package/dist/chat/index.d.ts +31 -3
- package/dist/chat/index.d.ts.map +1 -1
- package/dist/chat/index.js +31 -3
- package/dist/chat/index.js.map +1 -1
- package/dist/gallery.html +4 -4
- package/dist/styles.css +3 -3
- package/dist/theme.css +3 -3
- package/package.json +7 -1
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Parts — a streamed turn, drawn by what each piece of it IS.
|
|
5
|
+
*
|
|
6
|
+
* A completion's content is a list of parts, and until now this package had one
|
|
7
|
+
* answer for all of them: `words` flattens the list to prose and DROPS every
|
|
8
|
+
* part that is not text. An image, a tool call, a citation, an artifact — all of
|
|
9
|
+
* it arrived on the wire and none of it reached the screen. Six surfaces wrote
|
|
10
|
+
* six switch statements over the same union to get it back.
|
|
11
|
+
*
|
|
12
|
+
* `MessagePart` is that union, closed, and `Parts` is the dispatcher over it.
|
|
13
|
+
* Closed is the decision: `words`'s `Part` stays OPEN because it reads the wire
|
|
14
|
+
* and must survive a type it has never heard of, while this one is the CANON —
|
|
15
|
+
* the set a surface can exhaustively handle, and the set this package promises
|
|
16
|
+
* to draw. A part whose `type` is outside it still contributes its text, exactly
|
|
17
|
+
* as `words` does, so an unknown part degrades to prose instead of vanishing.
|
|
18
|
+
*
|
|
19
|
+
* Nothing here is new furniture. Every branch dispatches to a piece this package
|
|
20
|
+
* already had: `Code` for a tool's arguments and its output, `Step` for the call
|
|
21
|
+
* itself, `Failure` for an error, `Sources` for citations, `ArtifactCard` for a
|
|
22
|
+
* produced thing. That is the whole reason a typed renderer belongs here rather
|
|
23
|
+
* than in each surface — the parts were already drawn, one per surface, with no
|
|
24
|
+
* agreement about which part got which drawing.
|
|
25
|
+
*
|
|
26
|
+
* MARKDOWN IS STILL NOT HERE. `prose` is where a surface's pipeline enters, and
|
|
27
|
+
* with none supplied the words render plainly. The plugin set is per-surface —
|
|
28
|
+
* nine plugins, one plugin, or a regex under a bundle ceiling that cannot afford
|
|
29
|
+
* a parser — so this package ships no parser and takes the rendered nodes.
|
|
30
|
+
*/
|
|
31
|
+
import { Image, SizableText, XStack, YStack } from '@hanzo/gui';
|
|
32
|
+
import { Paperclip } from '@hanzogui/lucide-icons-2';
|
|
33
|
+
import { ArtifactCard } from '../agents/Pane.js';
|
|
34
|
+
import { ink } from '../backends/gui/ink.js';
|
|
35
|
+
import { slot } from '../backends/gui/slot.js';
|
|
36
|
+
import { Code } from './Code.js';
|
|
37
|
+
import { Failure } from './Failure.js';
|
|
38
|
+
import { Preview } from './Preview.js';
|
|
39
|
+
import { Sources } from './Sources.js';
|
|
40
|
+
import { Step } from './Step.js';
|
|
41
|
+
/**
|
|
42
|
+
* Adjacent prose, put back together.
|
|
43
|
+
*
|
|
44
|
+
* The wire splits a sentence across parts — and mid-word, which is why `words`
|
|
45
|
+
* joins with no separator — so drawing each text part as its own block would
|
|
46
|
+
* break one paragraph into a dozen and hand a markdown parser fragments that are
|
|
47
|
+
* not markdown. Runs of `text` and runs of `reasoning` each collapse to one;
|
|
48
|
+
* everything else passes through untouched and in order.
|
|
49
|
+
*
|
|
50
|
+
* This is what makes `Parts` a strict improvement on `words` rather than a
|
|
51
|
+
* different-looking one: an all-text turn renders exactly the string `words`
|
|
52
|
+
* would have produced.
|
|
53
|
+
*/
|
|
54
|
+
export function join(parts) {
|
|
55
|
+
const out = [];
|
|
56
|
+
for (const part of parts) {
|
|
57
|
+
const last = out[out.length - 1];
|
|
58
|
+
if ((part.type === 'text' || part.type === 'reasoning') &&
|
|
59
|
+
last &&
|
|
60
|
+
last.type === part.type) {
|
|
61
|
+
out[out.length - 1] = { type: part.type, text: last.text + part.text };
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
out.push(part);
|
|
65
|
+
}
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* What a tool was asked, or answered, as text.
|
|
70
|
+
*
|
|
71
|
+
* The wire sends JSON, so a caller holding the parsed object should not have to
|
|
72
|
+
* re-serialise it at every call site — that is six copies of two lines. The
|
|
73
|
+
* fallback exists because this takes `unknown` and a value that cannot be
|
|
74
|
+
* serialised must not take the page down with it.
|
|
75
|
+
*/
|
|
76
|
+
export const show = (value) => {
|
|
77
|
+
if (value == null)
|
|
78
|
+
return '';
|
|
79
|
+
if (typeof value === 'string')
|
|
80
|
+
return value;
|
|
81
|
+
try {
|
|
82
|
+
return JSON.stringify(value, null, 2);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return String(value);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
/** A size a person can read. Every surface writes this one; here it is once. */
|
|
89
|
+
const weigh = (bytes) => {
|
|
90
|
+
const units = ['B', 'KB', 'MB', 'GB'];
|
|
91
|
+
let n = bytes;
|
|
92
|
+
let i = 0;
|
|
93
|
+
while (n >= 1024 && i < units.length - 1) {
|
|
94
|
+
n /= 1024;
|
|
95
|
+
i += 1;
|
|
96
|
+
}
|
|
97
|
+
return `${i === 0 ? n : n.toFixed(1)} ${units[i]}`;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* One part.
|
|
101
|
+
*
|
|
102
|
+
* It spreads no residual props and owns no box, which is the one place this
|
|
103
|
+
* package's house rule does not apply: a piece IS whichever component its type
|
|
104
|
+
* names, and giving it a wrapper of its own would put an anonymous div between
|
|
105
|
+
* every part and the column that spaces them. `Parts` is the box.
|
|
106
|
+
*
|
|
107
|
+
* Named `Piece` and not `Part` because `Part` is already the name of `words`'s
|
|
108
|
+
* open wire type on this barrel, and a module cannot export one name as both a
|
|
109
|
+
* type and a value.
|
|
110
|
+
*/
|
|
111
|
+
export function Piece({ part, prose, onRetry, onOpen, onSource }) {
|
|
112
|
+
switch (part.type) {
|
|
113
|
+
case 'text':
|
|
114
|
+
return _jsx(_Fragment, { children: prose ? prose(part.text, part) : ink(part.text) });
|
|
115
|
+
case 'reasoning':
|
|
116
|
+
// Dimmed rather than recoloured: a surface's markdown paints its own
|
|
117
|
+
// colours, and a token on the container would not reach inside them.
|
|
118
|
+
return (_jsx(YStack, { ...slot('reasoning'), opacity: 0.72, children: prose ? prose(part.text, part) : ink(part.text) }));
|
|
119
|
+
case 'toolCall':
|
|
120
|
+
return (_jsx(Step, { name: part.name, status: "running", detail: part.id, children: part.args == null ? undefined : _jsx(Code, { language: "json", children: show(part.args) }) }));
|
|
121
|
+
case 'toolResult':
|
|
122
|
+
return (_jsx(Step, { name: part.name, status: part.status ?? 'done', detail: part.id, children: part.result == null ? undefined : _jsx(Code, { language: "json", children: show(part.result) }) }));
|
|
123
|
+
case 'image':
|
|
124
|
+
return (_jsx(YStack, { ...slot('image'), maxW: 420, rounded: "$4", overflow: "hidden", borderWidth: 1, borderColor: "$borderColor", children: _jsx(Image, { src: part.url, alt: part.alt ?? '', style: { width: '100%', height: 'auto', display: 'block' } }) }));
|
|
125
|
+
case 'file':
|
|
126
|
+
return (_jsxs(XStack, { ...slot('file'), items: "center", gap: "$2", maxW: 420, px: "$2.5", py: "$2", rounded: "$4", borderWidth: 1, borderColor: "$borderColor", bg: "$panel", children: [_jsx(Paperclip, { size: 13, color: "$quiet" }), _jsx(SizableText, { size: "$2", color: "$ink", numberOfLines: 1, flex: 1, children: part.name }), part.size == null ? null : (_jsx(SizableText, { size: "$1", color: "$quiet", children: weigh(part.size) }))] }));
|
|
127
|
+
case 'citation':
|
|
128
|
+
return _jsx(Sources, { sources: part.sources, onOpen: onSource });
|
|
129
|
+
case 'artifact':
|
|
130
|
+
// Held, so shown. `Preview` renders it with scripting disabled, which is
|
|
131
|
+
// what makes drawing model-authored markup a different question from
|
|
132
|
+
// loading a `uiResource`'s url — see that arm, and `Preview`'s own note.
|
|
133
|
+
return part.markup ? (_jsx(Preview, { title: part.title, markup: part.markup })) : (_jsx(ArtifactCard, { title: part.title, kind: part.kind, onOpen: onOpen ? () => onOpen(part) : undefined }));
|
|
134
|
+
case 'uiResource':
|
|
135
|
+
return (_jsx(Step, { name: part.uri, detail: part.mime, children: part.text ? _jsx(Code, { language: part.mime ?? 'text', children: part.text }) : undefined }));
|
|
136
|
+
case 'error':
|
|
137
|
+
return _jsx(Failure, { onRetry: onRetry, children: part.text });
|
|
138
|
+
default: {
|
|
139
|
+
// The union is closed and the WIRE is not, which is the one place those
|
|
140
|
+
// two facts have to meet. A part this does not know contributes its text
|
|
141
|
+
// and nothing else — the same answer `words` gives, so nothing a surface
|
|
142
|
+
// sends can go missing without also having been missing before.
|
|
143
|
+
const unknown = part;
|
|
144
|
+
return _jsx(_Fragment, { children: unknown.text ? ink(unknown.text) : null });
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/** A turn's parts, in order, spaced. Goes in a `Message`'s children — `Chat`
|
|
149
|
+
* puts it there for a turn whose content is a list. */
|
|
150
|
+
export function Parts({ parts, prose, onRetry, onOpen, onSource, ...props }) {
|
|
151
|
+
return (_jsx(YStack, { ...slot('parts'), width: "100%", gap: "$2", ...props, children: join(parts).map((part, i) => (_jsx(Piece, { part: part, prose: prose, onRetry: onRetry, onOpen: onOpen, onSource: onSource }, `${part.type}-${i}`))) }));
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=Parts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Parts.js","sourceRoot":"","sources":["../../src/chat/Parts.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use client';"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.clip = void 0;
|
|
5
|
+
exports.Persona = Persona;
|
|
6
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
|
+
/**
|
|
8
|
+
* Persona — a face on the canvas, and what it is doing.
|
|
9
|
+
*
|
|
10
|
+
* A persona is not a new engine. It is a MAPPING: an emotion names a clip, the
|
|
11
|
+
* clip goes to `Backdrop`'s `clips` mode, and that mode's preloaded crossfade
|
|
12
|
+
* does the switching it already does — one live frame over another, never a
|
|
13
|
+
* flash of black. So a mood change is a prop change, and there is exactly one
|
|
14
|
+
* piece of machinery playing video in this package rather than two.
|
|
15
|
+
*
|
|
16
|
+
* The mapping is the whole component, and it is deliberately thin. What an
|
|
17
|
+
* emotion MEANS — when a persona is listening, when it is thinking — belongs to
|
|
18
|
+
* whatever is driving the conversation; a component that guessed would be
|
|
19
|
+
* guessing from the one place with the least information.
|
|
20
|
+
*
|
|
21
|
+
* `idle` is required and every other emotion is optional, so a persona with one
|
|
22
|
+
* clip is a legal persona and adding a mood is adding a file. `clip` is pure and
|
|
23
|
+
* exported, which is what lets a surface preload the next mood, or test the
|
|
24
|
+
* mapping, without mounting anything.
|
|
25
|
+
*/
|
|
26
|
+
const Backdrop_1 = require("../backdrop/Backdrop.cjs");
|
|
27
|
+
/** The clip for this emotion, falling back to idle. */
|
|
28
|
+
const clip = (scenes, emotion) => scenes[emotion] ?? scenes.idle;
|
|
29
|
+
exports.clip = clip;
|
|
30
|
+
function Persona({ scenes, emotion = 'idle', ...props }) {
|
|
31
|
+
// One clip, so it loops itself rather than ending and handing over — a mood
|
|
32
|
+
// holds until something changes it, which is what a mood is.
|
|
33
|
+
return (0, jsx_runtime_1.jsx)(Backdrop_1.Backdrop, { ...props, mode: "clips", clips: [(0, exports.clip)(scenes, emotion)] });
|
|
34
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persona — a face on the canvas, and what it is doing.
|
|
3
|
+
*
|
|
4
|
+
* A persona is not a new engine. It is a MAPPING: an emotion names a clip, the
|
|
5
|
+
* clip goes to `Backdrop`'s `clips` mode, and that mode's preloaded crossfade
|
|
6
|
+
* does the switching it already does — one live frame over another, never a
|
|
7
|
+
* flash of black. So a mood change is a prop change, and there is exactly one
|
|
8
|
+
* piece of machinery playing video in this package rather than two.
|
|
9
|
+
*
|
|
10
|
+
* The mapping is the whole component, and it is deliberately thin. What an
|
|
11
|
+
* emotion MEANS — when a persona is listening, when it is thinking — belongs to
|
|
12
|
+
* whatever is driving the conversation; a component that guessed would be
|
|
13
|
+
* guessing from the one place with the least information.
|
|
14
|
+
*
|
|
15
|
+
* `idle` is required and every other emotion is optional, so a persona with one
|
|
16
|
+
* clip is a legal persona and adding a mood is adding a file. `clip` is pure and
|
|
17
|
+
* exported, which is what lets a surface preload the next mood, or test the
|
|
18
|
+
* mapping, without mounting anything.
|
|
19
|
+
*/
|
|
20
|
+
import { type BackdropProps } from '../backdrop/Backdrop.js';
|
|
21
|
+
/** What a persona is doing. The set a conversation can actually report. */
|
|
22
|
+
export type Emotion = 'idle' | 'listening' | 'thinking' | 'speaking' | 'happy' | 'sad' | 'surprised';
|
|
23
|
+
/** Which clip plays for each emotion. `idle` is required: it is what plays when
|
|
24
|
+
* a persona has nothing for the emotion at hand, so there is always something
|
|
25
|
+
* on the canvas and never a gap to design around. */
|
|
26
|
+
export type Scenes = {
|
|
27
|
+
idle: string;
|
|
28
|
+
} & Partial<Record<Emotion, string>>;
|
|
29
|
+
/** The clip for this emotion, falling back to idle. */
|
|
30
|
+
export declare const clip: (scenes: Scenes, emotion: Emotion) => string;
|
|
31
|
+
export interface PersonaProps extends Omit<BackdropProps, 'mode' | 'clips'> {
|
|
32
|
+
scenes: Scenes;
|
|
33
|
+
/** What the persona is doing right now. Defaults to idle. */
|
|
34
|
+
emotion?: Emotion;
|
|
35
|
+
}
|
|
36
|
+
export declare function Persona({ scenes, emotion, ...props }: PersonaProps): import("react").JSX.Element;
|
|
37
|
+
//# sourceMappingURL=Persona.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Persona.d.ts","sourceRoot":"","sources":["../../src/chat/Persona.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAEnE,2EAA2E;AAC3E,MAAM,MAAM,OAAO,GACf,MAAM,GACN,WAAW,GACX,UAAU,GACV,UAAU,GACV,OAAO,GACP,KAAK,GACL,WAAW,CAAA;AAEf;;sDAEsD;AACtD,MAAM,MAAM,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAA;AAExE,uDAAuD;AACvD,eAAO,MAAM,IAAI,WAAY,MAAM,WAAW,OAAO,KAAG,MAAwC,CAAA;AAEhG,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC;IACzE,MAAM,EAAE,MAAM,CAAA;IACd,6DAA6D;IAC7D,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,wBAAgB,OAAO,CAAC,EAAE,MAAM,EAAE,OAAgB,EAAE,GAAG,KAAK,EAAE,EAAE,YAAY,+BAI3E"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Persona — a face on the canvas, and what it is doing.
|
|
5
|
+
*
|
|
6
|
+
* A persona is not a new engine. It is a MAPPING: an emotion names a clip, the
|
|
7
|
+
* clip goes to `Backdrop`'s `clips` mode, and that mode's preloaded crossfade
|
|
8
|
+
* does the switching it already does — one live frame over another, never a
|
|
9
|
+
* flash of black. So a mood change is a prop change, and there is exactly one
|
|
10
|
+
* piece of machinery playing video in this package rather than two.
|
|
11
|
+
*
|
|
12
|
+
* The mapping is the whole component, and it is deliberately thin. What an
|
|
13
|
+
* emotion MEANS — when a persona is listening, when it is thinking — belongs to
|
|
14
|
+
* whatever is driving the conversation; a component that guessed would be
|
|
15
|
+
* guessing from the one place with the least information.
|
|
16
|
+
*
|
|
17
|
+
* `idle` is required and every other emotion is optional, so a persona with one
|
|
18
|
+
* clip is a legal persona and adding a mood is adding a file. `clip` is pure and
|
|
19
|
+
* exported, which is what lets a surface preload the next mood, or test the
|
|
20
|
+
* mapping, without mounting anything.
|
|
21
|
+
*/
|
|
22
|
+
import { Backdrop } from '../backdrop/Backdrop.js';
|
|
23
|
+
/** The clip for this emotion, falling back to idle. */
|
|
24
|
+
export const clip = (scenes, emotion) => scenes[emotion] ?? scenes.idle;
|
|
25
|
+
export function Persona({ scenes, emotion = 'idle', ...props }) {
|
|
26
|
+
// One clip, so it loops itself rather than ending and handing over — a mood
|
|
27
|
+
// holds until something changes it, which is what a mood is.
|
|
28
|
+
return _jsx(Backdrop, { ...props, mode: "clips", clips: [clip(scenes, emotion)] });
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=Persona.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Persona.js","sourceRoot":"","sources":["../../src/chat/Persona.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,QAAQ,EAAsB,MAAM,sBAAsB,CAAA;AAiBnE,uDAAuD;AACvD,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,MAAc,EAAE,OAAgB,EAAU,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,IAAI,CAAA;AAQhG,MAAM,UAAU,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,KAAK,EAAgB;IAC1E,4EAA4E;IAC5E,6DAA6D;IAC7D,OAAO,KAAC,QAAQ,OAAK,KAAK,EAAE,IAAI,EAAC,OAAO,EAAC,KAAK,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAI,CAAA;AAC7E,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use client';"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.Preview = Preview;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
/**
|
|
7
|
+
* Preview — an interface the model wrote, shown but not run.
|
|
8
|
+
*
|
|
9
|
+
* Generative UI arrives as markup, and markup from a model is untrusted input
|
|
10
|
+
* that happens to be a document. Rendering it into the host page is
|
|
11
|
+
* cross-site scripting with extra steps; refusing to render it at all leaves
|
|
12
|
+
* the feature as a paragraph of HTML source. Neither is the answer.
|
|
13
|
+
*
|
|
14
|
+
* The answer is `sandbox=""`. An empty allow-list is the STRICTEST setting the
|
|
15
|
+
* attribute has, not a lax one: no scripts, no same-origin, no forms, no
|
|
16
|
+
* navigation, no popups, no pointer lock. The document lays out and paints —
|
|
17
|
+
* real CSS, real fonts, real layout, a real screenshot — and can do nothing
|
|
18
|
+
* else. That is exactly the shape of a mockup, so nothing is lost by taking
|
|
19
|
+
* away the half that is dangerous.
|
|
20
|
+
*
|
|
21
|
+
* This is why `Parts` can draw an `artifact` and still refuses a `uiResource`.
|
|
22
|
+
* They are not the same risk: a `uiResource` is a URL, and loading one pulls a
|
|
23
|
+
* third-party origin into the page over the network. Inline markup with
|
|
24
|
+
* scripting off reaches nothing and runs nothing.
|
|
25
|
+
*
|
|
26
|
+
* Web only, like `Backdrop` — it is an `<iframe>`, and there is no such thing
|
|
27
|
+
* off the web. A surface that runs on native sends artifacts with no `markup`
|
|
28
|
+
* and gets `ArtifactCard`, which is where that decision already lived.
|
|
29
|
+
*/
|
|
30
|
+
const gui_1 = require("@hanzo/gui");
|
|
31
|
+
const slot_1 = require("../backends/gui/slot.cjs");
|
|
32
|
+
function Preview({ markup, title, height = 320, ...props }) {
|
|
33
|
+
const named = title ?? 'Preview';
|
|
34
|
+
return ((0, jsx_runtime_1.jsxs)(gui_1.YStack, { ...(0, slot_1.slot)('preview'), width: "100%", maxW: 720, rounded: "$4", overflow: "hidden", borderWidth: 1, borderColor: "$borderColor", bg: "$panel", ...props, children: [title ? ((0, jsx_runtime_1.jsx)(gui_1.XStack, { items: "center", gap: "$2", px: "$3", py: "$2", borderBottomWidth: 1, borderColor: "$borderColor", children: (0, jsx_runtime_1.jsx)(gui_1.SizableText, { size: "$1", color: "$soft", numberOfLines: 1, children: title }) })) : null, (0, jsx_runtime_1.jsx)("iframe", { title: named, srcDoc: markup, sandbox: "", referrerPolicy: "no-referrer", style: {
|
|
35
|
+
display: 'block',
|
|
36
|
+
width: '100%',
|
|
37
|
+
height,
|
|
38
|
+
border: 0,
|
|
39
|
+
background: '#fff',
|
|
40
|
+
colorScheme: 'light',
|
|
41
|
+
} })] }));
|
|
42
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preview — an interface the model wrote, shown but not run.
|
|
3
|
+
*
|
|
4
|
+
* Generative UI arrives as markup, and markup from a model is untrusted input
|
|
5
|
+
* that happens to be a document. Rendering it into the host page is
|
|
6
|
+
* cross-site scripting with extra steps; refusing to render it at all leaves
|
|
7
|
+
* the feature as a paragraph of HTML source. Neither is the answer.
|
|
8
|
+
*
|
|
9
|
+
* The answer is `sandbox=""`. An empty allow-list is the STRICTEST setting the
|
|
10
|
+
* attribute has, not a lax one: no scripts, no same-origin, no forms, no
|
|
11
|
+
* navigation, no popups, no pointer lock. The document lays out and paints —
|
|
12
|
+
* real CSS, real fonts, real layout, a real screenshot — and can do nothing
|
|
13
|
+
* else. That is exactly the shape of a mockup, so nothing is lost by taking
|
|
14
|
+
* away the half that is dangerous.
|
|
15
|
+
*
|
|
16
|
+
* This is why `Parts` can draw an `artifact` and still refuses a `uiResource`.
|
|
17
|
+
* They are not the same risk: a `uiResource` is a URL, and loading one pulls a
|
|
18
|
+
* third-party origin into the page over the network. Inline markup with
|
|
19
|
+
* scripting off reaches nothing and runs nothing.
|
|
20
|
+
*
|
|
21
|
+
* Web only, like `Backdrop` — it is an `<iframe>`, and there is no such thing
|
|
22
|
+
* off the web. A surface that runs on native sends artifacts with no `markup`
|
|
23
|
+
* and gets `ArtifactCard`, which is where that decision already lived.
|
|
24
|
+
*/
|
|
25
|
+
import { YStack } from '@hanzo/gui';
|
|
26
|
+
import type { ComponentProps } from 'react';
|
|
27
|
+
export interface PreviewProps extends Omit<ComponentProps<typeof YStack>, 'children'> {
|
|
28
|
+
/** A self-contained HTML document. Script in it will not run. */
|
|
29
|
+
markup: string;
|
|
30
|
+
/** Named in the frame's header. Also the frame's accessible name. */
|
|
31
|
+
title?: string;
|
|
32
|
+
/** Viewport height, px. The document scrolls inside it. */
|
|
33
|
+
height?: number;
|
|
34
|
+
}
|
|
35
|
+
export declare function Preview({ markup, title, height, ...props }: PreviewProps): import("react").JSX.Element;
|
|
36
|
+
//# sourceMappingURL=Preview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Preview.d.ts","sourceRoot":"","sources":["../../src/chat/Preview.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAAuB,MAAM,EAAE,MAAM,YAAY,CAAA;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAI3C,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC;IACnF,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAA;IACd,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,wBAAgB,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAY,EAAE,GAAG,KAAK,EAAE,EAAE,YAAY,+BAiD9E"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Preview — an interface the model wrote, shown but not run.
|
|
5
|
+
*
|
|
6
|
+
* Generative UI arrives as markup, and markup from a model is untrusted input
|
|
7
|
+
* that happens to be a document. Rendering it into the host page is
|
|
8
|
+
* cross-site scripting with extra steps; refusing to render it at all leaves
|
|
9
|
+
* the feature as a paragraph of HTML source. Neither is the answer.
|
|
10
|
+
*
|
|
11
|
+
* The answer is `sandbox=""`. An empty allow-list is the STRICTEST setting the
|
|
12
|
+
* attribute has, not a lax one: no scripts, no same-origin, no forms, no
|
|
13
|
+
* navigation, no popups, no pointer lock. The document lays out and paints —
|
|
14
|
+
* real CSS, real fonts, real layout, a real screenshot — and can do nothing
|
|
15
|
+
* else. That is exactly the shape of a mockup, so nothing is lost by taking
|
|
16
|
+
* away the half that is dangerous.
|
|
17
|
+
*
|
|
18
|
+
* This is why `Parts` can draw an `artifact` and still refuses a `uiResource`.
|
|
19
|
+
* They are not the same risk: a `uiResource` is a URL, and loading one pulls a
|
|
20
|
+
* third-party origin into the page over the network. Inline markup with
|
|
21
|
+
* scripting off reaches nothing and runs nothing.
|
|
22
|
+
*
|
|
23
|
+
* Web only, like `Backdrop` — it is an `<iframe>`, and there is no such thing
|
|
24
|
+
* off the web. A surface that runs on native sends artifacts with no `markup`
|
|
25
|
+
* and gets `ArtifactCard`, which is where that decision already lived.
|
|
26
|
+
*/
|
|
27
|
+
import { SizableText, XStack, YStack } from '@hanzo/gui';
|
|
28
|
+
import { slot } from '../backends/gui/slot.js';
|
|
29
|
+
export function Preview({ markup, title, height = 320, ...props }) {
|
|
30
|
+
const named = title ?? 'Preview';
|
|
31
|
+
return (_jsxs(YStack, { ...slot('preview'), width: "100%", maxW: 720, rounded: "$4", overflow: "hidden", borderWidth: 1, borderColor: "$borderColor", bg: "$panel", ...props, children: [title ? (_jsx(XStack, { items: "center", gap: "$2", px: "$3", py: "$2", borderBottomWidth: 1, borderColor: "$borderColor", children: _jsx(SizableText, { size: "$1", color: "$soft", numberOfLines: 1, children: title }) })) : null, _jsx("iframe", { title: named, srcDoc: markup, sandbox: "", referrerPolicy: "no-referrer", style: {
|
|
32
|
+
display: 'block',
|
|
33
|
+
width: '100%',
|
|
34
|
+
height,
|
|
35
|
+
border: 0,
|
|
36
|
+
background: '#fff',
|
|
37
|
+
colorScheme: 'light',
|
|
38
|
+
} })] }));
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=Preview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Preview.js","sourceRoot":"","sources":["../../src/chat/Preview.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAGxD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AAW3C,MAAM,UAAU,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE,GAAG,KAAK,EAAgB;IAC7E,MAAM,KAAK,GAAG,KAAK,IAAI,SAAS,CAAA;IAChC,OAAO,CACL,MAAC,MAAM,OACD,IAAI,CAAC,SAAS,CAAC,EACnB,KAAK,EAAC,MAAM,EACZ,IAAI,EAAE,GAAG,EACT,OAAO,EAAC,IAAI,EACZ,QAAQ,EAAC,QAAQ,EACjB,WAAW,EAAE,CAAC,EACd,WAAW,EAAC,cAAc,EAC1B,EAAE,EAAC,QAAQ,KACP,KAAK,aAER,KAAK,CAAC,CAAC,CAAC,CACP,KAAC,MAAM,IACL,KAAK,EAAC,QAAQ,EACd,GAAG,EAAC,IAAI,EACR,EAAE,EAAC,IAAI,EACP,EAAE,EAAC,IAAI,EACP,iBAAiB,EAAE,CAAC,EACpB,WAAW,EAAC,cAAc,YAE1B,KAAC,WAAW,IAAC,IAAI,EAAC,IAAI,EAAC,KAAK,EAAC,OAAO,EAAC,aAAa,EAAE,CAAC,YAClD,KAAK,GACM,GACP,CACV,CAAC,CAAC,CAAC,IAAI,EAMR,iBACE,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAC,EAAE,EACV,cAAc,EAAC,aAAa,EAC5B,KAAK,EAAE;oBACL,OAAO,EAAE,OAAO;oBAChB,KAAK,EAAE,MAAM;oBACb,MAAM;oBACN,MAAM,EAAE,CAAC;oBACT,UAAU,EAAE,MAAM;oBAClB,WAAW,EAAE,OAAO;iBACrB,GACD,IACK,CACV,CAAA;AACH,CAAC"}
|