@cloudbase/agent-react-ui 0.0.23
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 +135 -0
- package/components.json +21 -0
- package/dist/index.css +4241 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.mts +59 -0
- package/dist/index.d.ts +59 -0
- package/dist/index.js +2169 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2182 -0
- package/dist/index.mjs.map +1 -0
- package/example/.env.sample +2 -0
- package/example/App.tsx +368 -0
- package/example/app.css +1 -0
- package/example/index.html +12 -0
- package/example/main.tsx +9 -0
- package/example/vite.config.ts +34 -0
- package/package.json +75 -0
- package/postcss.config.cjs +3 -0
- package/src/components/ai-elements/agent.tsx +140 -0
- package/src/components/ai-elements/artifact.tsx +147 -0
- package/src/components/ai-elements/attachments.tsx +421 -0
- package/src/components/ai-elements/audio-player.tsx +228 -0
- package/src/components/ai-elements/canvas.tsx +22 -0
- package/src/components/ai-elements/chain-of-thought.tsx +228 -0
- package/src/components/ai-elements/checkpoint.tsx +71 -0
- package/src/components/ai-elements/code-block.tsx +532 -0
- package/src/components/ai-elements/commit.tsx +448 -0
- package/src/components/ai-elements/confirmation.tsx +176 -0
- package/src/components/ai-elements/connection.tsx +28 -0
- package/src/components/ai-elements/context.tsx +408 -0
- package/src/components/ai-elements/controls.tsx +18 -0
- package/src/components/ai-elements/conversation.tsx +100 -0
- package/src/components/ai-elements/edge.tsx +140 -0
- package/src/components/ai-elements/environment-variables.tsx +295 -0
- package/src/components/ai-elements/file-tree.tsx +258 -0
- package/src/components/ai-elements/image.tsx +24 -0
- package/src/components/ai-elements/inline-citation.tsx +287 -0
- package/src/components/ai-elements/message.tsx +336 -0
- package/src/components/ai-elements/mic-selector.tsx +370 -0
- package/src/components/ai-elements/model-selector.tsx +211 -0
- package/src/components/ai-elements/node.tsx +71 -0
- package/src/components/ai-elements/open-in-chat.tsx +365 -0
- package/src/components/ai-elements/package-info.tsx +233 -0
- package/src/components/ai-elements/panel.tsx +15 -0
- package/src/components/ai-elements/persona.tsx +270 -0
- package/src/components/ai-elements/plan.tsx +142 -0
- package/src/components/ai-elements/prompt-input.tsx +1263 -0
- package/src/components/ai-elements/queue.tsx +274 -0
- package/src/components/ai-elements/reasoning.tsx +193 -0
- package/src/components/ai-elements/sandbox.tsx +126 -0
- package/src/components/ai-elements/schema-display.tsx +458 -0
- package/src/components/ai-elements/shimmer.tsx +64 -0
- package/src/components/ai-elements/snippet.tsx +139 -0
- package/src/components/ai-elements/sources.tsx +77 -0
- package/src/components/ai-elements/speech-input.tsx +301 -0
- package/src/components/ai-elements/stack-trace.tsx +482 -0
- package/src/components/ai-elements/suggestion.tsx +53 -0
- package/src/components/ai-elements/task.tsx +87 -0
- package/src/components/ai-elements/terminal.tsx +261 -0
- package/src/components/ai-elements/test-results.tsx +485 -0
- package/src/components/ai-elements/tool.tsx +174 -0
- package/src/components/ai-elements/toolbar.tsx +16 -0
- package/src/components/ai-elements/transcription.tsx +124 -0
- package/src/components/ai-elements/voice-selector.tsx +479 -0
- package/src/components/ai-elements/web-preview.tsx +263 -0
- package/src/components/chat/Chat.tsx +178 -0
- package/src/components/chat/Input.tsx +98 -0
- package/src/components/chat/Message.tsx +276 -0
- package/src/components/chat/index.ts +2 -0
- package/src/components/index.ts +1 -0
- package/src/components/ui/accordion.tsx +64 -0
- package/src/components/ui/alert.tsx +66 -0
- package/src/components/ui/avatar.tsx +107 -0
- package/src/components/ui/badge.tsx +48 -0
- package/src/components/ui/button-group.tsx +83 -0
- package/src/components/ui/button.tsx +64 -0
- package/src/components/ui/card.tsx +92 -0
- package/src/components/ui/carousel.tsx +239 -0
- package/src/components/ui/collapsible.tsx +31 -0
- package/src/components/ui/command.tsx +184 -0
- package/src/components/ui/dialog.tsx +158 -0
- package/src/components/ui/dropdown-menu.tsx +257 -0
- package/src/components/ui/hover-card.tsx +42 -0
- package/src/components/ui/input-group.tsx +168 -0
- package/src/components/ui/input.tsx +21 -0
- package/src/components/ui/popover.tsx +87 -0
- package/src/components/ui/progress.tsx +31 -0
- package/src/components/ui/scroll-area.tsx +56 -0
- package/src/components/ui/select.tsx +190 -0
- package/src/components/ui/separator.tsx +28 -0
- package/src/components/ui/spinner.tsx +16 -0
- package/src/components/ui/switch.tsx +33 -0
- package/src/components/ui/tabs.tsx +91 -0
- package/src/components/ui/textarea.tsx +18 -0
- package/src/components/ui/tooltip.tsx +61 -0
- package/src/css/global.css +123 -0
- package/src/css/index.css +1 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/use-copy-to-clipboard.ts +31 -0
- package/src/index.ts +4 -0
- package/src/lib/utils.ts +6 -0
- package/src/locales/context.ts +8 -0
- package/src/locales/hooks.ts +20 -0
- package/src/locales/index.ts +3 -0
- package/src/locales/langs/en.ts +17 -0
- package/src/locales/langs/index.ts +12 -0
- package/src/locales/langs/zh-cn.ts +18 -0
- package/tsconfig.json +21 -0
- package/tsup.config.ts +21 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Button } from "@/components/ui/button";
|
|
4
|
+
import { ButtonGroup, ButtonGroupText } from "@/components/ui/button-group";
|
|
5
|
+
import { cn } from "@/lib/utils";
|
|
6
|
+
import type { Experimental_SpeechResult as SpeechResult } from "ai";
|
|
7
|
+
import {
|
|
8
|
+
MediaControlBar,
|
|
9
|
+
MediaController,
|
|
10
|
+
MediaDurationDisplay,
|
|
11
|
+
MediaMuteButton,
|
|
12
|
+
MediaPlayButton,
|
|
13
|
+
MediaSeekBackwardButton,
|
|
14
|
+
MediaSeekForwardButton,
|
|
15
|
+
MediaTimeDisplay,
|
|
16
|
+
MediaTimeRange,
|
|
17
|
+
MediaVolumeRange,
|
|
18
|
+
} from "media-chrome/react";
|
|
19
|
+
import type { ComponentProps, CSSProperties } from "react";
|
|
20
|
+
|
|
21
|
+
export type AudioPlayerProps = Omit<
|
|
22
|
+
ComponentProps<typeof MediaController>,
|
|
23
|
+
"audio"
|
|
24
|
+
>;
|
|
25
|
+
|
|
26
|
+
export const AudioPlayer = ({
|
|
27
|
+
className,
|
|
28
|
+
children,
|
|
29
|
+
style,
|
|
30
|
+
...props
|
|
31
|
+
}: AudioPlayerProps) => (
|
|
32
|
+
<MediaController
|
|
33
|
+
audio
|
|
34
|
+
data-slot="audio-player"
|
|
35
|
+
style={
|
|
36
|
+
{
|
|
37
|
+
"--media-button-icon-width": "1rem",
|
|
38
|
+
"--media-button-icon-height": "1rem",
|
|
39
|
+
"--media-icon-color": "currentColor",
|
|
40
|
+
"--media-font": "var(--font-sans)",
|
|
41
|
+
"--media-font-size": "10px",
|
|
42
|
+
"--media-control-background": "transparent",
|
|
43
|
+
"--media-control-hover-background": "var(--color-accent)",
|
|
44
|
+
"--media-control-padding": "0",
|
|
45
|
+
"--media-background-color": "transparent",
|
|
46
|
+
"--media-primary-color": "var(--color-primary)",
|
|
47
|
+
"--media-secondary-color": "var(--color-secondary)",
|
|
48
|
+
"--media-text-color": "var(--color-foreground)",
|
|
49
|
+
"--media-tooltip-background": "var(--color-background)",
|
|
50
|
+
"--media-range-bar-color": "var(--color-primary)",
|
|
51
|
+
"--media-tooltip-arrow-display": "none",
|
|
52
|
+
"--media-tooltip-border-radius": "var(--radius-md)",
|
|
53
|
+
"--media-preview-time-text-shadow": "none",
|
|
54
|
+
"--media-preview-time-background": "var(--color-background)",
|
|
55
|
+
"--media-preview-time-border-radius": "var(--radius-md)",
|
|
56
|
+
"--media-range-track-background": "var(--color-secondary)",
|
|
57
|
+
...style,
|
|
58
|
+
} as CSSProperties
|
|
59
|
+
}
|
|
60
|
+
{...props}
|
|
61
|
+
>
|
|
62
|
+
{children}
|
|
63
|
+
</MediaController>
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
export type AudioPlayerElementProps = Omit<ComponentProps<"audio">, "src"> &
|
|
67
|
+
(
|
|
68
|
+
| {
|
|
69
|
+
data: SpeechResult["audio"];
|
|
70
|
+
}
|
|
71
|
+
| {
|
|
72
|
+
src: string;
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
export const AudioPlayerElement = ({ ...props }: AudioPlayerElementProps) => (
|
|
77
|
+
<audio
|
|
78
|
+
data-slot="audio-player-element"
|
|
79
|
+
slot="media"
|
|
80
|
+
src={
|
|
81
|
+
"src" in props
|
|
82
|
+
? props.src
|
|
83
|
+
: `data:${props.data.mediaType};base64,${props.data.base64}`
|
|
84
|
+
}
|
|
85
|
+
{...props}
|
|
86
|
+
/>
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
export type AudioPlayerControlBarProps = ComponentProps<typeof MediaControlBar>;
|
|
90
|
+
|
|
91
|
+
export const AudioPlayerControlBar = ({
|
|
92
|
+
children,
|
|
93
|
+
...props
|
|
94
|
+
}: AudioPlayerControlBarProps) => (
|
|
95
|
+
<MediaControlBar data-slot="audio-player-control-bar" {...props}>
|
|
96
|
+
<ButtonGroup orientation="horizontal">{children}</ButtonGroup>
|
|
97
|
+
</MediaControlBar>
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
export type AudioPlayerPlayButtonProps = ComponentProps<typeof MediaPlayButton>;
|
|
101
|
+
|
|
102
|
+
export const AudioPlayerPlayButton = ({
|
|
103
|
+
className,
|
|
104
|
+
...props
|
|
105
|
+
}: AudioPlayerPlayButtonProps) => (
|
|
106
|
+
<Button asChild size="icon-sm" variant="outline">
|
|
107
|
+
<MediaPlayButton
|
|
108
|
+
className={cn("bg-transparent", className)}
|
|
109
|
+
data-slot="audio-player-play-button"
|
|
110
|
+
{...props}
|
|
111
|
+
/>
|
|
112
|
+
</Button>
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
export type AudioPlayerSeekBackwardButtonProps = ComponentProps<
|
|
116
|
+
typeof MediaSeekBackwardButton
|
|
117
|
+
>;
|
|
118
|
+
|
|
119
|
+
export const AudioPlayerSeekBackwardButton = ({
|
|
120
|
+
seekOffset = 10,
|
|
121
|
+
...props
|
|
122
|
+
}: AudioPlayerSeekBackwardButtonProps) => (
|
|
123
|
+
<Button asChild size="icon-sm" variant="outline">
|
|
124
|
+
<MediaSeekBackwardButton
|
|
125
|
+
data-slot="audio-player-seek-backward-button"
|
|
126
|
+
seekOffset={seekOffset}
|
|
127
|
+
{...props}
|
|
128
|
+
/>
|
|
129
|
+
</Button>
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
export type AudioPlayerSeekForwardButtonProps = ComponentProps<
|
|
133
|
+
typeof MediaSeekForwardButton
|
|
134
|
+
>;
|
|
135
|
+
|
|
136
|
+
export const AudioPlayerSeekForwardButton = ({
|
|
137
|
+
seekOffset = 10,
|
|
138
|
+
...props
|
|
139
|
+
}: AudioPlayerSeekForwardButtonProps) => (
|
|
140
|
+
<Button asChild size="icon-sm" variant="outline">
|
|
141
|
+
<MediaSeekForwardButton
|
|
142
|
+
data-slot="audio-player-seek-forward-button"
|
|
143
|
+
seekOffset={seekOffset}
|
|
144
|
+
{...props}
|
|
145
|
+
/>
|
|
146
|
+
</Button>
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
export type AudioPlayerTimeDisplayProps = ComponentProps<
|
|
150
|
+
typeof MediaTimeDisplay
|
|
151
|
+
>;
|
|
152
|
+
|
|
153
|
+
export const AudioPlayerTimeDisplay = ({
|
|
154
|
+
className,
|
|
155
|
+
...props
|
|
156
|
+
}: AudioPlayerTimeDisplayProps) => (
|
|
157
|
+
<ButtonGroupText asChild className="bg-transparent">
|
|
158
|
+
<MediaTimeDisplay
|
|
159
|
+
className={cn("tabular-nums", className)}
|
|
160
|
+
data-slot="audio-player-time-display"
|
|
161
|
+
{...props}
|
|
162
|
+
/>
|
|
163
|
+
</ButtonGroupText>
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
export type AudioPlayerTimeRangeProps = ComponentProps<typeof MediaTimeRange>;
|
|
167
|
+
|
|
168
|
+
export const AudioPlayerTimeRange = ({
|
|
169
|
+
className,
|
|
170
|
+
...props
|
|
171
|
+
}: AudioPlayerTimeRangeProps) => (
|
|
172
|
+
<ButtonGroupText asChild className="bg-transparent">
|
|
173
|
+
<MediaTimeRange
|
|
174
|
+
className={cn("", className)}
|
|
175
|
+
data-slot="audio-player-time-range"
|
|
176
|
+
{...props}
|
|
177
|
+
/>
|
|
178
|
+
</ButtonGroupText>
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
export type AudioPlayerDurationDisplayProps = ComponentProps<
|
|
182
|
+
typeof MediaDurationDisplay
|
|
183
|
+
>;
|
|
184
|
+
|
|
185
|
+
export const AudioPlayerDurationDisplay = ({
|
|
186
|
+
className,
|
|
187
|
+
...props
|
|
188
|
+
}: AudioPlayerDurationDisplayProps) => (
|
|
189
|
+
<ButtonGroupText asChild className="bg-transparent">
|
|
190
|
+
<MediaDurationDisplay
|
|
191
|
+
className={cn("tabular-nums", className)}
|
|
192
|
+
data-slot="audio-player-duration-display"
|
|
193
|
+
{...props}
|
|
194
|
+
/>
|
|
195
|
+
</ButtonGroupText>
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
export type AudioPlayerMuteButtonProps = ComponentProps<typeof MediaMuteButton>;
|
|
199
|
+
|
|
200
|
+
export const AudioPlayerMuteButton = ({
|
|
201
|
+
className,
|
|
202
|
+
...props
|
|
203
|
+
}: AudioPlayerMuteButtonProps) => (
|
|
204
|
+
<ButtonGroupText asChild className="bg-transparent">
|
|
205
|
+
<MediaMuteButton
|
|
206
|
+
className={cn("", className)}
|
|
207
|
+
data-slot="audio-player-mute-button"
|
|
208
|
+
{...props}
|
|
209
|
+
/>
|
|
210
|
+
</ButtonGroupText>
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
export type AudioPlayerVolumeRangeProps = ComponentProps<
|
|
214
|
+
typeof MediaVolumeRange
|
|
215
|
+
>;
|
|
216
|
+
|
|
217
|
+
export const AudioPlayerVolumeRange = ({
|
|
218
|
+
className,
|
|
219
|
+
...props
|
|
220
|
+
}: AudioPlayerVolumeRangeProps) => (
|
|
221
|
+
<ButtonGroupText asChild className="bg-transparent">
|
|
222
|
+
<MediaVolumeRange
|
|
223
|
+
className={cn("", className)}
|
|
224
|
+
data-slot="audio-player-volume-range"
|
|
225
|
+
{...props}
|
|
226
|
+
/>
|
|
227
|
+
</ButtonGroupText>
|
|
228
|
+
);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Background, ReactFlow, type ReactFlowProps } from "@xyflow/react";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
import "@xyflow/react/dist/style.css";
|
|
4
|
+
|
|
5
|
+
type CanvasProps = ReactFlowProps & {
|
|
6
|
+
children?: ReactNode;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const Canvas = ({ children, ...props }: CanvasProps) => (
|
|
10
|
+
<ReactFlow
|
|
11
|
+
deleteKeyCode={["Backspace", "Delete"]}
|
|
12
|
+
fitView
|
|
13
|
+
panOnDrag={false}
|
|
14
|
+
panOnScroll
|
|
15
|
+
selectionOnDrag={true}
|
|
16
|
+
zoomOnDoubleClick={false}
|
|
17
|
+
{...props}
|
|
18
|
+
>
|
|
19
|
+
<Background bgColor="var(--sidebar)" />
|
|
20
|
+
{children}
|
|
21
|
+
</ReactFlow>
|
|
22
|
+
);
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
4
|
+
import { Badge } from "@/components/ui/badge";
|
|
5
|
+
import {
|
|
6
|
+
Collapsible,
|
|
7
|
+
CollapsibleContent,
|
|
8
|
+
CollapsibleTrigger,
|
|
9
|
+
} from "@/components/ui/collapsible";
|
|
10
|
+
import { cn } from "@/lib/utils";
|
|
11
|
+
import {
|
|
12
|
+
BrainIcon,
|
|
13
|
+
ChevronDownIcon,
|
|
14
|
+
DotIcon,
|
|
15
|
+
type LucideIcon,
|
|
16
|
+
} from "lucide-react";
|
|
17
|
+
import type { ComponentProps, ReactNode } from "react";
|
|
18
|
+
import { createContext, memo, useContext, useMemo } from "react";
|
|
19
|
+
|
|
20
|
+
interface ChainOfThoughtContextValue {
|
|
21
|
+
isOpen: boolean;
|
|
22
|
+
setIsOpen: (open: boolean) => void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const ChainOfThoughtContext = createContext<ChainOfThoughtContextValue | null>(
|
|
26
|
+
null
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const useChainOfThought = () => {
|
|
30
|
+
const context = useContext(ChainOfThoughtContext);
|
|
31
|
+
if (!context) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
"ChainOfThought components must be used within ChainOfThought"
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
return context;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export type ChainOfThoughtProps = ComponentProps<"div"> & {
|
|
40
|
+
open?: boolean;
|
|
41
|
+
defaultOpen?: boolean;
|
|
42
|
+
onOpenChange?: (open: boolean) => void;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const ChainOfThought = memo(
|
|
46
|
+
({
|
|
47
|
+
className,
|
|
48
|
+
open,
|
|
49
|
+
defaultOpen = false,
|
|
50
|
+
onOpenChange,
|
|
51
|
+
children,
|
|
52
|
+
...props
|
|
53
|
+
}: ChainOfThoughtProps) => {
|
|
54
|
+
const [isOpen, setIsOpen] = useControllableState({
|
|
55
|
+
prop: open,
|
|
56
|
+
defaultProp: defaultOpen,
|
|
57
|
+
onChange: onOpenChange,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const chainOfThoughtContext = useMemo(
|
|
61
|
+
() => ({ isOpen, setIsOpen }),
|
|
62
|
+
[isOpen, setIsOpen]
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<ChainOfThoughtContext.Provider value={chainOfThoughtContext}>
|
|
67
|
+
<div className={cn("not-prose w-full space-y-4", className)} {...props}>
|
|
68
|
+
{children}
|
|
69
|
+
</div>
|
|
70
|
+
</ChainOfThoughtContext.Provider>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
export type ChainOfThoughtHeaderProps = ComponentProps<
|
|
76
|
+
typeof CollapsibleTrigger
|
|
77
|
+
>;
|
|
78
|
+
|
|
79
|
+
export const ChainOfThoughtHeader = memo(
|
|
80
|
+
({ className, children, ...props }: ChainOfThoughtHeaderProps) => {
|
|
81
|
+
const { isOpen, setIsOpen } = useChainOfThought();
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<Collapsible onOpenChange={setIsOpen} open={isOpen}>
|
|
85
|
+
<CollapsibleTrigger
|
|
86
|
+
className={cn(
|
|
87
|
+
"flex w-full items-center gap-2 text-muted-foreground text-sm transition-colors hover:text-foreground",
|
|
88
|
+
className
|
|
89
|
+
)}
|
|
90
|
+
{...props}
|
|
91
|
+
>
|
|
92
|
+
<BrainIcon className="size-4" />
|
|
93
|
+
<span className="flex-1 text-left">
|
|
94
|
+
{children ?? "Chain of Thought"}
|
|
95
|
+
</span>
|
|
96
|
+
<ChevronDownIcon
|
|
97
|
+
className={cn(
|
|
98
|
+
"size-4 transition-transform",
|
|
99
|
+
isOpen ? "rotate-180" : "rotate-0"
|
|
100
|
+
)}
|
|
101
|
+
/>
|
|
102
|
+
</CollapsibleTrigger>
|
|
103
|
+
</Collapsible>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
export type ChainOfThoughtStepProps = ComponentProps<"div"> & {
|
|
109
|
+
icon?: LucideIcon;
|
|
110
|
+
label: ReactNode;
|
|
111
|
+
description?: ReactNode;
|
|
112
|
+
status?: "complete" | "active" | "pending";
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export const ChainOfThoughtStep = memo(
|
|
116
|
+
({
|
|
117
|
+
className,
|
|
118
|
+
icon: Icon = DotIcon,
|
|
119
|
+
label,
|
|
120
|
+
description,
|
|
121
|
+
status = "complete",
|
|
122
|
+
children,
|
|
123
|
+
...props
|
|
124
|
+
}: ChainOfThoughtStepProps) => {
|
|
125
|
+
const statusStyles = {
|
|
126
|
+
complete: "text-muted-foreground",
|
|
127
|
+
active: "text-foreground",
|
|
128
|
+
pending: "text-muted-foreground/50",
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<div
|
|
133
|
+
className={cn(
|
|
134
|
+
"flex gap-2 text-sm",
|
|
135
|
+
statusStyles[status],
|
|
136
|
+
"fade-in-0 slide-in-from-top-2 animate-in",
|
|
137
|
+
className
|
|
138
|
+
)}
|
|
139
|
+
{...props}
|
|
140
|
+
>
|
|
141
|
+
<div className="relative mt-0.5">
|
|
142
|
+
<Icon className="size-4" />
|
|
143
|
+
<div className="absolute top-7 bottom-0 left-1/2 -mx-px w-px bg-border" />
|
|
144
|
+
</div>
|
|
145
|
+
<div className="flex-1 space-y-2 overflow-hidden">
|
|
146
|
+
<div>{label}</div>
|
|
147
|
+
{description && (
|
|
148
|
+
<div className="text-muted-foreground text-xs">{description}</div>
|
|
149
|
+
)}
|
|
150
|
+
{children}
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
export type ChainOfThoughtSearchResultsProps = ComponentProps<"div">;
|
|
158
|
+
|
|
159
|
+
export const ChainOfThoughtSearchResults = memo(
|
|
160
|
+
({ className, ...props }: ChainOfThoughtSearchResultsProps) => (
|
|
161
|
+
<div
|
|
162
|
+
className={cn("flex flex-wrap items-center gap-2", className)}
|
|
163
|
+
{...props}
|
|
164
|
+
/>
|
|
165
|
+
)
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
export type ChainOfThoughtSearchResultProps = ComponentProps<typeof Badge>;
|
|
169
|
+
|
|
170
|
+
export const ChainOfThoughtSearchResult = memo(
|
|
171
|
+
({ className, children, ...props }: ChainOfThoughtSearchResultProps) => (
|
|
172
|
+
<Badge
|
|
173
|
+
className={cn("gap-1 px-2 py-0.5 font-normal text-xs", className)}
|
|
174
|
+
variant="secondary"
|
|
175
|
+
{...props}
|
|
176
|
+
>
|
|
177
|
+
{children}
|
|
178
|
+
</Badge>
|
|
179
|
+
)
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
export type ChainOfThoughtContentProps = ComponentProps<
|
|
183
|
+
typeof CollapsibleContent
|
|
184
|
+
>;
|
|
185
|
+
|
|
186
|
+
export const ChainOfThoughtContent = memo(
|
|
187
|
+
({ className, children, ...props }: ChainOfThoughtContentProps) => {
|
|
188
|
+
const { isOpen } = useChainOfThought();
|
|
189
|
+
|
|
190
|
+
return (
|
|
191
|
+
<Collapsible open={isOpen}>
|
|
192
|
+
<CollapsibleContent
|
|
193
|
+
className={cn(
|
|
194
|
+
"mt-2 space-y-3",
|
|
195
|
+
"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-popover-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in",
|
|
196
|
+
className
|
|
197
|
+
)}
|
|
198
|
+
{...props}
|
|
199
|
+
>
|
|
200
|
+
{children}
|
|
201
|
+
</CollapsibleContent>
|
|
202
|
+
</Collapsible>
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
export type ChainOfThoughtImageProps = ComponentProps<"div"> & {
|
|
208
|
+
caption?: string;
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
export const ChainOfThoughtImage = memo(
|
|
212
|
+
({ className, children, caption, ...props }: ChainOfThoughtImageProps) => (
|
|
213
|
+
<div className={cn("mt-2 space-y-2", className)} {...props}>
|
|
214
|
+
<div className="relative flex max-h-[22rem] items-center justify-center overflow-hidden rounded-lg bg-muted p-3">
|
|
215
|
+
{children}
|
|
216
|
+
</div>
|
|
217
|
+
{caption && <p className="text-muted-foreground text-xs">{caption}</p>}
|
|
218
|
+
</div>
|
|
219
|
+
)
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
ChainOfThought.displayName = "ChainOfThought";
|
|
223
|
+
ChainOfThoughtHeader.displayName = "ChainOfThoughtHeader";
|
|
224
|
+
ChainOfThoughtStep.displayName = "ChainOfThoughtStep";
|
|
225
|
+
ChainOfThoughtSearchResults.displayName = "ChainOfThoughtSearchResults";
|
|
226
|
+
ChainOfThoughtSearchResult.displayName = "ChainOfThoughtSearchResult";
|
|
227
|
+
ChainOfThoughtContent.displayName = "ChainOfThoughtContent";
|
|
228
|
+
ChainOfThoughtImage.displayName = "ChainOfThoughtImage";
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Button } from "@/components/ui/button";
|
|
4
|
+
import { Separator } from "@/components/ui/separator";
|
|
5
|
+
import {
|
|
6
|
+
Tooltip,
|
|
7
|
+
TooltipContent,
|
|
8
|
+
TooltipTrigger,
|
|
9
|
+
} from "@/components/ui/tooltip";
|
|
10
|
+
import { cn } from "@/lib/utils";
|
|
11
|
+
import { BookmarkIcon, type LucideProps } from "lucide-react";
|
|
12
|
+
import type { ComponentProps, HTMLAttributes } from "react";
|
|
13
|
+
|
|
14
|
+
export type CheckpointProps = HTMLAttributes<HTMLDivElement>;
|
|
15
|
+
|
|
16
|
+
export const Checkpoint = ({
|
|
17
|
+
className,
|
|
18
|
+
children,
|
|
19
|
+
...props
|
|
20
|
+
}: CheckpointProps) => (
|
|
21
|
+
<div
|
|
22
|
+
className={cn(
|
|
23
|
+
"flex items-center gap-0.5 overflow-hidden text-muted-foreground",
|
|
24
|
+
className
|
|
25
|
+
)}
|
|
26
|
+
{...props}
|
|
27
|
+
>
|
|
28
|
+
{children}
|
|
29
|
+
<Separator />
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
export type CheckpointIconProps = LucideProps;
|
|
34
|
+
|
|
35
|
+
export const CheckpointIcon = ({
|
|
36
|
+
className,
|
|
37
|
+
children,
|
|
38
|
+
...props
|
|
39
|
+
}: CheckpointIconProps) =>
|
|
40
|
+
children ?? (
|
|
41
|
+
<BookmarkIcon className={cn("size-4 shrink-0", className)} {...props} />
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
export type CheckpointTriggerProps = ComponentProps<typeof Button> & {
|
|
45
|
+
tooltip?: string;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const CheckpointTrigger = ({
|
|
49
|
+
children,
|
|
50
|
+
className,
|
|
51
|
+
variant = "ghost",
|
|
52
|
+
size = "sm",
|
|
53
|
+
tooltip,
|
|
54
|
+
...props
|
|
55
|
+
}: CheckpointTriggerProps) =>
|
|
56
|
+
tooltip ? (
|
|
57
|
+
<Tooltip>
|
|
58
|
+
<TooltipTrigger asChild>
|
|
59
|
+
<Button size={size} type="button" variant={variant} {...props}>
|
|
60
|
+
{children}
|
|
61
|
+
</Button>
|
|
62
|
+
</TooltipTrigger>
|
|
63
|
+
<TooltipContent align="start" side="bottom">
|
|
64
|
+
{tooltip}
|
|
65
|
+
</TooltipContent>
|
|
66
|
+
</Tooltip>
|
|
67
|
+
) : (
|
|
68
|
+
<Button size={size} type="button" variant={variant} {...props}>
|
|
69
|
+
{children}
|
|
70
|
+
</Button>
|
|
71
|
+
);
|