@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 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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bind.test.d.ts.map
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=components.test.d.ts.map
@@ -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
+ });
@@ -0,0 +1,6 @@
1
+ export * from "./ir.js";
2
+ export * from "./render.js";
3
+ export * from "./types.js";
4
+ export * from "./bind.js";
5
+ export * from "./components.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -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
@@ -0,0 +1,5 @@
1
+ export * from "./ir.js";
2
+ export * from "./render.js";
3
+ export * from "./types.js";
4
+ export * from "./bind.js";
5
+ export * from "./components.js";
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
@@ -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,7 @@
1
+ export { jsx, jsxs, Fragment } from "./jsx-runtime.js";
2
+ export declare function jsxDEV(type: any, props: any, key?: any): {
3
+ type: any;
4
+ props: any;
5
+ key: any;
6
+ };
7
+ //# sourceMappingURL=jsx-dev-runtime.d.ts.map
@@ -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,4 @@
1
+ export { jsx, jsxs, Fragment } from "./jsx-runtime.js";
2
+ export function jsxDEV(type, props, key) {
3
+ return { type, props: props ?? {}, key };
4
+ }
@@ -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,6 @@
1
+ import { Fragment } from "./ir.js";
2
+ export { Fragment };
3
+ export function jsx(type, props, key) {
4
+ return { type: type, props: props ?? {}, key };
5
+ }
6
+ export const jsxs = jsx;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=jsx-runtime.test.d.ts.map
@@ -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
+ });
@@ -0,0 +1,3 @@
1
+ import { type BotNode, type Renderable } from "./ir.js";
2
+ export declare function renderToIR(ui: Renderable): BotNode[];
3
+ //# sourceMappingURL=render.d.ts.map
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=render.test.d.ts.map
@@ -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
+ });
@@ -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
+ }