agentic-ui-kit 0.3.0 → 0.5.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/README.md +6 -0
- package/dist/core.js +11 -4
- package/dist/index.js +492 -195
- package/dist/styles.css +1 -1
- package/dist/tailwind.css +3 -1
- package/dist/types/core/src/index.d.ts +1 -0
- package/dist/types/core/src/replaces.d.ts +15 -0
- package/dist/types/core/src/types.d.ts +2 -0
- package/dist/types/core/src/ui-markup.d.ts +6 -0
- package/dist/types/core/src/ui-tree.d.ts +6 -0
- package/dist/types/core/src/visualize.d.ts +7 -1
- package/dist/types/react/src/components/composer.d.ts +7 -1
- package/dist/types/react/src/components/effort-slider.d.ts +24 -0
- package/dist/types/react/src/components/message-list.d.ts +6 -2
- package/dist/types/react/src/components/messages.d.ts +22 -2
- package/dist/types/react/src/components/replacements.d.ts +29 -0
- package/dist/types/react/src/index.d.ts +11 -1
- package/dist/types/react/src/primitives/button.d.ts +10 -1
- package/dist/types/react/src/primitives/code-block.d.ts +3 -1
- package/dist/types/react/src/primitives/copy-button.d.ts +5 -0
- package/dist/types/react/src/primitives/icons.d.ts +7 -0
- package/dist/types/react/src/primitives/labels.d.ts +7 -0
- package/dist/types/react/src/primitives/menu.d.ts +3 -1
- package/dist/types/react/src/primitives/segmented-control.d.ts +22 -0
- package/dist/types/react/src/views/chat-view.d.ts +15 -3
- package/dist/types/react/src/views/sidebar.d.ts +3 -1
- package/dist/{ui-markup-6xbP-myu.js → ui-markup-CG9Lednh.js} +33 -9
- package/package.json +1 -1
|
@@ -25,6 +25,8 @@ export interface MenuItemProps extends Omit<AriaMenuItemProps, "className" | "ch
|
|
|
25
25
|
icon?: ReactNode;
|
|
26
26
|
/** Second line under the label ("For complex work and everyday tasks"). */
|
|
27
27
|
description?: ReactNode;
|
|
28
|
+
/** "below" (default) puts the description under the label; "beside" puts it after it on one line. */
|
|
29
|
+
descriptionPlacement?: "below" | "beside";
|
|
28
30
|
/** Right-aligned detail: the current value of a submenu ("Medium") or a badge. */
|
|
29
31
|
detail?: ReactNode;
|
|
30
32
|
/** Keyboard shortcut shown on the right ("⌘U", "P"). */
|
|
@@ -33,7 +35,7 @@ export interface MenuItemProps extends Omit<AriaMenuItemProps, "className" | "ch
|
|
|
33
35
|
tone?: "default" | "danger";
|
|
34
36
|
className?: string;
|
|
35
37
|
}
|
|
36
|
-
export declare function MenuItem({ children, icon, description, detail, shortcut, tone, className, ...props }: MenuItemProps): import("react").JSX.Element;
|
|
38
|
+
export declare function MenuItem({ children, icon, description, descriptionPlacement, detail, shortcut, tone, className, ...props }: MenuItemProps): import("react").JSX.Element;
|
|
37
39
|
export interface MenuSectionProps {
|
|
38
40
|
children: ReactNode;
|
|
39
41
|
title?: ReactNode;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export interface SegmentedOption<T extends string = string> {
|
|
3
|
+
id: T;
|
|
4
|
+
label: string;
|
|
5
|
+
icon?: ReactNode;
|
|
6
|
+
/** Show only the icon; the label becomes its accessible name and tooltip. */
|
|
7
|
+
iconOnly?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface SegmentedControlProps<T extends string = string> {
|
|
10
|
+
/** Accessible name of the group, e.g. "Mode". */
|
|
11
|
+
label: string;
|
|
12
|
+
options: readonly SegmentedOption<T>[];
|
|
13
|
+
value: T;
|
|
14
|
+
onChange: (value: T) => void;
|
|
15
|
+
className?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* One of a few options, side by side on a track, like claude.ai's Chat / Cowork switch. Themed with
|
|
19
|
+
* `--chat-segment-track` (default: a shade darker than the surface it sits on) and `--chat-segment-selected`
|
|
20
|
+
* (default `--chat-raised`).
|
|
21
|
+
*/
|
|
22
|
+
export declare function SegmentedControl<T extends string>({ label, options, value, onChange, className }: SegmentedControlProps<T>): import("react").JSX.Element;
|
|
@@ -2,7 +2,7 @@ import type { Message, Part } from "../../../core/src/index.js";
|
|
|
2
2
|
import { type CSSProperties, type ReactNode } from "react";
|
|
3
3
|
import type { PendingApproval } from "../hooks/use-chat";
|
|
4
4
|
import { type ComposerProps } from "../components/composer";
|
|
5
|
-
import type { Feedback } from "../components/messages";
|
|
5
|
+
import type { Feedback, MessageActions } from "../components/messages";
|
|
6
6
|
import { type WidgetHost } from "../components/widget-frame";
|
|
7
7
|
export type Density = "full" | "panel" | "inline";
|
|
8
8
|
/**
|
|
@@ -22,6 +22,10 @@ export interface ChatViewProps {
|
|
|
22
22
|
onRetry?: (assistantId: string) => void;
|
|
23
23
|
onEdit?: (userId: string) => void;
|
|
24
24
|
onFeedback?: (assistantId: string, feedback: Feedback) => void;
|
|
25
|
+
/** Read aloud button on assistant messages. */
|
|
26
|
+
onReadAloud?: (assistantId: string) => void;
|
|
27
|
+
/** Add your own buttons to each message's action row, or hide copy and the time. */
|
|
28
|
+
messageActions?: MessageActions;
|
|
25
29
|
renderPart?: (part: Part) => ReactNode;
|
|
26
30
|
/**
|
|
27
31
|
* What widgets (sandboxed visuals) may do: the domains they may load, and their callbacks. A widget's
|
|
@@ -40,6 +44,11 @@ export interface ChatViewProps {
|
|
|
40
44
|
emptyState?: (composer: ReactNode) => ReactNode;
|
|
41
45
|
/** Small print under the composer. */
|
|
42
46
|
disclaimer?: ReactNode;
|
|
47
|
+
/**
|
|
48
|
+
* Wraps the composer, on the empty screen and docked under the chat, to put things outside its box:
|
|
49
|
+
* buttons above or beside it, a row of chips under it. `where` says which of the two it is.
|
|
50
|
+
*/
|
|
51
|
+
renderComposer?: (composer: ReactNode, where: "empty" | "docked") => ReactNode;
|
|
43
52
|
/** "full": a page. "panel": a docked side panel. "inline": a small area inside a form. */
|
|
44
53
|
density?: Density;
|
|
45
54
|
/** Width of the message column, e.g. "48rem". Users can change it in settings. */
|
|
@@ -49,11 +58,14 @@ export interface ChatViewProps {
|
|
|
49
58
|
className?: string;
|
|
50
59
|
}
|
|
51
60
|
/** A whole chat: header, the conversation, the docked composer. An empty chat shows `emptyState`. */
|
|
52
|
-
export declare function ChatView({ messages, busy, onSend, onStop, approvals, onApprove, onRetry, onEdit, onFeedback, renderPart, widgets, header, composer, emptyState, disclaimer, density, contentWidth, contentPadding, className, }: ChatViewProps): import("react").JSX.Element;
|
|
61
|
+
export declare function ChatView({ messages, busy, onSend, onStop, approvals, onApprove, onRetry, onEdit, onFeedback, onReadAloud, messageActions, renderPart, widgets, header, composer, emptyState, disclaimer, renderComposer, density, contentWidth, contentPadding, className, }: ChatViewProps): import("react").JSX.Element;
|
|
53
62
|
export interface EmptyStateProps {
|
|
54
63
|
/** "Good evening, Alex". */
|
|
55
64
|
greeting: ReactNode;
|
|
56
|
-
/**
|
|
65
|
+
/**
|
|
66
|
+
* Mark left of the greeting, e.g. a logo. Its currentColor is --chat-empty-icon (default the accent), for
|
|
67
|
+
* one-color marks; a multi-color logo sets its own fills.
|
|
68
|
+
*/
|
|
57
69
|
icon?: ReactNode;
|
|
58
70
|
/** The centered composer. */
|
|
59
71
|
children: ReactNode;
|
|
@@ -2,6 +2,8 @@ import type { ReactNode } from "react";
|
|
|
2
2
|
export interface SidebarProps {
|
|
3
3
|
/** Name or logo at the top left; hidden when collapsed. */
|
|
4
4
|
brand?: ReactNode;
|
|
5
|
+
/** A logo mark left of `brand`, sized 1.25rem. It stays at the top of the collapsed rail. */
|
|
6
|
+
brandIcon?: ReactNode;
|
|
5
7
|
/** Buttons at the top right next to the collapse toggle, e.g. a mode switch. */
|
|
6
8
|
headerActions?: ReactNode;
|
|
7
9
|
/** Fixed items under the header: New chat, Search, Projects… (`SidebarItem`s). */
|
|
@@ -13,7 +15,7 @@ export interface SidebarProps {
|
|
|
13
15
|
className?: string;
|
|
14
16
|
}
|
|
15
17
|
/** The claude.ai sidebar frame. Collapses to an icon rail inside `AppShell`; a drawer on phones. */
|
|
16
|
-
export declare function Sidebar({ brand, headerActions, nav, children, footer, className }: SidebarProps): import("react").JSX.Element;
|
|
18
|
+
export declare function Sidebar({ brand, brandIcon, headerActions, nav, children, footer, className }: SidebarProps): import("react").JSX.Element;
|
|
17
19
|
export interface SidebarItemProps {
|
|
18
20
|
icon: ReactNode;
|
|
19
21
|
label: string;
|
|
@@ -422,6 +422,25 @@ function parseMessage(text) {
|
|
|
422
422
|
if (data.length === 0) return void 0;
|
|
423
423
|
return JSON.parse(data.join("\n"));
|
|
424
424
|
}
|
|
425
|
+
// ../core/src/replaces.ts
|
|
426
|
+
/**
|
|
427
|
+
* Updating a visual in place: the drawing tools (show_widget, show_ui, render_ui) take an optional
|
|
428
|
+
* `replaces`, the id of an earlier call of theirs. The kit draws the new call where the old one was (same
|
|
429
|
+
* reply) or folds the old one into a link to the new one (earlier reply). The model sees its own call ids in
|
|
430
|
+
* the history, so keep tool call ids when you send the history back.
|
|
431
|
+
*/
|
|
432
|
+
/** The `replaces` input property, shared by the drawing tools. */
|
|
433
|
+
const replacesProperty = {
|
|
434
|
+
type: "string",
|
|
435
|
+
description: "Id of an earlier call of this tool whose visual this one updates in place: after a fix, or when the user asks for a change. Leave it out for a new visual."
|
|
436
|
+
};
|
|
437
|
+
/** One line for a drawing tool's description or guide. */
|
|
438
|
+
const replacesGuide = "To change a visual you already drew (a fix, or the user asks for a change), call the tool again with `replaces` set to that call's id: it is redrawn in place. Never draw a second copy without it.";
|
|
439
|
+
/** The id a drawing tool call replaces, from its (streaming) input; undefined if none. */
|
|
440
|
+
function replacedId(input) {
|
|
441
|
+
const r = input?.replaces;
|
|
442
|
+
return typeof r === "string" && r ? r : void 0;
|
|
443
|
+
}
|
|
425
444
|
// ../core/src/ui-tree.ts
|
|
426
445
|
/**
|
|
427
446
|
* Host-registered components: instead of HTML, the model writes a small tree of components the host
|
|
@@ -557,6 +576,7 @@ function renderUiTool(components) {
|
|
|
557
576
|
Write a tree: { "root": { "component": "<name>", "props": { ... }, "children": [ ...nodes ] }, "state": { ... } }.
|
|
558
577
|
"root" is a JSON object, never a string. Only these components exist; a node with an unknown component or
|
|
559
578
|
props that don't fit is not shown. One visual per answer: don't also draw the same thing another way.
|
|
579
|
+
${replacesGuide}
|
|
560
580
|
${list}
|
|
561
581
|
|
|
562
582
|
Actions: a prop the schema marks as an action takes one of
|
|
@@ -577,7 +597,8 @@ Set apart what you added or changed from what was already there.`,
|
|
|
577
597
|
state: {
|
|
578
598
|
type: "object",
|
|
579
599
|
description: "Starting values of the widget's state."
|
|
580
|
-
}
|
|
600
|
+
},
|
|
601
|
+
replaces: replacesProperty
|
|
581
602
|
},
|
|
582
603
|
required: ["root"]
|
|
583
604
|
}
|
|
@@ -658,7 +679,7 @@ function checkUiTree(input, components, options = {}) {
|
|
|
658
679
|
return {
|
|
659
680
|
ok,
|
|
660
681
|
errors,
|
|
661
|
-
feedback: ok ? "Shown to the user." : `${bad === 0 ? "Not shown as written" : `Only part of it is shown: ${bad} of ${total} nodes were left out`}. Fix these and call ${toolName} again:\n` + errors.slice(0, 20).map((e) => `- ${e}`).join("\n") + (errors.length > 20 ? `\n- ...and ${errors.length - 20} more` : "")
|
|
682
|
+
feedback: ok ? "Shown to the user." : `${bad === 0 ? "Not shown as written" : `Only part of it is shown: ${bad} of ${total} nodes were left out`}. Fix these and call ${toolName} again with "replaces" set to this call's id, without remarking on the fix to the user:\n` + errors.slice(0, 20).map((e) => `- ${e}`).join("\n") + (errors.length > 20 ? `\n- ...and ${errors.length - 20} more` : "")
|
|
662
683
|
};
|
|
663
684
|
}
|
|
664
685
|
// ../core/src/ui-markup.ts
|
|
@@ -1039,13 +1060,16 @@ const showUiToolName = "show_ui";
|
|
|
1039
1060
|
function showUiTool(components, name = showUiToolName) {
|
|
1040
1061
|
return {
|
|
1041
1062
|
name,
|
|
1042
|
-
description: "Show interactive UI inline in your reply, built from the app's components: options to compare, a plan, a checklist, numbers at a glance. Write JSX in `markup`. Keep explaining in text around it; one call per answer unless the user asks for more
|
|
1063
|
+
description: "Show interactive UI inline in your reply, built from the app's components: options to compare, a plan, a checklist, numbers at a glance. Write JSX in `markup`. Keep explaining in text around it; one call per answer unless the user asks for more. " + replacesGuide + "\n\n" + markupRules(components),
|
|
1043
1064
|
inputSchema: {
|
|
1044
1065
|
type: "object",
|
|
1045
|
-
properties: {
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1066
|
+
properties: {
|
|
1067
|
+
markup: {
|
|
1068
|
+
type: "string",
|
|
1069
|
+
description: "JSX of the components above, e.g. <Card title=\"Plan\"><Metric label=\"Total\" value=\"€184\" /></Card>"
|
|
1070
|
+
},
|
|
1071
|
+
replaces: replacesProperty
|
|
1072
|
+
},
|
|
1049
1073
|
required: ["markup"]
|
|
1050
1074
|
}
|
|
1051
1075
|
};
|
|
@@ -1065,7 +1089,7 @@ function checkUiMarkupCode(markup, components, toolName = showUiToolName) {
|
|
|
1065
1089
|
return {
|
|
1066
1090
|
ok,
|
|
1067
1091
|
errors,
|
|
1068
|
-
feedback: ok ? "Shown to the user." : `Not all of it is shown. Fix these and call ${toolName} again:\n` + list(errors)
|
|
1092
|
+
feedback: ok ? "Shown to the user." : `Not all of it is shown. Fix these and call ${toolName} again with "replaces" set to this call's id, without remarking on the fix to the user:\n` + list(errors)
|
|
1069
1093
|
};
|
|
1070
1094
|
}
|
|
1071
1095
|
/**
|
|
@@ -1079,4 +1103,4 @@ When a visual helps more than text (options to compare, a plan, a checklist, num
|
|
|
1079
1103
|
${markupRules(components)}
|
|
1080
1104
|
- Keep explaining in text around the block. One block per answer, unless the user asks for more.`;
|
|
1081
1105
|
}
|
|
1082
|
-
export {
|
|
1106
|
+
export { resolveEffort as A, toBlocks as C, estimateTokens as D, awaitingToolCalls as E, parsePartialJson as M, salvageJson as N, outputTokens as O, isActivityPart as S, applyEvent as T, replacedId as _, readUiValue as a, formatEvent as b, uiMarkupGuide as c, isStateRef as d, matchesSchema as f, uiActionSchema as g, schemaErrors as h, parseUiMarkup as i, settleToolCall as j, reduceEvents as k, uiMarkupLanguage as l, renderUiToolName as m, checkUiMarkupCode as n, showUiTool as o, renderUiTool as p, findUiBlocks as r, showUiToolName as s, checkUiMarkup as t, checkUiTree as u, replacesGuide as v, activityTokens as w, readEventStream as x, replacesProperty as y };
|
package/package.json
CHANGED