@ai-gui/react 0.5.0 → 0.6.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.
- package/dist/index.cjs +6 -5
- package/dist/index.d.cts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +7 -6
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -126,7 +126,7 @@ function useActionState(runtime, key) {
|
|
|
126
126
|
/** Translate a framework-neutral RenderOutput into React nodes. */
|
|
127
127
|
function renderOutput(out, key, sanitize, context) {
|
|
128
128
|
switch (out.kind) {
|
|
129
|
-
case "html": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { dangerouslySetInnerHTML: { __html:
|
|
129
|
+
case "html": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { dangerouslySetInnerHTML: { __html: (0, __ai_gui_core.sanitizeRenderedHtml)(out.html, sanitize, out.trusted) } }, key);
|
|
130
130
|
case "element": return (0, react.createElement)(out.tag, {
|
|
131
131
|
key,
|
|
132
132
|
...out.props
|
|
@@ -226,10 +226,6 @@ function AsyncOutput({ promise, sanitize, context }) {
|
|
|
226
226
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { "data-aigui-async-error": true });
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
|
-
function sanitizeOutput(html, sanitize) {
|
|
230
|
-
if (sanitize === false) return html;
|
|
231
|
-
return (0, __ai_gui_core.sanitizeHtml)(html, typeof sanitize === "object" ? sanitize : void 0);
|
|
232
|
-
}
|
|
233
229
|
|
|
234
230
|
//#endregion
|
|
235
231
|
//#region src/render-node.tsx
|
|
@@ -396,6 +392,7 @@ const AIRenderer = (0, react.forwardRef)(function AIRenderer$1(props, ref) {
|
|
|
396
392
|
const { renderer, nodes, push, feed, reset: resetRenderer } = useAIRenderer(opts);
|
|
397
393
|
const actionScope = (0, react.useRef)(createActionScope());
|
|
398
394
|
const rendered = (0, react.useRef)("");
|
|
395
|
+
const root = (0, react.useRef)(null);
|
|
399
396
|
(0, react.useEffect)(() => () => {
|
|
400
397
|
actionScope.current.controller.abort();
|
|
401
398
|
actionScope.current = createActionScope();
|
|
@@ -447,16 +444,19 @@ const AIRenderer = (0, react.forwardRef)(function AIRenderer$1(props, ref) {
|
|
|
447
444
|
}
|
|
448
445
|
onCardAction?.(action);
|
|
449
446
|
}, [actionRuntime, onCardAction]);
|
|
447
|
+
const exportImages = (0, react.useCallback)((options) => root.current ? (0, __ai_gui_core.exportRenderedImages)(root.current, options) : Promise.resolve([]), []);
|
|
450
448
|
(0, react.useImperativeHandle)(ref, () => ({
|
|
451
449
|
debugSource: "renderer",
|
|
452
450
|
subscribeDebug: (listener) => renderer.subscribeDebug(listener),
|
|
453
451
|
push,
|
|
454
452
|
feed,
|
|
453
|
+
exportImages,
|
|
455
454
|
reset
|
|
456
455
|
}), [
|
|
457
456
|
renderer,
|
|
458
457
|
push,
|
|
459
458
|
feed,
|
|
459
|
+
exportImages,
|
|
460
460
|
reset
|
|
461
461
|
]);
|
|
462
462
|
const nodeRenderers = (0, react.useMemo)(() => (0, __ai_gui_core.collectNodeRenderers)(plugins, { debugTarget: renderer }), [plugins, renderer]);
|
|
@@ -473,6 +473,7 @@ const AIRenderer = (0, react.forwardRef)(function AIRenderer$1(props, ref) {
|
|
|
473
473
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
474
474
|
className,
|
|
475
475
|
"data-aigui-renderer": true,
|
|
476
|
+
ref: root,
|
|
476
477
|
children: nodes.map((n) => renderNode(n, ctx))
|
|
477
478
|
});
|
|
478
479
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AIGuiPlugin, ASTNode, ActionRuntime, ActionState, CardAction, CardRegistry, CardStore, DebugEventListener, FeedOptions, FeedSource, NodeRenderer, Patch, RenderOutput, Renderer, RendererOptions } from "@ai-gui/core";
|
|
1
|
+
import { AIGuiPlugin, ASTNode, ActionRuntime, ActionState, CardAction, CardRegistry, CardStore, DebugEventListener, ExportImageOptions, ExportedImage, FeedOptions, FeedSource, NodeRenderer, Patch, RenderOutput, Renderer, RendererOptions } from "@ai-gui/core";
|
|
2
2
|
import * as react0 from "react";
|
|
3
3
|
import * as react1 from "react";
|
|
4
4
|
import { ReactNode } from "react";
|
|
@@ -53,6 +53,13 @@ interface AIRendererHandle {
|
|
|
53
53
|
subscribeDebug: (listener: DebugEventListener) => () => void;
|
|
54
54
|
push: (chunk: string) => void;
|
|
55
55
|
feed: (source: FeedSource, options?: FeedOptions) => Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Export every drawing currently rendered, as PNG data URLs.
|
|
58
|
+
*
|
|
59
|
+
* The element the drawings live in belongs to the renderer, so a host offering "save this chart"
|
|
60
|
+
* would otherwise have to wrap it in one of its own just to find them.
|
|
61
|
+
*/
|
|
62
|
+
exportImages: (options?: ExportImageOptions) => Promise<ExportedImage[]>;
|
|
56
63
|
reset: () => void;
|
|
57
64
|
}
|
|
58
65
|
interface AIRendererProps {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react0 from "react";
|
|
2
2
|
import * as react1 from "react";
|
|
3
3
|
import { ReactNode } from "react";
|
|
4
|
-
import { AIGuiPlugin, ASTNode, ActionRuntime, ActionState, CardAction, CardRegistry, CardStore, DebugEventListener, FeedOptions, FeedSource, NodeRenderer, Patch, RenderOutput, Renderer, RendererOptions } from "@ai-gui/core";
|
|
4
|
+
import { AIGuiPlugin, ASTNode, ActionRuntime, ActionState, CardAction, CardRegistry, CardStore, DebugEventListener, ExportImageOptions, ExportedImage, FeedOptions, FeedSource, NodeRenderer, Patch, RenderOutput, Renderer, RendererOptions } from "@ai-gui/core";
|
|
5
5
|
|
|
6
6
|
//#region src/use-ai-renderer.d.ts
|
|
7
7
|
interface UseAIRendererResult {
|
|
@@ -53,6 +53,13 @@ interface AIRendererHandle {
|
|
|
53
53
|
subscribeDebug: (listener: DebugEventListener) => () => void;
|
|
54
54
|
push: (chunk: string) => void;
|
|
55
55
|
feed: (source: FeedSource, options?: FeedOptions) => Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Export every drawing currently rendered, as PNG data URLs.
|
|
58
|
+
*
|
|
59
|
+
* The element the drawings live in belongs to the renderer, so a host offering "save this chart"
|
|
60
|
+
* would otherwise have to wrap it in one of its own just to find them.
|
|
61
|
+
*/
|
|
62
|
+
exportImages: (options?: ExportImageOptions) => Promise<ExportedImage[]>;
|
|
56
63
|
reset: () => void;
|
|
57
64
|
}
|
|
58
65
|
interface AIRendererProps {
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Fragment, createElement, forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
2
|
-
import { Renderer, collectNodeRenderers, getIdleActionState, sanitizeHtml } from "@ai-gui/core";
|
|
2
|
+
import { Renderer, collectNodeRenderers, exportRenderedImages, getIdleActionState, sanitizeHtml, sanitizeRenderedHtml } from "@ai-gui/core";
|
|
3
3
|
import { createPortal } from "react-dom";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
|
|
@@ -102,7 +102,7 @@ function useActionState(runtime, key) {
|
|
|
102
102
|
/** Translate a framework-neutral RenderOutput into React nodes. */
|
|
103
103
|
function renderOutput(out, key, sanitize, context) {
|
|
104
104
|
switch (out.kind) {
|
|
105
|
-
case "html": return /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html:
|
|
105
|
+
case "html": return /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: sanitizeRenderedHtml(out.html, sanitize, out.trusted) } }, key);
|
|
106
106
|
case "element": return createElement(out.tag, {
|
|
107
107
|
key,
|
|
108
108
|
...out.props
|
|
@@ -202,10 +202,6 @@ function AsyncOutput({ promise, sanitize, context }) {
|
|
|
202
202
|
return /* @__PURE__ */ jsx("span", { "data-aigui-async-error": true });
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
|
-
function sanitizeOutput(html, sanitize) {
|
|
206
|
-
if (sanitize === false) return html;
|
|
207
|
-
return sanitizeHtml(html, typeof sanitize === "object" ? sanitize : void 0);
|
|
208
|
-
}
|
|
209
205
|
|
|
210
206
|
//#endregion
|
|
211
207
|
//#region src/render-node.tsx
|
|
@@ -372,6 +368,7 @@ const AIRenderer = forwardRef(function AIRenderer$1(props, ref) {
|
|
|
372
368
|
const { renderer, nodes, push, feed, reset: resetRenderer } = useAIRenderer(opts);
|
|
373
369
|
const actionScope = useRef(createActionScope());
|
|
374
370
|
const rendered = useRef("");
|
|
371
|
+
const root = useRef(null);
|
|
375
372
|
useEffect(() => () => {
|
|
376
373
|
actionScope.current.controller.abort();
|
|
377
374
|
actionScope.current = createActionScope();
|
|
@@ -423,16 +420,19 @@ const AIRenderer = forwardRef(function AIRenderer$1(props, ref) {
|
|
|
423
420
|
}
|
|
424
421
|
onCardAction?.(action);
|
|
425
422
|
}, [actionRuntime, onCardAction]);
|
|
423
|
+
const exportImages = useCallback((options) => root.current ? exportRenderedImages(root.current, options) : Promise.resolve([]), []);
|
|
426
424
|
useImperativeHandle(ref, () => ({
|
|
427
425
|
debugSource: "renderer",
|
|
428
426
|
subscribeDebug: (listener) => renderer.subscribeDebug(listener),
|
|
429
427
|
push,
|
|
430
428
|
feed,
|
|
429
|
+
exportImages,
|
|
431
430
|
reset
|
|
432
431
|
}), [
|
|
433
432
|
renderer,
|
|
434
433
|
push,
|
|
435
434
|
feed,
|
|
435
|
+
exportImages,
|
|
436
436
|
reset
|
|
437
437
|
]);
|
|
438
438
|
const nodeRenderers = useMemo(() => collectNodeRenderers(plugins, { debugTarget: renderer }), [plugins, renderer]);
|
|
@@ -449,6 +449,7 @@ const AIRenderer = forwardRef(function AIRenderer$1(props, ref) {
|
|
|
449
449
|
return /* @__PURE__ */ jsx("div", {
|
|
450
450
|
className,
|
|
451
451
|
"data-aigui-renderer": true,
|
|
452
|
+
ref: root,
|
|
452
453
|
children: nodes.map((n) => renderNode(n, ctx))
|
|
453
454
|
});
|
|
454
455
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-gui/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "React adapter for AIGUI — stream LLM output into live React components with cards, plugins, and interactive widgets.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"llm",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"access": "public"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@ai-gui/core": "0.
|
|
53
|
+
"@ai-gui/core": "0.6.0"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
56
|
"react": ">=18",
|