@copilotkit/bot-ui 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +171 -0
- package/dist/bind.d.ts +6 -0
- package/dist/bind.d.ts.map +1 -0
- package/dist/bind.js +18 -0
- package/dist/bind.test.d.ts +2 -0
- package/dist/bind.test.d.ts.map +1 -0
- package/dist/bind.test.js +14 -0
- package/dist/components.d.ts +98 -0
- package/dist/components.d.ts.map +1 -0
- package/dist/components.js +31 -0
- package/dist/components.test.d.ts +2 -0
- package/dist/components.test.d.ts.map +1 -0
- package/dist/components.test.js +71 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/ir.d.ts +11 -0
- package/dist/ir.d.ts.map +1 -0
- package/dist/ir.js +1 -0
- package/dist/jsx-dev-runtime.d.ts +7 -0
- package/dist/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/jsx-dev-runtime.js +4 -0
- package/dist/jsx-runtime.d.ts +30 -0
- package/dist/jsx-runtime.d.ts.map +1 -0
- package/dist/jsx-runtime.js +6 -0
- package/dist/jsx-runtime.test.d.ts +2 -0
- package/dist/jsx-runtime.test.d.ts.map +1 -0
- package/dist/jsx-runtime.test.js +17 -0
- package/dist/render.d.ts +3 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +37 -0
- package/dist/render.test.d.ts +2 -0
- package/dist/render.test.d.ts.map +1 -0
- package/dist/render.test.js +39 -0
- package/dist/types.d.ts +65 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +61 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Atai Barkai
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# @copilotkit/bot-ui
|
|
2
|
+
|
|
3
|
+
A pure **JSX runtime + intermediate representation (IR) + cross-platform
|
|
4
|
+
component vocabulary** for authoring rich bot messages. No React, no agent
|
|
5
|
+
runtime, no Slack — `@copilotkit/bot-ui` depends on nothing in the repo
|
|
6
|
+
except `@copilotkit/shared` (for `StandardSchemaV1` types). That's what lets
|
|
7
|
+
a platform adapter (e.g. `@copilotkit/bot-slack`) translate the same UI into
|
|
8
|
+
Block Kit, while keeping the component layer tree-shakeable and testable in
|
|
9
|
+
isolation.
|
|
10
|
+
|
|
11
|
+
You author UI as JSX, it normalizes to one serializable IR (`BotNode[]`), and
|
|
12
|
+
behavior props (`onClick` / `onSelect` / `onSubmit`) ride along on the nodes
|
|
13
|
+
for the engine (`@copilotkit/bot`) to bind.
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
pnpm add @copilotkit/bot-ui
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
To author components as JSX, point the TypeScript JSX factory at this package
|
|
22
|
+
in the consuming project's `tsconfig.json`:
|
|
23
|
+
|
|
24
|
+
```jsonc
|
|
25
|
+
{
|
|
26
|
+
"compilerOptions": {
|
|
27
|
+
"jsx": "react-jsx",
|
|
28
|
+
"jsxImportSource": "@copilotkit/bot-ui",
|
|
29
|
+
},
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
This package ships `@copilotkit/bot-ui/jsx-runtime` (and
|
|
34
|
+
`/jsx-dev-runtime`) exporting `jsx` / `jsxs` / `Fragment`. Author component
|
|
35
|
+
files as `.tsx`.
|
|
36
|
+
|
|
37
|
+
## Example
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
import {
|
|
41
|
+
Message,
|
|
42
|
+
Header,
|
|
43
|
+
Section,
|
|
44
|
+
Actions,
|
|
45
|
+
Button,
|
|
46
|
+
renderToIR,
|
|
47
|
+
} from "@copilotkit/bot-ui";
|
|
48
|
+
|
|
49
|
+
function Greeting({ name }: { name: string }) {
|
|
50
|
+
return (
|
|
51
|
+
<Message>
|
|
52
|
+
<Header>Hello {name}</Header>
|
|
53
|
+
<Section>Pick an option — **bold** and `code` work too.</Section>
|
|
54
|
+
<Actions>
|
|
55
|
+
<Button
|
|
56
|
+
style="primary"
|
|
57
|
+
onClick={(ctx) => ctx.thread.post("you clicked!")}
|
|
58
|
+
>
|
|
59
|
+
Continue
|
|
60
|
+
</Button>
|
|
61
|
+
</Actions>
|
|
62
|
+
</Message>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const ir = renderToIR(<Greeting name="Ada" />);
|
|
67
|
+
// ir is BotNode[] — hand it to an adapter, or let @copilotkit/bot post it.
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`renderToIR(ui: Renderable): BotNode[]` recursively invokes any component
|
|
71
|
+
function (passing its props) until only intrinsic string-typed nodes remain;
|
|
72
|
+
strings in children become `{ type: "text", props: { value } }`; `Fragment`
|
|
73
|
+
flattens its children. Components must be **pure functions of serializable
|
|
74
|
+
props** — same props in, same tree out — which is what makes content-stable
|
|
75
|
+
action binding and re-render rehydration possible in `@copilotkit/bot`.
|
|
76
|
+
|
|
77
|
+
`Renderable` also accepts a `{ raw }` escape hatch, which `renderToIR` passes
|
|
78
|
+
through as `{ type: "raw", props: { value } }` for adapters that want to
|
|
79
|
+
short-circuit to a native payload.
|
|
80
|
+
|
|
81
|
+
## Component vocabulary
|
|
82
|
+
|
|
83
|
+
Each component is a thin function returning a `BotNode` with a stable
|
|
84
|
+
intrinsic `type` string. An adapter maps these to native primitives.
|
|
85
|
+
|
|
86
|
+
Every component has a fully-typed prop interface (`MessageProps`,
|
|
87
|
+
`ButtonProps`, …, all exported), and the package ships its own `JSX` namespace
|
|
88
|
+
(resolved via `jsxImportSource: "@copilotkit/bot-ui"`). So JSX is statically
|
|
89
|
+
checked: unknown attributes, wrong prop values, and bad children are
|
|
90
|
+
compile-time errors — `<Section bogus={1} />` or `<Button style="nope">` won't
|
|
91
|
+
type-check. There are no lowercase intrinsic tags; the vocabulary is the
|
|
92
|
+
capitalized component set below.
|
|
93
|
+
|
|
94
|
+
| Component | Purpose |
|
|
95
|
+
| ---------- | ----------------------------------------------------------------- | ---------- |
|
|
96
|
+
| `Message` | Root container for a single posted message. |
|
|
97
|
+
| `Header` | Bold header / title row. |
|
|
98
|
+
| `Section` | A block of (markdown) body text. |
|
|
99
|
+
| `Markdown` | Explicit markdown text block. |
|
|
100
|
+
| `Field` | One label/value cell inside `Fields`. |
|
|
101
|
+
| `Fields` | A grid of `Field`s (two-column key/value layout). |
|
|
102
|
+
| `Context` | Small, muted secondary text (footnotes, metadata). |
|
|
103
|
+
| `Actions` | Row container for interactive controls. |
|
|
104
|
+
| `Button` | Clickable button — `onClick`, `value`, `style: "primary" | "danger"`. |
|
|
105
|
+
| `Select` | Dropdown — `onSelect`, `placeholder`, `options: {label,value}[]`. |
|
|
106
|
+
| `Input` | Text input — `onSubmit`, `placeholder`, `multiline`, `name`. |
|
|
107
|
+
| `Image` | An image block. |
|
|
108
|
+
| `Divider` | A horizontal rule. |
|
|
109
|
+
|
|
110
|
+
### Behavior props
|
|
111
|
+
|
|
112
|
+
Interactive components carry handler props typed as `ClickHandler`:
|
|
113
|
+
|
|
114
|
+
- `Button` → `onClick`
|
|
115
|
+
- `Select` → `onSelect`
|
|
116
|
+
- `Input` → `onSubmit`
|
|
117
|
+
|
|
118
|
+
A `ClickHandler` receives an `InteractionContext`, both generic over the
|
|
119
|
+
clicked control's value type:
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
type ClickHandler<TValue = unknown> = (
|
|
123
|
+
ctx: InteractionContext<TValue>,
|
|
124
|
+
) => void | Promise<void>;
|
|
125
|
+
|
|
126
|
+
interface InteractionContext<TValue = unknown> {
|
|
127
|
+
thread: Thread;
|
|
128
|
+
message: IncomingMessage;
|
|
129
|
+
action: { id: string; value?: TValue };
|
|
130
|
+
values: Record<string, unknown>;
|
|
131
|
+
user: PlatformUser;
|
|
132
|
+
platform: string;
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
`Button` is generic over its `value` prop, so `ctx.action.value` is **inferred**
|
|
137
|
+
from `value` — `<Button value={{ confirmed: true }} onClick={(ctx) => ctx.action.value?.confirmed}>`
|
|
138
|
+
type-checks with no cast. `Select`/`Input` resolve the value to `string`.
|
|
139
|
+
|
|
140
|
+
The structural types `Thread`, `IncomingMessage`, `PlatformUser`,
|
|
141
|
+
`MessageRef`, and `ClickHandler` are declared here for handler typing only —
|
|
142
|
+
they're implemented at runtime by `@copilotkit/bot` and its adapters.
|
|
143
|
+
`@copilotkit/bot-ui` has no runtime dependency on them.
|
|
144
|
+
|
|
145
|
+
## `bind()` — the Tier-2 escape hatch
|
|
146
|
+
|
|
147
|
+
Inline `onClick` handlers are bound by content (component identity + path +
|
|
148
|
+
serializable props), so a handler can be re-derived after a restart by
|
|
149
|
+
re-rendering the component. When a handler closes over data that **can't** be
|
|
150
|
+
reconstructed from props, wrap it with `bind()` so the engine persists that
|
|
151
|
+
small payload explicitly alongside the minted action id:
|
|
152
|
+
|
|
153
|
+
```tsx
|
|
154
|
+
import { bind } from "@copilotkit/bot-ui";
|
|
155
|
+
|
|
156
|
+
<Button onClick={bind(handleChoice, { choiceId: "abc123" })}>Choose</Button>;
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
`bind(handler, args)` returns a tagged handler; the action registry stores
|
|
160
|
+
`args` so a cold-path dispatch passes them back via `ctx.action.value`. Keep
|
|
161
|
+
`args` small — it's the only handler-specific state that survives a restart.
|
|
162
|
+
|
|
163
|
+
## Exports
|
|
164
|
+
|
|
165
|
+
Runtime: `renderToIR`, `Fragment`, `bind`, and the vocabulary
|
|
166
|
+
(`Message`, `Header`, `Section`, `Markdown`, `Field`, `Fields`, `Context`,
|
|
167
|
+
`Actions`, `Button`, `Select`, `Input`, `Image`, `Divider`).
|
|
168
|
+
Types: `BotNode`, `BotChildren`, `ComponentFn`, `Renderable`, `Thread`,
|
|
169
|
+
`InteractionContext`, `PlatformUser`, `IncomingMessage`, `MessageRef`,
|
|
170
|
+
`ClickHandler`, and the per-component prop types (`MessageProps`,
|
|
171
|
+
`ButtonProps`, `SelectProps`, `TableProps`, `TableColumn`, …).
|
package/dist/bind.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ClickHandler } from "./types.js";
|
|
2
|
+
export declare function bind(handler: ClickHandler, args: unknown): ClickHandler;
|
|
3
|
+
export declare function isBound(h: unknown): boolean;
|
|
4
|
+
export declare function getBoundArgs(h: unknown): unknown;
|
|
5
|
+
export declare function getBoundHandler(h: unknown): ClickHandler | undefined;
|
|
6
|
+
//# sourceMappingURL=bind.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bind.d.ts","sourceRoot":"","sources":["../src/bind.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAsB,MAAM,YAAY,CAAC;AAMnE,wBAAgB,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,GAAG,YAAY,CAQvE;AACD,wBAAgB,OAAO,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAE3C;AACD,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAEhD;AACD,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO,GAAG,YAAY,GAAG,SAAS,CAEpE"}
|
package/dist/bind.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const BOUND = Symbol.for("copilotkit.bot-ui.bound");
|
|
2
|
+
export function bind(handler, args) {
|
|
3
|
+
const wrapped = ((ctx) => handler({
|
|
4
|
+
...ctx,
|
|
5
|
+
action: { ...ctx.action, value: args },
|
|
6
|
+
}));
|
|
7
|
+
wrapped[BOUND] = { handler, args };
|
|
8
|
+
return wrapped;
|
|
9
|
+
}
|
|
10
|
+
export function isBound(h) {
|
|
11
|
+
return typeof h === "function" && !!h[BOUND];
|
|
12
|
+
}
|
|
13
|
+
export function getBoundArgs(h) {
|
|
14
|
+
return h[BOUND]?.args;
|
|
15
|
+
}
|
|
16
|
+
export function getBoundHandler(h) {
|
|
17
|
+
return h[BOUND]?.handler;
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bind.test.d.ts","sourceRoot":"","sources":["../src/bind.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { bind, isBound, getBoundArgs, getBoundHandler } from "./bind.js";
|
|
3
|
+
describe("bind", () => {
|
|
4
|
+
it("tags a handler with serializable args", () => {
|
|
5
|
+
const h = () => { };
|
|
6
|
+
const b = bind(h, { flightId: "x1" });
|
|
7
|
+
expect(isBound(b)).toBe(true);
|
|
8
|
+
expect(getBoundArgs(b)).toEqual({ flightId: "x1" });
|
|
9
|
+
expect(getBoundHandler(b)).toBe(h);
|
|
10
|
+
});
|
|
11
|
+
it("plain handler is not bound", () => {
|
|
12
|
+
expect(isBound(() => { })).toBe(false);
|
|
13
|
+
});
|
|
14
|
+
});
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { BotNode } from "./ir.js";
|
|
2
|
+
import type { ClickHandler } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Anything that can appear as a child in the component tree: nested elements,
|
|
5
|
+
* text, numbers, and conditionals (`false` / `null` / `undefined` render
|
|
6
|
+
* nothing), plus arrays thereof.
|
|
7
|
+
*/
|
|
8
|
+
export type BotChildren = BotNode | string | number | boolean | null | undefined | BotChildren[];
|
|
9
|
+
/** Mixin for the container components that wrap children. */
|
|
10
|
+
interface WithChildren {
|
|
11
|
+
children?: BotChildren;
|
|
12
|
+
}
|
|
13
|
+
export interface MessageProps extends WithChildren {
|
|
14
|
+
/** Accent color (hex, e.g. `#27AE60`) for the message's colored rail. */
|
|
15
|
+
accent?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface HeaderProps extends WithChildren {
|
|
18
|
+
}
|
|
19
|
+
export interface SectionProps extends WithChildren {
|
|
20
|
+
}
|
|
21
|
+
export interface MarkdownProps extends WithChildren {
|
|
22
|
+
}
|
|
23
|
+
export interface FieldsProps extends WithChildren {
|
|
24
|
+
}
|
|
25
|
+
export interface FieldProps extends WithChildren {
|
|
26
|
+
}
|
|
27
|
+
export interface ContextProps extends WithChildren {
|
|
28
|
+
}
|
|
29
|
+
export interface ActionsProps extends WithChildren {
|
|
30
|
+
}
|
|
31
|
+
export interface ImageProps {
|
|
32
|
+
/** Image URL. */
|
|
33
|
+
url: string;
|
|
34
|
+
/** Alternative text for accessibility. */
|
|
35
|
+
alt?: string;
|
|
36
|
+
}
|
|
37
|
+
/** `<Divider />` takes no props or children. */
|
|
38
|
+
export type DividerProps = {
|
|
39
|
+
children?: never;
|
|
40
|
+
};
|
|
41
|
+
export interface ButtonProps<TValue = unknown> extends WithChildren {
|
|
42
|
+
/**
|
|
43
|
+
* Inline handler run when the button is clicked (bound by the action
|
|
44
|
+
* registry). Its `ctx.action.value` is typed as `TValue`, inferred from
|
|
45
|
+
* `value`.
|
|
46
|
+
*/
|
|
47
|
+
onClick?: ClickHandler<TValue>;
|
|
48
|
+
/** Value echoed back to `onClick`/`awaitChoice` on click; drives `TValue`. */
|
|
49
|
+
value?: TValue;
|
|
50
|
+
/** Slack button accent. */
|
|
51
|
+
style?: "primary" | "danger";
|
|
52
|
+
}
|
|
53
|
+
export interface SelectOption {
|
|
54
|
+
label: string;
|
|
55
|
+
value: string;
|
|
56
|
+
}
|
|
57
|
+
export interface SelectProps {
|
|
58
|
+
/** Handler run on selection; `ctx.action.value` is the chosen option's `value`. */
|
|
59
|
+
onSelect?: ClickHandler<string>;
|
|
60
|
+
placeholder?: string;
|
|
61
|
+
options: SelectOption[];
|
|
62
|
+
}
|
|
63
|
+
export interface InputProps {
|
|
64
|
+
/** Handler run on submit; `ctx.action.value` is the entered text. */
|
|
65
|
+
onSubmit?: ClickHandler<string>;
|
|
66
|
+
placeholder?: string;
|
|
67
|
+
multiline?: boolean;
|
|
68
|
+
name?: string;
|
|
69
|
+
}
|
|
70
|
+
export interface TableColumn {
|
|
71
|
+
header: string;
|
|
72
|
+
align?: "left" | "center" | "right";
|
|
73
|
+
}
|
|
74
|
+
export interface TableProps extends WithChildren {
|
|
75
|
+
columns?: TableColumn[];
|
|
76
|
+
}
|
|
77
|
+
export interface RowProps extends WithChildren {
|
|
78
|
+
}
|
|
79
|
+
export interface CellProps extends WithChildren {
|
|
80
|
+
}
|
|
81
|
+
export declare const Message: (props: MessageProps) => BotNode;
|
|
82
|
+
export declare const Header: (props: HeaderProps) => BotNode;
|
|
83
|
+
export declare const Section: (props: SectionProps) => BotNode;
|
|
84
|
+
export declare const Markdown: (props: MarkdownProps) => BotNode;
|
|
85
|
+
export declare const Field: (props: FieldProps) => BotNode;
|
|
86
|
+
export declare const Fields: (props: FieldsProps) => BotNode;
|
|
87
|
+
export declare const Context: (props: ContextProps) => BotNode;
|
|
88
|
+
export declare const Actions: (props: ActionsProps) => BotNode;
|
|
89
|
+
export declare const Image: (props: ImageProps) => BotNode;
|
|
90
|
+
export declare const Divider: (props: DividerProps) => BotNode;
|
|
91
|
+
export declare const Row: (props: RowProps) => BotNode;
|
|
92
|
+
export declare const Cell: (props: CellProps) => BotNode;
|
|
93
|
+
export declare function Button<TValue = unknown>(props: ButtonProps<TValue>): BotNode;
|
|
94
|
+
export declare function Select(props: SelectProps): BotNode;
|
|
95
|
+
export declare function Input(props: InputProps): BotNode;
|
|
96
|
+
export declare function Table(props: TableProps): BotNode;
|
|
97
|
+
export {};
|
|
98
|
+
//# sourceMappingURL=components.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../src/components.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// ---- Components ----------------------------------------------------------
|
|
2
|
+
// `intrinsic` produces a typed component that lowers `<X .../>` to an IR node
|
|
3
|
+
// of the given `type`; the generic `P` is what gives each tag its prop type.
|
|
4
|
+
const intrinsic = (type) => (props) => ({
|
|
5
|
+
type,
|
|
6
|
+
props: (props ?? {}),
|
|
7
|
+
});
|
|
8
|
+
export const Message = intrinsic("message");
|
|
9
|
+
export const Header = intrinsic("header");
|
|
10
|
+
export const Section = intrinsic("section");
|
|
11
|
+
export const Markdown = intrinsic("markdown");
|
|
12
|
+
export const Field = intrinsic("field");
|
|
13
|
+
export const Fields = intrinsic("fields");
|
|
14
|
+
export const Context = intrinsic("context");
|
|
15
|
+
export const Actions = intrinsic("actions");
|
|
16
|
+
export const Image = intrinsic("image");
|
|
17
|
+
export const Divider = intrinsic("divider");
|
|
18
|
+
export const Row = intrinsic("row");
|
|
19
|
+
export const Cell = intrinsic("cell");
|
|
20
|
+
export function Button(props) {
|
|
21
|
+
return { type: "button", props: props };
|
|
22
|
+
}
|
|
23
|
+
export function Select(props) {
|
|
24
|
+
return { type: "select", props: props };
|
|
25
|
+
}
|
|
26
|
+
export function Input(props) {
|
|
27
|
+
return { type: "input", props: props };
|
|
28
|
+
}
|
|
29
|
+
export function Table(props) {
|
|
30
|
+
return { type: "table", props: props };
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.test.d.ts","sourceRoot":"","sources":["../src/components.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@copilotkit/bot-ui/jsx-runtime";
|
|
2
|
+
import { describe, it, expect } from "vitest";
|
|
3
|
+
import { renderToIR } from "./render.js";
|
|
4
|
+
import { Message, Header, Section, Actions, Button, Divider, Table, Row, Cell, Image, Select, } from "./components.js";
|
|
5
|
+
/**
|
|
6
|
+
* Compile-time prop type guards. This arrow is never invoked — the assertions
|
|
7
|
+
* are validated by `tsc` (build / check-types). Each `@ts-expect-error` fails
|
|
8
|
+
* the type-check if the props ever stop being enforced (regression guard); the
|
|
9
|
+
* trailing valid cases fail if a legitimate usage is wrongly rejected.
|
|
10
|
+
*/
|
|
11
|
+
const __typeGuards = () => {
|
|
12
|
+
// @ts-expect-error unknown prop on a container component
|
|
13
|
+
_jsx(Section, { bogus: 1 });
|
|
14
|
+
// @ts-expect-error invalid Button.style value
|
|
15
|
+
_jsx(Button, { style: "nope", children: "x" });
|
|
16
|
+
// @ts-expect-error excess prop on Button
|
|
17
|
+
_jsx(Button, { extra: true, children: "x" });
|
|
18
|
+
// @ts-expect-error Message.accent must be a string
|
|
19
|
+
_jsx(Message, { accent: 1 });
|
|
20
|
+
// @ts-expect-error Divider takes no children
|
|
21
|
+
_jsx(Divider, { children: "x" });
|
|
22
|
+
// @ts-expect-error Image.url is required
|
|
23
|
+
_jsx(Image, { alt: "x" });
|
|
24
|
+
// @ts-expect-error Select.options is required
|
|
25
|
+
_jsx(Select, { placeholder: "p" });
|
|
26
|
+
// Valid usages — must type-check cleanly.
|
|
27
|
+
_jsxs(Section, { children: ["hello ", 42] });
|
|
28
|
+
_jsx(Message, { accent: "#27AE60", children: _jsx(Header, { children: "Title" }) });
|
|
29
|
+
_jsx(Button, { style: "primary", value: { ok: true }, onClick: () => { }, children: "Go" });
|
|
30
|
+
_jsx(Image, { url: "https://example.com/x.png", alt: "x" });
|
|
31
|
+
// Button.value flows into onClick: ctx.action.value is inferred, not unknown.
|
|
32
|
+
_jsx(Button, { value: { confirmed: true }, onClick: (ctx) => {
|
|
33
|
+
ctx.action.value?.confirmed;
|
|
34
|
+
// @ts-expect-error 'nope' is not on the inferred value type
|
|
35
|
+
ctx.action.value?.nope;
|
|
36
|
+
}, children: "Confirm" });
|
|
37
|
+
};
|
|
38
|
+
void __typeGuards;
|
|
39
|
+
describe("component vocabulary", () => {
|
|
40
|
+
it("Message wraps children with intrinsic type 'message'", () => {
|
|
41
|
+
const out = renderToIR(_jsx(Message, { children: _jsx(Header, { children: "Hi" }) }));
|
|
42
|
+
expect(out[0].type).toBe("message");
|
|
43
|
+
});
|
|
44
|
+
it("Button carries onClick and style in props", () => {
|
|
45
|
+
const fn = () => { };
|
|
46
|
+
const out = renderToIR(_jsx(Actions, { children: _jsx(Button, { onClick: fn, style: "primary", children: "Go" }) }));
|
|
47
|
+
const actions = out[0];
|
|
48
|
+
const button = actions.props.children[0];
|
|
49
|
+
expect(button.type).toBe("button");
|
|
50
|
+
expect(button.props.onClick).toBe(fn);
|
|
51
|
+
expect(button.props.style).toBe("primary");
|
|
52
|
+
});
|
|
53
|
+
it("Divider renders with no children", () => {
|
|
54
|
+
const out = renderToIR(_jsx(Divider, {}));
|
|
55
|
+
expect(out[0]).toMatchObject({ type: "divider" });
|
|
56
|
+
});
|
|
57
|
+
it("Table carries columns and nests Row→Cell→text children", () => {
|
|
58
|
+
const out = renderToIR(_jsx(Table, { columns: [{ header: "Name" }, { header: "Status", align: "center" }], children: _jsxs(Row, { children: [_jsx(Cell, { children: "Ana" }), _jsx(Cell, { children: "Active" })] }) }));
|
|
59
|
+
const table = out[0];
|
|
60
|
+
expect(table.type).toBe("table");
|
|
61
|
+
expect(table.props.columns.length).toBe(2);
|
|
62
|
+
const rows = table.props.children;
|
|
63
|
+
const row = rows[0];
|
|
64
|
+
expect(row.type).toBe("row");
|
|
65
|
+
const cells = row.props.children;
|
|
66
|
+
expect(cells.length).toBe(2);
|
|
67
|
+
expect(cells[0].type).toBe("cell");
|
|
68
|
+
const cellText = cells[0].props.children[0];
|
|
69
|
+
expect(cellText).toMatchObject({ type: "text", props: { value: "Ana" } });
|
|
70
|
+
});
|
|
71
|
+
});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
package/dist/ir.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type ComponentFn = (props: Record<string, unknown>) => BotNode | BotNode[] | string | null;
|
|
2
|
+
export interface BotNode {
|
|
3
|
+
type: string | ComponentFn | symbol;
|
|
4
|
+
props: Record<string, unknown>;
|
|
5
|
+
key?: string | number;
|
|
6
|
+
}
|
|
7
|
+
export type Renderable = string | BotNode | BotNode[] | {
|
|
8
|
+
raw: unknown;
|
|
9
|
+
};
|
|
10
|
+
export declare const Fragment: unique symbol;
|
|
11
|
+
//# sourceMappingURL=ir.d.ts.map
|
package/dist/ir.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ir.d.ts","sourceRoot":"","sources":["../src/ir.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,CACxB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC3B,OAAO,GAAG,OAAO,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC;AACzC,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AACD,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,EAAE,GAAG;IAAE,GAAG,EAAE,OAAO,CAAA;CAAE,CAAC;AACzE,eAAO,MAAM,QAAQ,EAAE,OAAO,MAAiD,CAAC"}
|
package/dist/ir.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const Fragment = Symbol.for("copilotkit.bot-ui.Fragment");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsx-dev-runtime.d.ts","sourceRoot":"","sources":["../src/jsx-dev-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,wBAAgB,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG;;;;EAEtD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Fragment, type BotNode } from "./ir.js";
|
|
2
|
+
export { Fragment };
|
|
3
|
+
export declare function jsx(type: string | ((props: never) => unknown) | symbol, props: Record<string, unknown> | null, key?: string | number): BotNode;
|
|
4
|
+
export declare const jsxs: typeof jsx;
|
|
5
|
+
/**
|
|
6
|
+
* The JSX type contract for this runtime. Declaring it here (rather than
|
|
7
|
+
* relying on a global `JSX` namespace) is what makes the compiler actually
|
|
8
|
+
* check element props: unknown attributes and bad children are errors, and
|
|
9
|
+
* every element returns an {@link BotNode}.
|
|
10
|
+
*
|
|
11
|
+
* Resolved by TypeScript because `jsxImportSource` points at this package, so
|
|
12
|
+
* `<Section foo={1} />` is checked against `SectionProps` with excess-property
|
|
13
|
+
* checking — there are no lowercase intrinsic tags.
|
|
14
|
+
*/
|
|
15
|
+
export declare namespace JSX {
|
|
16
|
+
/** The result of evaluating a JSX expression. */
|
|
17
|
+
type Element = BotNode;
|
|
18
|
+
/** Tells TypeScript which prop receives nested children. */
|
|
19
|
+
interface ElementChildrenAttribute {
|
|
20
|
+
children: {};
|
|
21
|
+
}
|
|
22
|
+
/** Props implicitly accepted by every element. */
|
|
23
|
+
interface IntrinsicAttributes {
|
|
24
|
+
key?: string | number;
|
|
25
|
+
}
|
|
26
|
+
/** No lowercase intrinsic tags — the vocabulary is the capitalized components. */
|
|
27
|
+
interface IntrinsicElements {
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=jsx-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsx-runtime.d.ts","sourceRoot":"","sources":["../src/jsx-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,CAAC;AAEpB,wBAAgB,GAAG,CACjB,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,GAAG,MAAM,EACnD,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EACrC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GACpB,OAAO,CAET;AACD,eAAO,MAAM,IAAI,YAAM,CAAC;AAExB;;;;;;;;;GASG;AACH,yBAAiB,GAAG,CAAC;IACnB,iDAAiD;IACjD,KAAY,OAAO,GAAG,OAAO,CAAC;IAC9B,4DAA4D;IAC5D,UAAiB,wBAAwB;QACvC,QAAQ,EAAE,EAAE,CAAC;KACd;IACD,kDAAkD;IAClD,UAAiB,mBAAmB;QAClC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KACvB;IACD,kFAAkF;IAClF,UAAiB,iBAAiB;KAAG;CACtC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsx-runtime.test.d.ts","sourceRoot":"","sources":["../src/jsx-runtime.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { jsx, jsxs, Fragment } from "./jsx-runtime.js";
|
|
3
|
+
describe("jsx factory", () => {
|
|
4
|
+
it("builds an BotNode with type and props", () => {
|
|
5
|
+
const node = jsx("section", { children: "hi" });
|
|
6
|
+
expect(node.type).toBe("section");
|
|
7
|
+
expect(node.props.children).toBe("hi");
|
|
8
|
+
});
|
|
9
|
+
it("jsxs keeps array children", () => {
|
|
10
|
+
const node = jsxs("actions", { children: ["a", "b"] });
|
|
11
|
+
expect(Array.isArray(node.props.children)).toBe(true);
|
|
12
|
+
});
|
|
13
|
+
it("Fragment is a stable sentinel", () => {
|
|
14
|
+
const node = jsx(Fragment, { children: ["a", "b"] });
|
|
15
|
+
expect(node.type).toBe(Fragment);
|
|
16
|
+
});
|
|
17
|
+
});
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAkClE,wBAAgB,UAAU,CAAC,EAAE,EAAE,UAAU,GAAG,OAAO,EAAE,CAKpD"}
|
package/dist/render.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Fragment } from "./ir.js";
|
|
2
|
+
function isBotNode(v) {
|
|
3
|
+
return typeof v === "object" && v !== null && "type" in v && "props" in v;
|
|
4
|
+
}
|
|
5
|
+
function expand(node) {
|
|
6
|
+
if (node == null || node === false || node === true)
|
|
7
|
+
return [];
|
|
8
|
+
if (typeof node === "string" || typeof node === "number") {
|
|
9
|
+
return [{ type: "text", props: { value: String(node) } }];
|
|
10
|
+
}
|
|
11
|
+
if (Array.isArray(node))
|
|
12
|
+
return node.flatMap(expand);
|
|
13
|
+
if (!isBotNode(node))
|
|
14
|
+
return [];
|
|
15
|
+
if (node.type === Fragment)
|
|
16
|
+
return expand(node.props.children);
|
|
17
|
+
if (typeof node.type === "function") {
|
|
18
|
+
return expand(node.type(node.props));
|
|
19
|
+
}
|
|
20
|
+
const { children, ...rest } = node.props;
|
|
21
|
+
const expandedChildren = children === undefined ? undefined : expand(children);
|
|
22
|
+
return [
|
|
23
|
+
{
|
|
24
|
+
type: node.type,
|
|
25
|
+
props: expandedChildren === undefined
|
|
26
|
+
? rest
|
|
27
|
+
: { ...rest, children: expandedChildren },
|
|
28
|
+
key: node.key,
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
export function renderToIR(ui) {
|
|
33
|
+
if (typeof ui === "object" && ui !== null && "raw" in ui) {
|
|
34
|
+
return [{ type: "raw", props: { value: ui.raw } }];
|
|
35
|
+
}
|
|
36
|
+
return expand(ui);
|
|
37
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.test.d.ts","sourceRoot":"","sources":["../src/render.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "@copilotkit/bot-ui/jsx-runtime";
|
|
2
|
+
import { describe, it, expect } from "vitest";
|
|
3
|
+
import { renderToIR } from "./render.js";
|
|
4
|
+
function Card(props) {
|
|
5
|
+
return { type: "section", props: { children: props.title } };
|
|
6
|
+
}
|
|
7
|
+
describe("renderToIR", () => {
|
|
8
|
+
it("wraps a bare string into a text node", () => {
|
|
9
|
+
expect(renderToIR("hi")).toEqual([
|
|
10
|
+
{ type: "text", props: { value: "hi" } },
|
|
11
|
+
]);
|
|
12
|
+
});
|
|
13
|
+
it("expands a component function with its props", () => {
|
|
14
|
+
const out = renderToIR(_jsx(Card, { title: "Flights" }));
|
|
15
|
+
expect(out).toEqual([
|
|
16
|
+
{
|
|
17
|
+
type: "section",
|
|
18
|
+
props: { children: [{ type: "text", props: { value: "Flights" } }] },
|
|
19
|
+
},
|
|
20
|
+
]);
|
|
21
|
+
});
|
|
22
|
+
it("flattens Fragment children and nested components", () => {
|
|
23
|
+
const out = renderToIR(_jsxs(_Fragment, { children: [_jsx(Card, { title: "A" }), _jsx(Card, { title: "B" })] }));
|
|
24
|
+
expect(out.map((n) => n.type)).toEqual(["section", "section"]);
|
|
25
|
+
});
|
|
26
|
+
it("wraps string children inside intrinsic nodes recursively", () => {
|
|
27
|
+
const out = renderToIR({ type: "actions", props: { children: ["x"] } });
|
|
28
|
+
const actions = out[0];
|
|
29
|
+
expect(actions.props.children[0]).toEqual({
|
|
30
|
+
type: "text",
|
|
31
|
+
props: { value: "x" },
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
it("passes {raw} through as a raw node", () => {
|
|
35
|
+
expect(renderToIR({ raw: [{ block: 1 }] })).toEqual([
|
|
36
|
+
{ type: "raw", props: { value: [{ block: 1 }] } },
|
|
37
|
+
]);
|
|
38
|
+
});
|
|
39
|
+
});
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export interface MessageRef {
|
|
2
|
+
id: string;
|
|
3
|
+
[k: string]: unknown;
|
|
4
|
+
}
|
|
5
|
+
export interface PlatformUser {
|
|
6
|
+
id: string;
|
|
7
|
+
name?: string;
|
|
8
|
+
handle?: string;
|
|
9
|
+
email?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface IncomingMessage {
|
|
12
|
+
text: string;
|
|
13
|
+
user: PlatformUser;
|
|
14
|
+
ref: MessageRef;
|
|
15
|
+
platform: string;
|
|
16
|
+
}
|
|
17
|
+
export interface ThreadMessage {
|
|
18
|
+
user?: PlatformUser;
|
|
19
|
+
text: string;
|
|
20
|
+
ts?: string;
|
|
21
|
+
isBot?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface Thread {
|
|
24
|
+
readonly platform: string;
|
|
25
|
+
post(ui: unknown): Promise<MessageRef>;
|
|
26
|
+
update(ref: MessageRef, ui: unknown): Promise<MessageRef>;
|
|
27
|
+
delete(ref: MessageRef): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Post a picker and block until an interaction resolves it to the clicked
|
|
30
|
+
* button's `value`. Pass the expected value type, e.g.
|
|
31
|
+
* `awaitChoice<{ confirmed: boolean }>(<Picker/>)`.
|
|
32
|
+
*/
|
|
33
|
+
awaitChoice<T = unknown>(ui: unknown): Promise<T>;
|
|
34
|
+
runAgent(input?: unknown): Promise<MessageRef | undefined>;
|
|
35
|
+
resume(value: unknown): Promise<MessageRef | undefined>;
|
|
36
|
+
stream(src: string | AsyncIterable<string>): Promise<MessageRef>;
|
|
37
|
+
postFile(args: {
|
|
38
|
+
bytes: Uint8Array;
|
|
39
|
+
filename: string;
|
|
40
|
+
title?: string;
|
|
41
|
+
altText?: string;
|
|
42
|
+
}): Promise<{
|
|
43
|
+
ok: boolean;
|
|
44
|
+
fileId?: string;
|
|
45
|
+
error?: string;
|
|
46
|
+
}>;
|
|
47
|
+
/** Read the conversation's messages (capability-gated; returns `[]` when the adapter can't read history). */
|
|
48
|
+
getMessages(): Promise<ThreadMessage[]>;
|
|
49
|
+
/** Resolve a platform user by a free-form query (capability-gated; returns `undefined` when unsupported). */
|
|
50
|
+
lookupUser(query: string): Promise<PlatformUser | undefined>;
|
|
51
|
+
}
|
|
52
|
+
export interface InteractionContext<TValue = unknown> {
|
|
53
|
+
thread: Thread;
|
|
54
|
+
message: IncomingMessage;
|
|
55
|
+
/** The clicked control: its opaque `id` and the `value` it carried (typed as `TValue`). */
|
|
56
|
+
action: {
|
|
57
|
+
id: string;
|
|
58
|
+
value?: TValue;
|
|
59
|
+
};
|
|
60
|
+
values: Record<string, unknown>;
|
|
61
|
+
user: PlatformUser;
|
|
62
|
+
platform: string;
|
|
63
|
+
}
|
|
64
|
+
export type ClickHandler<TValue = unknown> = (ctx: InteractionContext<TValue>) => void | Promise<void>;
|
|
65
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB;AACD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AACD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,YAAY,CAAC;IACnB,GAAG,EAAE,UAAU,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AACD,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AACD,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACvC,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC1D,MAAM,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC;;;;OAIG;IACH,WAAW,CAAC,CAAC,GAAG,OAAO,EAAE,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAClD,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IAC3D,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IACxD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACjE,QAAQ,CAAC,IAAI,EAAE;QACb,KAAK,EAAE,UAAU,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D,6GAA6G;IAC7G,WAAW,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACxC,6GAA6G;IAC7G,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;CAC9D;AACD,MAAM,WAAW,kBAAkB,CAAC,MAAM,GAAG,OAAO;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,eAAe,CAAC;IACzB,2FAA2F;IAC3F,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AACD,MAAM,MAAM,YAAY,CAAC,MAAM,GAAG,OAAO,IAAI,CAC3C,GAAG,EAAE,kBAAkB,CAAC,MAAM,CAAC,KAC5B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@copilotkit/bot-ui",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "JSX runtime, IR, and cross-platform component vocabulary for CopilotKit bots.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/CopilotKit/CopilotKit.git"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/CopilotKit/CopilotKit",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"ai",
|
|
13
|
+
"agent",
|
|
14
|
+
"bot",
|
|
15
|
+
"jsx",
|
|
16
|
+
"block-kit",
|
|
17
|
+
"ui",
|
|
18
|
+
"copilotkit",
|
|
19
|
+
"ag-ui"
|
|
20
|
+
],
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"import": "./dist/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./jsx-runtime": {
|
|
33
|
+
"types": "./dist/jsx-runtime.d.ts",
|
|
34
|
+
"import": "./dist/jsx-runtime.js"
|
|
35
|
+
},
|
|
36
|
+
"./jsx-dev-runtime": {
|
|
37
|
+
"types": "./dist/jsx-dev-runtime.d.ts",
|
|
38
|
+
"import": "./dist/jsx-dev-runtime.js"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"dist"
|
|
43
|
+
],
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@copilotkit/shared": "^1.59.5"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/node": "^22.10.0",
|
|
49
|
+
"typescript": "^5.6.3",
|
|
50
|
+
"vitest": "^4.1.3",
|
|
51
|
+
"@copilotkit/typescript-config": "^1.55.0-next.8"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "tsc -p tsconfig.json",
|
|
55
|
+
"check-types": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.check.json",
|
|
56
|
+
"test": "vitest run",
|
|
57
|
+
"test:watch": "vitest",
|
|
58
|
+
"publint": "publint .",
|
|
59
|
+
"attw": "attw --pack . --profile esm-only"
|
|
60
|
+
}
|
|
61
|
+
}
|