@dudousxd/nestjs-agent-core 0.44.0 → 0.45.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/ag-ui/index.cjs +6 -1
- package/dist/ag-ui/index.cjs.map +1 -1
- package/dist/ag-ui/index.d.cts +2 -2
- package/dist/ag-ui/index.d.ts +2 -2
- package/dist/ag-ui/index.js +6 -1
- package/dist/ag-ui/index.js.map +1 -1
- package/dist/{catalog-G8usJpx5.d.cts → catalog-BUmTnAqU.d.cts} +14 -1
- package/dist/{catalog-G8usJpx5.d.ts → catalog-BUmTnAqU.d.ts} +14 -1
- package/dist/genui/builtins.cjs +1 -0
- package/dist/genui/builtins.cjs.map +1 -1
- package/dist/genui/builtins.d.cts +1 -1
- package/dist/genui/builtins.d.ts +1 -1
- package/dist/genui/builtins.js +1 -0
- package/dist/genui/builtins.js.map +1 -1
- package/dist/genui/index.cjs +232 -14
- package/dist/genui/index.cjs.map +1 -1
- package/dist/genui/index.d.cts +99 -14
- package/dist/genui/index.d.ts +99 -14
- package/dist/genui/index.js +230 -14
- package/dist/genui/index.js.map +1 -1
- package/dist/guardrails/index.d.cts +3 -3
- package/dist/guardrails/index.d.ts +3 -3
- package/dist/index.cjs +534 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +107 -6
- package/dist/index.d.ts +107 -6
- package/dist/index.js +528 -16
- package/dist/index.js.map +1 -1
- package/dist/{processors-BANqZT3O.d.cts → processors-BhOGaMPY.d.cts} +1 -1
- package/dist/{processors-C9mor-73.d.ts → processors-DDKKky_6.d.ts} +1 -1
- package/dist/{stream-events-BfxJAckJ.d.cts → stream-events-CqCqYjJw.d.ts} +63 -4
- package/dist/{stream-events-DFa2Do42.d.ts → stream-events-qB6NOOvn.d.cts} +63 -4
- package/package.json +1 -1
package/dist/genui/index.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { a as Catalog, J as JsonSchema, G as GenuiValidation, b as GenuiIssue } from '../catalog-
|
|
2
|
-
export { A as AjvLike,
|
|
1
|
+
import { a as Catalog, J as JsonSchema, G as GenuiValidation, b as GenuiStreaming, c as GenuiIssue } from '../catalog-BUmTnAqU.cjs';
|
|
2
|
+
export { A as AjvLike, d as COMPONENT_NAME, e as CatalogOptions, C as ComponentDefinition, f as JsonSchemaValidator, P as PropsSchema, g as ajvValidator, h as builtinJsonSchemaValidator, i as defineCatalog, j as defineComponent, k as flatComponents, l as formatIssues, m as isStandardSchema, t as toJsonSchema, n as toSnakeCase, o as toolNameFor, v as validateProps, p as validatePropsSync } from '../catalog-BUmTnAqU.cjs';
|
|
3
|
+
import { P as PartialToolInput, a as Actor, T as ToolSpec, b as ToolHandler, c as ToolPresentation } from '../stream-events-qB6NOOvn.cjs';
|
|
4
|
+
export { C as ChartProps, d as ComponentFactory, e as ComponentManifest, f as ComponentPresentation, g as ComponentRegistry, h as ComponentRenderer, i as PreparedUiEmission, j as TableCell, k as TableProps, U as UiCapabilities, l as chart, m as createComponent, n as createComponentRegistry, o as negotiateCatalog, p as prepareUiEmission, s as snapshotComponentPresentation, t as table, v as validatePresentationBatch, q as validateUiCapabilities } from '../stream-events-qB6NOOvn.cjs';
|
|
3
5
|
import { StandardSchemaV1, StandardJSONSchemaV1 } from '@standard-schema/spec';
|
|
4
|
-
import { a as Actor, T as ToolSpec, b as ToolHandler, c as ToolPresentation } from '../stream-events-BfxJAckJ.cjs';
|
|
5
|
-
export { C as ChartProps, d as ComponentFactory, e as ComponentManifest, f as ComponentPresentation, g as ComponentRegistry, h as ComponentRenderer, P as PreparedUiEmission, i as TableCell, j as TableProps, U as UiCapabilities, k as chart, l as createComponent, m as createComponentRegistry, n as negotiateCatalog, p as prepareUiEmission, s as snapshotComponentPresentation, t as table, v as validatePresentationBatch, o as validateUiCapabilities } from '../stream-events-BfxJAckJ.cjs';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* One node of a composed UI: a catalog component, its props, and — for components declared with
|
|
@@ -40,12 +40,33 @@ interface TreeLimits {
|
|
|
40
40
|
*/
|
|
41
41
|
declare function validateTree(catalog: Catalog, tree: unknown, limits?: TreeLimits, phase?: 'input' | 'output'): Promise<GenuiValidation<GenuiElement>>;
|
|
42
42
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
43
|
+
* How exactly a tree-mode tool's input is described to the model ({@link treeJsonSchema}):
|
|
44
|
+
*
|
|
45
|
+
* - `'strict'` (default): every node's `props` is its component's own props schema, and `children`
|
|
46
|
+
* is a discriminated union by `type` over the components — each variant with its exact props, and
|
|
47
|
+
* `children` only on components that take them (recursive, through `$defs` / `$ref`).
|
|
48
|
+
* - `'loose'`: one `{ type, props: object, children }` node shape — for a provider that refuses
|
|
49
|
+
* `$ref` in tool parameters. The props are then only described in the tool's text.
|
|
50
|
+
*/
|
|
51
|
+
type TreeSchemaMode = 'strict' | 'loose';
|
|
52
|
+
/**
|
|
53
|
+
* The JSON Schema of a tree-mode tool's input. Whatever it says, {@link validateTree} remains the
|
|
54
|
+
* check every call goes through: a provider is free to ignore the schema.
|
|
55
|
+
*
|
|
56
|
+
* Strict (the default), it is shaped for what the providers accept in tool parameters:
|
|
57
|
+
* - the root is a plain `type: 'object'` — OpenAI and Anthropic both refuse a union at the top
|
|
58
|
+
* level of a tool's parameters — whose `type` lists every component and whose `props` is any of
|
|
59
|
+
* their props schemas;
|
|
60
|
+
* - every `children` item is `{ $ref: '#/$defs/node' }`, an `anyOf` of one variant per component
|
|
61
|
+
* (`type` a one-value `enum`, `props` that component's schema, `children` only where taken,
|
|
62
|
+
* `additionalProperties: false`);
|
|
63
|
+
* - a component whose props schema is not self-contained (it carries its own `$ref`, `$defs` or
|
|
64
|
+
* `definitions`, as a recursive Zod schema does) is described as `{ type: 'object' }`, since its
|
|
65
|
+
* references would not resolve once embedded; `$schema` is dropped.
|
|
47
66
|
*/
|
|
48
|
-
declare function treeJsonSchema(catalog: Catalog
|
|
67
|
+
declare function treeJsonSchema(catalog: Catalog, options?: {
|
|
68
|
+
schema?: TreeSchemaMode;
|
|
69
|
+
}): JsonSchema;
|
|
49
70
|
/** A json-render flat spec: `{ root, elements: { [id]: { type, props, children: id[] } } }`. */
|
|
50
71
|
interface FlatSpec {
|
|
51
72
|
root: string;
|
|
@@ -58,6 +79,47 @@ interface FlatSpec {
|
|
|
58
79
|
/** Convert a tree to a json-render flat spec (ids are `el-0`, `el-1`, … in depth-first order). */
|
|
59
80
|
declare function treeToFlatSpec(root: GenuiElement): FlatSpec;
|
|
60
81
|
|
|
82
|
+
/**
|
|
83
|
+
* One node of a tree the model is still writing — what a partial `genui:tree` frame carries.
|
|
84
|
+
*
|
|
85
|
+
* `id` is the node's position: `root`, then `<parent id>.<index>` (`root.1.0`). It never changes as
|
|
86
|
+
* the tree grows (a model only ever appends), and the final tree's nodes are addressed by the same
|
|
87
|
+
* rule, so a renderer keyed on it keeps every node mounted from the first preview to the final frame.
|
|
88
|
+
*/
|
|
89
|
+
interface GenuiPartialElement {
|
|
90
|
+
id: string;
|
|
91
|
+
type: string;
|
|
92
|
+
props: Record<string, unknown>;
|
|
93
|
+
children?: GenuiPartialElement[];
|
|
94
|
+
/** The model has not finished writing this node: its props (or children) may still grow. */
|
|
95
|
+
incomplete?: true;
|
|
96
|
+
/**
|
|
97
|
+
* The node's component streams `complete`: its props and children are held back until its whole
|
|
98
|
+
* subtree has arrived (`props` is `{}`). Draw a placeholder, never the component.
|
|
99
|
+
*/
|
|
100
|
+
held?: true;
|
|
101
|
+
}
|
|
102
|
+
/** The id of the child at `index` of the node `parentId` (the root is `root`). */
|
|
103
|
+
declare function treeNodeId(parentId: string, index: number): string;
|
|
104
|
+
interface PartialTreeOptions {
|
|
105
|
+
/** How a component without its own `streaming` appears. Default `'complete'`. */
|
|
106
|
+
streaming?: GenuiStreaming;
|
|
107
|
+
limits?: TreeLimits;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* The part of a streaming `ui__render` input worth drawing: every node whose `type` has fully
|
|
111
|
+
* arrived and names a component of `catalog` (the negotiated one: what this client draws), with its
|
|
112
|
+
* props so far — unvalidated, and flagged `incomplete` while still open. A node whose component
|
|
113
|
+
* streams `complete` is a `held` placeholder until it closes.
|
|
114
|
+
*
|
|
115
|
+
* `{ root: null }` while nothing is drawable yet. `null` when the input can no longer become a tree
|
|
116
|
+
* this client draws (an unknown or undrawable component, children where none are taken, past the
|
|
117
|
+
* size limits): the preview stops there, and the final push decides what is shown.
|
|
118
|
+
*/
|
|
119
|
+
declare function partialTree(catalog: Catalog, input: PartialToolInput, options?: PartialTreeOptions): {
|
|
120
|
+
root: GenuiPartialElement | null;
|
|
121
|
+
} | null;
|
|
122
|
+
|
|
61
123
|
/**
|
|
62
124
|
* Plain text (Slack mrkdwn compatible) for a pushed component: its definition's `fallbackText`, or
|
|
63
125
|
* the props as a JSON block when the catalog has no text for it. A tree frame
|
|
@@ -117,12 +179,20 @@ interface GenuiCatalogScope {
|
|
|
117
179
|
type ResolveGenuiCatalog = (scope: GenuiCatalogScope) => Catalog | Promise<Catalog>;
|
|
118
180
|
interface GenuiToolsOptions {
|
|
119
181
|
/**
|
|
120
|
-
* `
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
* `
|
|
182
|
+
* `tree` (default): a single `ui__render` tool whose input is a nested `{ type, props, children }`
|
|
183
|
+
* tree composed from the catalog (json-render's nested shape). A tree of one component with no
|
|
184
|
+
* children is pushed as that component, exactly as its `ui__show_*` tool would push it.
|
|
185
|
+
* `per-component`: one tool per model-facing component, `ui__show_<snake>`, whose input IS the
|
|
186
|
+
* component's props — for small models, or when each tool should carry its exact schema. Layouts
|
|
187
|
+
* (`children: true`) get none: a flat input cannot fill them.
|
|
124
188
|
*/
|
|
125
189
|
mode?: 'per-component' | 'tree';
|
|
190
|
+
/**
|
|
191
|
+
* How the tree tool's input schema describes the nodes (see {@link treeJsonSchema}): `'strict'`
|
|
192
|
+
* (default) — a recursive union by `type` with each component's exact props; `'loose'` — one
|
|
193
|
+
* generic node shape, for a provider that refuses `$ref` in tool parameters.
|
|
194
|
+
*/
|
|
195
|
+
treeSchema?: TreeSchemaMode;
|
|
126
196
|
/**
|
|
127
197
|
* The model's turn ends once a genui call succeeds — no further model call to narrate what the UI
|
|
128
198
|
* already shows. Stamped as `spec.terminal`.
|
|
@@ -136,6 +206,21 @@ interface GenuiToolsOptions {
|
|
|
136
206
|
treeInstructions?: string;
|
|
137
207
|
/** Size limits for `tree`. */
|
|
138
208
|
treeLimits?: TreeLimits;
|
|
209
|
+
/**
|
|
210
|
+
* Tree mode: whether the layout is drawn WHILE the model writes it.
|
|
211
|
+
*
|
|
212
|
+
* - `'complete'` (default): nothing is drawn until the call has run; then the validated tree
|
|
213
|
+
* appears whole.
|
|
214
|
+
* - `'partial'`: the server parses the streaming `ui__render` arguments and pushes the tree so far
|
|
215
|
+
* as `partial` `ui` frames under the id the final push replaces — throttled, unvalidated, never
|
|
216
|
+
* persisted, never sent to a text channel. Nodes still being written are flagged `incomplete`; a
|
|
217
|
+
* component declared `streaming: 'complete'` is a `held` placeholder until its subtree closes.
|
|
218
|
+
*
|
|
219
|
+
* A component's own {@link ComponentDefinition.streaming} overrides this per component.
|
|
220
|
+
*/
|
|
221
|
+
streaming?: GenuiStreaming;
|
|
222
|
+
/** Least time between two partial tree frames of one call, in ms. Default 100. */
|
|
223
|
+
streamingThrottleMs?: number;
|
|
139
224
|
/**
|
|
140
225
|
* Also offer ONE generic tool taking `{ component, props }`, validated against the (resolved)
|
|
141
226
|
* catalog — how a model reaches components that only exist per request (a tenant's own), which a
|
|
@@ -175,4 +260,4 @@ type JsonStandardSchema = StandardSchemaV1 & StandardJSONSchemaV1;
|
|
|
175
260
|
*/
|
|
176
261
|
declare function jsonStandardSchema(schema: JsonSchema, validate: (value: unknown) => GenuiIssue[]): JsonStandardSchema;
|
|
177
262
|
|
|
178
|
-
export { Catalog, type CatalogTextOptions, type FlatSpec, GENUI_SHOW_TOOL, GENUI_TREE_COMPONENT, type GenuiCatalogScope, type GenuiElement, GenuiIssue, type GenuiTool, type GenuiToolOutput, type GenuiToolsOptions, type GenuiTreeProps, GenuiValidation, JsonSchema, type ResolveGenuiCatalog, type TreeLimits, catalogToModelText, componentToText, fillTemplate, genuiTools, getPath, jsonStandardSchema, showToolJsonSchema, summarizeSchema, treeJsonSchema, treeToFlatSpec, treeToText, validateTree };
|
|
263
|
+
export { Catalog, type CatalogTextOptions, type FlatSpec, GENUI_SHOW_TOOL, GENUI_TREE_COMPONENT, type GenuiCatalogScope, type GenuiElement, GenuiIssue, type GenuiPartialElement, GenuiStreaming, type GenuiTool, type GenuiToolOutput, type GenuiToolsOptions, type GenuiTreeProps, GenuiValidation, JsonSchema, type PartialTreeOptions, type ResolveGenuiCatalog, type TreeLimits, type TreeSchemaMode, catalogToModelText, componentToText, fillTemplate, genuiTools, getPath, jsonStandardSchema, partialTree, showToolJsonSchema, summarizeSchema, treeJsonSchema, treeNodeId, treeToFlatSpec, treeToText, validateTree };
|
package/dist/genui/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { a as Catalog, J as JsonSchema, G as GenuiValidation, b as GenuiIssue } from '../catalog-
|
|
2
|
-
export { A as AjvLike,
|
|
1
|
+
import { a as Catalog, J as JsonSchema, G as GenuiValidation, b as GenuiStreaming, c as GenuiIssue } from '../catalog-BUmTnAqU.js';
|
|
2
|
+
export { A as AjvLike, d as COMPONENT_NAME, e as CatalogOptions, C as ComponentDefinition, f as JsonSchemaValidator, P as PropsSchema, g as ajvValidator, h as builtinJsonSchemaValidator, i as defineCatalog, j as defineComponent, k as flatComponents, l as formatIssues, m as isStandardSchema, t as toJsonSchema, n as toSnakeCase, o as toolNameFor, v as validateProps, p as validatePropsSync } from '../catalog-BUmTnAqU.js';
|
|
3
|
+
import { P as PartialToolInput, a as Actor, T as ToolSpec, b as ToolHandler, c as ToolPresentation } from '../stream-events-CqCqYjJw.js';
|
|
4
|
+
export { C as ChartProps, d as ComponentFactory, e as ComponentManifest, f as ComponentPresentation, g as ComponentRegistry, h as ComponentRenderer, i as PreparedUiEmission, j as TableCell, k as TableProps, U as UiCapabilities, l as chart, m as createComponent, n as createComponentRegistry, o as negotiateCatalog, p as prepareUiEmission, s as snapshotComponentPresentation, t as table, v as validatePresentationBatch, q as validateUiCapabilities } from '../stream-events-CqCqYjJw.js';
|
|
3
5
|
import { StandardSchemaV1, StandardJSONSchemaV1 } from '@standard-schema/spec';
|
|
4
|
-
import { a as Actor, T as ToolSpec, b as ToolHandler, c as ToolPresentation } from '../stream-events-DFa2Do42.js';
|
|
5
|
-
export { C as ChartProps, d as ComponentFactory, e as ComponentManifest, f as ComponentPresentation, g as ComponentRegistry, h as ComponentRenderer, P as PreparedUiEmission, i as TableCell, j as TableProps, U as UiCapabilities, k as chart, l as createComponent, m as createComponentRegistry, n as negotiateCatalog, p as prepareUiEmission, s as snapshotComponentPresentation, t as table, v as validatePresentationBatch, o as validateUiCapabilities } from '../stream-events-DFa2Do42.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* One node of a composed UI: a catalog component, its props, and — for components declared with
|
|
@@ -40,12 +40,33 @@ interface TreeLimits {
|
|
|
40
40
|
*/
|
|
41
41
|
declare function validateTree(catalog: Catalog, tree: unknown, limits?: TreeLimits, phase?: 'input' | 'output'): Promise<GenuiValidation<GenuiElement>>;
|
|
42
42
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
43
|
+
* How exactly a tree-mode tool's input is described to the model ({@link treeJsonSchema}):
|
|
44
|
+
*
|
|
45
|
+
* - `'strict'` (default): every node's `props` is its component's own props schema, and `children`
|
|
46
|
+
* is a discriminated union by `type` over the components — each variant with its exact props, and
|
|
47
|
+
* `children` only on components that take them (recursive, through `$defs` / `$ref`).
|
|
48
|
+
* - `'loose'`: one `{ type, props: object, children }` node shape — for a provider that refuses
|
|
49
|
+
* `$ref` in tool parameters. The props are then only described in the tool's text.
|
|
50
|
+
*/
|
|
51
|
+
type TreeSchemaMode = 'strict' | 'loose';
|
|
52
|
+
/**
|
|
53
|
+
* The JSON Schema of a tree-mode tool's input. Whatever it says, {@link validateTree} remains the
|
|
54
|
+
* check every call goes through: a provider is free to ignore the schema.
|
|
55
|
+
*
|
|
56
|
+
* Strict (the default), it is shaped for what the providers accept in tool parameters:
|
|
57
|
+
* - the root is a plain `type: 'object'` — OpenAI and Anthropic both refuse a union at the top
|
|
58
|
+
* level of a tool's parameters — whose `type` lists every component and whose `props` is any of
|
|
59
|
+
* their props schemas;
|
|
60
|
+
* - every `children` item is `{ $ref: '#/$defs/node' }`, an `anyOf` of one variant per component
|
|
61
|
+
* (`type` a one-value `enum`, `props` that component's schema, `children` only where taken,
|
|
62
|
+
* `additionalProperties: false`);
|
|
63
|
+
* - a component whose props schema is not self-contained (it carries its own `$ref`, `$defs` or
|
|
64
|
+
* `definitions`, as a recursive Zod schema does) is described as `{ type: 'object' }`, since its
|
|
65
|
+
* references would not resolve once embedded; `$schema` is dropped.
|
|
47
66
|
*/
|
|
48
|
-
declare function treeJsonSchema(catalog: Catalog
|
|
67
|
+
declare function treeJsonSchema(catalog: Catalog, options?: {
|
|
68
|
+
schema?: TreeSchemaMode;
|
|
69
|
+
}): JsonSchema;
|
|
49
70
|
/** A json-render flat spec: `{ root, elements: { [id]: { type, props, children: id[] } } }`. */
|
|
50
71
|
interface FlatSpec {
|
|
51
72
|
root: string;
|
|
@@ -58,6 +79,47 @@ interface FlatSpec {
|
|
|
58
79
|
/** Convert a tree to a json-render flat spec (ids are `el-0`, `el-1`, … in depth-first order). */
|
|
59
80
|
declare function treeToFlatSpec(root: GenuiElement): FlatSpec;
|
|
60
81
|
|
|
82
|
+
/**
|
|
83
|
+
* One node of a tree the model is still writing — what a partial `genui:tree` frame carries.
|
|
84
|
+
*
|
|
85
|
+
* `id` is the node's position: `root`, then `<parent id>.<index>` (`root.1.0`). It never changes as
|
|
86
|
+
* the tree grows (a model only ever appends), and the final tree's nodes are addressed by the same
|
|
87
|
+
* rule, so a renderer keyed on it keeps every node mounted from the first preview to the final frame.
|
|
88
|
+
*/
|
|
89
|
+
interface GenuiPartialElement {
|
|
90
|
+
id: string;
|
|
91
|
+
type: string;
|
|
92
|
+
props: Record<string, unknown>;
|
|
93
|
+
children?: GenuiPartialElement[];
|
|
94
|
+
/** The model has not finished writing this node: its props (or children) may still grow. */
|
|
95
|
+
incomplete?: true;
|
|
96
|
+
/**
|
|
97
|
+
* The node's component streams `complete`: its props and children are held back until its whole
|
|
98
|
+
* subtree has arrived (`props` is `{}`). Draw a placeholder, never the component.
|
|
99
|
+
*/
|
|
100
|
+
held?: true;
|
|
101
|
+
}
|
|
102
|
+
/** The id of the child at `index` of the node `parentId` (the root is `root`). */
|
|
103
|
+
declare function treeNodeId(parentId: string, index: number): string;
|
|
104
|
+
interface PartialTreeOptions {
|
|
105
|
+
/** How a component without its own `streaming` appears. Default `'complete'`. */
|
|
106
|
+
streaming?: GenuiStreaming;
|
|
107
|
+
limits?: TreeLimits;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* The part of a streaming `ui__render` input worth drawing: every node whose `type` has fully
|
|
111
|
+
* arrived and names a component of `catalog` (the negotiated one: what this client draws), with its
|
|
112
|
+
* props so far — unvalidated, and flagged `incomplete` while still open. A node whose component
|
|
113
|
+
* streams `complete` is a `held` placeholder until it closes.
|
|
114
|
+
*
|
|
115
|
+
* `{ root: null }` while nothing is drawable yet. `null` when the input can no longer become a tree
|
|
116
|
+
* this client draws (an unknown or undrawable component, children where none are taken, past the
|
|
117
|
+
* size limits): the preview stops there, and the final push decides what is shown.
|
|
118
|
+
*/
|
|
119
|
+
declare function partialTree(catalog: Catalog, input: PartialToolInput, options?: PartialTreeOptions): {
|
|
120
|
+
root: GenuiPartialElement | null;
|
|
121
|
+
} | null;
|
|
122
|
+
|
|
61
123
|
/**
|
|
62
124
|
* Plain text (Slack mrkdwn compatible) for a pushed component: its definition's `fallbackText`, or
|
|
63
125
|
* the props as a JSON block when the catalog has no text for it. A tree frame
|
|
@@ -117,12 +179,20 @@ interface GenuiCatalogScope {
|
|
|
117
179
|
type ResolveGenuiCatalog = (scope: GenuiCatalogScope) => Catalog | Promise<Catalog>;
|
|
118
180
|
interface GenuiToolsOptions {
|
|
119
181
|
/**
|
|
120
|
-
* `
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
* `
|
|
182
|
+
* `tree` (default): a single `ui__render` tool whose input is a nested `{ type, props, children }`
|
|
183
|
+
* tree composed from the catalog (json-render's nested shape). A tree of one component with no
|
|
184
|
+
* children is pushed as that component, exactly as its `ui__show_*` tool would push it.
|
|
185
|
+
* `per-component`: one tool per model-facing component, `ui__show_<snake>`, whose input IS the
|
|
186
|
+
* component's props — for small models, or when each tool should carry its exact schema. Layouts
|
|
187
|
+
* (`children: true`) get none: a flat input cannot fill them.
|
|
124
188
|
*/
|
|
125
189
|
mode?: 'per-component' | 'tree';
|
|
190
|
+
/**
|
|
191
|
+
* How the tree tool's input schema describes the nodes (see {@link treeJsonSchema}): `'strict'`
|
|
192
|
+
* (default) — a recursive union by `type` with each component's exact props; `'loose'` — one
|
|
193
|
+
* generic node shape, for a provider that refuses `$ref` in tool parameters.
|
|
194
|
+
*/
|
|
195
|
+
treeSchema?: TreeSchemaMode;
|
|
126
196
|
/**
|
|
127
197
|
* The model's turn ends once a genui call succeeds — no further model call to narrate what the UI
|
|
128
198
|
* already shows. Stamped as `spec.terminal`.
|
|
@@ -136,6 +206,21 @@ interface GenuiToolsOptions {
|
|
|
136
206
|
treeInstructions?: string;
|
|
137
207
|
/** Size limits for `tree`. */
|
|
138
208
|
treeLimits?: TreeLimits;
|
|
209
|
+
/**
|
|
210
|
+
* Tree mode: whether the layout is drawn WHILE the model writes it.
|
|
211
|
+
*
|
|
212
|
+
* - `'complete'` (default): nothing is drawn until the call has run; then the validated tree
|
|
213
|
+
* appears whole.
|
|
214
|
+
* - `'partial'`: the server parses the streaming `ui__render` arguments and pushes the tree so far
|
|
215
|
+
* as `partial` `ui` frames under the id the final push replaces — throttled, unvalidated, never
|
|
216
|
+
* persisted, never sent to a text channel. Nodes still being written are flagged `incomplete`; a
|
|
217
|
+
* component declared `streaming: 'complete'` is a `held` placeholder until its subtree closes.
|
|
218
|
+
*
|
|
219
|
+
* A component's own {@link ComponentDefinition.streaming} overrides this per component.
|
|
220
|
+
*/
|
|
221
|
+
streaming?: GenuiStreaming;
|
|
222
|
+
/** Least time between two partial tree frames of one call, in ms. Default 100. */
|
|
223
|
+
streamingThrottleMs?: number;
|
|
139
224
|
/**
|
|
140
225
|
* Also offer ONE generic tool taking `{ component, props }`, validated against the (resolved)
|
|
141
226
|
* catalog — how a model reaches components that only exist per request (a tenant's own), which a
|
|
@@ -175,4 +260,4 @@ type JsonStandardSchema = StandardSchemaV1 & StandardJSONSchemaV1;
|
|
|
175
260
|
*/
|
|
176
261
|
declare function jsonStandardSchema(schema: JsonSchema, validate: (value: unknown) => GenuiIssue[]): JsonStandardSchema;
|
|
177
262
|
|
|
178
|
-
export { Catalog, type CatalogTextOptions, type FlatSpec, GENUI_SHOW_TOOL, GENUI_TREE_COMPONENT, type GenuiCatalogScope, type GenuiElement, GenuiIssue, type GenuiTool, type GenuiToolOutput, type GenuiToolsOptions, type GenuiTreeProps, GenuiValidation, JsonSchema, type ResolveGenuiCatalog, type TreeLimits, catalogToModelText, componentToText, fillTemplate, genuiTools, getPath, jsonStandardSchema, showToolJsonSchema, summarizeSchema, treeJsonSchema, treeToFlatSpec, treeToText, validateTree };
|
|
263
|
+
export { Catalog, type CatalogTextOptions, type FlatSpec, GENUI_SHOW_TOOL, GENUI_TREE_COMPONENT, type GenuiCatalogScope, type GenuiElement, GenuiIssue, type GenuiPartialElement, GenuiStreaming, type GenuiTool, type GenuiToolOutput, type GenuiToolsOptions, type GenuiTreeProps, GenuiValidation, JsonSchema, type PartialTreeOptions, type ResolveGenuiCatalog, type TreeLimits, type TreeSchemaMode, catalogToModelText, componentToText, fillTemplate, genuiTools, getPath, jsonStandardSchema, partialTree, showToolJsonSchema, summarizeSchema, treeJsonSchema, treeNodeId, treeToFlatSpec, treeToText, validateTree };
|
package/dist/genui/index.js
CHANGED
|
@@ -355,6 +355,7 @@ function defineComponent(definition) {
|
|
|
355
355
|
}
|
|
356
356
|
if (definition.version !== void 0 && (!Number.isSafeInteger(definition.version) || definition.version <= 0)) throw new RangeError("genui: component version must be a positive safe integer");
|
|
357
357
|
if (definition.fallbackText !== void 0 && typeof definition.fallbackText !== "function") throw new TypeError("genui: fallbackText must be a function");
|
|
358
|
+
if (definition.streaming !== void 0 && definition.streaming !== "partial" && definition.streaming !== "complete") throw new TypeError("genui: streaming must be 'partial' or 'complete'");
|
|
358
359
|
return definition;
|
|
359
360
|
}
|
|
360
361
|
__name(defineComponent, "defineComponent");
|
|
@@ -439,6 +440,97 @@ function toolNameFor(component, prefix = "ui__show_") {
|
|
|
439
440
|
}
|
|
440
441
|
__name(toolNameFor, "toolNameFor");
|
|
441
442
|
|
|
443
|
+
// src/genui/progressive.ts
|
|
444
|
+
function treeNodeId(parentId, index) {
|
|
445
|
+
return `${parentId}.${index}`;
|
|
446
|
+
}
|
|
447
|
+
__name(treeNodeId, "treeNodeId");
|
|
448
|
+
function isRecord(value) {
|
|
449
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
450
|
+
}
|
|
451
|
+
__name(isRecord, "isRecord");
|
|
452
|
+
function partialTree(catalog, input, options = {}) {
|
|
453
|
+
const maxDepth = options.limits?.maxDepth ?? 12;
|
|
454
|
+
const maxNodes = options.limits?.maxNodes ?? 200;
|
|
455
|
+
const fallback = options.streaming ?? "complete";
|
|
456
|
+
let nodes = 0;
|
|
457
|
+
let broken = false;
|
|
458
|
+
const visit = /* @__PURE__ */ __name((value, id, depth) => {
|
|
459
|
+
if (broken) return void 0;
|
|
460
|
+
if (!isRecord(value)) {
|
|
461
|
+
if (value !== void 0) broken = true;
|
|
462
|
+
return void 0;
|
|
463
|
+
}
|
|
464
|
+
const open = input.isOpen(value);
|
|
465
|
+
const type = value.type;
|
|
466
|
+
if (typeof type !== "string" || open && input.pendingMember(value) === "type") {
|
|
467
|
+
if (!open) broken = true;
|
|
468
|
+
return void 0;
|
|
469
|
+
}
|
|
470
|
+
const definition = catalog.get(type);
|
|
471
|
+
nodes += 1;
|
|
472
|
+
if (definition === void 0 || definition.internal === true || nodes > maxNodes || depth > maxDepth) {
|
|
473
|
+
broken = true;
|
|
474
|
+
return void 0;
|
|
475
|
+
}
|
|
476
|
+
const mode = definition.streaming ?? fallback;
|
|
477
|
+
if (mode === "complete") {
|
|
478
|
+
const checked = open ? void 0 : validatePropsSync(definition.props, value.props ?? {}, catalog.validator);
|
|
479
|
+
if (checked === void 0 || !checked.ok) {
|
|
480
|
+
return {
|
|
481
|
+
id,
|
|
482
|
+
type,
|
|
483
|
+
props: {},
|
|
484
|
+
incomplete: true,
|
|
485
|
+
held: true
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
const children2 = childrenOf(value, id, depth, definition.children === true);
|
|
489
|
+
return {
|
|
490
|
+
id,
|
|
491
|
+
type,
|
|
492
|
+
props: checked.value,
|
|
493
|
+
...children2 !== void 0 && children2.length > 0 ? {
|
|
494
|
+
children: children2
|
|
495
|
+
} : {}
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
const props = isRecord(value.props) ? value.props : {};
|
|
499
|
+
const children = childrenOf(value, id, depth, definition.children === true);
|
|
500
|
+
return {
|
|
501
|
+
id,
|
|
502
|
+
type,
|
|
503
|
+
props,
|
|
504
|
+
...children !== void 0 && children.length > 0 ? {
|
|
505
|
+
children
|
|
506
|
+
} : {},
|
|
507
|
+
...open ? {
|
|
508
|
+
incomplete: true
|
|
509
|
+
} : {}
|
|
510
|
+
};
|
|
511
|
+
}, "visit");
|
|
512
|
+
const childrenOf = /* @__PURE__ */ __name((value, id, depth, takesChildren) => {
|
|
513
|
+
const raw = value.children;
|
|
514
|
+
if (!Array.isArray(raw)) return void 0;
|
|
515
|
+
if (raw.length > 0 && !takesChildren) {
|
|
516
|
+
broken = true;
|
|
517
|
+
return void 0;
|
|
518
|
+
}
|
|
519
|
+
const children = [];
|
|
520
|
+
for (const [index, child] of raw.entries()) {
|
|
521
|
+
const next = visit(child, treeNodeId(id, index), depth + 1);
|
|
522
|
+
if (next !== void 0) children.push(next);
|
|
523
|
+
}
|
|
524
|
+
return children;
|
|
525
|
+
}, "childrenOf");
|
|
526
|
+
const root = visit(input.value, "root", 1);
|
|
527
|
+
if (broken) return null;
|
|
528
|
+
return {
|
|
529
|
+
root: root ?? null
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
__name(partialTree, "partialTree");
|
|
533
|
+
|
|
442
534
|
// src/genui/tree.ts
|
|
443
535
|
var GENUI_TREE_COMPONENT = "genui:tree";
|
|
444
536
|
async function validateTree(catalog, tree, limits = {}, phase = "output") {
|
|
@@ -571,34 +663,120 @@ async function validateTree(catalog, tree, limits = {}, phase = "output") {
|
|
|
571
663
|
};
|
|
572
664
|
}
|
|
573
665
|
__name(validateTree, "validateTree");
|
|
574
|
-
function treeJsonSchema(catalog) {
|
|
666
|
+
function treeJsonSchema(catalog, options = {}) {
|
|
667
|
+
const components = catalog.modelComponents();
|
|
668
|
+
const names = components.map((component) => component.name);
|
|
669
|
+
if (options.schema === "loose") {
|
|
670
|
+
return {
|
|
671
|
+
type: "object",
|
|
672
|
+
properties: {
|
|
673
|
+
type: {
|
|
674
|
+
type: "string",
|
|
675
|
+
enum: names,
|
|
676
|
+
description: "Component name from the catalog"
|
|
677
|
+
},
|
|
678
|
+
props: {
|
|
679
|
+
type: "object",
|
|
680
|
+
description: "The component's props, as the catalog describes them"
|
|
681
|
+
},
|
|
682
|
+
children: {
|
|
683
|
+
type: "array",
|
|
684
|
+
items: {
|
|
685
|
+
$ref: "#"
|
|
686
|
+
},
|
|
687
|
+
description: "Nested elements, only for components that take children. A literal JSON array, never a JSON-stringified one."
|
|
688
|
+
}
|
|
689
|
+
},
|
|
690
|
+
required: [
|
|
691
|
+
"type",
|
|
692
|
+
"props"
|
|
693
|
+
]
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
const defs = {};
|
|
697
|
+
const childrenSchema = {
|
|
698
|
+
type: "array",
|
|
699
|
+
items: {
|
|
700
|
+
$ref: "#/$defs/node"
|
|
701
|
+
},
|
|
702
|
+
description: "Nested elements. A literal JSON array, never a JSON-stringified one."
|
|
703
|
+
};
|
|
704
|
+
for (const component of components) {
|
|
705
|
+
defs[`props_${component.name}`] = embeddableProps(toJsonSchema(component.props));
|
|
706
|
+
defs[`node_${component.name}`] = {
|
|
707
|
+
type: "object",
|
|
708
|
+
properties: {
|
|
709
|
+
type: {
|
|
710
|
+
type: "string",
|
|
711
|
+
enum: [
|
|
712
|
+
component.name
|
|
713
|
+
]
|
|
714
|
+
},
|
|
715
|
+
props: {
|
|
716
|
+
$ref: `#/$defs/props_${component.name}`
|
|
717
|
+
},
|
|
718
|
+
...component.children === true ? {
|
|
719
|
+
children: childrenSchema
|
|
720
|
+
} : {}
|
|
721
|
+
},
|
|
722
|
+
required: [
|
|
723
|
+
"type",
|
|
724
|
+
"props"
|
|
725
|
+
],
|
|
726
|
+
additionalProperties: false
|
|
727
|
+
};
|
|
728
|
+
}
|
|
729
|
+
defs.node = {
|
|
730
|
+
anyOf: components.map((component) => ({
|
|
731
|
+
$ref: `#/$defs/node_${component.name}`
|
|
732
|
+
}))
|
|
733
|
+
};
|
|
575
734
|
return {
|
|
576
735
|
type: "object",
|
|
577
736
|
properties: {
|
|
578
737
|
type: {
|
|
579
738
|
type: "string",
|
|
580
|
-
enum:
|
|
581
|
-
description: "Component name from the catalog"
|
|
739
|
+
enum: names,
|
|
740
|
+
description: "Component name from the catalog. A single component (no children) is a valid tree."
|
|
582
741
|
},
|
|
583
742
|
props: {
|
|
584
|
-
|
|
585
|
-
|
|
743
|
+
description: "The component's props: the schema of the component named by `type`",
|
|
744
|
+
anyOf: components.map((component) => ({
|
|
745
|
+
$ref: `#/$defs/props_${component.name}`
|
|
746
|
+
}))
|
|
586
747
|
},
|
|
587
748
|
children: {
|
|
588
|
-
|
|
589
|
-
items: {
|
|
590
|
-
$ref: "#"
|
|
591
|
-
},
|
|
749
|
+
...childrenSchema,
|
|
592
750
|
description: "Nested elements, only for components that take children. A literal JSON array, never a JSON-stringified one."
|
|
593
751
|
}
|
|
594
752
|
},
|
|
595
753
|
required: [
|
|
596
754
|
"type",
|
|
597
755
|
"props"
|
|
598
|
-
]
|
|
756
|
+
],
|
|
757
|
+
additionalProperties: false,
|
|
758
|
+
$defs: defs
|
|
599
759
|
};
|
|
600
760
|
}
|
|
601
761
|
__name(treeJsonSchema, "treeJsonSchema");
|
|
762
|
+
function embeddableProps(schema) {
|
|
763
|
+
if (schema === void 0 || typeof schema !== "object" || schema === null) {
|
|
764
|
+
return {
|
|
765
|
+
type: "object"
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
const references = /* @__PURE__ */ __name((value) => {
|
|
769
|
+
if (Array.isArray(value)) return value.some(references);
|
|
770
|
+
if (typeof value !== "object" || value === null) return false;
|
|
771
|
+
return Object.entries(value).some(([key, nested]) => key === "$ref" || key === "$defs" || key === "definitions" || references(nested));
|
|
772
|
+
}, "references");
|
|
773
|
+
if (references(schema)) return {
|
|
774
|
+
type: "object"
|
|
775
|
+
};
|
|
776
|
+
const { $schema: _schema, ...rest } = schema;
|
|
777
|
+
return rest;
|
|
778
|
+
}
|
|
779
|
+
__name(embeddableProps, "embeddableProps");
|
|
602
780
|
function treeToFlatSpec(root) {
|
|
603
781
|
const elements = {};
|
|
604
782
|
let next = 0;
|
|
@@ -869,9 +1047,9 @@ __name(prepareUiEmission, "prepareUiEmission");
|
|
|
869
1047
|
// src/genui/tools.ts
|
|
870
1048
|
var GENUI_SHOW_TOOL = "ui__show";
|
|
871
1049
|
function genuiTools(catalog, options = {}) {
|
|
872
|
-
const tools = options.mode === "
|
|
1050
|
+
const tools = options.mode === "per-component" ? flatComponents(catalog).map((component) => componentTool(catalog, component, options)) : [
|
|
873
1051
|
treeTool(catalog, options)
|
|
874
|
-
]
|
|
1052
|
+
];
|
|
875
1053
|
if (options.showTool !== void 0 && options.showTool !== false) {
|
|
876
1054
|
tools.push(showTool(catalog, options));
|
|
877
1055
|
}
|
|
@@ -982,6 +1160,9 @@ function treeTool(catalog, options) {
|
|
|
982
1160
|
})
|
|
983
1161
|
].join("\n"), "describeFor");
|
|
984
1162
|
const dynamic = options.resolveCatalog !== void 0;
|
|
1163
|
+
const treeSchemaOptions = options.treeSchema !== void 0 ? {
|
|
1164
|
+
schema: options.treeSchema
|
|
1165
|
+
} : {};
|
|
985
1166
|
const handler = {
|
|
986
1167
|
async execute(input, ctx) {
|
|
987
1168
|
const resolved = await catalogFor(catalog, options, scopeOf(ctx));
|
|
@@ -990,6 +1171,10 @@ function treeTool(catalog, options) {
|
|
|
990
1171
|
throw new Error(`invalid UI tree: ${formatIssues(result.issues)}`);
|
|
991
1172
|
}
|
|
992
1173
|
const root = result.value;
|
|
1174
|
+
const single = flatComponent(resolved, root.type);
|
|
1175
|
+
if (root.children === void 0 && single !== void 0) {
|
|
1176
|
+
return push(ctx, root.type, root.props, single.version);
|
|
1177
|
+
}
|
|
993
1178
|
return push(ctx, GENUI_TREE_COMPONENT, {
|
|
994
1179
|
root
|
|
995
1180
|
});
|
|
@@ -1000,7 +1185,36 @@ function treeTool(catalog, options) {
|
|
|
1000
1185
|
return {
|
|
1001
1186
|
available: resolved.modelComponents().length > 0,
|
|
1002
1187
|
description: describeFor(resolved),
|
|
1003
|
-
inputSchema: permissiveSchema(treeJsonSchema(resolved))
|
|
1188
|
+
inputSchema: permissiveSchema(treeJsonSchema(resolved, treeSchemaOptions))
|
|
1189
|
+
};
|
|
1190
|
+
};
|
|
1191
|
+
handler.previewInput = async (scope) => {
|
|
1192
|
+
const resolved = negotiateCatalog(await catalogFor(catalog, options, scopeOf(scope)), scope.uiCapabilities);
|
|
1193
|
+
const streaming = options.streaming ?? "complete";
|
|
1194
|
+
if (!resolved.modelComponents().some((each) => (each.streaming ?? streaming) === "partial")) {
|
|
1195
|
+
return void 0;
|
|
1196
|
+
}
|
|
1197
|
+
return {
|
|
1198
|
+
...options.streamingThrottleMs !== void 0 ? {
|
|
1199
|
+
throttleMs: options.streamingThrottleMs
|
|
1200
|
+
} : {},
|
|
1201
|
+
render(input) {
|
|
1202
|
+
const tree = partialTree(resolved, input, {
|
|
1203
|
+
streaming,
|
|
1204
|
+
...options.treeLimits !== void 0 ? {
|
|
1205
|
+
limits: options.treeLimits
|
|
1206
|
+
} : {}
|
|
1207
|
+
});
|
|
1208
|
+
if (tree === null) return null;
|
|
1209
|
+
if (tree.root === null) return void 0;
|
|
1210
|
+
return {
|
|
1211
|
+
component: GENUI_TREE_COMPONENT,
|
|
1212
|
+
props: {
|
|
1213
|
+
root: tree.root
|
|
1214
|
+
},
|
|
1215
|
+
version: 1
|
|
1216
|
+
};
|
|
1217
|
+
}
|
|
1004
1218
|
};
|
|
1005
1219
|
};
|
|
1006
1220
|
return {
|
|
@@ -1008,7 +1222,7 @@ function treeTool(catalog, options) {
|
|
|
1008
1222
|
name,
|
|
1009
1223
|
kind: "read",
|
|
1010
1224
|
description: describeFor(catalog),
|
|
1011
|
-
inputSchema: dynamic ? permissiveSchema(treeJsonSchema(catalog)) : asyncJsonStandardSchema(treeJsonSchema(catalog), async (value) => {
|
|
1225
|
+
inputSchema: dynamic ? permissiveSchema(treeJsonSchema(catalog, treeSchemaOptions)) : asyncJsonStandardSchema(treeJsonSchema(catalog, treeSchemaOptions), async (value) => {
|
|
1012
1226
|
const result = await validateTree(catalog, value, options.treeLimits, "input");
|
|
1013
1227
|
return result.ok ? {
|
|
1014
1228
|
value: result.value
|
|
@@ -1856,6 +2070,7 @@ export {
|
|
|
1856
2070
|
isStandardSchema,
|
|
1857
2071
|
jsonStandardSchema,
|
|
1858
2072
|
negotiateCatalog,
|
|
2073
|
+
partialTree,
|
|
1859
2074
|
prepareUiEmission,
|
|
1860
2075
|
showToolJsonSchema,
|
|
1861
2076
|
snapshotComponentPresentation,
|
|
@@ -1865,6 +2080,7 @@ export {
|
|
|
1865
2080
|
toSnakeCase,
|
|
1866
2081
|
toolNameFor,
|
|
1867
2082
|
treeJsonSchema,
|
|
2083
|
+
treeNodeId,
|
|
1868
2084
|
treeToFlatSpec,
|
|
1869
2085
|
treeToText,
|
|
1870
2086
|
validatePresentationBatch,
|