@adonis-agora/agent 0.72.0 → 0.74.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/CHANGELOG.md +20 -0
- package/dist/configure.d.ts +5 -4
- package/dist/configure.d.ts.map +1 -1
- package/dist/configure.js +8 -4
- package/dist/configure.js.map +1 -1
- package/dist/providers/agent_provider.d.ts.map +1 -1
- package/dist/providers/agent_provider.js +5 -1
- package/dist/providers/agent_provider.js.map +1 -1
- package/dist/src/a2ui/adapter.d.ts.map +1 -1
- package/dist/src/a2ui/adapter.js +1 -0
- package/dist/src/a2ui/adapter.js.map +1 -1
- package/dist/src/a2ui/core.d.ts.map +1 -1
- package/dist/src/a2ui/core.js +11 -1
- package/dist/src/a2ui/core.js.map +1 -1
- package/dist/src/action-proposal-executor.d.ts.map +1 -1
- package/dist/src/action-proposal-executor.js +3 -0
- package/dist/src/action-proposal-executor.js.map +1 -1
- package/dist/src/ag-ui/adapter.d.ts.map +1 -1
- package/dist/src/ag-ui/adapter.js +2 -0
- package/dist/src/ag-ui/adapter.js.map +1 -1
- package/dist/src/ag-ui/core/encoder.d.ts.map +1 -1
- package/dist/src/ag-ui/core/encoder.js +3 -0
- package/dist/src/ag-ui/core/encoder.js.map +1 -1
- package/dist/src/agent-loop.d.ts.map +1 -1
- package/dist/src/agent-loop.js +18 -0
- package/dist/src/agent-loop.js.map +1 -1
- package/dist/src/agent-service.d.ts +6 -0
- package/dist/src/agent-service.d.ts.map +1 -1
- package/dist/src/agent-service.js +5 -3
- package/dist/src/agent-service.js.map +1 -1
- package/dist/src/channels/adapters/evolution_api.d.ts.map +1 -1
- package/dist/src/channels/adapters/evolution_api.js +35 -0
- package/dist/src/channels/adapters/evolution_api.js.map +1 -1
- package/dist/src/channels/adapters/telegram.d.ts.map +1 -1
- package/dist/src/channels/adapters/telegram.js +25 -7
- package/dist/src/channels/adapters/telegram.js.map +1 -1
- package/dist/src/channels/adapters/whatsapp_cloud.d.ts.map +1 -1
- package/dist/src/channels/adapters/whatsapp_cloud.js +44 -0
- package/dist/src/channels/adapters/whatsapp_cloud.js.map +1 -1
- package/dist/src/channels/handler.d.ts +21 -1
- package/dist/src/channels/handler.d.ts.map +1 -1
- package/dist/src/channels/handler.js +230 -9
- package/dist/src/channels/handler.js.map +1 -1
- package/dist/src/channels/index.d.ts +2 -2
- package/dist/src/channels/index.d.ts.map +1 -1
- package/dist/src/channels/index.js.map +1 -1
- package/dist/src/channels/types.d.ts +40 -0
- package/dist/src/channels/types.d.ts.map +1 -1
- package/dist/src/genui/catalog.d.ts +12 -1
- package/dist/src/genui/catalog.d.ts.map +1 -1
- package/dist/src/genui/catalog.js +12 -1
- package/dist/src/genui/catalog.js.map +1 -1
- package/dist/src/genui/channels.d.ts +206 -0
- package/dist/src/genui/channels.d.ts.map +1 -0
- package/dist/src/genui/channels.js +322 -0
- package/dist/src/genui/channels.js.map +1 -0
- package/dist/src/genui/chart-image.d.ts +46 -0
- package/dist/src/genui/chart-image.d.ts.map +1 -0
- package/dist/src/genui/chart-image.js +155 -0
- package/dist/src/genui/chart-image.js.map +1 -0
- package/dist/src/genui/factory.d.ts +23 -1
- package/dist/src/genui/factory.d.ts.map +1 -1
- package/dist/src/genui/factory.js +13 -1
- package/dist/src/genui/factory.js.map +1 -1
- package/dist/src/genui/index.d.ts.map +1 -1
- package/dist/src/genui/index.js +64 -3
- package/dist/src/genui/index.js.map +1 -1
- package/dist/src/genui/kit/adonis.d.ts +4 -0
- package/dist/src/genui/kit/adonis.d.ts.map +1 -0
- package/dist/src/genui/kit/adonis.js +38 -0
- package/dist/src/genui/kit/adonis.js.map +1 -0
- package/dist/src/genui/kit/bundle.d.ts +25 -0
- package/dist/src/genui/kit/bundle.d.ts.map +1 -0
- package/dist/src/genui/kit/bundle.js +144 -0
- package/dist/src/genui/kit/bundle.js.map +1 -0
- package/dist/src/genui/kit/discover.d.ts +41 -0
- package/dist/src/genui/kit/discover.d.ts.map +1 -0
- package/dist/src/genui/kit/discover.js +100 -0
- package/dist/src/genui/kit/discover.js.map +1 -0
- package/dist/src/genui/kit/docs.d.ts +22 -0
- package/dist/src/genui/kit/docs.d.ts.map +1 -0
- package/dist/src/genui/kit/docs.js +237 -0
- package/dist/src/genui/kit/docs.js.map +1 -0
- package/dist/src/genui/kit/files.d.ts +27 -0
- package/dist/src/genui/kit/files.d.ts.map +1 -0
- package/dist/src/genui/kit/files.js +126 -0
- package/dist/src/genui/kit/files.js.map +1 -0
- package/dist/src/genui/kit/index.d.ts +12 -0
- package/dist/src/genui/kit/index.d.ts.map +1 -0
- package/dist/src/genui/kit/index.js +12 -0
- package/dist/src/genui/kit/index.js.map +1 -0
- package/dist/src/genui/kit/plugin.d.ts +52 -0
- package/dist/src/genui/kit/plugin.d.ts.map +1 -0
- package/dist/src/genui/kit/plugin.js +314 -0
- package/dist/src/genui/kit/plugin.js.map +1 -0
- package/dist/src/genui/kit/write.d.ts +14 -0
- package/dist/src/genui/kit/write.d.ts.map +1 -0
- package/dist/src/genui/kit/write.js +39 -0
- package/dist/src/genui/kit/write.js.map +1 -0
- package/dist/src/genui/public.d.ts +7 -3
- package/dist/src/genui/public.d.ts.map +1 -1
- package/dist/src/genui/public.js +5 -1
- package/dist/src/genui/public.js.map +1 -1
- package/dist/src/genui/sandbox-jsx.d.ts +29 -0
- package/dist/src/genui/sandbox-jsx.d.ts.map +1 -0
- package/dist/src/genui/sandbox-jsx.js +656 -0
- package/dist/src/genui/sandbox-jsx.js.map +1 -0
- package/dist/src/genui/sandbox-kit.d.ts +88 -0
- package/dist/src/genui/sandbox-kit.d.ts.map +1 -0
- package/dist/src/genui/sandbox-kit.js +89 -0
- package/dist/src/genui/sandbox-kit.js.map +1 -0
- package/dist/src/genui/sandbox-theme.d.ts +61 -0
- package/dist/src/genui/sandbox-theme.d.ts.map +1 -0
- package/dist/src/genui/sandbox-theme.js +255 -0
- package/dist/src/genui/sandbox-theme.js.map +1 -0
- package/dist/src/genui/sandbox.d.ts +73 -2
- package/dist/src/genui/sandbox.d.ts.map +1 -1
- package/dist/src/genui/sandbox.js +87 -14
- package/dist/src/genui/sandbox.js.map +1 -1
- package/dist/src/genui/text.d.ts.map +1 -1
- package/dist/src/genui/text.js +33 -1
- package/dist/src/genui/text.js.map +1 -1
- package/dist/src/genui/tools.d.ts +26 -0
- package/dist/src/genui/tools.d.ts.map +1 -1
- package/dist/src/genui/tools.js +94 -14
- package/dist/src/genui/tools.js.map +1 -1
- package/dist/src/genui/tree.d.ts +25 -2
- package/dist/src/genui/tree.d.ts.map +1 -1
- package/dist/src/genui/tree.js +161 -4
- package/dist/src/genui/tree.js.map +1 -1
- package/dist/src/hooks/genui_kit.d.ts +20 -0
- package/dist/src/hooks/genui_kit.d.ts.map +1 -0
- package/dist/src/hooks/genui_kit.js +55 -0
- package/dist/src/hooks/genui_kit.js.map +1 -0
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/react/core/genui/sandbox-assets.d.ts +32 -0
- package/dist/src/react/core/genui/sandbox-assets.d.ts.map +1 -0
- package/dist/src/react/core/genui/sandbox-assets.js +174 -0
- package/dist/src/react/core/genui/sandbox-assets.js.map +1 -0
- package/dist/src/react/core/genui/sandbox.d.ts +9 -0
- package/dist/src/react/core/genui/sandbox.d.ts.map +1 -1
- package/dist/src/react/core/genui/sandbox.js +115 -19
- package/dist/src/react/core/genui/sandbox.js.map +1 -1
- package/dist/src/react/core/index.d.ts +1 -1
- package/dist/src/react/core/index.d.ts.map +1 -1
- package/dist/src/react/core/index.js +1 -1
- package/dist/src/react/core/index.js.map +1 -1
- package/dist/src/react/core/presentation/phrasing.d.ts +3 -2
- package/dist/src/react/core/presentation/phrasing.d.ts.map +1 -1
- package/dist/src/react/core/presentation/phrasing.js +4 -27
- package/dist/src/react/core/presentation/phrasing.js.map +1 -1
- package/dist/src/react/core/presentation/tool-activity.d.ts +8 -0
- package/dist/src/react/core/presentation/tool-activity.d.ts.map +1 -1
- package/dist/src/react/core/presentation/tool-activity.js +28 -1
- package/dist/src/react/core/presentation/tool-activity.js.map +1 -1
- package/dist/src/react/core/transcript/model.d.ts +6 -0
- package/dist/src/react/core/transcript/model.d.ts.map +1 -1
- package/dist/src/react/core/transcript/model.js +6 -1
- package/dist/src/react/core/transcript/model.js.map +1 -1
- package/dist/src/react/core/transcript/use-chat-transcript.d.ts +5 -0
- package/dist/src/react/core/transcript/use-chat-transcript.d.ts.map +1 -1
- package/dist/src/react/core/transcript/use-chat-transcript.js +3 -0
- package/dist/src/react/core/transcript/use-chat-transcript.js.map +1 -1
- package/dist/src/spi/tool.d.ts +7 -0
- package/dist/src/spi/tool.d.ts.map +1 -1
- package/dist/src/tool-presentation.d.ts +15 -0
- package/dist/src/tool-presentation.d.ts.map +1 -1
- package/dist/src/tool-presentation.js +48 -0
- package/dist/src/tool-presentation.js.map +1 -1
- package/dist/src/tool-registry.d.ts.map +1 -1
- package/dist/src/tool-registry.js +2 -0
- package/dist/src/tool-registry.js.map +1 -1
- package/dist/src/types.d.ts +10 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/vite/index.d.ts +24 -0
- package/dist/src/vite/index.d.ts.map +1 -0
- package/dist/src/vite/index.js +29 -0
- package/dist/src/vite/index.js.map +1 -0
- package/package.json +38 -2
- package/skills/agent-setup/SKILL.md +3 -1
- package/skills/agent-tools/SKILL.md +5 -3
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-channel generative UI: what a turn may draw depends on where it is read. A web page draws the
|
|
3
|
+
* catalog's components (and the sandbox); WhatsApp and Telegram draw text, reply buttons, lists and
|
|
4
|
+
* images; an email draws HTML. `genui({ channels: { … } })` sets, per channel, which tools the model
|
|
5
|
+
* is offered and how what it pushes is delivered — and the model is told only what that channel can
|
|
6
|
+
* draw.
|
|
7
|
+
*
|
|
8
|
+
* Framework-free and isomorphic, like the rest of `genui`.
|
|
9
|
+
*/
|
|
10
|
+
import type { UiAction } from './actions.js';
|
|
11
|
+
import { type Catalog, type ComponentDefinition, type GenuiStreaming } from './catalog.js';
|
|
12
|
+
import { type DefineSandboxOptions } from './sandbox.js';
|
|
13
|
+
/** The channel a turn runs on when nothing says otherwise: a browser (AG-UI, the HTTP chat, A2UI). */
|
|
14
|
+
export declare const WEB_CHANNEL = "web";
|
|
15
|
+
/** The `channels` entry that serves every channel without one of its own. */
|
|
16
|
+
export declare const DEFAULT_CHANNEL = "default";
|
|
17
|
+
/** Channels a person reads in a messaging app or a mailbox: the server draws for them. */
|
|
18
|
+
export declare const MESSAGING_CHANNELS: readonly string[];
|
|
19
|
+
/**
|
|
20
|
+
* What the model is offered on a channel: `tree` — one `ui__render` tool composing the catalog (and
|
|
21
|
+
* the sandbox, when on); `per-component` — one `ui__show_<component>` tool per component that can be
|
|
22
|
+
* drawn there; `text` — no UI tools, the model answers in text.
|
|
23
|
+
*/
|
|
24
|
+
export type GenuiChannelMode = 'tree' | 'per-component' | 'text';
|
|
25
|
+
/**
|
|
26
|
+
* How what the model pushed reaches a channel the server draws for (WhatsApp, Telegram, email):
|
|
27
|
+
* `native` — each component's channel conversion (`defineComponent(…, { channels })`: text, reply
|
|
28
|
+
* buttons, a list, an image), its text summary otherwise; `text` — always the text summary; `html` —
|
|
29
|
+
* HTML (email). A web channel draws in the browser and ignores it.
|
|
30
|
+
*/
|
|
31
|
+
export type GenuiChannelRender = 'native' | 'text' | 'html';
|
|
32
|
+
/** One channel's generative UI — every field falls back to the `default` entry, then to the top level. */
|
|
33
|
+
export interface GenuiChannelOptions {
|
|
34
|
+
/** Default: the top-level `mode` on a web channel; `per-component` on a messaging channel. */
|
|
35
|
+
mode?: GenuiChannelMode;
|
|
36
|
+
/** Tree mode: draw the layout while the model writes it (`partial`) or once it is whole. */
|
|
37
|
+
streaming?: GenuiStreaming;
|
|
38
|
+
/**
|
|
39
|
+
* The sandbox on this channel: `false` for none, `true` / a config for the sandbox with those
|
|
40
|
+
* options (a web channel may use the app's kit while a mobile one does not). Default: the
|
|
41
|
+
* top-level `sandbox` on a web channel; never on a messaging channel (it cannot run there).
|
|
42
|
+
*/
|
|
43
|
+
sandbox?: boolean | DefineSandboxOptions;
|
|
44
|
+
/** Default `native` (`html` for `email`). */
|
|
45
|
+
render?: GenuiChannelRender;
|
|
46
|
+
/** Charts as PNG images on a channel that takes images ({@link ChartImageRenderer}, `chartImages()`). */
|
|
47
|
+
chartImages?: ChartImageRenderer;
|
|
48
|
+
/** Extra words for the model on this channel, added to the UI tools' descriptions. */
|
|
49
|
+
instructions?: string;
|
|
50
|
+
}
|
|
51
|
+
/** `genui({ channels })`: an entry per channel name, plus `default` for every other one. */
|
|
52
|
+
export interface GenuiChannels {
|
|
53
|
+
web?: GenuiChannelOptions;
|
|
54
|
+
mobile?: GenuiChannelOptions;
|
|
55
|
+
whatsapp?: GenuiChannelOptions;
|
|
56
|
+
telegram?: GenuiChannelOptions;
|
|
57
|
+
email?: GenuiChannelOptions;
|
|
58
|
+
default?: GenuiChannelOptions;
|
|
59
|
+
[channel: string]: GenuiChannelOptions | undefined;
|
|
60
|
+
}
|
|
61
|
+
/** The top-level genui options a channel falls back to. */
|
|
62
|
+
export interface GenuiChannelBase {
|
|
63
|
+
mode?: 'per-component' | 'tree';
|
|
64
|
+
streaming?: GenuiStreaming;
|
|
65
|
+
sandbox?: boolean | DefineSandboxOptions;
|
|
66
|
+
}
|
|
67
|
+
/** A channel's options with every default applied — what the tools and the channel handler follow. */
|
|
68
|
+
export interface ResolvedGenuiChannel {
|
|
69
|
+
/** The channel's name (`web`, `whatsapp`, `mobile`, …). */
|
|
70
|
+
name: string;
|
|
71
|
+
/** The server draws for it (WhatsApp, Telegram, email): it never runs a sandbox or a React renderer. */
|
|
72
|
+
messaging: boolean;
|
|
73
|
+
/** `channels` has an entry for it (its own or `default`). `false` → it behaves as it always did. */
|
|
74
|
+
configured: boolean;
|
|
75
|
+
mode: GenuiChannelMode;
|
|
76
|
+
streaming?: GenuiStreaming;
|
|
77
|
+
/** `undefined` → the catalog's own sandbox (if it has one) is left as it is. */
|
|
78
|
+
sandbox?: boolean | DefineSandboxOptions;
|
|
79
|
+
render: GenuiChannelRender;
|
|
80
|
+
chartImages?: ChartImageRenderer;
|
|
81
|
+
instructions?: string;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* THE rule for which channel a turn runs on, read from its page context:
|
|
85
|
+
*
|
|
86
|
+
* - `pageContext.channel` is a string → that channel (an explicit override: `send({ channel })`, a
|
|
87
|
+
* mobile client posting `pageContext: { channel: 'mobile' }`);
|
|
88
|
+
* - `pageContext.channel` is the address a text-channel adapter stamps (`{ name, conversation,
|
|
89
|
+
* kind? }`) → its `kind` (`whatsapp`, `telegram`), else its `name`;
|
|
90
|
+
* - nothing → `web`: what AG-UI, the HTTP chat and A2UI serve (they stamp nothing, so a tool that
|
|
91
|
+
* skips skeletons when `pageContext.channel` is set keeps working).
|
|
92
|
+
*/
|
|
93
|
+
export declare function turnChannel(pageContext: {
|
|
94
|
+
[key: string]: unknown;
|
|
95
|
+
} | undefined): string;
|
|
96
|
+
/** WhatsApp, Telegram and email are drawn by the server; every other channel by a client. */
|
|
97
|
+
export declare function isMessagingChannel(channel: string): boolean;
|
|
98
|
+
/** One channel's options, its own entry over `default` over the top level. */
|
|
99
|
+
export declare function resolveGenuiChannel(base: GenuiChannelBase, channels: GenuiChannels | undefined, channel: string | undefined): ResolvedGenuiChannel;
|
|
100
|
+
/** Throws on a `channels` entry that names an unknown mode or render. */
|
|
101
|
+
export declare function assertGenuiChannels(channels: GenuiChannels | undefined): void;
|
|
102
|
+
/**
|
|
103
|
+
* A reply button. Pressed, it becomes the user's next turn — a {@link UiAction} whose text is the
|
|
104
|
+
* label and whose context is `value`, exactly like a sandbox's `agent.send`.
|
|
105
|
+
*/
|
|
106
|
+
export interface ChannelNativeButton {
|
|
107
|
+
label: string;
|
|
108
|
+
/** The action's name. Default `select`. */
|
|
109
|
+
action?: string;
|
|
110
|
+
/** The values that go with the press (JSON). */
|
|
111
|
+
value?: Record<string, unknown>;
|
|
112
|
+
}
|
|
113
|
+
export interface ChannelNativeListItem extends ChannelNativeButton {
|
|
114
|
+
/** A second line under the label. */
|
|
115
|
+
description?: string;
|
|
116
|
+
}
|
|
117
|
+
/** A list to pick one entry from (a WhatsApp list message, a Telegram keyboard of one row each). */
|
|
118
|
+
export interface ChannelNativeList {
|
|
119
|
+
/** The label of the button that opens the list (WhatsApp). */
|
|
120
|
+
button: string;
|
|
121
|
+
/** A heading over the entries. */
|
|
122
|
+
title?: string;
|
|
123
|
+
items: ChannelNativeListItem[];
|
|
124
|
+
}
|
|
125
|
+
/** An image: by an `https` url the provider fetches, or its bytes. */
|
|
126
|
+
export interface ChannelNativeImage {
|
|
127
|
+
url?: string;
|
|
128
|
+
data?: Uint8Array;
|
|
129
|
+
/** Default `image/png`. */
|
|
130
|
+
contentType?: string;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* What a component is on a channel the server draws for. Each field is optional; a message with an
|
|
134
|
+
* image sends `text` as its caption, one with buttons or a list sends `text` as its body.
|
|
135
|
+
*/
|
|
136
|
+
export interface ChannelNativeMessage {
|
|
137
|
+
/** In the model's markdown — converted to the channel's. */
|
|
138
|
+
text?: string;
|
|
139
|
+
/** For `render: 'html'` (email). Trusted markup: build it from props, escaping what you insert. */
|
|
140
|
+
html?: string;
|
|
141
|
+
/** Reply buttons — at most 3 on WhatsApp; more become a list. */
|
|
142
|
+
buttons?: ChannelNativeButton[];
|
|
143
|
+
list?: ChannelNativeList;
|
|
144
|
+
image?: ChannelNativeImage;
|
|
145
|
+
}
|
|
146
|
+
/** `defineComponent(…, { channels: { whatsapp: (props) => ({ text, buttons }) } })`. */
|
|
147
|
+
export type ChannelConversion<P = Record<string, unknown>> = {
|
|
148
|
+
convert(props: P, context: {
|
|
149
|
+
channel: string;
|
|
150
|
+
}): ChannelNativeMessage | ChannelNativeMessage[] | null | undefined | Promise<ChannelNativeMessage | ChannelNativeMessage[] | null | undefined>;
|
|
151
|
+
}['convert'];
|
|
152
|
+
/**
|
|
153
|
+
* A component's conversions, by channel name. `false` → the component is never offered on that
|
|
154
|
+
* channel (it has nothing to say there).
|
|
155
|
+
*/
|
|
156
|
+
export type ComponentChannels<P = Record<string, unknown>> = {
|
|
157
|
+
[channel: string]: ChannelConversion<P> | false | undefined;
|
|
158
|
+
};
|
|
159
|
+
/** Renders chart components as images, for a channel that takes them. */
|
|
160
|
+
export interface ChartImageRenderer {
|
|
161
|
+
/** The components it draws (default for `chartImages()`: `['Chart']`). */
|
|
162
|
+
readonly components: readonly string[];
|
|
163
|
+
render(component: string, props: Record<string, unknown>): Promise<ChannelNativeImage | null>;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Whether `definition` can be drawn on `channel`. On a web channel every component can (the client's
|
|
167
|
+
* `uiCapabilities` narrow it); on a messaging channel a component can when it has a conversion for
|
|
168
|
+
* it, a chart renderer draws it, or it has a text summary (`fallbackText`) — a component without one
|
|
169
|
+
* would arrive as a JSON dump, so it is not offered. A sandbox never can, and `channels: { x: false }`
|
|
170
|
+
* opts a component out.
|
|
171
|
+
*/
|
|
172
|
+
export declare function canRenderOnChannel(definition: ComponentDefinition<unknown>, channel: ResolvedGenuiChannel): boolean;
|
|
173
|
+
/**
|
|
174
|
+
* The catalog as `channel` may draw it: only what it can render, and its own sandbox (or none). With
|
|
175
|
+
* no `channels` configured the catalog is returned as it is.
|
|
176
|
+
*/
|
|
177
|
+
export declare function channelCatalog(catalog: Catalog, channel: ResolvedGenuiChannel): Catalog;
|
|
178
|
+
/** What a UI tool's description says about the channel the conversation is on. */
|
|
179
|
+
export declare function channelInstructions(channel: ResolvedGenuiChannel): string | undefined;
|
|
180
|
+
/** A pushed component, as a channel delivers it. */
|
|
181
|
+
export interface ChannelComponentInput {
|
|
182
|
+
/** The frame's id — what a button press reports as its `componentId`. */
|
|
183
|
+
id?: string;
|
|
184
|
+
name: string;
|
|
185
|
+
props: Record<string, unknown>;
|
|
186
|
+
}
|
|
187
|
+
/** {@link ChannelNativeMessage} plus the component it came from (so a press can name it). */
|
|
188
|
+
export interface ChannelRenderedMessage extends ChannelNativeMessage {
|
|
189
|
+
component: string;
|
|
190
|
+
componentId?: string;
|
|
191
|
+
title?: string;
|
|
192
|
+
}
|
|
193
|
+
/** Plain text as minimal HTML: paragraphs, line breaks, `*bold*`. */
|
|
194
|
+
export declare function textToHtml(text: string): string;
|
|
195
|
+
/**
|
|
196
|
+
* What a pushed component (a tree included) is on a channel the server draws for: one or more
|
|
197
|
+
* messages — its conversions, chart images, and the text summary of everything else, in order.
|
|
198
|
+
* Consecutive text is joined. Never throws: a conversion that fails sends the summary.
|
|
199
|
+
*/
|
|
200
|
+
export declare function renderChannelMessages(catalog: Catalog, component: ChannelComponentInput, channel: ResolvedGenuiChannel): Promise<ChannelRenderedMessage[]>;
|
|
201
|
+
/** The UI action a pressed button (or picked list entry) stands for — the user's next turn. */
|
|
202
|
+
export declare function channelButtonAction(button: ChannelNativeButton, from: {
|
|
203
|
+
componentId?: string;
|
|
204
|
+
title?: string;
|
|
205
|
+
}): UiAction;
|
|
206
|
+
//# sourceMappingURL=channels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channels.d.ts","sourceRoot":"","sources":["../../../src/genui/channels.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
import { defineCatalog, } from './catalog.js';
|
|
2
|
+
import { defineSandbox, sandboxPolicyOf } from './sandbox.js';
|
|
3
|
+
import { componentToText } from './text.js';
|
|
4
|
+
import { GENUI_TREE_COMPONENT } from './tree.js';
|
|
5
|
+
/** The channel a turn runs on when nothing says otherwise: a browser (AG-UI, the HTTP chat, A2UI). */
|
|
6
|
+
export const WEB_CHANNEL = 'web';
|
|
7
|
+
/** The `channels` entry that serves every channel without one of its own. */
|
|
8
|
+
export const DEFAULT_CHANNEL = 'default';
|
|
9
|
+
/** Channels a person reads in a messaging app or a mailbox: the server draws for them. */
|
|
10
|
+
export const MESSAGING_CHANNELS = Object.freeze([
|
|
11
|
+
'whatsapp',
|
|
12
|
+
'telegram',
|
|
13
|
+
'email',
|
|
14
|
+
]);
|
|
15
|
+
function isRecord(value) {
|
|
16
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* THE rule for which channel a turn runs on, read from its page context:
|
|
20
|
+
*
|
|
21
|
+
* - `pageContext.channel` is a string → that channel (an explicit override: `send({ channel })`, a
|
|
22
|
+
* mobile client posting `pageContext: { channel: 'mobile' }`);
|
|
23
|
+
* - `pageContext.channel` is the address a text-channel adapter stamps (`{ name, conversation,
|
|
24
|
+
* kind? }`) → its `kind` (`whatsapp`, `telegram`), else its `name`;
|
|
25
|
+
* - nothing → `web`: what AG-UI, the HTTP chat and A2UI serve (they stamp nothing, so a tool that
|
|
26
|
+
* skips skeletons when `pageContext.channel` is set keeps working).
|
|
27
|
+
*/
|
|
28
|
+
export function turnChannel(pageContext) {
|
|
29
|
+
const value = pageContext?.channel;
|
|
30
|
+
if (typeof value === 'string' && value.length > 0)
|
|
31
|
+
return value;
|
|
32
|
+
if (isRecord(value)) {
|
|
33
|
+
if (typeof value.kind === 'string' && value.kind.length > 0)
|
|
34
|
+
return value.kind;
|
|
35
|
+
if (typeof value.name === 'string' && value.name.length > 0)
|
|
36
|
+
return value.name;
|
|
37
|
+
}
|
|
38
|
+
return WEB_CHANNEL;
|
|
39
|
+
}
|
|
40
|
+
/** WhatsApp, Telegram and email are drawn by the server; every other channel by a client. */
|
|
41
|
+
export function isMessagingChannel(channel) {
|
|
42
|
+
return MESSAGING_CHANNELS.includes(channel);
|
|
43
|
+
}
|
|
44
|
+
/** One channel's options, its own entry over `default` over the top level. */
|
|
45
|
+
export function resolveGenuiChannel(base, channels, channel) {
|
|
46
|
+
const name = channel ?? WEB_CHANNEL;
|
|
47
|
+
const messaging = isMessagingChannel(name);
|
|
48
|
+
const entry = channels === undefined ? undefined : (channels[name] ?? channels.default);
|
|
49
|
+
if (entry === undefined) {
|
|
50
|
+
return {
|
|
51
|
+
name,
|
|
52
|
+
messaging,
|
|
53
|
+
configured: false,
|
|
54
|
+
mode: base.mode ?? 'tree',
|
|
55
|
+
...(base.streaming !== undefined ? { streaming: base.streaming } : {}),
|
|
56
|
+
...(base.sandbox !== undefined ? { sandbox: base.sandbox } : {}),
|
|
57
|
+
render: name === 'email' ? 'html' : 'native',
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const sandbox = messaging ? false : (entry.sandbox ?? base.sandbox);
|
|
61
|
+
const streaming = entry.streaming ?? base.streaming;
|
|
62
|
+
return {
|
|
63
|
+
name,
|
|
64
|
+
messaging,
|
|
65
|
+
configured: true,
|
|
66
|
+
mode: entry.mode ?? (messaging ? 'per-component' : (base.mode ?? 'tree')),
|
|
67
|
+
...(streaming !== undefined ? { streaming } : {}),
|
|
68
|
+
...(sandbox !== undefined ? { sandbox } : {}),
|
|
69
|
+
render: entry.render ?? (name === 'email' ? 'html' : 'native'),
|
|
70
|
+
...(entry.chartImages !== undefined ? { chartImages: entry.chartImages } : {}),
|
|
71
|
+
...(entry.instructions !== undefined ? { instructions: entry.instructions } : {}),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/** Throws on a `channels` entry that names an unknown mode or render. */
|
|
75
|
+
export function assertGenuiChannels(channels) {
|
|
76
|
+
if (channels === undefined)
|
|
77
|
+
return;
|
|
78
|
+
if (!isRecord(channels))
|
|
79
|
+
throw new TypeError('genui: channels must be an object');
|
|
80
|
+
for (const [name, entry] of Object.entries(channels)) {
|
|
81
|
+
if (entry === undefined)
|
|
82
|
+
continue;
|
|
83
|
+
if (!isRecord(entry))
|
|
84
|
+
throw new TypeError(`genui: channels.${name} must be an object`);
|
|
85
|
+
if (entry.mode !== undefined && !['tree', 'per-component', 'text'].includes(String(entry.mode)))
|
|
86
|
+
throw new TypeError(`genui: channels.${name}.mode must be 'tree', 'per-component' or 'text'`);
|
|
87
|
+
if (entry.render !== undefined && !['native', 'text', 'html'].includes(String(entry.render)))
|
|
88
|
+
throw new TypeError(`genui: channels.${name}.render must be 'native', 'text' or 'html'`);
|
|
89
|
+
if (entry.streaming !== undefined &&
|
|
90
|
+
entry.streaming !== 'partial' &&
|
|
91
|
+
entry.streaming !== 'complete')
|
|
92
|
+
throw new TypeError(`genui: channels.${name}.streaming must be 'partial' or 'complete'`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function conversionOf(definition, channel) {
|
|
96
|
+
const channels = definition?.channels;
|
|
97
|
+
return channels === undefined || !Object.hasOwn(channels, channel)
|
|
98
|
+
? undefined
|
|
99
|
+
: channels[channel];
|
|
100
|
+
}
|
|
101
|
+
/** A sandbox component (it carries a sandbox policy). */
|
|
102
|
+
function isSandbox(definition) {
|
|
103
|
+
return sandboxPolicyOf(definition) !== undefined;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Whether `definition` can be drawn on `channel`. On a web channel every component can (the client's
|
|
107
|
+
* `uiCapabilities` narrow it); on a messaging channel a component can when it has a conversion for
|
|
108
|
+
* it, a chart renderer draws it, or it has a text summary (`fallbackText`) — a component without one
|
|
109
|
+
* would arrive as a JSON dump, so it is not offered. A sandbox never can, and `channels: { x: false }`
|
|
110
|
+
* opts a component out.
|
|
111
|
+
*/
|
|
112
|
+
export function canRenderOnChannel(definition, channel) {
|
|
113
|
+
if (definition.internal === true)
|
|
114
|
+
return false;
|
|
115
|
+
if (isSandbox(definition))
|
|
116
|
+
return !channel.messaging && channel.sandbox !== false;
|
|
117
|
+
if (!channel.messaging)
|
|
118
|
+
return conversionOf(definition, channel.name) !== false;
|
|
119
|
+
const conversion = conversionOf(definition, channel.name);
|
|
120
|
+
if (conversion === false)
|
|
121
|
+
return false;
|
|
122
|
+
if (definition.fallbackText !== undefined)
|
|
123
|
+
return true;
|
|
124
|
+
if (channel.render === 'text')
|
|
125
|
+
return false;
|
|
126
|
+
if (typeof conversion === 'function')
|
|
127
|
+
return true;
|
|
128
|
+
return channel.chartImages?.components.includes(definition.name) === true;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* The catalog as `channel` may draw it: only what it can render, and its own sandbox (or none). With
|
|
132
|
+
* no `channels` configured the catalog is returned as it is.
|
|
133
|
+
*/
|
|
134
|
+
export function channelCatalog(catalog, channel) {
|
|
135
|
+
if (!channel.configured)
|
|
136
|
+
return catalog;
|
|
137
|
+
if (channel.mode === 'text')
|
|
138
|
+
return defineCatalog([], { jsonSchemaValidator: catalog.validator });
|
|
139
|
+
const existing = catalog.components.find(isSandbox);
|
|
140
|
+
const kept = catalog.components.filter((definition) => !isSandbox(definition) && canRenderOnChannel(definition, channel));
|
|
141
|
+
const sandbox = channel.messaging || channel.sandbox === false
|
|
142
|
+
? undefined
|
|
143
|
+
: channel.sandbox === undefined || channel.sandbox === true
|
|
144
|
+
? (existing ?? (channel.sandbox === true ? defineSandbox() : undefined))
|
|
145
|
+
: defineSandbox({
|
|
146
|
+
...(existing !== undefined ? { name: existing.name } : {}),
|
|
147
|
+
...channel.sandbox,
|
|
148
|
+
});
|
|
149
|
+
return defineCatalog(sandbox === undefined ? kept : [...kept, sandbox], {
|
|
150
|
+
jsonSchemaValidator: catalog.validator,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
const CHANNEL_LABELS = {
|
|
154
|
+
whatsapp: 'WhatsApp',
|
|
155
|
+
telegram: 'Telegram',
|
|
156
|
+
email: 'email',
|
|
157
|
+
};
|
|
158
|
+
/** What a UI tool's description says about the channel the conversation is on. */
|
|
159
|
+
export function channelInstructions(channel) {
|
|
160
|
+
if (!channel.configured)
|
|
161
|
+
return undefined;
|
|
162
|
+
const lines = [];
|
|
163
|
+
if (channel.messaging) {
|
|
164
|
+
const label = CHANNEL_LABELS[channel.name] ?? channel.name;
|
|
165
|
+
lines.push(channel.render === 'html'
|
|
166
|
+
? `This conversation is read by ${label}: components arrive as formatted messages.`
|
|
167
|
+
: channel.render === 'text'
|
|
168
|
+
? `This conversation is on ${label}: components arrive as their text summary.`
|
|
169
|
+
: `This conversation is on ${label}: components arrive as ${label} messages (text, reply buttons, lists, images) — no interactive views, no custom layouts.`);
|
|
170
|
+
}
|
|
171
|
+
if (channel.instructions !== undefined)
|
|
172
|
+
lines.push(channel.instructions);
|
|
173
|
+
return lines.length > 0 ? lines.join(' ') : undefined;
|
|
174
|
+
}
|
|
175
|
+
function titleOf(props) {
|
|
176
|
+
return typeof props.title === 'string' && props.title.length > 0 ? props.title : undefined;
|
|
177
|
+
}
|
|
178
|
+
function escapeHtml(text) {
|
|
179
|
+
return text
|
|
180
|
+
.replace(/&/g, '&')
|
|
181
|
+
.replace(/</g, '<')
|
|
182
|
+
.replace(/>/g, '>')
|
|
183
|
+
.replace(/"/g, '"');
|
|
184
|
+
}
|
|
185
|
+
/** Plain text as minimal HTML: paragraphs, line breaks, `*bold*`. */
|
|
186
|
+
export function textToHtml(text) {
|
|
187
|
+
return text
|
|
188
|
+
.split(/\n{2,}/)
|
|
189
|
+
.filter((block) => block.trim() !== '')
|
|
190
|
+
.map((block) => `<p>${escapeHtml(block)
|
|
191
|
+
.replace(/\*\*([^*\n]+)\*\*/g, '<strong>$1</strong>')
|
|
192
|
+
.replace(/\*([^*\n]+)\*/g, '<strong>$1</strong>')
|
|
193
|
+
.replace(/\n/g, '<br>')}</p>`)
|
|
194
|
+
.join('\n');
|
|
195
|
+
}
|
|
196
|
+
async function nodeMessages(catalog, name, props, channel) {
|
|
197
|
+
if (channel.render === 'text')
|
|
198
|
+
return undefined;
|
|
199
|
+
const definition = catalog.get(name);
|
|
200
|
+
const conversion = conversionOf(definition, channel.name);
|
|
201
|
+
if (typeof conversion === 'function') {
|
|
202
|
+
try {
|
|
203
|
+
const converted = await conversion(props, { channel: channel.name });
|
|
204
|
+
if (converted !== null && converted !== undefined)
|
|
205
|
+
return Array.isArray(converted) ? converted : [converted];
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
/* a failing conversion falls back to the text summary */
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (channel.chartImages?.components.includes(name) === true) {
|
|
212
|
+
try {
|
|
213
|
+
const image = await channel.chartImages.render(name, props);
|
|
214
|
+
if (image !== null) {
|
|
215
|
+
const title = titleOf(props);
|
|
216
|
+
return [{ image, ...(title !== undefined ? { text: `*${title}*` } : {}) }];
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
/* no image: the text summary */
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return undefined;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* What a pushed component (a tree included) is on a channel the server draws for: one or more
|
|
227
|
+
* messages — its conversions, chart images, and the text summary of everything else, in order.
|
|
228
|
+
* Consecutive text is joined. Never throws: a conversion that fails sends the summary.
|
|
229
|
+
*/
|
|
230
|
+
export async function renderChannelMessages(catalog, component, channel) {
|
|
231
|
+
const out = [];
|
|
232
|
+
const pushText = (text, from) => {
|
|
233
|
+
// (`from` names where the text came from: the first component of a run of text.)
|
|
234
|
+
if (text.trim() === '')
|
|
235
|
+
return;
|
|
236
|
+
const last = out.at(-1);
|
|
237
|
+
if (last !== undefined &&
|
|
238
|
+
last.buttons === undefined &&
|
|
239
|
+
last.list === undefined &&
|
|
240
|
+
last.image === undefined &&
|
|
241
|
+
last.html === undefined &&
|
|
242
|
+
last.text !== undefined) {
|
|
243
|
+
last.text = `${last.text}\n\n${text}`;
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
out.push({
|
|
247
|
+
text,
|
|
248
|
+
component: from.name,
|
|
249
|
+
...(from.id !== undefined ? { componentId: from.id } : {}),
|
|
250
|
+
...(from.title !== undefined ? { title: from.title } : {}),
|
|
251
|
+
});
|
|
252
|
+
};
|
|
253
|
+
const visit = async (name, props, id, children, depth) => {
|
|
254
|
+
if (depth > 32)
|
|
255
|
+
return;
|
|
256
|
+
const title = titleOf(props);
|
|
257
|
+
const from = {
|
|
258
|
+
name,
|
|
259
|
+
...(id !== undefined ? { id } : {}),
|
|
260
|
+
...(title !== undefined ? { title } : {}),
|
|
261
|
+
};
|
|
262
|
+
const native = await nodeMessages(catalog, name, props, channel);
|
|
263
|
+
if (native !== undefined) {
|
|
264
|
+
for (const message of native) {
|
|
265
|
+
if (message.image === undefined &&
|
|
266
|
+
message.buttons === undefined &&
|
|
267
|
+
message.list === undefined &&
|
|
268
|
+
message.html === undefined &&
|
|
269
|
+
typeof message.text === 'string') {
|
|
270
|
+
pushText(message.text, from);
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
out.push({
|
|
274
|
+
...message,
|
|
275
|
+
component: name,
|
|
276
|
+
...(id !== undefined ? { componentId: id } : {}),
|
|
277
|
+
...(title !== undefined ? { title } : {}),
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
const definition = catalog.get(name);
|
|
283
|
+
const own = definition?.children === true && definition.fallbackText === undefined
|
|
284
|
+
? ''
|
|
285
|
+
: componentToText(catalog, name, props);
|
|
286
|
+
pushText(own, from);
|
|
287
|
+
}
|
|
288
|
+
for (const child of children ?? [])
|
|
289
|
+
await visit(child.type, child.props, id, child.children, depth + 1);
|
|
290
|
+
};
|
|
291
|
+
if (component.name === GENUI_TREE_COMPONENT) {
|
|
292
|
+
const root = component.props.root;
|
|
293
|
+
if (root !== undefined) {
|
|
294
|
+
await visit(root.type, root.props, component.id, root.children, 0);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
await visit(component.name, component.props, component.id, undefined, 0);
|
|
299
|
+
}
|
|
300
|
+
if (channel.render === 'html') {
|
|
301
|
+
for (const message of out) {
|
|
302
|
+
if (message.html === undefined && message.text !== undefined)
|
|
303
|
+
message.html = textToHtml(message.text);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return out;
|
|
307
|
+
}
|
|
308
|
+
/** The UI action a pressed button (or picked list entry) stands for — the user's next turn. */
|
|
309
|
+
export function channelButtonAction(button, from) {
|
|
310
|
+
return {
|
|
311
|
+
source: 'component',
|
|
312
|
+
name: button.action !== undefined && /^[A-Za-z0-9_.:-]{1,64}$/.test(button.action)
|
|
313
|
+
? button.action
|
|
314
|
+
: 'select',
|
|
315
|
+
context: isRecord(button.value) ? button.value : {},
|
|
316
|
+
text: button.label,
|
|
317
|
+
...(from.componentId !== undefined ? { componentId: from.componentId } : {}),
|
|
318
|
+
...(from.title !== undefined ? { title: from.title } : {}),
|
|
319
|
+
timestamp: new Date().toISOString(),
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
//# sourceMappingURL=channels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channels.js","sourceRoot":"","sources":["../../../src/genui/channels.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Charts as images, for channels that take images but cannot draw a chart (WhatsApp, Telegram, an
|
|
3
|
+
* email): `chartSvg(props)` draws the builtin `Chart` (bar or line) as SVG, and `chartImages()` turns
|
|
4
|
+
* it into a PNG with `@resvg/resvg-js` — an OPTIONAL peer dependency, loaded only when a chart is
|
|
5
|
+
* actually drawn.
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { chartImages } from '@adonis-agora/agent/genui/chart-image'
|
|
9
|
+
* genui({ catalog, channels: { whatsapp: { chartImages: chartImages() } } })
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
import type { ChartImageRenderer } from './channels.js';
|
|
13
|
+
import type { ChartProps } from './registry.js';
|
|
14
|
+
export interface ChartSvgOptions {
|
|
15
|
+
/** Default 800. */
|
|
16
|
+
width?: number;
|
|
17
|
+
/** Default 450. */
|
|
18
|
+
height?: number;
|
|
19
|
+
/** Series colors, in order. Default: a palette readable on white. */
|
|
20
|
+
colors?: readonly string[];
|
|
21
|
+
/** Default `#ffffff`. */
|
|
22
|
+
background?: string;
|
|
23
|
+
/** Default `#1f2328`. */
|
|
24
|
+
foreground?: string;
|
|
25
|
+
/** Default: a list of common sans-serif families (resvg picks the first installed one). */
|
|
26
|
+
fontFamily?: string;
|
|
27
|
+
}
|
|
28
|
+
/** The builtin `Chart` as an SVG document: axes, gridlines, bars or lines, a legend for 2+ series. */
|
|
29
|
+
export declare function chartSvg(props: ChartProps, options?: ChartSvgOptions): string;
|
|
30
|
+
export interface ChartImagesOptions extends ChartSvgOptions {
|
|
31
|
+
/** The components drawn as images, all taking {@link ChartProps}. Default `['Chart']`. */
|
|
32
|
+
components?: readonly string[];
|
|
33
|
+
/** Font files for resvg (a server without system fonts draws no text otherwise). */
|
|
34
|
+
fontFiles?: readonly string[];
|
|
35
|
+
}
|
|
36
|
+
/** SVG → PNG bytes, with `@resvg/resvg-js`. */
|
|
37
|
+
export declare function svgToPng(svg: string, options?: {
|
|
38
|
+
width?: number;
|
|
39
|
+
fontFiles?: readonly string[];
|
|
40
|
+
}): Promise<Uint8Array>;
|
|
41
|
+
/**
|
|
42
|
+
* Charts as PNG images on a channel (`genui({ channels: { whatsapp: { chartImages: chartImages() } } })`).
|
|
43
|
+
* A chart the renderer cannot draw (resvg missing, bad props) falls back to its text summary.
|
|
44
|
+
*/
|
|
45
|
+
export declare function chartImages(options?: ChartImagesOptions): ChartImageRenderer;
|
|
46
|
+
//# sourceMappingURL=chart-image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-image.d.ts","sourceRoot":"","sources":["../../../src/genui/chart-image.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAsB,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC5E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,mBAAmB;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mBAAmB;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,yBAAyB;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2FAA2F;IAC3F,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA8BD,sGAAsG;AACtG,wBAAgB,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,GAAE,eAAoB,GAAG,MAAM,CAoGjF;AAED,MAAM,WAAW,kBAAmB,SAAQ,eAAe;IACzD,0FAA0F;IAC1F,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,oFAAoF;IACpF,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B;AAuBD,+CAA+C;AAC/C,wBAAsB,QAAQ,CAC5B,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAO,GAC9D,OAAO,CAAC,UAAU,CAAC,CAUrB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,kBAAkB,CAehF"}
|