@june-ai/june-ui 0.2.7 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -2
- package/README.md +633 -400
- package/dist/{chunk-VFZI3SEL.js → chunk-27XM6EVX.js} +8 -8
- package/dist/chunk-3NVO336D.cjs +4314 -0
- package/dist/chunk-G6YPSE6J.cjs +520 -0
- package/dist/chunk-H26BMR5S.js +4314 -0
- package/dist/{document-engine-RKD5SLXR.js → document-engine-BUTK73DW.js} +1 -1
- package/dist/document-engine-GXZH2LNW.cjs +12 -0
- package/dist/entry-core.cjs +148 -0
- package/dist/entry-core.d.cts +1005 -0
- package/dist/entry-core.d.ts +1005 -0
- package/dist/entry-core.js +149 -0
- package/dist/index.cjs +171 -4244
- package/dist/index.d.cts +81 -525
- package/dist/index.d.ts +81 -525
- package/dist/index.js +156 -3604
- package/dist/june.css +94 -0
- package/docs/architecture.md +95 -0
- package/docs/component-registration.md +115 -0
- package/docs/custom-features.md +68 -0
- package/docs/streaming.md +76 -0
- package/docs/theming.md +65 -0
- package/docs/troubleshooting.md +59 -0
- package/package.json +19 -5
|
@@ -0,0 +1,1005 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ComponentProps as ComponentProps$1, Component, ReactNode, ErrorInfo, CSSProperties, ComponentType } from 'react';
|
|
3
|
+
import * as _openuidev_react_lang from '@openuidev/react-lang';
|
|
4
|
+
import { Renderer, DefinedComponent, ComponentRenderProps, PromptOptions, createLibrary, defineComponent as defineComponent$1, Library } from '@openuidev/react-lang';
|
|
5
|
+
import { z } from 'zod/v4';
|
|
6
|
+
import { $ZodObject } from 'zod/v4/core';
|
|
7
|
+
import * as _openuidev_lang_core from '@openuidev/lang-core';
|
|
8
|
+
|
|
9
|
+
/** CSS custom properties June reads. Any other `--name` is passed through as well. */
|
|
10
|
+
type JuneThemeToken = "--june-foreground" | "--june-muted" | "--june-border" | "--june-accent" | "--june-danger";
|
|
11
|
+
/** CSS variable values, e.g. { "--june-accent": "#0ea5e9" }. */
|
|
12
|
+
type JuneThemeVars = Partial<Record<JuneThemeToken, string>> & Record<string, string>;
|
|
13
|
+
/** Separate overrides per resolved mode. */
|
|
14
|
+
interface JuneThemeSet {
|
|
15
|
+
light?: JuneThemeVars;
|
|
16
|
+
dark?: JuneThemeVars;
|
|
17
|
+
}
|
|
18
|
+
/** `themeVars` accepts one set for both modes, or a set per mode. */
|
|
19
|
+
type JuneThemeInput = JuneThemeVars | JuneThemeSet;
|
|
20
|
+
type JuneThemeMode = "light" | "dark" | "system";
|
|
21
|
+
type JuneResolvedTheme = "light" | "dark";
|
|
22
|
+
|
|
23
|
+
/** Props of OpenUI's real Renderer. Derived, never hand-copied. */
|
|
24
|
+
type OpenUIRendererProps = ComponentProps$1<typeof Renderer>;
|
|
25
|
+
/** The library type OpenUI's Renderer accepts. */
|
|
26
|
+
type OpenUILibrary = OpenUIRendererProps["library"];
|
|
27
|
+
/** The event OpenUI passes to onAction. */
|
|
28
|
+
type OpenUIActionEvent = Parameters<NonNullable<OpenUIRendererProps["onAction"]>>[0];
|
|
29
|
+
|
|
30
|
+
type JuneErrorCode = "PARSE_ERROR" | "RENDER_ERROR" | "STREAM_ERROR" | "STREAM_ABORTED" | "STREAM_EMPTY" | "NETWORK_ERROR" | "ACTION_ERROR" | "ACTION_VALIDATION_ERROR" | "ACTION_REJECTED" | "LIBRARY_ERROR" | "DOCUMENT_ERROR" | "EXPORT_ERROR";
|
|
31
|
+
interface JuneErrorOptions {
|
|
32
|
+
cause?: unknown;
|
|
33
|
+
details?: unknown;
|
|
34
|
+
}
|
|
35
|
+
declare class JuneError extends Error {
|
|
36
|
+
readonly code: JuneErrorCode;
|
|
37
|
+
readonly details?: unknown;
|
|
38
|
+
constructor(code: JuneErrorCode, message: string, options?: JuneErrorOptions);
|
|
39
|
+
}
|
|
40
|
+
declare function isJuneError(value: unknown): value is JuneError;
|
|
41
|
+
declare function toJuneError(error: unknown, fallbackCode: JuneErrorCode, message?: string): JuneError;
|
|
42
|
+
|
|
43
|
+
/** Anything with a zod-style safeParse. No hard dependency on zod. */
|
|
44
|
+
interface SchemaLike<T> {
|
|
45
|
+
safeParse(data: unknown): {
|
|
46
|
+
success: true;
|
|
47
|
+
data: T;
|
|
48
|
+
} | {
|
|
49
|
+
success: false;
|
|
50
|
+
error: unknown;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
interface JuneActionContext {
|
|
54
|
+
name: string;
|
|
55
|
+
/** The raw OpenUI action event. */
|
|
56
|
+
event: unknown;
|
|
57
|
+
}
|
|
58
|
+
interface JuneActionDefinition<TPayload = unknown> {
|
|
59
|
+
description?: string;
|
|
60
|
+
/** Validates the payload before the handler runs. */
|
|
61
|
+
schema?: SchemaLike<TPayload>;
|
|
62
|
+
/** Sensitive actions are denied unless a confirm handler approves them. */
|
|
63
|
+
sensitive?: boolean;
|
|
64
|
+
/** Per-action confirmation; overrides the global confirmAction. */
|
|
65
|
+
confirm?: (args: {
|
|
66
|
+
name: string;
|
|
67
|
+
payload: TPayload;
|
|
68
|
+
description?: string;
|
|
69
|
+
}) => boolean | Promise<boolean>;
|
|
70
|
+
handler: (payload: TPayload, context: JuneActionContext) => void | Promise<void>;
|
|
71
|
+
}
|
|
72
|
+
type JuneAction<TPayload = unknown> = Readonly<JuneActionDefinition<TPayload>> & {
|
|
73
|
+
readonly __june: "action";
|
|
74
|
+
};
|
|
75
|
+
type JuneActionMap = Record<string, JuneAction<any>>;
|
|
76
|
+
declare function defineJuneAction<TPayload = unknown>(definition: JuneActionDefinition<TPayload>): JuneAction<TPayload>;
|
|
77
|
+
|
|
78
|
+
interface ParsedActionEvent {
|
|
79
|
+
name: string;
|
|
80
|
+
payload: unknown;
|
|
81
|
+
}
|
|
82
|
+
type ActionEventParser = (event: OpenUIActionEvent) => ParsedActionEvent | null;
|
|
83
|
+
type ConfirmAction = (args: {
|
|
84
|
+
name: string;
|
|
85
|
+
payload: unknown;
|
|
86
|
+
description?: string;
|
|
87
|
+
}) => boolean | Promise<boolean>;
|
|
88
|
+
type ActionOutcome = "handled" | "unhandled" | "rejected" | "failed";
|
|
89
|
+
/**
|
|
90
|
+
* BEST-EFFORT default: reads the action name from `type`/`name`/`action` and
|
|
91
|
+
* the payload from `params`/`payload`/`data`. Verify against OpenUI's actual
|
|
92
|
+
* action event type (see the .d.ts) and override with `parseActionEvent`
|
|
93
|
+
* if the shape differs. This is the only place that guesses the event shape.
|
|
94
|
+
*/
|
|
95
|
+
declare const defaultParseActionEvent: ActionEventParser;
|
|
96
|
+
interface RunActionOptions {
|
|
97
|
+
actions: JuneActionMap;
|
|
98
|
+
parseEvent?: ActionEventParser;
|
|
99
|
+
confirm?: ConfirmAction;
|
|
100
|
+
onError?: (error: JuneError) => void;
|
|
101
|
+
onUnhandled?: (event: OpenUIActionEvent) => void;
|
|
102
|
+
}
|
|
103
|
+
/** Looks up and runs a registered action. Never evaluates model-provided code. */
|
|
104
|
+
declare function runAction(event: OpenUIActionEvent, options: RunActionOptions): Promise<ActionOutcome>;
|
|
105
|
+
declare function createActionHandler(options: RunActionOptions): (event: OpenUIActionEvent) => void;
|
|
106
|
+
|
|
107
|
+
interface PendingUpdate {
|
|
108
|
+
json: DocJSON;
|
|
109
|
+
title: string;
|
|
110
|
+
/** AI changes merged in, with the user's version kept where both changed the same blocks. */
|
|
111
|
+
merged: DocJSON;
|
|
112
|
+
conflicts: number;
|
|
113
|
+
}
|
|
114
|
+
interface DocumentRecord {
|
|
115
|
+
id: string;
|
|
116
|
+
title: string;
|
|
117
|
+
documentType?: string;
|
|
118
|
+
status?: string;
|
|
119
|
+
/** What the user currently sees. */
|
|
120
|
+
json: DocJSON;
|
|
121
|
+
/** The last AI version that was accepted. Used as the merge base. */
|
|
122
|
+
baseJson: DocJSON;
|
|
123
|
+
baseTitle: string;
|
|
124
|
+
lastIncomingKey: string;
|
|
125
|
+
/** Increments whenever `json` changes. */
|
|
126
|
+
revision: number;
|
|
127
|
+
/** Which editor (or "external") produced the latest change. */
|
|
128
|
+
origin: string;
|
|
129
|
+
pending: PendingUpdate | null;
|
|
130
|
+
updatedAt: number;
|
|
131
|
+
}
|
|
132
|
+
interface IncomingDocument {
|
|
133
|
+
id: string;
|
|
134
|
+
title: string;
|
|
135
|
+
json: DocJSON;
|
|
136
|
+
documentType?: string;
|
|
137
|
+
status?: string;
|
|
138
|
+
}
|
|
139
|
+
type ReceiveOutcome = "created" | "unchanged" | "applied" | "merged" | "conflict";
|
|
140
|
+
type ResolveChoice = "merge" | "replace" | "keep";
|
|
141
|
+
interface DocumentStore {
|
|
142
|
+
get(id: string): DocumentRecord | undefined;
|
|
143
|
+
list(): DocumentRecord[];
|
|
144
|
+
subscribe(listener: () => void): () => void;
|
|
145
|
+
/** An AI version arrived. Applies it, merges it with user edits, or records a conflict. */
|
|
146
|
+
receive(incoming: IncomingDocument): ReceiveOutcome;
|
|
147
|
+
/** Seed or replace a document, for example from your database. */
|
|
148
|
+
hydrate(doc: IncomingDocument): void;
|
|
149
|
+
edit(id: string, json: DocJSON, origin: string): void;
|
|
150
|
+
setTitle(id: string, title: string): void;
|
|
151
|
+
resolve(id: string, choice: ResolveChoice): void;
|
|
152
|
+
remove(id: string): void;
|
|
153
|
+
}
|
|
154
|
+
declare function createDocumentStore(): DocumentStore;
|
|
155
|
+
/**
|
|
156
|
+
* Remembers content produced from the user's own edits (for example when JuneUI rewrites
|
|
157
|
+
* the OpenUI program). When that content comes back through the DocumentEditor props it is
|
|
158
|
+
* ignored instead of being treated as a new AI version.
|
|
159
|
+
*/
|
|
160
|
+
declare function rememberDocumentEcho(store: DocumentStore, id: string, content: string): void;
|
|
161
|
+
declare function isDocumentEcho(store: DocumentStore, id: string, content: string): boolean;
|
|
162
|
+
/** The shared in-memory store used when none is provided. Documents are keyed by documentId. */
|
|
163
|
+
declare function getDefaultDocumentStore(): DocumentStore;
|
|
164
|
+
|
|
165
|
+
/** Structural type of a Tiptap / ProseMirror JSON node. Dependency-free on purpose. */
|
|
166
|
+
interface DocNode {
|
|
167
|
+
type: string;
|
|
168
|
+
attrs?: Record<string, unknown>;
|
|
169
|
+
content?: DocNode[];
|
|
170
|
+
marks?: {
|
|
171
|
+
type: string;
|
|
172
|
+
attrs?: Record<string, unknown>;
|
|
173
|
+
}[];
|
|
174
|
+
text?: string;
|
|
175
|
+
}
|
|
176
|
+
/** Canonical document format: a Tiptap JSON document. */
|
|
177
|
+
interface DocJSON {
|
|
178
|
+
type: "doc";
|
|
179
|
+
content?: DocNode[];
|
|
180
|
+
}
|
|
181
|
+
type DocumentExportFormat = "html" | "markdown" | "txt" | "docx" | "pdf";
|
|
182
|
+
declare const ALL_EXPORT_FORMATS: readonly DocumentExportFormat[];
|
|
183
|
+
interface DocumentSnapshot {
|
|
184
|
+
documentId: string;
|
|
185
|
+
title: string;
|
|
186
|
+
documentType?: string;
|
|
187
|
+
status?: string;
|
|
188
|
+
json: DocJSON;
|
|
189
|
+
}
|
|
190
|
+
interface DocumentChange extends DocumentSnapshot {
|
|
191
|
+
/** user = typed in the editor, ai = new AI version applied, merge = AI merged with user edits, resolve = conflict resolved. */
|
|
192
|
+
source: "user" | "ai" | "merge" | "resolve";
|
|
193
|
+
}
|
|
194
|
+
interface DocumentSavePayload extends DocumentSnapshot {
|
|
195
|
+
html: string;
|
|
196
|
+
markdown: string;
|
|
197
|
+
}
|
|
198
|
+
interface DocumentExportEvent {
|
|
199
|
+
documentId: string;
|
|
200
|
+
format: string;
|
|
201
|
+
filename: string;
|
|
202
|
+
mimeType: string;
|
|
203
|
+
blob?: Blob;
|
|
204
|
+
text?: string;
|
|
205
|
+
/** True when the exporter delivered the file itself (for example the PDF print dialog). */
|
|
206
|
+
handled?: boolean;
|
|
207
|
+
}
|
|
208
|
+
interface DocumentConflict {
|
|
209
|
+
documentId: string;
|
|
210
|
+
title: string;
|
|
211
|
+
/** Number of regions that both the user and the assistant changed. */
|
|
212
|
+
conflicts: number;
|
|
213
|
+
}
|
|
214
|
+
interface JuneDocumentOptions {
|
|
215
|
+
/** Share one store across editors. Defaults to a global in-memory store, keyed by documentId. */
|
|
216
|
+
store?: DocumentStore;
|
|
217
|
+
/** Debounce for autosave in ms (default 1500). 0 or less disables autosave. */
|
|
218
|
+
autosaveDelay?: number;
|
|
219
|
+
onDocumentChange?: (change: DocumentChange) => void;
|
|
220
|
+
/** Persist the document. Called by autosave, the Save button and Ctrl/Cmd+S. */
|
|
221
|
+
onSave?: (payload: DocumentSavePayload) => void | Promise<void>;
|
|
222
|
+
onExport?: (event: DocumentExportEvent) => void;
|
|
223
|
+
onDocumentReady?: (snapshot: DocumentSnapshot) => void;
|
|
224
|
+
onConflict?: (conflict: DocumentConflict) => void;
|
|
225
|
+
onError?: (error: JuneError) => void;
|
|
226
|
+
}
|
|
227
|
+
interface DocumentEditorProps {
|
|
228
|
+
documentId: string;
|
|
229
|
+
title?: string;
|
|
230
|
+
/** Markdown, a Tiptap JSON string, or a Tiptap JSON object. */
|
|
231
|
+
content?: string | DocJSON;
|
|
232
|
+
documentType?: string;
|
|
233
|
+
/** Default "draft". Drafts show an "AI draft" badge. */
|
|
234
|
+
status?: string;
|
|
235
|
+
editable?: boolean;
|
|
236
|
+
exportFormats?: string[];
|
|
237
|
+
/** "auto" follows the June theme context. */
|
|
238
|
+
theme?: "auto" | "light" | "dark";
|
|
239
|
+
className?: string;
|
|
240
|
+
/** Show the drafting placeholder instead of the editor (use while content is streaming). */
|
|
241
|
+
generating?: boolean;
|
|
242
|
+
/** Callbacks and store. Merged over the values provided through JuneUI's `documents` prop. */
|
|
243
|
+
options?: JuneDocumentOptions;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
interface ResponseChangeInfo {
|
|
247
|
+
documentId: string;
|
|
248
|
+
title: string;
|
|
249
|
+
/** The document body written into the program, as Markdown. */
|
|
250
|
+
markdown: string;
|
|
251
|
+
source: DocumentChange["source"];
|
|
252
|
+
}
|
|
253
|
+
interface DocumentBridgeOptions {
|
|
254
|
+
/** Callbacks and store given by the app. */
|
|
255
|
+
documents?: JuneDocumentOptions;
|
|
256
|
+
/** The current OpenUI program (the renderer's `response`). */
|
|
257
|
+
response: string | null;
|
|
258
|
+
/** Receives the program rewritten with the user's document edits. */
|
|
259
|
+
onResponseChange?: (response: string, change: ResponseChangeInfo) => void;
|
|
260
|
+
/** Debounce for onResponseChange in ms (default 300). */
|
|
261
|
+
responseChangeDelay?: number;
|
|
262
|
+
/** Document and sync errors. */
|
|
263
|
+
onJuneError?: (error: JuneError) => void;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Connects document editors to the response they came from. Returns the options to provide
|
|
267
|
+
* through `JuneDocumentContext`: the app's callbacks, plus a debounced write-back of user edits
|
|
268
|
+
* (body as Markdown, and title) into the matching `DocumentEditor(...)` call of the program.
|
|
269
|
+
*
|
|
270
|
+
* Kept in the document feature so the renderer knows nothing about documents.
|
|
271
|
+
*/
|
|
272
|
+
declare function useDocumentBridge(options: DocumentBridgeOptions): JuneDocumentOptions;
|
|
273
|
+
|
|
274
|
+
interface FallbackArgs {
|
|
275
|
+
error: Error;
|
|
276
|
+
reset: () => void;
|
|
277
|
+
}
|
|
278
|
+
interface JuneErrorBoundaryProps {
|
|
279
|
+
children?: ReactNode;
|
|
280
|
+
fallback?: ReactNode | ((args: FallbackArgs) => ReactNode);
|
|
281
|
+
onError?: (error: Error, info: ErrorInfo) => void;
|
|
282
|
+
/** When any value changes, a caught error is cleared and children re-render. */
|
|
283
|
+
resetKeys?: readonly unknown[];
|
|
284
|
+
}
|
|
285
|
+
interface State {
|
|
286
|
+
error: Error | null;
|
|
287
|
+
}
|
|
288
|
+
declare class JuneErrorBoundary extends Component<JuneErrorBoundaryProps, State> {
|
|
289
|
+
state: State;
|
|
290
|
+
static getDerivedStateFromError(error: Error): State;
|
|
291
|
+
componentDidCatch(error: Error, info: ErrorInfo): void;
|
|
292
|
+
componentDidUpdate(prev: JuneErrorBoundaryProps): void;
|
|
293
|
+
reset: () => void;
|
|
294
|
+
render(): ReactNode;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/** How prose around the OpenUI program is drawn. */
|
|
298
|
+
type TextFormat = "plain" | "markdown";
|
|
299
|
+
type JuneRendererProps = Omit<OpenUIRendererProps, "library" | "response" | "isStreaming" | "onAction" | "onError" | "className" | "style"> & {
|
|
300
|
+
library: OpenUILibrary;
|
|
301
|
+
/** Accumulated model output. OpenUI does the incremental parsing. */
|
|
302
|
+
response: string | null;
|
|
303
|
+
isStreaming?: boolean;
|
|
304
|
+
/** Allow prose around OpenUI statements (default true). */
|
|
305
|
+
mixedContent?: boolean;
|
|
306
|
+
/**
|
|
307
|
+
* "plain" (default): each prose paragraph is a `<p class="june-text">`.
|
|
308
|
+
* "markdown": prose keeps its line breaks and code blocks and is drawn as Markdown.
|
|
309
|
+
*/
|
|
310
|
+
textFormat?: TextFormat;
|
|
311
|
+
/** Custom renderer for prose segments. Overrides `textFormat`'s default drawing. */
|
|
312
|
+
renderText?: (text: string, index: number) => ReactNode;
|
|
313
|
+
/**
|
|
314
|
+
* Rewrite common model mistakes after streaming ends (default true):
|
|
315
|
+
* Grid and shorthand Card calls, and charts or tables left off root.
|
|
316
|
+
* Set false to hand the program to OpenUI unchanged.
|
|
317
|
+
*/
|
|
318
|
+
repair?: boolean;
|
|
319
|
+
/** Omit to inherit the host app's look. "light" | "dark" | "system" opt in to June's colors. */
|
|
320
|
+
theme?: JuneThemeMode;
|
|
321
|
+
/** CSS variable overrides: one map, or `{ light, dark }`. */
|
|
322
|
+
themeVars?: JuneThemeInput;
|
|
323
|
+
className?: string;
|
|
324
|
+
style?: CSSProperties;
|
|
325
|
+
actions?: JuneActionMap;
|
|
326
|
+
confirmAction?: ConfirmAction;
|
|
327
|
+
parseActionEvent?: ActionEventParser;
|
|
328
|
+
/** Raw OpenUI action event (called for every action, before June actions). */
|
|
329
|
+
onAction?: (event: OpenUIActionEvent) => void;
|
|
330
|
+
/** Raw OpenUI errors (called with [] when they resolve). */
|
|
331
|
+
onError?: (errors: unknown[]) => void;
|
|
332
|
+
/** Structured errors: parse, render, action, document and export failures. */
|
|
333
|
+
onJuneError?: (error: JuneError) => void;
|
|
334
|
+
/** Document editor callbacks and store. Memoize this object. */
|
|
335
|
+
documents?: JuneDocumentOptions;
|
|
336
|
+
/**
|
|
337
|
+
* Called with an updated OpenUI program when the user edits a document (body or title).
|
|
338
|
+
* The matching `DocumentEditor(id, title, content)` call is rewritten with the new title and
|
|
339
|
+
* the body as Markdown; nothing else in the program changes. Store the value and pass it back
|
|
340
|
+
* as `response` to keep your program (and any "OpenUI Lang" view) in sync with the editor.
|
|
341
|
+
*/
|
|
342
|
+
onResponseChange?: (response: string, change: ResponseChangeInfo) => void;
|
|
343
|
+
/** Debounce for onResponseChange in ms (default 300). */
|
|
344
|
+
responseChangeDelay?: number;
|
|
345
|
+
loadingFallback?: ReactNode;
|
|
346
|
+
emptyFallback?: ReactNode;
|
|
347
|
+
errorFallback?: ReactNode | ((args: FallbackArgs) => ReactNode);
|
|
348
|
+
resetKeys?: readonly unknown[];
|
|
349
|
+
};
|
|
350
|
+
/**
|
|
351
|
+
* Renders a model response: prose segments plus one OpenUI program, inside June's theme root,
|
|
352
|
+
* runtime context, document bridge and error boundary. Requires an explicit `library`.
|
|
353
|
+
*/
|
|
354
|
+
declare function JuneRenderer(props: JuneRendererProps): react.JSX.Element;
|
|
355
|
+
|
|
356
|
+
interface MarkdownTextProps {
|
|
357
|
+
text: string;
|
|
358
|
+
className?: string;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Renders a prose segment as Markdown with OpenUI's MarkDownRenderer (react-markdown: no raw HTML).
|
|
362
|
+
* Until it loads, the text shows as a plain paragraph.
|
|
363
|
+
*/
|
|
364
|
+
declare function MarkdownText({ text, className }: MarkdownTextProps): react.JSX.Element;
|
|
365
|
+
|
|
366
|
+
interface SplitResponse {
|
|
367
|
+
/** Prose before the first OpenUI statement. */
|
|
368
|
+
before: string[];
|
|
369
|
+
/** All OpenUI statements joined, so one Renderer resolves every reference. */
|
|
370
|
+
ui: string;
|
|
371
|
+
/** Prose after (or between) statements. */
|
|
372
|
+
after: string[];
|
|
373
|
+
/** True when the input is already pure OpenUI Lang (no prose, no code fences). */
|
|
374
|
+
pure: boolean;
|
|
375
|
+
}
|
|
376
|
+
interface SplitOptions {
|
|
377
|
+
/** Hold back a trailing half-typed identifier so it doesn't flash as prose. */
|
|
378
|
+
streaming?: boolean;
|
|
379
|
+
/**
|
|
380
|
+
* Keep prose as Markdown (default false):
|
|
381
|
+
* - lines inside a paragraph are joined with "\n" instead of " ";
|
|
382
|
+
* - fenced code blocks tagged with another language (```python) are kept whole, as prose.
|
|
383
|
+
* Fences without a language, or tagged `openui` / `openui-lang`, still hold OpenUI Lang.
|
|
384
|
+
*/
|
|
385
|
+
markdown?: boolean;
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Separates model prose from OpenUI Lang statements. Multi-line statements,
|
|
389
|
+
* `$state` variables and ``` fences are handled. This does not parse OpenUI
|
|
390
|
+
* Lang; OpenUI's Renderer still does all parsing. Pure function, no React.
|
|
391
|
+
*/
|
|
392
|
+
declare function splitResponse(source: string, options?: SplitOptions): SplitResponse;
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Rewrites OpenUI programs the library cannot paint, then hands the result to
|
|
396
|
+
* the existing renderer. A program that is already valid is returned unchanged.
|
|
397
|
+
*
|
|
398
|
+
* Two cases currently produce an empty assistant bubble:
|
|
399
|
+
* - `Grid(...)` and `Card("title", "value")` are not components in the library.
|
|
400
|
+
* - A bar chart, line chart, or table that is never referenced from `root` is
|
|
401
|
+
* dropped, so mixed replies render only the root node.
|
|
402
|
+
*/
|
|
403
|
+
declare function normalizeProgram(source: string): string;
|
|
404
|
+
|
|
405
|
+
interface MixedContentOptions {
|
|
406
|
+
/** Split prose from OpenUI statements (default true). False passes the response through. */
|
|
407
|
+
mixedContent?: boolean;
|
|
408
|
+
isStreaming?: boolean;
|
|
409
|
+
/** Rewrite common model mistakes once streaming ends (default true). */
|
|
410
|
+
repair?: boolean;
|
|
411
|
+
/** Keep prose as Markdown: line breaks and foreign code fences survive (default false). */
|
|
412
|
+
markdown?: boolean;
|
|
413
|
+
}
|
|
414
|
+
interface MixedContent {
|
|
415
|
+
/** Prose before the OpenUI program. */
|
|
416
|
+
before: string[];
|
|
417
|
+
/** The OpenUI program to hand to the renderer (repaired when allowed), or null/"" when none. */
|
|
418
|
+
ui: string | null;
|
|
419
|
+
/** Prose after (or between) statements. */
|
|
420
|
+
after: string[];
|
|
421
|
+
hasUi: boolean;
|
|
422
|
+
hasText: boolean;
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Turns an accumulated model response into prose segments and one OpenUI program.
|
|
426
|
+
* Pure and synchronous: the renderer memoizes it per response.
|
|
427
|
+
*/
|
|
428
|
+
declare function resolveMixedContent(response: string | null, options?: MixedContentOptions): MixedContent;
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Extra information June keeps next to a component. OpenUI ignores it.
|
|
432
|
+
* `metadata` is free-form: use it for docs, tooling or feature flags.
|
|
433
|
+
*/
|
|
434
|
+
interface JuneComponentMeta {
|
|
435
|
+
/**
|
|
436
|
+
* Parent components whose child list should accept this one, as OpenUI `extend` slots:
|
|
437
|
+
* `"Card"` (parent with a single slot) or `"Card.children"`. Lets the model place the
|
|
438
|
+
* component inside those parents, and lists it there in the generated prompt.
|
|
439
|
+
*/
|
|
440
|
+
slots?: readonly string[];
|
|
441
|
+
metadata?: Readonly<Record<string, unknown>>;
|
|
442
|
+
}
|
|
443
|
+
/** Props given to a `render` function: OpenUI's renderer props (`props`, `renderNode`, `statementId`). */
|
|
444
|
+
type JuneRenderProps<P> = ComponentRenderProps<P>;
|
|
445
|
+
interface DefineComponentBase<S extends $ZodObject> extends JuneComponentMeta {
|
|
446
|
+
/** Name used in OpenUI Lang, e.g. `card = CustomCard("Title", "Body")`. PascalCase. */
|
|
447
|
+
name: string;
|
|
448
|
+
/**
|
|
449
|
+
* What the component is for. Shown to the model in the generated system prompt,
|
|
450
|
+
* so write it for the model: when to use it and what the arguments mean.
|
|
451
|
+
*/
|
|
452
|
+
description: string;
|
|
453
|
+
/**
|
|
454
|
+
* Zod object schema for the props. Key order is the positional argument order in
|
|
455
|
+
* OpenUI Lang. Use `import { z } from "zod/v4"` (or `"zod"` on Zod 4).
|
|
456
|
+
*/
|
|
457
|
+
schema: S;
|
|
458
|
+
}
|
|
459
|
+
/** A plain React component: receives the validated props directly. */
|
|
460
|
+
interface WithComponent<S extends $ZodObject> extends DefineComponentBase<S> {
|
|
461
|
+
component: ComponentType<z.infer<S>>;
|
|
462
|
+
render?: never;
|
|
463
|
+
}
|
|
464
|
+
/** Full OpenUI control: receives `{ props, renderNode, statementId }` (needed to draw child nodes). */
|
|
465
|
+
interface WithRender<S extends $ZodObject> extends DefineComponentBase<S> {
|
|
466
|
+
render: (args: JuneRenderProps<z.infer<S>>) => ReactNode;
|
|
467
|
+
component?: never;
|
|
468
|
+
}
|
|
469
|
+
type DefineComponentOptions<S extends $ZodObject> = WithComponent<S> | WithRender<S>;
|
|
470
|
+
/**
|
|
471
|
+
* A component ready for the registry. It *is* an OpenUI `DefinedComponent`, so it can also be
|
|
472
|
+
* passed straight to OpenUI's `createLibrary` or `library.extend`.
|
|
473
|
+
*/
|
|
474
|
+
type JuneComponent<S extends $ZodObject = $ZodObject> = DefinedComponent<S> & {
|
|
475
|
+
readonly june: JuneComponentMeta;
|
|
476
|
+
};
|
|
477
|
+
/** Any component the registry accepts: June's or one made with OpenUI's `defineComponent`. */
|
|
478
|
+
type AnyComponentDefinition = DefinedComponent<any>;
|
|
479
|
+
/** Infers the props type of a component definition. */
|
|
480
|
+
type ComponentProps<C> = C extends DefinedComponent<infer S> ? z.infer<S> : never;
|
|
481
|
+
/** Checks the parts of a definition OpenUI needs. Throws a `JuneError("LIBRARY_ERROR")` with a fix. */
|
|
482
|
+
declare function validateComponentDefinition(definition: {
|
|
483
|
+
name?: unknown;
|
|
484
|
+
description?: unknown;
|
|
485
|
+
schema?: unknown;
|
|
486
|
+
component?: unknown;
|
|
487
|
+
render?: unknown;
|
|
488
|
+
}): void;
|
|
489
|
+
/**
|
|
490
|
+
* Defines a component the model can use in OpenUI Lang.
|
|
491
|
+
*
|
|
492
|
+
* ```tsx
|
|
493
|
+
* const CustomCard = defineComponent({
|
|
494
|
+
* name: "CustomCard",
|
|
495
|
+
* description: "A card with a title and a description.",
|
|
496
|
+
* schema: z.object({ title: z.string(), description: z.string() }),
|
|
497
|
+
* component: ({ title, description }) => <section><h3>{title}</h3><p>{description}</p></section>,
|
|
498
|
+
* });
|
|
499
|
+
* ```
|
|
500
|
+
*
|
|
501
|
+
* OpenUI validates the model's arguments against `schema` before your component renders.
|
|
502
|
+
*/
|
|
503
|
+
declare function defineComponent<S extends $ZodObject>(options: DefineComponentOptions<S>): JuneComponent<S>;
|
|
504
|
+
/** True when the value was made by June's `defineComponent`. */
|
|
505
|
+
declare function isJuneComponent(value: unknown): value is JuneComponent;
|
|
506
|
+
|
|
507
|
+
interface RegisterOptions {
|
|
508
|
+
/** Replace a component that already exists (built-in or registered). Default false. */
|
|
509
|
+
override?: boolean;
|
|
510
|
+
}
|
|
511
|
+
interface ComponentRegistryOptions {
|
|
512
|
+
/**
|
|
513
|
+
* Library to extend, e.g. June's default library or OpenUI's `openuiLibrary`.
|
|
514
|
+
* Omit to start empty (then set `root`).
|
|
515
|
+
*/
|
|
516
|
+
base?: OpenUILibrary;
|
|
517
|
+
/** Root component name. Only used when there is no `base`. */
|
|
518
|
+
root?: string;
|
|
519
|
+
/** Components to add. Names must be new. */
|
|
520
|
+
components?: readonly AnyComponentDefinition[];
|
|
521
|
+
/** Components that replace existing ones with the same name. */
|
|
522
|
+
overrides?: readonly AnyComponentDefinition[];
|
|
523
|
+
/** Names to remove from `base`. */
|
|
524
|
+
remove?: readonly string[];
|
|
525
|
+
}
|
|
526
|
+
type Listener = () => void;
|
|
527
|
+
/**
|
|
528
|
+
* The set of components the OpenUI renderer can draw.
|
|
529
|
+
*
|
|
530
|
+
* Built on OpenUI's own `library.extend` (add / override / remove), so the result is a normal
|
|
531
|
+
* OpenUI library: pass `registry.library` anywhere a library is expected, and call
|
|
532
|
+
* `registry.prompt()` to generate the model's system prompt from the same components.
|
|
533
|
+
*
|
|
534
|
+
* Changes are validated immediately: a bad registration throws `JuneError("LIBRARY_ERROR")`
|
|
535
|
+
* and leaves the registry unchanged. `library` keeps the same reference until something changes,
|
|
536
|
+
* which matters because OpenUI memoizes parsing by library identity.
|
|
537
|
+
*/
|
|
538
|
+
declare class ComponentRegistry {
|
|
539
|
+
private readonly base;
|
|
540
|
+
private readonly root;
|
|
541
|
+
private added;
|
|
542
|
+
private overridden;
|
|
543
|
+
private removed;
|
|
544
|
+
private cached;
|
|
545
|
+
private listeners;
|
|
546
|
+
constructor(options?: ComponentRegistryOptions);
|
|
547
|
+
/** The OpenUI library for the current set of components. Stable until the registry changes. */
|
|
548
|
+
get library(): OpenUILibrary;
|
|
549
|
+
/** Adds one or more components. Set `override: true` to replace an existing name. */
|
|
550
|
+
register(components: AnyComponentDefinition | readonly AnyComponentDefinition[], options?: RegisterOptions): this;
|
|
551
|
+
/** Replaces existing components by name (same as `register(c, { override: true })`). */
|
|
552
|
+
override(components: AnyComponentDefinition | readonly AnyComponentDefinition[]): this;
|
|
553
|
+
/**
|
|
554
|
+
* Removes a component. A registered component is dropped; an overridden built-in goes back to
|
|
555
|
+
* the original; a built-in is removed from the library.
|
|
556
|
+
*/
|
|
557
|
+
unregister(name: string): this;
|
|
558
|
+
/** Drops every change and returns to the base library. */
|
|
559
|
+
reset(): this;
|
|
560
|
+
has(name: string): boolean;
|
|
561
|
+
get(name: string): AnyComponentDefinition | undefined;
|
|
562
|
+
/** June metadata (`slots`, `metadata`) of a component, when it was made with June's defineComponent. */
|
|
563
|
+
getMeta(name: string): JuneComponentMeta | undefined;
|
|
564
|
+
/** Every component name in the library. */
|
|
565
|
+
names(): string[];
|
|
566
|
+
/** Names added or overridden through this registry. */
|
|
567
|
+
customNames(): string[];
|
|
568
|
+
/** The system prompt for these components (OpenUI's `library.prompt`). Usually called on the server. */
|
|
569
|
+
prompt(options?: PromptOptions): string;
|
|
570
|
+
/** For `useSyncExternalStore`: called after every change. */
|
|
571
|
+
subscribe: (listener: Listener) => (() => void);
|
|
572
|
+
getSnapshot: () => OpenUILibrary;
|
|
573
|
+
private exists;
|
|
574
|
+
private applyRegister;
|
|
575
|
+
private applyRemove;
|
|
576
|
+
/** Applies changes atomically: on error the previous state is restored and the error rethrown. */
|
|
577
|
+
private transaction;
|
|
578
|
+
private changed;
|
|
579
|
+
private notify;
|
|
580
|
+
private build;
|
|
581
|
+
private rebuild;
|
|
582
|
+
}
|
|
583
|
+
/** Creates a component registry. See {@link ComponentRegistry}. */
|
|
584
|
+
declare function createComponentRegistry(options?: ComponentRegistryOptions): ComponentRegistry;
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Returns the registry's current OpenUI library and re-renders when components are registered,
|
|
588
|
+
* overridden or removed at runtime.
|
|
589
|
+
*/
|
|
590
|
+
declare function useRegistryLibrary(registry: ComponentRegistry): OpenUILibrary;
|
|
591
|
+
|
|
592
|
+
/** Re-export of OpenUI's component definer under a June name. */
|
|
593
|
+
declare const defineJuneComponent: typeof defineComponent$1;
|
|
594
|
+
type OpenUILibraryOptions = Parameters<typeof createLibrary>[0];
|
|
595
|
+
type JuneLibraryOptions = OpenUILibraryOptions & {
|
|
596
|
+
/** If set, only these component names are kept (allowlist). */
|
|
597
|
+
allow?: readonly string[];
|
|
598
|
+
/** Component names to remove (applied after allow). */
|
|
599
|
+
deny?: readonly string[];
|
|
600
|
+
};
|
|
601
|
+
/**
|
|
602
|
+
* Thin wrapper over OpenUI's createLibrary that validates names and
|
|
603
|
+
* supports allow/deny lists. Create the library once at module scope so its
|
|
604
|
+
* reference stays stable.
|
|
605
|
+
*/
|
|
606
|
+
declare function createJuneLibrary(options: JuneLibraryOptions): ReturnType<typeof createLibrary>;
|
|
607
|
+
|
|
608
|
+
interface JuneContextValue {
|
|
609
|
+
mode: JuneThemeMode;
|
|
610
|
+
theme: JuneResolvedTheme;
|
|
611
|
+
}
|
|
612
|
+
/** `{ mode, theme }` of the nearest June root; `theme` is the resolved "light" or "dark". */
|
|
613
|
+
declare function useJuneTheme(): JuneContextValue;
|
|
614
|
+
|
|
615
|
+
interface JuneRuntimeValue {
|
|
616
|
+
/** True while the response is still streaming. Custom components use it to defer heavy work. */
|
|
617
|
+
isStreaming: boolean;
|
|
618
|
+
}
|
|
619
|
+
declare const JuneRuntimeContext: react.Context<JuneRuntimeValue>;
|
|
620
|
+
/** Runtime state of the surrounding June renderer (for custom components). */
|
|
621
|
+
declare function useJuneRuntime(): JuneRuntimeValue;
|
|
622
|
+
|
|
623
|
+
/** Resolves "system" to the OS preference and follows its changes. */
|
|
624
|
+
declare function useResolvedTheme(mode: JuneThemeMode): JuneResolvedTheme;
|
|
625
|
+
interface JuneThemeProviderProps {
|
|
626
|
+
/**
|
|
627
|
+
* Omit to inherit the host app's look: no colors, fonts or color-scheme are applied.
|
|
628
|
+
* "light" | "dark" | "system" opt in to June's text colors.
|
|
629
|
+
*/
|
|
630
|
+
mode?: JuneThemeMode;
|
|
631
|
+
/**
|
|
632
|
+
* CSS variable overrides: one map for both modes ({ "--june-accent": "#0ea5e9" }),
|
|
633
|
+
* or one per mode ({ light: {...}, dark: {...} }).
|
|
634
|
+
*/
|
|
635
|
+
vars?: JuneThemeInput;
|
|
636
|
+
className?: string;
|
|
637
|
+
style?: CSSProperties;
|
|
638
|
+
children?: ReactNode;
|
|
639
|
+
}
|
|
640
|
+
/** The `.june-ui-root` element: applies theme variables and provides `useJuneTheme()`. */
|
|
641
|
+
declare function JuneThemeProvider({ mode, vars, className, style, children }: JuneThemeProviderProps): react.JSX.Element;
|
|
642
|
+
|
|
643
|
+
/** Colors only. June never sets fonts, radii or backgrounds. */
|
|
644
|
+
declare const lightTheme: JuneThemeVars;
|
|
645
|
+
|
|
646
|
+
declare const darkTheme: JuneThemeVars;
|
|
647
|
+
|
|
648
|
+
/** True when `input` is `{ light?, dark? }` rather than a flat variable map. */
|
|
649
|
+
declare function isThemeSet(input: JuneThemeInput | undefined): input is JuneThemeSet;
|
|
650
|
+
/** The variables for one resolved mode. */
|
|
651
|
+
declare function resolveThemeVars(input: JuneThemeInput | undefined, mode: JuneResolvedTheme): JuneThemeVars | undefined;
|
|
652
|
+
/**
|
|
653
|
+
* Builds a full theme from June's palettes plus your overrides. Pass the result as `themeVars`.
|
|
654
|
+
*
|
|
655
|
+
* ```ts
|
|
656
|
+
* const brand = createTheme({ light: { "--june-accent": "#0ea5e9" }, dark: { "--june-accent": "#38bdf8" } });
|
|
657
|
+
* <JuneUI theme="system" themeVars={brand} ... />
|
|
658
|
+
* ```
|
|
659
|
+
*/
|
|
660
|
+
declare function createTheme(overrides?: JuneThemeSet): Required<JuneThemeSet>;
|
|
661
|
+
|
|
662
|
+
type StreamStatus = "idle" | "streaming" | "done" | "error" | "aborted";
|
|
663
|
+
type StreamChunk = string | Uint8Array;
|
|
664
|
+
type StreamSource = ReadableStream<Uint8Array> | ReadableStream<string> | AsyncIterable<StreamChunk>;
|
|
665
|
+
interface ConsumeStreamOptions {
|
|
666
|
+
signal?: AbortSignal;
|
|
667
|
+
/** Called per decoded chunk with the new text and the full text so far. */
|
|
668
|
+
onText?: (delta: string, accumulated: string) => void;
|
|
669
|
+
/** Resolve with "" instead of throwing STREAM_EMPTY. */
|
|
670
|
+
allowEmpty?: boolean;
|
|
671
|
+
}
|
|
672
|
+
interface SseOptions {
|
|
673
|
+
/** Map an SSE frame to text. Return null/"" to skip. Default: the raw data. */
|
|
674
|
+
extract?: (data: string, event: string) => string | null | undefined;
|
|
675
|
+
/** Frame data that ends the stream. Default "[DONE]". Use null to disable. */
|
|
676
|
+
doneSentinel?: string | null;
|
|
677
|
+
}
|
|
678
|
+
type FetchStreamOptions = RequestInit & {
|
|
679
|
+
sse?: boolean | SseOptions;
|
|
680
|
+
};
|
|
681
|
+
interface JuneStreamState {
|
|
682
|
+
response: string;
|
|
683
|
+
isStreaming: boolean;
|
|
684
|
+
status: StreamStatus;
|
|
685
|
+
error: JuneError | null;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
type StreamStarter = StreamSource | ((signal: AbortSignal) => StreamSource | Promise<StreamSource>);
|
|
689
|
+
interface UseJuneStreamOptions {
|
|
690
|
+
allowEmpty?: boolean;
|
|
691
|
+
onError?: (error: JuneError) => void;
|
|
692
|
+
onComplete?: (text: string) => void;
|
|
693
|
+
}
|
|
694
|
+
interface UseJuneStreamResult extends JuneStreamState {
|
|
695
|
+
start: (source: StreamStarter) => Promise<string | null>;
|
|
696
|
+
startFetch: (input: RequestInfo | URL, options?: FetchStreamOptions) => Promise<string | null>;
|
|
697
|
+
abort: () => void;
|
|
698
|
+
reset: () => void;
|
|
699
|
+
}
|
|
700
|
+
/**
|
|
701
|
+
* Accumulates a stream into `response`, with state updates coalesced to
|
|
702
|
+
* roughly one per frame, abort support, and cleanup on unmount.
|
|
703
|
+
* Starting a new stream cancels the previous one.
|
|
704
|
+
*/
|
|
705
|
+
declare function useJuneStream(options?: UseJuneStreamOptions): UseJuneStreamResult;
|
|
706
|
+
|
|
707
|
+
declare function toAsyncIterable(source: StreamSource, signal?: AbortSignal): AsyncIterable<StreamChunk>;
|
|
708
|
+
/**
|
|
709
|
+
* Reads a stream to completion, decoding bytes safely (multi-byte characters
|
|
710
|
+
* split across chunks are handled) and accumulating text. Does not parse
|
|
711
|
+
* OpenUI Lang; parsing stays with OpenUI's Renderer.
|
|
712
|
+
*/
|
|
713
|
+
declare function consumeStream(source: StreamSource, options?: ConsumeStreamOptions): Promise<string>;
|
|
714
|
+
|
|
715
|
+
/** fetch() wrapper that returns a StreamSource, with structured errors. */
|
|
716
|
+
declare function fetchStream(input: RequestInfo | URL, options?: FetchStreamOptions): Promise<StreamSource>;
|
|
717
|
+
|
|
718
|
+
/** Converts a Server-Sent Events byte/text stream into an async iterable of text. */
|
|
719
|
+
declare function sseToText(source: StreamSource, options?: SseOptions & {
|
|
720
|
+
signal?: AbortSignal;
|
|
721
|
+
}): AsyncGenerator<string, void, undefined>;
|
|
722
|
+
/**
|
|
723
|
+
* Builds an `extract` function that reads a string at a dotted JSON path,
|
|
724
|
+
* e.g. jsonFieldExtractor("choices.0.delta.content").
|
|
725
|
+
*/
|
|
726
|
+
declare function jsonFieldExtractor(path: string): (data: string) => string | null;
|
|
727
|
+
|
|
728
|
+
declare const DOCUMENT_COMPONENT_DESCRIPTION = "Custom component. An editable document. DocumentEditor(documentId, title, content, documentType?, status?, editable?, exportFormats?). Place it in the root container (Card or Stack). \"content\" is the full document body as one Markdown string. Reuse documentId when revising the same document. Use it only when the user asks to create or revise a document.";
|
|
729
|
+
/** Standalone editor. While a June response is still streaming, shows a placeholder instead of mounting Tiptap. */
|
|
730
|
+
declare function DocumentEditor(props: DocumentEditorProps): react.JSX.Element;
|
|
731
|
+
declare const JuneDocumentEditorComponent: _openuidev_react_lang.DefinedComponent<z.ZodObject<{
|
|
732
|
+
documentId: z.ZodString;
|
|
733
|
+
title: z.ZodString;
|
|
734
|
+
content: z.ZodString;
|
|
735
|
+
documentType: z.ZodOptional<z.ZodString>;
|
|
736
|
+
status: z.ZodOptional<z.ZodString>;
|
|
737
|
+
editable: z.ZodOptional<z.ZodBoolean>;
|
|
738
|
+
exportFormats: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
739
|
+
}, z.core.$strip>>;
|
|
740
|
+
type Extendable = Library & {
|
|
741
|
+
extend: NonNullable<Library["extend"]>;
|
|
742
|
+
};
|
|
743
|
+
/**
|
|
744
|
+
* Returns a library that contains every component of `library` plus DocumentEditor.
|
|
745
|
+
* On Zod 4.1+ it also joins Card's children. Zod 3.25 (what the app bundles) has no
|
|
746
|
+
* `util.mergeDefs`, and OpenUI's slot clone calls that, so the slot step is skipped
|
|
747
|
+
* there. The component is still registered and can be rendered.
|
|
748
|
+
*/
|
|
749
|
+
declare function withDocumentEditor(library: Extendable): Required<_openuidev_lang_core.Library<_openuidev_react_lang.ComponentRenderer<any>, _openuidev_lang_core.DefinedAction<any, string>>>;
|
|
750
|
+
|
|
751
|
+
declare const JuneDocumentContext: react.Context<JuneDocumentOptions>;
|
|
752
|
+
declare function useDocumentOptions(): JuneDocumentOptions;
|
|
753
|
+
|
|
754
|
+
/** Provides document options (and edit write-back) to every DocumentEditor below it. */
|
|
755
|
+
declare function DocumentBridge({ children, ...options }: DocumentBridgeOptions & {
|
|
756
|
+
children?: ReactNode;
|
|
757
|
+
}): react.JSX.Element;
|
|
758
|
+
|
|
759
|
+
/**
|
|
760
|
+
* Rewrites the arguments of a `DocumentEditor(documentId, title, content, ...)` call inside an
|
|
761
|
+
* OpenUI Lang program, leaving every other character of the program untouched.
|
|
762
|
+
*/
|
|
763
|
+
interface DocumentProgramUpdate {
|
|
764
|
+
title?: string;
|
|
765
|
+
/** New document body (Markdown or a Tiptap JSON string). */
|
|
766
|
+
content?: string;
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* Finds the DocumentEditor call whose first argument equals `documentId` and replaces its title
|
|
770
|
+
* and/or content. Returns the new program, or null when no matching call was found.
|
|
771
|
+
*/
|
|
772
|
+
declare function updateDocumentInProgram(program: string, documentId: string, update: DocumentProgramUpdate, componentName?: string): string | null;
|
|
773
|
+
/** Reads the current title and content of a DocumentEditor call, or null. */
|
|
774
|
+
declare function readDocumentFromProgram(program: string, documentId: string, componentName?: string): {
|
|
775
|
+
title: string;
|
|
776
|
+
content: string;
|
|
777
|
+
} | null;
|
|
778
|
+
|
|
779
|
+
declare function mergeDocuments(base: DocJSON, local: DocJSON, incoming: DocJSON): {
|
|
780
|
+
doc: DocJSON;
|
|
781
|
+
conflicts: number;
|
|
782
|
+
};
|
|
783
|
+
|
|
784
|
+
interface ExportContext {
|
|
785
|
+
documentId: string;
|
|
786
|
+
title: string;
|
|
787
|
+
json: DocJSON;
|
|
788
|
+
/** File name without extension. */
|
|
789
|
+
basename: string;
|
|
790
|
+
}
|
|
791
|
+
interface ExportResult {
|
|
792
|
+
filename: string;
|
|
793
|
+
mimeType: string;
|
|
794
|
+
blob?: Blob;
|
|
795
|
+
text?: string;
|
|
796
|
+
/** True when the exporter delivered the file itself, for example the print dialog for PDF. */
|
|
797
|
+
handled?: boolean;
|
|
798
|
+
}
|
|
799
|
+
type DocumentExporter = (context: ExportContext) => ExportResult | Promise<ExportResult>;
|
|
800
|
+
/** Adds or replaces an export format. */
|
|
801
|
+
declare function registerDocumentExporter(format: string, exporter: DocumentExporter): void;
|
|
802
|
+
declare function listDocumentExporters(): string[];
|
|
803
|
+
declare function exportDocument(format: string, doc: {
|
|
804
|
+
documentId: string;
|
|
805
|
+
title: string;
|
|
806
|
+
json: DocJSON;
|
|
807
|
+
}): Promise<ExportResult>;
|
|
808
|
+
/** Starts a browser download for results that carry a Blob. */
|
|
809
|
+
declare function downloadResult(result: ExportResult): void;
|
|
810
|
+
/** Copies rich text and plain text. Returns false if the browser refuses. */
|
|
811
|
+
declare function copyDocumentToClipboard(doc: {
|
|
812
|
+
title: string;
|
|
813
|
+
json: DocJSON;
|
|
814
|
+
}): Promise<boolean>;
|
|
815
|
+
|
|
816
|
+
interface DocumentInstructionOptions {
|
|
817
|
+
/** Examples of document types for your product. Default covers common business documents. */
|
|
818
|
+
documentTypes?: string[];
|
|
819
|
+
/** Extra rules appended after the built-in ones (tone, legal disclaimers, language, ...). */
|
|
820
|
+
extraRules?: string[];
|
|
821
|
+
/** Name of the component in your library. Default "DocumentEditor". */
|
|
822
|
+
componentName?: string;
|
|
823
|
+
}
|
|
824
|
+
/** Rules for the model. Pass them through your backend to any agent. */
|
|
825
|
+
declare function getDocumentEditorRules(options?: DocumentInstructionOptions): string[];
|
|
826
|
+
/** Text block you can paste into any agent's system prompt. */
|
|
827
|
+
declare function getDocumentEditorInstructions(options?: DocumentInstructionOptions): string;
|
|
828
|
+
/**
|
|
829
|
+
* Options for OpenUI's `library.prompt(options)`. Merge these with your own PromptOptions.
|
|
830
|
+
* Example: library.prompt({ ...documentPromptOptions(), preamble: "..." })
|
|
831
|
+
*/
|
|
832
|
+
declare function documentPromptOptions(options?: DocumentInstructionOptions): {
|
|
833
|
+
additionalRules: string[];
|
|
834
|
+
examples: string[];
|
|
835
|
+
};
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* Serialises the documents the user currently has (including their edits) as Markdown,
|
|
839
|
+
* ready to attach to the next message so the agent can edit the right text.
|
|
840
|
+
*/
|
|
841
|
+
declare function serializeDocumentsForAgent(options?: {
|
|
842
|
+
store?: DocumentStore;
|
|
843
|
+
ids?: string[];
|
|
844
|
+
}): Promise<string>;
|
|
845
|
+
|
|
846
|
+
type ApprovalChoice = "approve" | "reject" | "edit";
|
|
847
|
+
type ToolApprovalStatus = "pending" | "approved" | "rejected" | "running" | "completed" | "failed";
|
|
848
|
+
/** A tool call waiting for the user's decision. */
|
|
849
|
+
interface ToolApprovalRequest {
|
|
850
|
+
/** Unique id. `useToolApproval().request` creates one when omitted. */
|
|
851
|
+
id: string;
|
|
852
|
+
/** Tool or action name, e.g. "send_email". */
|
|
853
|
+
tool: string;
|
|
854
|
+
/** What the call will do, in words the user understands. */
|
|
855
|
+
description?: string;
|
|
856
|
+
/** The arguments the agent wants to call the tool with. */
|
|
857
|
+
arguments?: unknown;
|
|
858
|
+
risk?: "low" | "medium" | "high";
|
|
859
|
+
/** What kind of change the tool makes. */
|
|
860
|
+
sideEffect?: "read" | "write" | "destructive";
|
|
861
|
+
/** Choices offered. Default ["approve", "reject"]. Add "edit" to let the user change the arguments. */
|
|
862
|
+
options?: readonly ApprovalChoice[];
|
|
863
|
+
/** Free-form data for custom approval UIs. */
|
|
864
|
+
metadata?: Readonly<Record<string, unknown>>;
|
|
865
|
+
}
|
|
866
|
+
interface ToolApprovalDecision {
|
|
867
|
+
choice: ApprovalChoice;
|
|
868
|
+
/** Parsed JSON the user entered, when `choice` is "edit". */
|
|
869
|
+
editedArguments?: unknown;
|
|
870
|
+
}
|
|
871
|
+
interface ToolApprovalEntry {
|
|
872
|
+
request: ToolApprovalRequest;
|
|
873
|
+
status: ToolApprovalStatus;
|
|
874
|
+
decision?: ToolApprovalDecision;
|
|
875
|
+
/** Error text when `status` is "failed". */
|
|
876
|
+
error?: string;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
interface ToolApprovalLabels {
|
|
880
|
+
approve: string;
|
|
881
|
+
reject: string;
|
|
882
|
+
edit: string;
|
|
883
|
+
save: string;
|
|
884
|
+
cancel: string;
|
|
885
|
+
invalidJson: string;
|
|
886
|
+
status: Record<Exclude<ToolApprovalStatus, "pending">, string>;
|
|
887
|
+
sideEffect: Record<NonNullable<ToolApprovalRequest["sideEffect"]>, string>;
|
|
888
|
+
risk: (risk: NonNullable<ToolApprovalRequest["risk"]>) => string;
|
|
889
|
+
}
|
|
890
|
+
declare const defaultToolApprovalLabels: ToolApprovalLabels;
|
|
891
|
+
interface ToolApprovalProps {
|
|
892
|
+
request: ToolApprovalRequest;
|
|
893
|
+
/** Default "pending": shows the choices. Any other status shows a status line instead. */
|
|
894
|
+
status?: ToolApprovalStatus;
|
|
895
|
+
onDecide?: (decision: ToolApprovalDecision) => void;
|
|
896
|
+
/** Disables the buttons (for example while another decision is being sent). */
|
|
897
|
+
disabled?: boolean;
|
|
898
|
+
/** Error text shown when status is "failed". */
|
|
899
|
+
error?: string;
|
|
900
|
+
labels?: Partial<ToolApprovalLabels>;
|
|
901
|
+
/** Custom drawing of the arguments. Default: formatted JSON. */
|
|
902
|
+
renderArguments?: (args: unknown) => ReactNode;
|
|
903
|
+
className?: string;
|
|
904
|
+
}
|
|
905
|
+
/**
|
|
906
|
+
* Asks the user to approve, reject or edit a tool call. Styled only through `june-approval*`
|
|
907
|
+
* classes and June theme variables: restyle with CSS, or build your own UI on `useToolApproval`.
|
|
908
|
+
*/
|
|
909
|
+
declare function ToolApproval({ request, status, onDecide, disabled, error, labels: labelOverrides, renderArguments, className, }: ToolApprovalProps): react.JSX.Element;
|
|
910
|
+
|
|
911
|
+
type ToolApprovalInput = Omit<ToolApprovalRequest, "id"> & {
|
|
912
|
+
id?: string;
|
|
913
|
+
};
|
|
914
|
+
interface UseToolApprovalResult {
|
|
915
|
+
/** Every request seen, oldest first, with its status. */
|
|
916
|
+
entries: ToolApprovalEntry[];
|
|
917
|
+
/** Only the requests still waiting for a decision. */
|
|
918
|
+
pending: ToolApprovalEntry[];
|
|
919
|
+
/** Shows a request and resolves with the user's decision. */
|
|
920
|
+
request: (input: ToolApprovalInput) => Promise<ToolApprovalDecision>;
|
|
921
|
+
/** Records a decision (call from your UI; `ToolApprovalList` does this for you). */
|
|
922
|
+
decide: (id: string, decision: ToolApprovalDecision) => void;
|
|
923
|
+
/** Updates the status after the decision, e.g. "running", then "completed" or "failed". */
|
|
924
|
+
setStatus: (id: string, status: ToolApprovalStatus, error?: string) => void;
|
|
925
|
+
/** Removes one entry, or all when no id is given. Pending ones resolve as rejected. */
|
|
926
|
+
dismiss: (id?: string) => void;
|
|
927
|
+
/**
|
|
928
|
+
* Plug into `<JuneUI confirmAction={...}>`: sensitive June actions then ask through this UI.
|
|
929
|
+
* Resolves true on approve (or edit), false on reject.
|
|
930
|
+
*/
|
|
931
|
+
confirmAction: ConfirmAction;
|
|
932
|
+
}
|
|
933
|
+
/**
|
|
934
|
+
* State for human-in-the-loop tool approval. Render `entries` with `<ToolApproval>` (or
|
|
935
|
+
* `<ToolApprovalList approvals={...}>`), and `await request(...)` wherever a decision is needed.
|
|
936
|
+
* Requests still pending on unmount resolve as rejected.
|
|
937
|
+
*/
|
|
938
|
+
declare function useToolApproval(): UseToolApprovalResult;
|
|
939
|
+
|
|
940
|
+
interface ToolApprovalListProps {
|
|
941
|
+
approvals: Pick<UseToolApprovalResult, "entries" | "decide">;
|
|
942
|
+
/** Show only pending requests (default false: decided ones stay, with their status). */
|
|
943
|
+
pendingOnly?: boolean;
|
|
944
|
+
/** Replace the default card. */
|
|
945
|
+
renderItem?: (entry: ToolApprovalEntry, decide: UseToolApprovalResult["decide"]) => ReactNode;
|
|
946
|
+
labels?: ToolApprovalProps["labels"];
|
|
947
|
+
className?: string;
|
|
948
|
+
}
|
|
949
|
+
/** Renders every request from `useToolApproval()` and wires its buttons. */
|
|
950
|
+
declare function ToolApprovalList({ approvals, pendingOnly, renderItem, labels, className }: ToolApprovalListProps): react.JSX.Element | null;
|
|
951
|
+
|
|
952
|
+
/**
|
|
953
|
+
* LangGraph adapter: turns a LangGraph run stream (SSE from the LangGraph server API, e.g.
|
|
954
|
+
* `POST /threads/{thread_id}/runs/stream`) into the plain text June renders.
|
|
955
|
+
*
|
|
956
|
+
* Supported stream modes:
|
|
957
|
+
* - `messages-tuple`: `event: messages`, data `[messageChunk, metadata]`; each chunk is a delta.
|
|
958
|
+
* - `messages`: `event: messages/partial`, data `[message, ...]`; each message is the full text so
|
|
959
|
+
* far, so only the new part is emitted.
|
|
960
|
+
* Subgraph events (`messages|<namespace>`) are handled the same way. Other events are skipped.
|
|
961
|
+
*
|
|
962
|
+
* Pure functions, no React, no network: pair them with `fetchStream` / `useJuneStream`.
|
|
963
|
+
*/
|
|
964
|
+
|
|
965
|
+
interface LangGraphExtractorOptions {
|
|
966
|
+
/** Only keep messages produced by these graph nodes (`metadata.langgraph_node`). Default: all. */
|
|
967
|
+
nodes?: readonly string[];
|
|
968
|
+
}
|
|
969
|
+
/** Text of a LangChain message `content`: a string, or the `text` of its text blocks. */
|
|
970
|
+
declare function messageContentToText(content: unknown): string;
|
|
971
|
+
/**
|
|
972
|
+
* Creates an `extract` function for `sseToText` / `fetchStream({ sse: { extract } })`.
|
|
973
|
+
* Stateful (it remembers how much of each partial message was emitted): create one per stream.
|
|
974
|
+
*/
|
|
975
|
+
declare function createLangGraphExtractor(options?: LangGraphExtractorOptions): (data: string, event: string) => string | null;
|
|
976
|
+
/**
|
|
977
|
+
* Options to spread into `startFetch` / `fetchStream` for a LangGraph run stream.
|
|
978
|
+
* Call it for every run: the extractor inside is stateful.
|
|
979
|
+
*
|
|
980
|
+
* ```ts
|
|
981
|
+
* stream.startFetch(`${api}/threads/${threadId}/runs/stream`, {
|
|
982
|
+
* method: "POST",
|
|
983
|
+
* headers: { "Content-Type": "application/json" },
|
|
984
|
+
* body: JSON.stringify({ assistant_id: "agent", input, stream_mode: ["messages-tuple"] }),
|
|
985
|
+
* ...langGraphStreamOptions({ nodes: ["agent"] }),
|
|
986
|
+
* });
|
|
987
|
+
* ```
|
|
988
|
+
*/
|
|
989
|
+
declare function langGraphStreamOptions(options?: LangGraphExtractorOptions): {
|
|
990
|
+
sse: SseOptions;
|
|
991
|
+
};
|
|
992
|
+
/**
|
|
993
|
+
* Reads interrupt values from a LangGraph `updates` event (data `{ "__interrupt__": [{ value }] }`).
|
|
994
|
+
* Returns [] for anything else. Use it in your own SSE handling to drive human-in-the-loop UI.
|
|
995
|
+
*/
|
|
996
|
+
declare function readLangGraphInterrupts(data: string, event?: string): unknown[];
|
|
997
|
+
/**
|
|
998
|
+
* Best-effort mapping of an interrupt value to approval requests. Understands the
|
|
999
|
+
* `{ action_requests: [{ name, args, description }], review_configs: [{ action_name, allowed_decisions }] }`
|
|
1000
|
+
* shape used by LangChain's human-in-the-loop middleware. For your own interrupt payloads, build
|
|
1001
|
+
* `ToolApprovalRequest`s yourself. Returns [] when the value does not match.
|
|
1002
|
+
*/
|
|
1003
|
+
declare function interruptToApprovalRequests(value: unknown, idPrefix?: string): ToolApprovalRequest[];
|
|
1004
|
+
|
|
1005
|
+
export { ALL_EXPORT_FORMATS, type ActionEventParser, type ActionOutcome, type AnyComponentDefinition, type ApprovalChoice, type ComponentProps, ComponentRegistry, type ComponentRegistryOptions, type ConfirmAction, type ConsumeStreamOptions, DOCUMENT_COMPONENT_DESCRIPTION, type DefineComponentOptions, type DocJSON, type DocNode, DocumentBridge, type DocumentBridgeOptions, type DocumentChange, type DocumentConflict, DocumentEditor, type DocumentEditorProps, type DocumentExportEvent, type DocumentExportFormat, type DocumentExporter, type DocumentInstructionOptions, type DocumentProgramUpdate, type DocumentRecord, type DocumentSavePayload, type DocumentSnapshot, type DocumentStore, type ExportContext, type ExportResult, type FallbackArgs, type FetchStreamOptions, type IncomingDocument, type JuneAction, type JuneActionContext, type JuneActionDefinition, type JuneActionMap, type JuneComponent, type JuneComponentMeta, type JuneContextValue, JuneDocumentContext, JuneDocumentEditorComponent, type JuneDocumentOptions, JuneError, JuneErrorBoundary, type JuneErrorBoundaryProps, type JuneErrorCode, type JuneErrorOptions, type JuneLibraryOptions, type JuneRenderProps, JuneRenderer, type JuneRendererProps, type JuneResolvedTheme, JuneRuntimeContext, type JuneRuntimeValue, type JuneStreamState, type JuneThemeInput, type JuneThemeMode, JuneThemeProvider, type JuneThemeProviderProps, type JuneThemeSet, type JuneThemeToken, type JuneThemeVars, type LangGraphExtractorOptions, MarkdownText, type MarkdownTextProps, type MixedContent, type MixedContentOptions, type OpenUIActionEvent, type OpenUILibrary, type OpenUIRendererProps, type ParsedActionEvent, type PendingUpdate, type ReceiveOutcome, type RegisterOptions, type ResolveChoice, type ResponseChangeInfo, type RunActionOptions, type SchemaLike, type SplitOptions, type SplitResponse, type SseOptions, type StreamChunk, type StreamSource, type StreamStarter, type StreamStatus, type TextFormat, ToolApproval, type ToolApprovalDecision, type ToolApprovalEntry, type ToolApprovalInput, type ToolApprovalLabels, ToolApprovalList, type ToolApprovalListProps, type ToolApprovalProps, type ToolApprovalRequest, type ToolApprovalStatus, type UseJuneStreamOptions, type UseJuneStreamResult, type UseToolApprovalResult, consumeStream, copyDocumentToClipboard, createActionHandler, createComponentRegistry, createDocumentStore, createJuneLibrary, createLangGraphExtractor, createTheme, darkTheme, defaultParseActionEvent, defaultToolApprovalLabels, defineComponent, defineJuneAction, defineJuneComponent, documentPromptOptions, downloadResult, exportDocument, fetchStream, getDefaultDocumentStore, getDocumentEditorInstructions, getDocumentEditorRules, interruptToApprovalRequests, isDocumentEcho, isJuneComponent, isJuneError, isThemeSet, jsonFieldExtractor, langGraphStreamOptions, lightTheme, listDocumentExporters, mergeDocuments, messageContentToText, normalizeProgram, readDocumentFromProgram, readLangGraphInterrupts, registerDocumentExporter, rememberDocumentEcho, resolveMixedContent, resolveThemeVars, runAction, serializeDocumentsForAgent, splitResponse, sseToText, toAsyncIterable, toJuneError, updateDocumentInProgram, useDocumentBridge, useDocumentOptions, useJuneRuntime, useJuneStream, useJuneTheme, useRegistryLibrary, useResolvedTheme, useToolApproval, validateComponentDefinition, withDocumentEditor };
|