@assistant-ui/react-generative-ui 0.0.2
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/LICENSE +21 -0
- package/README.md +140 -0
- package/dist/JSONGenerativeUI.client.d.ts +23 -0
- package/dist/JSONGenerativeUI.client.d.ts.map +1 -0
- package/dist/JSONGenerativeUI.client.js +48 -0
- package/dist/JSONGenerativeUI.client.js.map +1 -0
- package/dist/JSONGenerativeUI.server.d.ts +25 -0
- package/dist/JSONGenerativeUI.server.d.ts.map +1 -0
- package/dist/JSONGenerativeUI.server.js +32 -0
- package/dist/JSONGenerativeUI.server.js.map +1 -0
- package/dist/JSONGenerativeUI.shared.d.ts +53 -0
- package/dist/JSONGenerativeUI.shared.d.ts.map +1 -0
- package/dist/JSONGenerativeUI.shared.js +31 -0
- package/dist/JSONGenerativeUI.shared.js.map +1 -0
- package/dist/buildPresentParameters.d.ts +24 -0
- package/dist/buildPresentParameters.d.ts.map +1 -0
- package/dist/buildPresentParameters.js +68 -0
- package/dist/buildPresentParameters.js.map +1 -0
- package/dist/constants.d.ts +14 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +15 -0
- package/dist/constants.js.map +1 -0
- package/dist/defineGenerativeComponents.d.ts +33 -0
- package/dist/defineGenerativeComponents.d.ts.map +1 -0
- package/dist/defineGenerativeComponents.js +34 -0
- package/dist/defineGenerativeComponents.js.map +1 -0
- package/dist/generativeUIToJSX.d.ts +16 -0
- package/dist/generativeUIToJSX.d.ts.map +1 -0
- package/dist/generativeUIToJSX.js +46 -0
- package/dist/generativeUIToJSX.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +7 -0
- package/dist/node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts +141 -0
- package/dist/node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts.map +1 -0
- package/dist/renderGenerativeUI.d.ts +17 -0
- package/dist/renderGenerativeUI.d.ts.map +1 -0
- package/dist/renderGenerativeUI.js +85 -0
- package/dist/renderGenerativeUI.js.map +1 -0
- package/dist/types.d.ts +94 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +0 -0
- package/package.json +82 -0
- package/src/JSONGenerativeUI.client.tsx +66 -0
- package/src/JSONGenerativeUI.server.tsx +39 -0
- package/src/JSONGenerativeUI.shared.ts +74 -0
- package/src/JSONGenerativeUI.test.tsx +89 -0
- package/src/buildPresentParameters.ts +90 -0
- package/src/constants.ts +10 -0
- package/src/defineGenerativeComponents.ts +38 -0
- package/src/generativeUIToJSX.test.ts +64 -0
- package/src/generativeUIToJSX.ts +63 -0
- package/src/index.ts +26 -0
- package/src/renderGenerativeUI.test.tsx +204 -0
- package/src/renderGenerativeUI.tsx +135 -0
- package/src/types.ts +104 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 AgentbaseAI Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# @assistant-ui/react-generative-ui
|
|
2
|
+
|
|
3
|
+
Generative UI tools for assistant-ui.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @assistant-ui/react-generative-ui
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
Declare the components the model is allowed to render in a library, then expose
|
|
14
|
+
them through the `present` tool. The model emits a `{ $type, ...props }` tree
|
|
15
|
+
(`$type` names the component, so a real `type` prop never collides); the tool
|
|
16
|
+
renders it against the library.
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
import { JSONGenerativeUI } from "@assistant-ui/react-generative-ui";
|
|
20
|
+
import { Thread, Tools } from "@assistant-ui/react";
|
|
21
|
+
import { z } from "zod";
|
|
22
|
+
|
|
23
|
+
const generativeUI = new JSONGenerativeUI({
|
|
24
|
+
library: {
|
|
25
|
+
Card: {
|
|
26
|
+
description: "A card container with a title.",
|
|
27
|
+
properties: z.object({ title: z.string() }),
|
|
28
|
+
render: ({ title, children }) => (
|
|
29
|
+
<section className="card">
|
|
30
|
+
<h3>{title}</h3>
|
|
31
|
+
{children}
|
|
32
|
+
</section>
|
|
33
|
+
),
|
|
34
|
+
},
|
|
35
|
+
Text: {
|
|
36
|
+
description: "A run of text.",
|
|
37
|
+
properties: z.object({ tone: z.enum(["muted", "normal"]).optional() }),
|
|
38
|
+
render: ({ tone, children }) => <p data-tone={tone}>{children}</p>,
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const toolkit = {
|
|
44
|
+
present: generativeUI.present(),
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
function App() {
|
|
48
|
+
return (
|
|
49
|
+
<Thread>
|
|
50
|
+
<Tools toolkit={toolkit} />
|
|
51
|
+
{/* MessageList, Composer, ... */}
|
|
52
|
+
</Thread>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
A node's `children` prop is rendered recursively, so components can be nested:
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"$type": "Card",
|
|
62
|
+
"title": "Hello",
|
|
63
|
+
"children": [{ "$type": "Text", "tone": "muted", "children": "Nested text" }]
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Streaming props
|
|
68
|
+
|
|
69
|
+
By default a component renders only once its props have fully arrived, so
|
|
70
|
+
`render` always sees complete props. Opt into rendering from partial props with
|
|
71
|
+
`streamProperties`. When you do, `render` receives an injected `$status` prop
|
|
72
|
+
that discriminates the props: while `"streaming"` they are `Partial`, and once
|
|
73
|
+
`"done"` they are complete.
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
const generativeUI = new JSONGenerativeUI({
|
|
77
|
+
library: {
|
|
78
|
+
Weather: {
|
|
79
|
+
description: "A live weather card.",
|
|
80
|
+
properties: z.object({ city: z.string(), temp: z.number() }),
|
|
81
|
+
streamProperties: true,
|
|
82
|
+
render: (props) => {
|
|
83
|
+
if (props.$status === "done") {
|
|
84
|
+
return <Card>{`${props.city}: ${props.temp}°`}</Card>; // complete props
|
|
85
|
+
}
|
|
86
|
+
return <Card>{props.city ?? "Loading…"}</Card>; // partial props
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`render` is a function of `props`, not a React component — but it runs on its
|
|
94
|
+
own fiber, so you can call hooks inside it as usual.
|
|
95
|
+
|
|
96
|
+
## `"use generative"` authoring
|
|
97
|
+
|
|
98
|
+
The examples above wire the library up by hand on the client. With the
|
|
99
|
+
`"use generative"` compiler (`@assistant-ui/next` or `@assistant-ui/vite`) you
|
|
100
|
+
can instead colocate a component's `properties` schema with its `render` and
|
|
101
|
+
expose the library as tools, and the build splits each half to the right target:
|
|
102
|
+
the schema goes to the server (so the model sees the tool), the `render` stays on
|
|
103
|
+
the client.
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
"use generative";
|
|
107
|
+
|
|
108
|
+
import { z } from "zod";
|
|
109
|
+
import { Weather } from "@/components/weather";
|
|
110
|
+
import { defineToolkit } from "@assistant-ui/react";
|
|
111
|
+
import {
|
|
112
|
+
JSONGenerativeUI,
|
|
113
|
+
defineGenerativeComponents,
|
|
114
|
+
} from "@assistant-ui/react-generative-ui";
|
|
115
|
+
|
|
116
|
+
const generative = new JSONGenerativeUI({
|
|
117
|
+
library: defineGenerativeComponents({
|
|
118
|
+
Weather: {
|
|
119
|
+
description: "Show a weather card.",
|
|
120
|
+
properties: z.object({ city: z.string() }),
|
|
121
|
+
render: (props) => <Weather {...props} />,
|
|
122
|
+
},
|
|
123
|
+
}),
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
export default defineToolkit({
|
|
127
|
+
// `present` displays a component; `prompt_user` is a human-in-the-loop prompt.
|
|
128
|
+
present: generative.present(),
|
|
129
|
+
prompt_user: generative.promptUser(),
|
|
130
|
+
});
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The model calls `present` with a node like `{ "$type": "Weather", "city": "SF" }`.
|
|
134
|
+
Pass `present({ display: "standalone" })` to render the component on its own
|
|
135
|
+
surface instead of inline. See the
|
|
136
|
+
[`"use generative"` docs](https://www.assistant-ui.com/docs) for the build setup.
|
|
137
|
+
|
|
138
|
+
## License
|
|
139
|
+
|
|
140
|
+
MIT
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { JSONGenerativeUIOptions, PresentTool, PresentToolOptions, PromptUserTool } from "./JSONGenerativeUI.shared.js";
|
|
2
|
+
|
|
3
|
+
//#region src/JSONGenerativeUI.client.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Client build of {@link JSONGenerativeUI}, resolved through the package's
|
|
6
|
+
* `default` export condition (browser and SSR).
|
|
7
|
+
*
|
|
8
|
+
* `present` is a frontend tool that renders the model's `{ $type, ...props }`
|
|
9
|
+
* tree against the library and resolves immediately. `prompt_user` is a
|
|
10
|
+
* human-in-the-loop tool: the model pauses and the rendered UI supplies the
|
|
11
|
+
* result. Both draw the tree the same way, so they share one `render`.
|
|
12
|
+
*/
|
|
13
|
+
declare class JSONGenerativeUI {
|
|
14
|
+
private readonly library;
|
|
15
|
+
private readonly parameters;
|
|
16
|
+
constructor(options: JSONGenerativeUIOptions);
|
|
17
|
+
private readonly render;
|
|
18
|
+
present(options?: PresentToolOptions): PresentTool;
|
|
19
|
+
promptUser(): PromptUserTool;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { JSONGenerativeUI };
|
|
23
|
+
//# sourceMappingURL=JSONGenerativeUI.client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JSONGenerativeUI.client.d.ts","names":[],"sources":["../src/JSONGenerativeUI.client.tsx"],"mappings":";;;;;AA+BA;;;;;;;cAAa,gBAAA;EAAA,iBACM,OAAA;EAAA,iBACA,UAAA;cAEL,OAAA,EAAS,uBAAA;EAAA,iBAKJ,MAAA;EASjB,OAAA,CAAQ,OAAA,GAAU,kBAAA,GAAqB,WAAA;EASvC,UAAA,IAAc,cAAA;AAAA"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { buildPresentParameters } from "./buildPresentParameters.js";
|
|
2
|
+
import { presentToolBase, promptUserToolBase } from "./JSONGenerativeUI.shared.js";
|
|
3
|
+
import { renderGenerativeUI } from "./renderGenerativeUI.js";
|
|
4
|
+
//#region src/JSONGenerativeUI.client.tsx
|
|
5
|
+
/** Maps a tool-call part status to the generative-UI streaming status. Only a
|
|
6
|
+
* `complete` call has fully-arrived args; `running` and `incomplete`
|
|
7
|
+
* (aborted/errored, so args may be partial) both render as `"streaming"` so a
|
|
8
|
+
* non-streaming component is never handed partial props. */
|
|
9
|
+
function uiStatus(status) {
|
|
10
|
+
return status.type === "complete" ? "done" : "streaming";
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Client build of {@link JSONGenerativeUI}, resolved through the package's
|
|
14
|
+
* `default` export condition (browser and SSR).
|
|
15
|
+
*
|
|
16
|
+
* `present` is a frontend tool that renders the model's `{ $type, ...props }`
|
|
17
|
+
* tree against the library and resolves immediately. `prompt_user` is a
|
|
18
|
+
* human-in-the-loop tool: the model pauses and the rendered UI supplies the
|
|
19
|
+
* result. Both draw the tree the same way, so they share one `render`.
|
|
20
|
+
*/
|
|
21
|
+
var JSONGenerativeUI = class {
|
|
22
|
+
library;
|
|
23
|
+
parameters;
|
|
24
|
+
constructor(options) {
|
|
25
|
+
this.library = options.library;
|
|
26
|
+
this.parameters = buildPresentParameters(options.library);
|
|
27
|
+
}
|
|
28
|
+
render = ({ args, status }) => renderGenerativeUI(args, this.library, { status: uiStatus(status) });
|
|
29
|
+
present(options) {
|
|
30
|
+
return {
|
|
31
|
+
...presentToolBase(this.parameters, options),
|
|
32
|
+
unstable_backendDefault: { parameters: true },
|
|
33
|
+
execute: async () => ({}),
|
|
34
|
+
render: this.render
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
promptUser() {
|
|
38
|
+
return {
|
|
39
|
+
...promptUserToolBase(this.parameters),
|
|
40
|
+
unstable_backendDefault: { parameters: true },
|
|
41
|
+
render: this.render
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
//#endregion
|
|
46
|
+
export { JSONGenerativeUI };
|
|
47
|
+
|
|
48
|
+
//# sourceMappingURL=JSONGenerativeUI.client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JSONGenerativeUI.client.js","names":[],"sources":["../src/JSONGenerativeUI.client.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { buildPresentParameters } from \"./buildPresentParameters\";\nimport {\n presentToolBase,\n promptUserToolBase,\n type JSONGenerativeUIOptions,\n type PresentParameters,\n type PresentTool,\n type PresentToolOptions,\n type PromptUserTool,\n} from \"./JSONGenerativeUI.shared\";\nimport { renderGenerativeUI } from \"./renderGenerativeUI\";\nimport type { GenerativeUILibrary, GenerativeUIStatus } from \"./types\";\n\n/** Maps a tool-call part status to the generative-UI streaming status. Only a\n * `complete` call has fully-arrived args; `running` and `incomplete`\n * (aborted/errored, so args may be partial) both render as `\"streaming\"` so a\n * non-streaming component is never handed partial props. */\nfunction uiStatus(status: { type: string }): GenerativeUIStatus {\n return status.type === \"complete\" ? \"done\" : \"streaming\";\n}\n\n/**\n * Client build of {@link JSONGenerativeUI}, resolved through the package's\n * `default` export condition (browser and SSR).\n *\n * `present` is a frontend tool that renders the model's `{ $type, ...props }`\n * tree against the library and resolves immediately. `prompt_user` is a\n * human-in-the-loop tool: the model pauses and the rendered UI supplies the\n * result. Both draw the tree the same way, so they share one `render`.\n */\nexport class JSONGenerativeUI {\n private readonly library: GenerativeUILibrary;\n private readonly parameters: PresentParameters;\n\n constructor(options: JSONGenerativeUIOptions) {\n this.library = options.library;\n this.parameters = buildPresentParameters(options.library);\n }\n\n private readonly render = ({\n args,\n status,\n }: {\n args: unknown;\n status: { type: string };\n }): ReactNode =>\n renderGenerativeUI(args, this.library, { status: uiStatus(status) });\n\n present(options?: PresentToolOptions): PresentTool {\n return {\n ...presentToolBase(this.parameters, options),\n unstable_backendDefault: { parameters: true },\n execute: async () => ({}),\n render: this.render,\n };\n }\n\n promptUser(): PromptUserTool {\n return {\n ...promptUserToolBase(this.parameters),\n unstable_backendDefault: { parameters: true },\n render: this.render,\n };\n }\n}\n"],"mappings":";;;;;;;;AAkBA,SAAS,SAAS,QAA8C;CAC9D,OAAO,OAAO,SAAS,aAAa,SAAS;AAC/C;;;;;;;;;;AAWA,IAAa,mBAAb,MAA8B;CAC5B;CACA;CAEA,YAAY,SAAkC;EAC5C,KAAK,UAAU,QAAQ;EACvB,KAAK,aAAa,uBAAuB,QAAQ,OAAO;CAC1D;CAEA,UAA2B,EACzB,MACA,aAKA,mBAAmB,MAAM,KAAK,SAAS,EAAE,QAAQ,SAAS,MAAM,EAAE,CAAC;CAErE,QAAQ,SAA2C;EACjD,OAAO;GACL,GAAG,gBAAgB,KAAK,YAAY,OAAO;GAC3C,yBAAyB,EAAE,YAAY,KAAK;GAC5C,SAAS,aAAa,CAAC;GACvB,QAAQ,KAAK;EACf;CACF;CAEA,aAA6B;EAC3B,OAAO;GACL,GAAG,mBAAmB,KAAK,UAAU;GACrC,yBAAyB,EAAE,YAAY,KAAK;GAC5C,QAAQ,KAAK;EACf;CACF;AACF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { JSONGenerativeUIOptions, PresentTool, PresentToolOptions, PromptUserTool } from "./JSONGenerativeUI.shared.js";
|
|
2
|
+
|
|
3
|
+
//#region src/JSONGenerativeUI.server.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Server build of {@link JSONGenerativeUI}, resolved through the package's
|
|
6
|
+
* `react-server` export condition.
|
|
7
|
+
*
|
|
8
|
+
* The model only needs each tool's `type`, `description`, and `parameters` on
|
|
9
|
+
* the server, so `present`/`prompt_user` return exactly that — no `execute` and
|
|
10
|
+
* no `render`, keeping the renderer (and React) out of the server graph. The
|
|
11
|
+
* client build adds those back. The two builds share one set of public types, so
|
|
12
|
+
* consumers see a single {@link JSONGenerativeUI} either way.
|
|
13
|
+
*
|
|
14
|
+
* `as` casts here because the tool types require a `render` for frontend/human
|
|
15
|
+
* tools; on the server it is structurally absent and never read.
|
|
16
|
+
*/
|
|
17
|
+
declare class JSONGenerativeUI {
|
|
18
|
+
private readonly parameters;
|
|
19
|
+
constructor(options: JSONGenerativeUIOptions);
|
|
20
|
+
present(options?: PresentToolOptions): PresentTool;
|
|
21
|
+
promptUser(): PromptUserTool;
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { JSONGenerativeUI };
|
|
25
|
+
//# sourceMappingURL=JSONGenerativeUI.server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JSONGenerativeUI.server.d.ts","names":[],"sources":["../src/JSONGenerativeUI.server.tsx"],"mappings":";;;;;AAwBA;;;;;;;;;;;cAAa,gBAAA;EAAA,iBACM,UAAA;cAEL,OAAA,EAAS,uBAAA;EAIrB,OAAA,CAAQ,OAAA,GAAU,kBAAA,GAAqB,WAAA;EAIvC,UAAA,IAAc,cAAA;AAAA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { buildPresentParameters } from "./buildPresentParameters.js";
|
|
2
|
+
import { presentToolBase, promptUserToolBase } from "./JSONGenerativeUI.shared.js";
|
|
3
|
+
//#region src/JSONGenerativeUI.server.tsx
|
|
4
|
+
/**
|
|
5
|
+
* Server build of {@link JSONGenerativeUI}, resolved through the package's
|
|
6
|
+
* `react-server` export condition.
|
|
7
|
+
*
|
|
8
|
+
* The model only needs each tool's `type`, `description`, and `parameters` on
|
|
9
|
+
* the server, so `present`/`prompt_user` return exactly that — no `execute` and
|
|
10
|
+
* no `render`, keeping the renderer (and React) out of the server graph. The
|
|
11
|
+
* client build adds those back. The two builds share one set of public types, so
|
|
12
|
+
* consumers see a single {@link JSONGenerativeUI} either way.
|
|
13
|
+
*
|
|
14
|
+
* `as` casts here because the tool types require a `render` for frontend/human
|
|
15
|
+
* tools; on the server it is structurally absent and never read.
|
|
16
|
+
*/
|
|
17
|
+
var JSONGenerativeUI = class {
|
|
18
|
+
parameters;
|
|
19
|
+
constructor(options) {
|
|
20
|
+
this.parameters = buildPresentParameters(options.library);
|
|
21
|
+
}
|
|
22
|
+
present(options) {
|
|
23
|
+
return presentToolBase(this.parameters, options);
|
|
24
|
+
}
|
|
25
|
+
promptUser() {
|
|
26
|
+
return promptUserToolBase(this.parameters);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
//#endregion
|
|
30
|
+
export { JSONGenerativeUI };
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=JSONGenerativeUI.server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JSONGenerativeUI.server.js","names":[],"sources":["../src/JSONGenerativeUI.server.tsx"],"sourcesContent":["import { buildPresentParameters } from \"./buildPresentParameters\";\nimport {\n presentToolBase,\n promptUserToolBase,\n type JSONGenerativeUIOptions,\n type PresentParameters,\n type PresentTool,\n type PresentToolOptions,\n type PromptUserTool,\n} from \"./JSONGenerativeUI.shared\";\n\n/**\n * Server build of {@link JSONGenerativeUI}, resolved through the package's\n * `react-server` export condition.\n *\n * The model only needs each tool's `type`, `description`, and `parameters` on\n * the server, so `present`/`prompt_user` return exactly that — no `execute` and\n * no `render`, keeping the renderer (and React) out of the server graph. The\n * client build adds those back. The two builds share one set of public types, so\n * consumers see a single {@link JSONGenerativeUI} either way.\n *\n * `as` casts here because the tool types require a `render` for frontend/human\n * tools; on the server it is structurally absent and never read.\n */\nexport class JSONGenerativeUI {\n private readonly parameters: PresentParameters;\n\n constructor(options: JSONGenerativeUIOptions) {\n this.parameters = buildPresentParameters(options.library);\n }\n\n present(options?: PresentToolOptions): PresentTool {\n return presentToolBase(this.parameters, options) as PresentTool;\n }\n\n promptUser(): PromptUserTool {\n return promptUserToolBase(this.parameters) as PromptUserTool;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAwBA,IAAa,mBAAb,MAA8B;CAC5B;CAEA,YAAY,SAAkC;EAC5C,KAAK,aAAa,uBAAuB,QAAQ,OAAO;CAC1D;CAEA,QAAQ,SAA2C;EACjD,OAAO,gBAAgB,KAAK,YAAY,OAAO;CACjD;CAEA,aAA6B;EAC3B,OAAO,mBAAmB,KAAK,UAAU;CAC3C;AACF"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { JSONSchema7 } from "./node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.js";
|
|
2
|
+
import { GenerativeUILibrary } from "./types.js";
|
|
3
|
+
import { ToolDefinition } from "@assistant-ui/react";
|
|
4
|
+
|
|
5
|
+
//#region src/JSONGenerativeUI.shared.d.ts
|
|
6
|
+
/** Options for {@link JSONGenerativeUI}. */
|
|
7
|
+
type JSONGenerativeUIOptions = {
|
|
8
|
+
/**
|
|
9
|
+
* The components the model is allowed to render, keyed by the `$type` it
|
|
10
|
+
* selects them with. Author it with `defineGenerativeComponents({ ... })` so a
|
|
11
|
+
* `"use generative"` build can split each `render` from its `properties`.
|
|
12
|
+
*/
|
|
13
|
+
library: GenerativeUILibrary;
|
|
14
|
+
};
|
|
15
|
+
/** Options for {@link JSONGenerativeUI.present}. */
|
|
16
|
+
type PresentToolOptions = {
|
|
17
|
+
/**
|
|
18
|
+
* Set `"standalone"` to render the component on its own surface (outside the
|
|
19
|
+
* chain-of-thought trace), e.g. a full-bleed artifact like a card. Omit it for
|
|
20
|
+
* the default inline rendering — there is no `"inline"` value because that is
|
|
21
|
+
* already the default.
|
|
22
|
+
*/
|
|
23
|
+
display?: "standalone";
|
|
24
|
+
};
|
|
25
|
+
/** The `present` tool, as the model sees it (no client `render`/`execute`). */
|
|
26
|
+
type PresentTool = ToolDefinition<Record<string, unknown>, Record<string, never>>;
|
|
27
|
+
/** The `prompt_user` tool, as the model sees it (no client `render`). */
|
|
28
|
+
type PromptUserTool = ToolDefinition<Record<string, unknown>, unknown>;
|
|
29
|
+
/** The tool `parameters` schema, built once per instance (see `buildPresentParameters`). */
|
|
30
|
+
type PresentParameters = JSONSchema7;
|
|
31
|
+
/**
|
|
32
|
+
* The schema-only half of the `present` tool, shared by both builds. The server
|
|
33
|
+
* build returns exactly this; the client build adds `execute` and `render`.
|
|
34
|
+
* Takes the already-built `parameters` so it isn't recomputed per tool.
|
|
35
|
+
*/
|
|
36
|
+
declare function presentToolBase(parameters: PresentParameters, options?: PresentToolOptions): {
|
|
37
|
+
display?: "standalone";
|
|
38
|
+
type: "frontend";
|
|
39
|
+
description: string;
|
|
40
|
+
parameters: JSONSchema7;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* The schema-only half of the `prompt_user` tool, shared by both builds. The
|
|
44
|
+
* server build returns exactly this; the client build adds `render`.
|
|
45
|
+
*/
|
|
46
|
+
declare function promptUserToolBase(parameters: PresentParameters): {
|
|
47
|
+
type: "human";
|
|
48
|
+
description: string;
|
|
49
|
+
parameters: JSONSchema7;
|
|
50
|
+
};
|
|
51
|
+
//#endregion
|
|
52
|
+
export { JSONGenerativeUIOptions, PresentParameters, PresentTool, PresentToolOptions, PromptUserTool, presentToolBase, promptUserToolBase };
|
|
53
|
+
//# sourceMappingURL=JSONGenerativeUI.shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JSONGenerativeUI.shared.d.ts","names":[],"sources":["../src/JSONGenerativeUI.shared.ts"],"mappings":";;;;;;KAKY,uBAAA;EAAA;;;;AAMkB;EAA5B,OAAA,EAAS,mBAAmB;AAAA;;KAIlB,kBAAA;EAOH;AAIT;;;;;EAJE,OAAO;AAAA;;KAIG,WAAA,GAAc,cAAA,CACxB,MAAA,mBACA,MAAA;;KAIU,cAAA,GAAiB,cAAc,CAAC,MAAA;;KAYhC,iBAAA,GAAoB,WAAW;AAZ3C;;;;AAAkD;AAAlD,iBAmBgB,eAAA,CACd,UAAA,EAAY,iBAAA,EACZ,OAAA,GAAU,kBAAA;;;;;;;;;;iBAcI,kBAAA,CAAmB,UAAA,EAAY,iBAAA;;;cAAA,WAAA;AAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//#region src/JSONGenerativeUI.shared.ts
|
|
2
|
+
const PRESENT_DESCRIPTION = "Present a UI component to the user. Select a component with `$type` and provide its props inline; nest components with `children`.";
|
|
3
|
+
const PROMPT_USER_DESCRIPTION = "Present a UI component to the user and wait for their response. Select a component with `$type` and provide its props inline; nest components with `children`. The user interacts with it and the result is returned to you.";
|
|
4
|
+
/**
|
|
5
|
+
* The schema-only half of the `present` tool, shared by both builds. The server
|
|
6
|
+
* build returns exactly this; the client build adds `execute` and `render`.
|
|
7
|
+
* Takes the already-built `parameters` so it isn't recomputed per tool.
|
|
8
|
+
*/
|
|
9
|
+
function presentToolBase(parameters, options) {
|
|
10
|
+
return {
|
|
11
|
+
type: "frontend",
|
|
12
|
+
description: PRESENT_DESCRIPTION,
|
|
13
|
+
parameters,
|
|
14
|
+
...options?.display !== void 0 ? { display: options.display } : {}
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The schema-only half of the `prompt_user` tool, shared by both builds. The
|
|
19
|
+
* server build returns exactly this; the client build adds `render`.
|
|
20
|
+
*/
|
|
21
|
+
function promptUserToolBase(parameters) {
|
|
22
|
+
return {
|
|
23
|
+
type: "human",
|
|
24
|
+
description: PROMPT_USER_DESCRIPTION,
|
|
25
|
+
parameters
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { presentToolBase, promptUserToolBase };
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=JSONGenerativeUI.shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JSONGenerativeUI.shared.js","names":[],"sources":["../src/JSONGenerativeUI.shared.ts"],"sourcesContent":["import type { ToolDefinition } from \"@assistant-ui/react\";\nimport type { JSONSchema7 } from \"json-schema\";\nimport type { GenerativeUILibrary } from \"./types\";\n\n/** Options for {@link JSONGenerativeUI}. */\nexport type JSONGenerativeUIOptions = {\n /**\n * The components the model is allowed to render, keyed by the `$type` it\n * selects them with. Author it with `defineGenerativeComponents({ ... })` so a\n * `\"use generative\"` build can split each `render` from its `properties`.\n */\n library: GenerativeUILibrary;\n};\n\n/** Options for {@link JSONGenerativeUI.present}. */\nexport type PresentToolOptions = {\n /**\n * Set `\"standalone\"` to render the component on its own surface (outside the\n * chain-of-thought trace), e.g. a full-bleed artifact like a card. Omit it for\n * the default inline rendering — there is no `\"inline\"` value because that is\n * already the default.\n */\n display?: \"standalone\";\n};\n\n/** The `present` tool, as the model sees it (no client `render`/`execute`). */\nexport type PresentTool = ToolDefinition<\n Record<string, unknown>,\n Record<string, never>\n>;\n\n/** The `prompt_user` tool, as the model sees it (no client `render`). */\nexport type PromptUserTool = ToolDefinition<Record<string, unknown>, unknown>;\n\nconst PRESENT_DESCRIPTION =\n \"Present a UI component to the user. Select a component with `$type` and \" +\n \"provide its props inline; nest components with `children`.\";\n\nconst PROMPT_USER_DESCRIPTION =\n \"Present a UI component to the user and wait for their response. Select a \" +\n \"component with `$type` and provide its props inline; nest components with \" +\n \"`children`. The user interacts with it and the result is returned to you.\";\n\n/** The tool `parameters` schema, built once per instance (see `buildPresentParameters`). */\nexport type PresentParameters = JSONSchema7;\n\n/**\n * The schema-only half of the `present` tool, shared by both builds. The server\n * build returns exactly this; the client build adds `execute` and `render`.\n * Takes the already-built `parameters` so it isn't recomputed per tool.\n */\nexport function presentToolBase(\n parameters: PresentParameters,\n options?: PresentToolOptions,\n) {\n return {\n type: \"frontend\" as const,\n description: PRESENT_DESCRIPTION,\n parameters,\n ...(options?.display !== undefined ? { display: options.display } : {}),\n };\n}\n\n/**\n * The schema-only half of the `prompt_user` tool, shared by both builds. The\n * server build returns exactly this; the client build adds `render`.\n */\nexport function promptUserToolBase(parameters: PresentParameters) {\n return {\n type: \"human\" as const,\n description: PROMPT_USER_DESCRIPTION,\n parameters,\n };\n}\n"],"mappings":";AAkCA,MAAM,sBACJ;AAGF,MAAM,0BACJ;;;;;;AAYF,SAAgB,gBACd,YACA,SACA;CACA,OAAO;EACL,MAAM;EACN,aAAa;EACb;EACA,GAAI,SAAS,YAAY,KAAA,IAAY,EAAE,SAAS,QAAQ,QAAQ,IAAI,CAAC;CACvE;AACF;;;;;AAMA,SAAgB,mBAAmB,YAA+B;CAChE,OAAO;EACL,MAAM;EACN,aAAa;EACb;CACF;AACF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { JSONSchema7 } from "./node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.js";
|
|
2
|
+
import { GenerativeUILibrary } from "./types.js";
|
|
3
|
+
|
|
4
|
+
//#region src/buildPresentParameters.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Builds the JSON schema for the `present` tool from a {@link GenerativeUILibrary}.
|
|
7
|
+
*
|
|
8
|
+
* The model produces a node `{ $type, ...props }` where `$type` selects a
|
|
9
|
+
* component and the rest are its props. The schema is a flat object: `$type` is
|
|
10
|
+
* an enum of the component names, every component's props are merged into one
|
|
11
|
+
* optional bag, and `children` recurses via `$defs` so the tree can nest.
|
|
12
|
+
*
|
|
13
|
+
* It is intentionally flat rather than a per-`$type` discriminated union. Tool /
|
|
14
|
+
* function-call schemas (OpenAI and others) require the top-level parameters to
|
|
15
|
+
* be a plain object and reject a top-level `oneOf`/`anyOf`/`enum`. So props can't
|
|
16
|
+
* be refined per `$type` at the root; the model is guided instead by `$type`'s
|
|
17
|
+
* description (which lists each component) and each prop's own description. The
|
|
18
|
+
* renderer validates nothing here — an unknown `$type` or stray prop is handled
|
|
19
|
+
* at render time — so a looser schema only costs the model a hint, not safety.
|
|
20
|
+
*/
|
|
21
|
+
declare function buildPresentParameters(library: GenerativeUILibrary): JSONSchema7;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { buildPresentParameters };
|
|
24
|
+
//# sourceMappingURL=buildPresentParameters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildPresentParameters.d.ts","names":[],"sources":["../src/buildPresentParameters.ts"],"mappings":";;;;;;AAqBA;;;;;;;;AAEc;;;;;;iBAFE,sBAAA,CACd,OAAA,EAAS,mBAAA,GACR,WAAW"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { TYPE_KEY } from "./constants.js";
|
|
2
|
+
import { toJSONSchema } from "assistant-stream";
|
|
3
|
+
//#region src/buildPresentParameters.ts
|
|
4
|
+
/**
|
|
5
|
+
* Builds the JSON schema for the `present` tool from a {@link GenerativeUILibrary}.
|
|
6
|
+
*
|
|
7
|
+
* The model produces a node `{ $type, ...props }` where `$type` selects a
|
|
8
|
+
* component and the rest are its props. The schema is a flat object: `$type` is
|
|
9
|
+
* an enum of the component names, every component's props are merged into one
|
|
10
|
+
* optional bag, and `children` recurses via `$defs` so the tree can nest.
|
|
11
|
+
*
|
|
12
|
+
* It is intentionally flat rather than a per-`$type` discriminated union. Tool /
|
|
13
|
+
* function-call schemas (OpenAI and others) require the top-level parameters to
|
|
14
|
+
* be a plain object and reject a top-level `oneOf`/`anyOf`/`enum`. So props can't
|
|
15
|
+
* be refined per `$type` at the root; the model is guided instead by `$type`'s
|
|
16
|
+
* description (which lists each component) and each prop's own description. The
|
|
17
|
+
* renderer validates nothing here — an unknown `$type` or stray prop is handled
|
|
18
|
+
* at render time — so a looser schema only costs the model a hint, not safety.
|
|
19
|
+
*/
|
|
20
|
+
function buildPresentParameters(library) {
|
|
21
|
+
const names = Object.keys(library);
|
|
22
|
+
const props = {};
|
|
23
|
+
for (const name of names) {
|
|
24
|
+
const propsSchema = toJSONSchema(library[name].properties);
|
|
25
|
+
if (propsSchema.type !== "object") throw new Error(`[@assistant-ui/react-generative-ui] Component "${name}": \`properties\` must be an object schema (e.g. \`z.object({ ... })\`).`);
|
|
26
|
+
for (const [key, schema] of Object.entries(propsSchema.properties ?? {})) {
|
|
27
|
+
if (key === "$type" || key === "children") continue;
|
|
28
|
+
if (!(key in props)) props[key] = schema;
|
|
29
|
+
else if (process.env["NODE_ENV"] !== "production") console.warn(`[@assistant-ui/react-generative-ui] Prop "${key}" is declared by more than one component; the first component's schema is kept and the rest are ignored. Rename or align the type to avoid an ambiguous schema.`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const typeDescription = names.length > 0 ? `The component to render. ${names.map((name) => `"${name}": ${library[name].description}`).join("; ")}` : "The component to render.";
|
|
33
|
+
const node = {
|
|
34
|
+
type: "object",
|
|
35
|
+
properties: {
|
|
36
|
+
[TYPE_KEY]: {
|
|
37
|
+
type: "string",
|
|
38
|
+
enum: names,
|
|
39
|
+
description: typeDescription
|
|
40
|
+
},
|
|
41
|
+
...props,
|
|
42
|
+
children: { $ref: "#/$defs/children" }
|
|
43
|
+
},
|
|
44
|
+
required: [TYPE_KEY]
|
|
45
|
+
};
|
|
46
|
+
const children = {
|
|
47
|
+
description: "Nested generative UI rendered inside this component.",
|
|
48
|
+
anyOf: [
|
|
49
|
+
{ type: "string" },
|
|
50
|
+
{ $ref: "#/$defs/node" },
|
|
51
|
+
{
|
|
52
|
+
type: "array",
|
|
53
|
+
items: { anyOf: [{ type: "string" }, { $ref: "#/$defs/node" }] }
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
};
|
|
57
|
+
return {
|
|
58
|
+
...node,
|
|
59
|
+
$defs: {
|
|
60
|
+
node,
|
|
61
|
+
children
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
export { buildPresentParameters };
|
|
67
|
+
|
|
68
|
+
//# sourceMappingURL=buildPresentParameters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildPresentParameters.js","names":[],"sources":["../src/buildPresentParameters.ts"],"sourcesContent":["import { toJSONSchema } from \"assistant-stream\";\nimport type { JSONSchema7, JSONSchema7Definition } from \"json-schema\";\nimport { TYPE_KEY } from \"./constants\";\nimport type { GenerativeUILibrary } from \"./types\";\n\n/**\n * Builds the JSON schema for the `present` tool from a {@link GenerativeUILibrary}.\n *\n * The model produces a node `{ $type, ...props }` where `$type` selects a\n * component and the rest are its props. The schema is a flat object: `$type` is\n * an enum of the component names, every component's props are merged into one\n * optional bag, and `children` recurses via `$defs` so the tree can nest.\n *\n * It is intentionally flat rather than a per-`$type` discriminated union. Tool /\n * function-call schemas (OpenAI and others) require the top-level parameters to\n * be a plain object and reject a top-level `oneOf`/`anyOf`/`enum`. So props can't\n * be refined per `$type` at the root; the model is guided instead by `$type`'s\n * description (which lists each component) and each prop's own description. The\n * renderer validates nothing here — an unknown `$type` or stray prop is handled\n * at render time — so a looser schema only costs the model a hint, not safety.\n */\nexport function buildPresentParameters(\n library: GenerativeUILibrary,\n): JSONSchema7 {\n const names = Object.keys(library);\n\n // Merge every component's props into one optional bag. `$type`/`children` are\n // framework-reserved, so drop any author-declared copies. On a name clash the\n // first component's schema wins — props are an advisory hint here, not a\n // strict per-component contract.\n const props: Record<string, JSONSchema7Definition> = {};\n for (const name of names) {\n const propsSchema = toJSONSchema(library[name]!.properties);\n if (propsSchema.type !== \"object\") {\n throw new Error(\n `[@assistant-ui/react-generative-ui] Component \"${name}\": ` +\n \"`properties` must be an object schema (e.g. `z.object({ ... })`).\",\n );\n }\n for (const [key, schema] of Object.entries(propsSchema.properties ?? {})) {\n if (key === TYPE_KEY || key === \"children\") continue;\n if (!(key in props)) {\n props[key] = schema;\n } else if (process.env[\"NODE_ENV\"] !== \"production\") {\n // eslint-disable-next-line no-console\n console.warn(\n `[@assistant-ui/react-generative-ui] Prop \"${key}\" is declared by more ` +\n \"than one component; the first component's schema is kept and the rest \" +\n \"are ignored. Rename or align the type to avoid an ambiguous schema.\",\n );\n }\n }\n }\n\n // Carry each component's description on the `$type` enum, since there are no\n // per-branch schemas to hang them on anymore.\n const typeDescription =\n names.length > 0\n ? `The component to render. ${names\n .map((name) => `\"${name}\": ${library[name]!.description}`)\n .join(\"; \")}`\n : \"The component to render.\";\n\n const node: JSONSchema7 = {\n type: \"object\",\n properties: {\n [TYPE_KEY]: { type: \"string\", enum: names, description: typeDescription },\n ...props,\n children: { $ref: \"#/$defs/children\" },\n },\n required: [TYPE_KEY],\n };\n\n const children: JSONSchema7 = {\n description: \"Nested generative UI rendered inside this component.\",\n anyOf: [\n { type: \"string\" },\n { $ref: \"#/$defs/node\" },\n {\n type: \"array\",\n items: { anyOf: [{ type: \"string\" }, { $ref: \"#/$defs/node\" }] },\n },\n ],\n };\n\n return {\n ...node,\n $defs: { node, children },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,uBACd,SACa;CACb,MAAM,QAAQ,OAAO,KAAK,OAAO;CAMjC,MAAM,QAA+C,CAAC;CACtD,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,cAAc,aAAa,QAAQ,MAAO,UAAU;EAC1D,IAAI,YAAY,SAAS,UACvB,MAAM,IAAI,MACR,kDAAkD,KAAK,yEAEzD;EAEF,KAAK,MAAM,CAAC,KAAK,WAAW,OAAO,QAAQ,YAAY,cAAc,CAAC,CAAC,GAAG;GACxE,IAAI,QAAA,WAAoB,QAAQ,YAAY;GAC5C,IAAI,EAAE,OAAO,QACX,MAAM,OAAO;QACR,IAAI,QAAQ,IAAI,gBAAgB,cAErC,QAAQ,KACN,6CAA6C,IAAI,gKAGnD;EAEJ;CACF;CAIA,MAAM,kBACJ,MAAM,SAAS,IACX,4BAA4B,MACzB,KAAK,SAAS,IAAI,KAAK,KAAK,QAAQ,MAAO,aAAa,EACxD,KAAK,IAAI,MACZ;CAEN,MAAM,OAAoB;EACxB,MAAM;EACN,YAAY;IACT,WAAW;IAAE,MAAM;IAAU,MAAM;IAAO,aAAa;GAAgB;GACxE,GAAG;GACH,UAAU,EAAE,MAAM,mBAAmB;EACvC;EACA,UAAU,CAAC,QAAQ;CACrB;CAEA,MAAM,WAAwB;EAC5B,aAAa;EACb,OAAO;GACL,EAAE,MAAM,SAAS;GACjB,EAAE,MAAM,eAAe;GACvB;IACE,MAAM;IACN,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,SAAS,GAAG,EAAE,MAAM,eAAe,CAAC,EAAE;GACjE;EACF;CACF;CAEA,OAAO;EACL,GAAG;EACH,OAAO;GAAE;GAAM;EAAS;CAC1B;AACF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/constants.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* The wire key naming the component to render.
|
|
4
|
+
*
|
|
5
|
+
* The model emits nodes as flat objects `{ [TYPE_KEY]: name, ...props }`. We
|
|
6
|
+
* use `$type` rather than `type` so a component's own `type` prop (e.g. a
|
|
7
|
+
* button's `type="submit"`) flows through as an ordinary prop without
|
|
8
|
+
* colliding with the discriminator. It mirrors the `$type` discriminator
|
|
9
|
+
* convention used by JSON polymorphism elsewhere.
|
|
10
|
+
*/
|
|
11
|
+
declare const TYPE_KEY = "$type";
|
|
12
|
+
//#endregion
|
|
13
|
+
export { TYPE_KEY };
|
|
14
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","names":[],"sources":["../src/constants.ts"],"mappings":";;AASA;;;;AAAqB;;;;cAAR,QAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/constants.ts
|
|
2
|
+
/**
|
|
3
|
+
* The wire key naming the component to render.
|
|
4
|
+
*
|
|
5
|
+
* The model emits nodes as flat objects `{ [TYPE_KEY]: name, ...props }`. We
|
|
6
|
+
* use `$type` rather than `type` so a component's own `type` prop (e.g. a
|
|
7
|
+
* button's `type="submit"`) flows through as an ordinary prop without
|
|
8
|
+
* colliding with the discriminator. It mirrors the `$type` discriminator
|
|
9
|
+
* convention used by JSON polymorphism elsewhere.
|
|
10
|
+
*/
|
|
11
|
+
const TYPE_KEY = "$type";
|
|
12
|
+
//#endregion
|
|
13
|
+
export { TYPE_KEY };
|
|
14
|
+
|
|
15
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","names":[],"sources":["../src/constants.ts"],"sourcesContent":["/**\n * The wire key naming the component to render.\n *\n * The model emits nodes as flat objects `{ [TYPE_KEY]: name, ...props }`. We\n * use `$type` rather than `type` so a component's own `type` prop (e.g. a\n * button's `type=\"submit\"`) flows through as an ordinary prop without\n * colliding with the discriminator. It mirrors the `$type` discriminator\n * convention used by JSON polymorphism elsewhere.\n */\nexport const TYPE_KEY = \"$type\";\n"],"mappings":";;;;;;;;;;AASA,MAAa,WAAW"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { GenerativeUILibrary } from "./types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/defineGenerativeComponents.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Authoring helper for a `"use generative"` generative-UI library — the set of
|
|
6
|
+
* components the model may render. Each component colocates its `properties`
|
|
7
|
+
* schema (kept on every build, drives the tool parameters) with its `render`
|
|
8
|
+
* (kept only on the client). Pass the result to {@link JSONGenerativeUI}:
|
|
9
|
+
*
|
|
10
|
+
* ```tsx
|
|
11
|
+
* "use generative";
|
|
12
|
+
* const generative = new JSONGenerativeUI({
|
|
13
|
+
* library: defineGenerativeComponents({
|
|
14
|
+
* Card: {
|
|
15
|
+
* description: "A card.",
|
|
16
|
+
* properties: z.object({ title: z.string() }),
|
|
17
|
+
* render: (props) => <Card {...props} />,
|
|
18
|
+
* },
|
|
19
|
+
* }),
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* Unlike {@link defineToolkit}, it has **no runtime implementation**. A
|
|
24
|
+
* `"use generative"` compiler unwraps the `defineGenerativeComponents(...)` call
|
|
25
|
+
* per build, dropping each `render` (and its client-only imports) from the server
|
|
26
|
+
* build. Reaching it at runtime means the module wasn't compiled (the directive
|
|
27
|
+
* is missing, or it was used outside a `"use generative"` file), so it throws
|
|
28
|
+
* rather than shipping client `render` code to the server.
|
|
29
|
+
*/
|
|
30
|
+
declare function defineGenerativeComponents(_library: GenerativeUILibrary): GenerativeUILibrary;
|
|
31
|
+
//#endregion
|
|
32
|
+
export { defineGenerativeComponents };
|
|
33
|
+
//# sourceMappingURL=defineGenerativeComponents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineGenerativeComponents.d.ts","names":[],"sources":["../src/defineGenerativeComponents.ts"],"mappings":";;;;;AA4BA;;;;;;;;AAEsB;;;;;;;;;;;;;;;;iBAFN,0BAAA,CACd,QAAA,EAAU,mBAAA,GACT,mBAAmB"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/defineGenerativeComponents.ts
|
|
2
|
+
/**
|
|
3
|
+
* Authoring helper for a `"use generative"` generative-UI library — the set of
|
|
4
|
+
* components the model may render. Each component colocates its `properties`
|
|
5
|
+
* schema (kept on every build, drives the tool parameters) with its `render`
|
|
6
|
+
* (kept only on the client). Pass the result to {@link JSONGenerativeUI}:
|
|
7
|
+
*
|
|
8
|
+
* ```tsx
|
|
9
|
+
* "use generative";
|
|
10
|
+
* const generative = new JSONGenerativeUI({
|
|
11
|
+
* library: defineGenerativeComponents({
|
|
12
|
+
* Card: {
|
|
13
|
+
* description: "A card.",
|
|
14
|
+
* properties: z.object({ title: z.string() }),
|
|
15
|
+
* render: (props) => <Card {...props} />,
|
|
16
|
+
* },
|
|
17
|
+
* }),
|
|
18
|
+
* });
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Unlike {@link defineToolkit}, it has **no runtime implementation**. A
|
|
22
|
+
* `"use generative"` compiler unwraps the `defineGenerativeComponents(...)` call
|
|
23
|
+
* per build, dropping each `render` (and its client-only imports) from the server
|
|
24
|
+
* build. Reaching it at runtime means the module wasn't compiled (the directive
|
|
25
|
+
* is missing, or it was used outside a `"use generative"` file), so it throws
|
|
26
|
+
* rather than shipping client `render` code to the server.
|
|
27
|
+
*/
|
|
28
|
+
function defineGenerativeComponents(_library) {
|
|
29
|
+
throw new Error("[assistant-ui] defineGenerativeComponents() has no runtime implementation — it is stripped at build time by the use-generative compiler. Reaching it means this module was not compiled (e.g. used outside a \"use generative\" file). Add the directive, or do not use it here.");
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { defineGenerativeComponents };
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=defineGenerativeComponents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineGenerativeComponents.js","names":[],"sources":["../src/defineGenerativeComponents.ts"],"sourcesContent":["import type { GenerativeUILibrary } from \"./types\";\n\n/**\n * Authoring helper for a `\"use generative\"` generative-UI library — the set of\n * components the model may render. Each component colocates its `properties`\n * schema (kept on every build, drives the tool parameters) with its `render`\n * (kept only on the client). Pass the result to {@link JSONGenerativeUI}:\n *\n * ```tsx\n * \"use generative\";\n * const generative = new JSONGenerativeUI({\n * library: defineGenerativeComponents({\n * Card: {\n * description: \"A card.\",\n * properties: z.object({ title: z.string() }),\n * render: (props) => <Card {...props} />,\n * },\n * }),\n * });\n * ```\n *\n * Unlike {@link defineToolkit}, it has **no runtime implementation**. A\n * `\"use generative\"` compiler unwraps the `defineGenerativeComponents(...)` call\n * per build, dropping each `render` (and its client-only imports) from the server\n * build. Reaching it at runtime means the module wasn't compiled (the directive\n * is missing, or it was used outside a `\"use generative\"` file), so it throws\n * rather than shipping client `render` code to the server.\n */\nexport function defineGenerativeComponents(\n _library: GenerativeUILibrary,\n): GenerativeUILibrary {\n throw new Error(\n \"[assistant-ui] defineGenerativeComponents() has no runtime implementation \" +\n \"— it is stripped at build time by the use-generative compiler. Reaching \" +\n \"it means this module was not compiled (e.g. used outside a \" +\n '\"use generative\" file). Add the directive, or do not use it here.',\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,SAAgB,2BACd,UACqB;CACrB,MAAM,IAAI,MACR,kRAIF;AACF"}
|