@chat-js/cli 0.6.1 → 0.6.2
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/dist/index.js +16938 -16786
- package/package.json +1 -1
- package/templates/chat-app/app/(auth)/login/page.tsx +3 -3
- package/templates/chat-app/app/(chat)/api/chat/route.ts +4 -60
- package/templates/chat-app/app/not-found.tsx +2 -2
- package/templates/chat-app/chat.config.ts +3 -0
- package/templates/chat-app/components/ai-elements/actions.tsx +44 -44
- package/templates/chat-app/components/ai-elements/artifact.tsx +92 -92
- package/templates/chat-app/components/ai-elements/code-block.tsx +143 -143
- package/templates/chat-app/components/ai-elements/context.tsx +313 -313
- package/templates/chat-app/components/ai-elements/conversation.tsx +65 -65
- package/templates/chat-app/components/ai-elements/extra/conversation-content-scroll-area.tsx +29 -29
- package/templates/chat-app/components/ai-elements/extra/mcp-tool-header.tsx +27 -27
- package/templates/chat-app/components/ai-elements/message.tsx +341 -344
- package/templates/chat-app/components/ai-elements/parseIncompleteMarkdown.tsx +122 -122
- package/templates/chat-app/components/ai-elements/prompt-input.tsx +1059 -1059
- package/templates/chat-app/components/ai-elements/reasoning.tsx +131 -131
- package/templates/chat-app/components/ai-elements/response.tsx +15 -12
- package/templates/chat-app/components/ai-elements/sandbox.tsx +84 -84
- package/templates/chat-app/components/ai-elements/shimmer.tsx +47 -47
- package/templates/chat-app/components/ai-elements/suggestion.tsx +33 -33
- package/templates/chat-app/components/ai-elements/tool.tsx +118 -118
- package/templates/chat-app/components/app-sidebar-history-conditional.tsx +3 -3
- package/templates/chat-app/components/app-sidebar.tsx +3 -3
- package/templates/chat-app/components/connectors-dropdown.tsx +6 -3
- package/templates/chat-app/components/deep-research-progress.tsx +1 -1
- package/templates/chat-app/components/header-breadcrumb.tsx +14 -11
- package/templates/chat-app/components/internal-link.tsx +73 -0
- package/templates/chat-app/components/login-form.tsx +5 -5
- package/templates/chat-app/components/message-parts.tsx +1 -71
- package/templates/chat-app/components/model-selector.tsx +3 -3
- package/templates/chat-app/components/new-chat-button.tsx +4 -4
- package/templates/chat-app/components/part/document-common.tsx +3 -3
- package/templates/chat-app/components/part/document-tool.tsx +3 -3
- package/templates/chat-app/components/part/message-annotations.tsx +2 -2
- package/templates/chat-app/components/part/tool-part.tsx +92 -0
- package/templates/chat-app/components/project-chat-item.tsx +2 -2
- package/templates/chat-app/components/research-progress.tsx +2 -2
- package/templates/chat-app/components/research-task.tsx +1 -1
- package/templates/chat-app/components/research-tasks.tsx +1 -1
- package/templates/chat-app/components/settings/connectors-settings.tsx +4 -4
- package/templates/chat-app/components/settings/mcp-details-page.tsx +5 -5
- package/templates/chat-app/components/settings/settings-nav.tsx +3 -3
- package/templates/chat-app/components/sidebar-chat-item.tsx +4 -12
- package/templates/chat-app/components/sidebar-project-item.tsx +4 -11
- package/templates/chat-app/components/sidebar-top-row.tsx +7 -7
- package/templates/chat-app/components/sidebar-user-nav.tsx +3 -3
- package/templates/chat-app/components/signup-form.tsx +8 -5
- package/templates/chat-app/components/source-badge.tsx +3 -9
- package/templates/chat-app/components/sources.tsx +1 -1
- package/templates/chat-app/components/ui/accordion.tsx +32 -32
- package/templates/chat-app/components/ui/alert-dialog.tsx +103 -103
- package/templates/chat-app/components/ui/alert.tsx +36 -36
- package/templates/chat-app/components/ui/avatar.tsx +28 -28
- package/templates/chat-app/components/ui/badge.tsx +22 -22
- package/templates/chat-app/components/ui/breadcrumb.tsx +72 -72
- package/templates/chat-app/components/ui/button-group.tsx +58 -58
- package/templates/chat-app/components/ui/button.tsx +45 -45
- package/templates/chat-app/components/ui/card.tsx +65 -65
- package/templates/chat-app/components/ui/checkbox.tsx +16 -16
- package/templates/chat-app/components/ui/collapsible.tsx +1 -1
- package/templates/chat-app/components/ui/command.tsx +137 -137
- package/templates/chat-app/components/ui/dialog.tsx +94 -94
- package/templates/chat-app/components/ui/drawer.tsx +68 -68
- package/templates/chat-app/components/ui/dropdown-menu.tsx +184 -184
- package/templates/chat-app/components/ui/empty.tsx +76 -76
- package/templates/chat-app/components/ui/extra/action-container.tsx +3 -3
- package/templates/chat-app/components/ui/extra/scroll-area-viewport-ref.tsx +24 -24
- package/templates/chat-app/components/ui/form.tsx +112 -112
- package/templates/chat-app/components/ui/hover-card.tsx +25 -25
- package/templates/chat-app/components/ui/input-group.tsx +126 -126
- package/templates/chat-app/components/ui/input.tsx +13 -13
- package/templates/chat-app/components/ui/label.tsx +12 -12
- package/templates/chat-app/components/ui/popover.tsx +25 -25
- package/templates/chat-app/components/ui/progress.tsx +19 -19
- package/templates/chat-app/components/ui/resizable.tsx +27 -27
- package/templates/chat-app/components/ui/scroll-area.tsx +30 -30
- package/templates/chat-app/components/ui/select.tsx +108 -108
- package/templates/chat-app/components/ui/separator.tsx +16 -16
- package/templates/chat-app/components/ui/sheet.tsx +91 -91
- package/templates/chat-app/components/ui/sidebar.tsx +615 -615
- package/templates/chat-app/components/ui/skeleton.tsx +7 -7
- package/templates/chat-app/components/ui/slider.tsx +50 -50
- package/templates/chat-app/components/ui/spinner.tsx +8 -8
- package/templates/chat-app/components/ui/switch.tsx +16 -16
- package/templates/chat-app/components/ui/table.tsx +71 -71
- package/templates/chat-app/components/ui/tabs.tsx +31 -31
- package/templates/chat-app/components/ui/textarea.tsx +10 -10
- package/templates/chat-app/components/ui/toggle.tsx +31 -31
- package/templates/chat-app/components/ui/tooltip.tsx +48 -48
- package/templates/chat-app/components/upgrade-cta/limit-display.tsx +7 -7
- package/templates/chat-app/components/upgrade-cta/login-cta-banner.tsx +3 -3
- package/templates/chat-app/components/upgrade-cta/login-prompt.tsx +3 -3
- package/templates/chat-app/hooks/use-mobile.ts +13 -13
- package/templates/chat-app/lib/ai/core-chat-agent.ts +25 -14
- package/templates/chat-app/lib/ai/eval-agent.ts +4 -5
- package/templates/chat-app/lib/ai/installed-tools.ts +12 -0
- package/templates/chat-app/lib/ai/mcp/mcp-client.ts +2 -2
- package/templates/chat-app/lib/ai/models.generated.ts +4236 -4585
- package/templates/chat-app/lib/ai/tool-renderer-registry.ts +31 -0
- package/templates/chat-app/lib/ai/types.ts +15 -20
- package/templates/chat-app/lib/config-requirements.ts +11 -6
- package/templates/chat-app/lib/config-schema.ts +13 -0
- package/templates/chat-app/lib/stores/hooks-message-parts.ts +1 -1
- package/templates/chat-app/lib/utils.ts +157 -157
- package/templates/chat-app/package.json +1 -1
- package/templates/chat-app/scripts/check-env.ts +229 -2
- package/templates/chat-app/tools/chatjs/_shared/lib/tool-part.ts +5 -0
- package/templates/chat-app/{components/part/weather.tsx → tools/chatjs/get-weather/renderer.tsx} +24 -38
- package/templates/chat-app/{components/part/retrieve-url.tsx → tools/chatjs/retrieve-url/renderer.tsx} +20 -15
- package/templates/chat-app/{lib/ai/tools/retrieve-url.ts → tools/chatjs/retrieve-url/tool.ts} +46 -7
- package/templates/chat-app/tools/chatjs/tools.ts +16 -0
- package/templates/chat-app/tools/chatjs/ui.ts +17 -0
- package/templates/chat-app/tools/chatjs/word-count/renderer.tsx +50 -0
- package/templates/chat-app/tools/chatjs/word-count/tool.ts +30 -0
- package/templates/chat-app/{lib/ai/tools → tools/platform}/code-execution.ts +3 -5
- package/templates/chat-app/{lib/ai/tools → tools/platform}/deep-research/deep-research.ts +2 -3
- package/templates/chat-app/{lib/ai/tools → tools/platform}/deep-research/pipeline.ts +1 -1
- package/templates/chat-app/{lib/ai/tools → tools/platform}/deep-research/types.ts +1 -1
- package/templates/chat-app/{lib/ai/tools → tools/platform}/deep-research/utils.ts +7 -7
- package/templates/chat-app/{lib/ai/tools → tools/platform}/documents/types.ts +1 -1
- package/templates/chat-app/{lib/ai/tools → tools/platform}/generate-video.ts +4 -6
- package/templates/chat-app/{lib/ai/tools → tools/platform}/read-document.ts +2 -2
- package/templates/chat-app/{lib/ai/tools → tools/platform}/steps/multi-query-web-search.ts +1 -1
- package/templates/chat-app/{lib/ai/tools → tools/platform}/steps/web-search.ts +1 -1
- package/templates/chat-app/{lib/ai/tools → tools/platform}/tools.ts +20 -20
- package/templates/chat-app/{lib/ai/tools → tools/platform}/web-search.ts +7 -5
- package/templates/electron/CHANGELOG.md +7 -1
- package/templates/electron/package.json +1 -1
- package/templates/chat-app/lib/ai/tools/tools-definitions.ts +0 -83
- /package/templates/chat-app/{lib/ai/tools/get-weather.ts → tools/chatjs/get-weather/tool.ts} +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/code-execution.javascript.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/code-execution.python.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/code-execution.shared.test.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/code-execution.shared.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/code-execution.types.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/deep-research/configuration.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/deep-research/prompts.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/deep-research/researcher-agent.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/deep-research/supervisor-agent.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/documents/code-guidelines.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/documents/create-code-document.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/documents/create-sheet-document.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/documents/create-text-document.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/documents/edit-code-document.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/documents/edit-sheet-document.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/documents/edit-text-document.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/documents/sheet-guidelines.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/documents/text-guidelines.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/generate-image.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/research-updates-schema.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/steps/search-utils.ts +0 -0
- /package/templates/chat-app/{lib/ai/tools → tools/platform}/types.ts +0 -0
|
@@ -1,455 +1,452 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
ButtonGroupText,
|
|
7
|
-
} from "@/components/ui/button-group";
|
|
8
|
-
import {
|
|
9
|
-
Tooltip,
|
|
10
|
-
TooltipContent,
|
|
11
|
-
TooltipProvider,
|
|
12
|
-
TooltipTrigger,
|
|
13
|
-
} from "@/components/ui/tooltip";
|
|
14
|
-
import { cn } from "@/lib/utils";
|
|
3
|
+
import { code } from "@streamdown/code";
|
|
4
|
+
import { math } from "@streamdown/math";
|
|
5
|
+
import { mermaid } from "@streamdown/mermaid";
|
|
15
6
|
import type { FileUIPart, UIMessage } from "ai";
|
|
16
7
|
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
8
|
+
ChevronLeftIcon,
|
|
9
|
+
ChevronRightIcon,
|
|
10
|
+
PaperclipIcon,
|
|
11
|
+
XIcon,
|
|
21
12
|
} from "lucide-react";
|
|
22
13
|
import type { ComponentProps, HTMLAttributes, ReactElement } from "react";
|
|
23
14
|
import { createContext, memo, useContext, useEffect, useState } from "react";
|
|
24
|
-
import { code } from "@streamdown/code";
|
|
25
|
-
import { math } from "@streamdown/math";
|
|
26
|
-
import { mermaid } from "@streamdown/mermaid";
|
|
27
15
|
import { Streamdown } from "streamdown";
|
|
16
|
+
import { Button } from "@/components/ui/button";
|
|
17
|
+
import { ButtonGroup, ButtonGroupText } from "@/components/ui/button-group";
|
|
18
|
+
import {
|
|
19
|
+
Tooltip,
|
|
20
|
+
TooltipContent,
|
|
21
|
+
TooltipProvider,
|
|
22
|
+
TooltipTrigger,
|
|
23
|
+
} from "@/components/ui/tooltip";
|
|
24
|
+
import { cn } from "@/lib/utils";
|
|
28
25
|
import "streamdown/styles.css";
|
|
29
26
|
|
|
30
27
|
const plugins = { code, mermaid, math };
|
|
31
28
|
|
|
32
29
|
export type MessageProps = HTMLAttributes<HTMLDivElement> & {
|
|
33
|
-
|
|
30
|
+
from: UIMessage["role"];
|
|
34
31
|
};
|
|
35
32
|
|
|
36
33
|
export const Message = ({ className, from, ...props }: MessageProps) => (
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
34
|
+
<div
|
|
35
|
+
className={cn(
|
|
36
|
+
"group flex w-full max-w-[80%] gap-2",
|
|
37
|
+
from === "user" ? "is-user ml-auto justify-end" : "is-assistant",
|
|
38
|
+
className,
|
|
39
|
+
)}
|
|
40
|
+
{...props}
|
|
41
|
+
/>
|
|
45
42
|
);
|
|
46
43
|
|
|
47
44
|
export type MessageContentProps = HTMLAttributes<HTMLDivElement>;
|
|
48
45
|
|
|
49
46
|
export const MessageContent = ({
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
children,
|
|
48
|
+
className,
|
|
49
|
+
...props
|
|
53
50
|
}: MessageContentProps) => (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
51
|
+
<div
|
|
52
|
+
className={cn(
|
|
53
|
+
"is-user:dark flex w-fit flex-col gap-2 overflow-hidden text-sm",
|
|
54
|
+
"group-[.is-user]:ml-auto group-[.is-user]:rounded-lg group-[.is-user]:bg-secondary group-[.is-user]:px-4 group-[.is-user]:py-3 group-[.is-user]:text-foreground",
|
|
55
|
+
"group-[.is-assistant]:text-foreground",
|
|
56
|
+
className,
|
|
57
|
+
)}
|
|
58
|
+
{...props}
|
|
59
|
+
>
|
|
60
|
+
{children}
|
|
61
|
+
</div>
|
|
65
62
|
);
|
|
66
63
|
|
|
67
64
|
export type MessageActionsProps = ComponentProps<"div">;
|
|
68
65
|
|
|
69
66
|
export const MessageActions = ({
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
className,
|
|
68
|
+
children,
|
|
69
|
+
...props
|
|
73
70
|
}: MessageActionsProps) => (
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
<div className={cn("flex items-center gap-1", className)} {...props}>
|
|
72
|
+
{children}
|
|
73
|
+
</div>
|
|
77
74
|
);
|
|
78
75
|
|
|
79
76
|
export type MessageActionProps = ComponentProps<typeof Button> & {
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
tooltip?: string;
|
|
78
|
+
label?: string;
|
|
82
79
|
};
|
|
83
80
|
|
|
84
81
|
export const MessageAction = ({
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
82
|
+
tooltip,
|
|
83
|
+
children,
|
|
84
|
+
label,
|
|
85
|
+
variant = "ghost",
|
|
86
|
+
size = "icon-sm",
|
|
87
|
+
...props
|
|
91
88
|
}: MessageActionProps) => {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
89
|
+
const button = (
|
|
90
|
+
<Button size={size} type="button" variant={variant} {...props}>
|
|
91
|
+
{children}
|
|
92
|
+
<span className="sr-only">{label || tooltip}</span>
|
|
93
|
+
</Button>
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
if (tooltip) {
|
|
97
|
+
return (
|
|
98
|
+
<TooltipProvider>
|
|
99
|
+
<Tooltip>
|
|
100
|
+
<TooltipTrigger asChild>{button}</TooltipTrigger>
|
|
101
|
+
<TooltipContent>
|
|
102
|
+
<p>{tooltip}</p>
|
|
103
|
+
</TooltipContent>
|
|
104
|
+
</Tooltip>
|
|
105
|
+
</TooltipProvider>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return button;
|
|
113
110
|
};
|
|
114
111
|
|
|
115
112
|
type MessageBranchContextType = {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
113
|
+
currentBranch: number;
|
|
114
|
+
totalBranches: number;
|
|
115
|
+
goToPrevious: () => void;
|
|
116
|
+
goToNext: () => void;
|
|
117
|
+
branches: ReactElement[];
|
|
118
|
+
setBranches: (branches: ReactElement[]) => void;
|
|
122
119
|
};
|
|
123
120
|
|
|
124
121
|
const MessageBranchContext = createContext<MessageBranchContextType | null>(
|
|
125
|
-
|
|
122
|
+
null,
|
|
126
123
|
);
|
|
127
124
|
|
|
128
125
|
const useMessageBranch = () => {
|
|
129
|
-
|
|
126
|
+
const context = useContext(MessageBranchContext);
|
|
130
127
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
128
|
+
if (!context) {
|
|
129
|
+
throw new Error(
|
|
130
|
+
"MessageBranch components must be used within MessageBranch",
|
|
131
|
+
);
|
|
132
|
+
}
|
|
136
133
|
|
|
137
|
-
|
|
134
|
+
return context;
|
|
138
135
|
};
|
|
139
136
|
|
|
140
137
|
export type MessageBranchProps = HTMLAttributes<HTMLDivElement> & {
|
|
141
|
-
|
|
142
|
-
|
|
138
|
+
defaultBranch?: number;
|
|
139
|
+
onBranchChange?: (branchIndex: number) => void;
|
|
143
140
|
};
|
|
144
141
|
|
|
145
142
|
export const MessageBranch = ({
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
143
|
+
defaultBranch = 0,
|
|
144
|
+
onBranchChange,
|
|
145
|
+
className,
|
|
146
|
+
...props
|
|
150
147
|
}: MessageBranchProps) => {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
148
|
+
const [currentBranch, setCurrentBranch] = useState(defaultBranch);
|
|
149
|
+
const [branches, setBranches] = useState<ReactElement[]>([]);
|
|
150
|
+
|
|
151
|
+
const handleBranchChange = (newBranch: number) => {
|
|
152
|
+
setCurrentBranch(newBranch);
|
|
153
|
+
onBranchChange?.(newBranch);
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const goToPrevious = () => {
|
|
157
|
+
const newBranch =
|
|
158
|
+
currentBranch > 0 ? currentBranch - 1 : branches.length - 1;
|
|
159
|
+
handleBranchChange(newBranch);
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const goToNext = () => {
|
|
163
|
+
const newBranch =
|
|
164
|
+
currentBranch < branches.length - 1 ? currentBranch + 1 : 0;
|
|
165
|
+
handleBranchChange(newBranch);
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
const contextValue: MessageBranchContextType = {
|
|
169
|
+
currentBranch,
|
|
170
|
+
totalBranches: branches.length,
|
|
171
|
+
goToPrevious,
|
|
172
|
+
goToNext,
|
|
173
|
+
branches,
|
|
174
|
+
setBranches,
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
return (
|
|
178
|
+
<MessageBranchContext.Provider value={contextValue}>
|
|
179
|
+
<div
|
|
180
|
+
className={cn("grid w-full gap-2 [&>div]:pb-0", className)}
|
|
181
|
+
{...props}
|
|
182
|
+
/>
|
|
183
|
+
</MessageBranchContext.Provider>
|
|
184
|
+
);
|
|
188
185
|
};
|
|
189
186
|
|
|
190
187
|
export type MessageBranchContentProps = HTMLAttributes<HTMLDivElement>;
|
|
191
188
|
|
|
192
189
|
export const MessageBranchContent = ({
|
|
193
|
-
|
|
194
|
-
|
|
190
|
+
children,
|
|
191
|
+
...props
|
|
195
192
|
}: MessageBranchContentProps) => {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
193
|
+
const { currentBranch, setBranches, branches } = useMessageBranch();
|
|
194
|
+
const childrenArray = Array.isArray(children) ? children : [children];
|
|
195
|
+
|
|
196
|
+
// Use useEffect to update branches when they change
|
|
197
|
+
useEffect(() => {
|
|
198
|
+
if (branches.length !== childrenArray.length) {
|
|
199
|
+
setBranches(childrenArray);
|
|
200
|
+
}
|
|
201
|
+
}, [childrenArray, branches, setBranches]);
|
|
202
|
+
|
|
203
|
+
return childrenArray.map((branch, index) => (
|
|
204
|
+
<div
|
|
205
|
+
className={cn(
|
|
206
|
+
"grid gap-2 overflow-hidden [&>div]:pb-0",
|
|
207
|
+
index === currentBranch ? "block" : "hidden",
|
|
208
|
+
)}
|
|
209
|
+
key={branch.key}
|
|
210
|
+
{...props}
|
|
211
|
+
>
|
|
212
|
+
{branch}
|
|
213
|
+
</div>
|
|
214
|
+
));
|
|
218
215
|
};
|
|
219
216
|
|
|
220
217
|
export type MessageBranchSelectorProps = HTMLAttributes<HTMLDivElement> & {
|
|
221
|
-
|
|
218
|
+
from: UIMessage["role"];
|
|
222
219
|
};
|
|
223
220
|
|
|
224
221
|
export const MessageBranchSelector = ({
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
222
|
+
className,
|
|
223
|
+
from,
|
|
224
|
+
...props
|
|
228
225
|
}: MessageBranchSelectorProps) => {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
226
|
+
const { totalBranches } = useMessageBranch();
|
|
227
|
+
|
|
228
|
+
// Don't render if there's only one branch
|
|
229
|
+
if (totalBranches <= 1) {
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return (
|
|
234
|
+
<ButtonGroup
|
|
235
|
+
className="[&>*:not(:first-child)]:rounded-l-md [&>*:not(:last-child)]:rounded-r-md"
|
|
236
|
+
orientation="horizontal"
|
|
237
|
+
{...props}
|
|
238
|
+
/>
|
|
239
|
+
);
|
|
243
240
|
};
|
|
244
241
|
|
|
245
242
|
export type MessageBranchPreviousProps = ComponentProps<typeof Button>;
|
|
246
243
|
|
|
247
244
|
export const MessageBranchPrevious = ({
|
|
248
|
-
|
|
249
|
-
|
|
245
|
+
children,
|
|
246
|
+
...props
|
|
250
247
|
}: MessageBranchPreviousProps) => {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
248
|
+
const { goToPrevious, totalBranches } = useMessageBranch();
|
|
249
|
+
|
|
250
|
+
return (
|
|
251
|
+
<Button
|
|
252
|
+
aria-label="Previous branch"
|
|
253
|
+
disabled={totalBranches <= 1}
|
|
254
|
+
onClick={goToPrevious}
|
|
255
|
+
size="icon-sm"
|
|
256
|
+
type="button"
|
|
257
|
+
variant="ghost"
|
|
258
|
+
{...props}
|
|
259
|
+
>
|
|
260
|
+
{children ?? <ChevronLeftIcon size={14} />}
|
|
261
|
+
</Button>
|
|
262
|
+
);
|
|
266
263
|
};
|
|
267
264
|
|
|
268
265
|
export type MessageBranchNextProps = ComponentProps<typeof Button>;
|
|
269
266
|
|
|
270
267
|
export const MessageBranchNext = ({
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
268
|
+
children,
|
|
269
|
+
className,
|
|
270
|
+
...props
|
|
274
271
|
}: MessageBranchNextProps) => {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
272
|
+
const { goToNext, totalBranches } = useMessageBranch();
|
|
273
|
+
|
|
274
|
+
return (
|
|
275
|
+
<Button
|
|
276
|
+
aria-label="Next branch"
|
|
277
|
+
disabled={totalBranches <= 1}
|
|
278
|
+
onClick={goToNext}
|
|
279
|
+
size="icon-sm"
|
|
280
|
+
type="button"
|
|
281
|
+
variant="ghost"
|
|
282
|
+
{...props}
|
|
283
|
+
>
|
|
284
|
+
{children ?? <ChevronRightIcon size={14} />}
|
|
285
|
+
</Button>
|
|
286
|
+
);
|
|
290
287
|
};
|
|
291
288
|
|
|
292
289
|
export type MessageBranchPageProps = HTMLAttributes<HTMLSpanElement>;
|
|
293
290
|
|
|
294
291
|
export const MessageBranchPage = ({
|
|
295
|
-
|
|
296
|
-
|
|
292
|
+
className,
|
|
293
|
+
...props
|
|
297
294
|
}: MessageBranchPageProps) => {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
295
|
+
const { currentBranch, totalBranches } = useMessageBranch();
|
|
296
|
+
|
|
297
|
+
return (
|
|
298
|
+
<ButtonGroupText
|
|
299
|
+
className={cn(
|
|
300
|
+
"border-none bg-transparent text-muted-foreground shadow-none",
|
|
301
|
+
className,
|
|
302
|
+
)}
|
|
303
|
+
{...props}
|
|
304
|
+
>
|
|
305
|
+
{currentBranch + 1} of {totalBranches}
|
|
306
|
+
</ButtonGroupText>
|
|
307
|
+
);
|
|
311
308
|
};
|
|
312
309
|
|
|
313
310
|
export type MessageResponseProps = ComponentProps<typeof Streamdown>;
|
|
314
311
|
|
|
315
312
|
export const MessageResponse = memo(
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
313
|
+
({ className, ...props }: MessageResponseProps) => (
|
|
314
|
+
<Streamdown
|
|
315
|
+
className={cn(
|
|
316
|
+
"size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0",
|
|
317
|
+
className,
|
|
318
|
+
)}
|
|
319
|
+
plugins={plugins}
|
|
320
|
+
{...props}
|
|
321
|
+
/>
|
|
322
|
+
),
|
|
323
|
+
(prevProps, nextProps) => prevProps.children === nextProps.children,
|
|
327
324
|
);
|
|
328
325
|
|
|
329
326
|
MessageResponse.displayName = "MessageResponse";
|
|
330
327
|
|
|
331
328
|
export type MessageAttachmentProps = HTMLAttributes<HTMLDivElement> & {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
329
|
+
data: FileUIPart;
|
|
330
|
+
className?: string;
|
|
331
|
+
onRemove?: () => void;
|
|
335
332
|
};
|
|
336
333
|
|
|
337
334
|
export function MessageAttachment({
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
335
|
+
data,
|
|
336
|
+
className,
|
|
337
|
+
onRemove,
|
|
338
|
+
...props
|
|
342
339
|
}: MessageAttachmentProps) {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
340
|
+
const filename = data.filename || "";
|
|
341
|
+
const mediaType =
|
|
342
|
+
data.mediaType?.startsWith("image/") && data.url ? "image" : "file";
|
|
343
|
+
const isImage = mediaType === "image";
|
|
344
|
+
const attachmentLabel = filename || (isImage ? "Image" : "Attachment");
|
|
345
|
+
|
|
346
|
+
return (
|
|
347
|
+
<div
|
|
348
|
+
className={cn(
|
|
349
|
+
"group relative size-24 overflow-hidden rounded-lg",
|
|
350
|
+
className,
|
|
351
|
+
)}
|
|
352
|
+
{...props}
|
|
353
|
+
>
|
|
354
|
+
{isImage ? (
|
|
355
|
+
<>
|
|
356
|
+
<img
|
|
357
|
+
alt={filename || "attachment"}
|
|
358
|
+
className="size-full object-cover"
|
|
359
|
+
height={100}
|
|
360
|
+
src={data.url}
|
|
361
|
+
width={100}
|
|
362
|
+
/>
|
|
363
|
+
{onRemove && (
|
|
364
|
+
<Button
|
|
365
|
+
aria-label="Remove attachment"
|
|
366
|
+
className="absolute top-2 right-2 size-6 rounded-full bg-background/80 p-0 opacity-0 backdrop-blur-sm transition-opacity hover:bg-background group-hover:opacity-100 [&>svg]:size-3"
|
|
367
|
+
onClick={(e) => {
|
|
368
|
+
e.stopPropagation();
|
|
369
|
+
onRemove();
|
|
370
|
+
}}
|
|
371
|
+
type="button"
|
|
372
|
+
variant="ghost"
|
|
373
|
+
>
|
|
374
|
+
<XIcon />
|
|
375
|
+
<span className="sr-only">Remove</span>
|
|
376
|
+
</Button>
|
|
377
|
+
)}
|
|
378
|
+
</>
|
|
379
|
+
) : (
|
|
380
|
+
<>
|
|
381
|
+
<Tooltip>
|
|
382
|
+
<TooltipTrigger asChild>
|
|
383
|
+
<div className="flex size-full shrink-0 items-center justify-center rounded-lg bg-muted text-muted-foreground">
|
|
384
|
+
<PaperclipIcon className="size-4" />
|
|
385
|
+
</div>
|
|
386
|
+
</TooltipTrigger>
|
|
387
|
+
<TooltipContent>
|
|
388
|
+
<p>{attachmentLabel}</p>
|
|
389
|
+
</TooltipContent>
|
|
390
|
+
</Tooltip>
|
|
391
|
+
{onRemove && (
|
|
392
|
+
<Button
|
|
393
|
+
aria-label="Remove attachment"
|
|
394
|
+
className="size-6 shrink-0 rounded-full p-0 opacity-0 transition-opacity hover:bg-accent group-hover:opacity-100 [&>svg]:size-3"
|
|
395
|
+
onClick={(e) => {
|
|
396
|
+
e.stopPropagation();
|
|
397
|
+
onRemove();
|
|
398
|
+
}}
|
|
399
|
+
type="button"
|
|
400
|
+
variant="ghost"
|
|
401
|
+
>
|
|
402
|
+
<XIcon />
|
|
403
|
+
<span className="sr-only">Remove</span>
|
|
404
|
+
</Button>
|
|
405
|
+
)}
|
|
406
|
+
</>
|
|
407
|
+
)}
|
|
408
|
+
</div>
|
|
409
|
+
);
|
|
413
410
|
}
|
|
414
411
|
|
|
415
412
|
export type MessageAttachmentsProps = ComponentProps<"div">;
|
|
416
413
|
|
|
417
414
|
export function MessageAttachments({
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
415
|
+
children,
|
|
416
|
+
className,
|
|
417
|
+
...props
|
|
421
418
|
}: MessageAttachmentsProps) {
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
419
|
+
if (!children) {
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
return (
|
|
424
|
+
<div
|
|
425
|
+
className={cn(
|
|
426
|
+
"ml-auto flex w-fit flex-wrap items-start gap-2",
|
|
427
|
+
className,
|
|
428
|
+
)}
|
|
429
|
+
{...props}
|
|
430
|
+
>
|
|
431
|
+
{children}
|
|
432
|
+
</div>
|
|
433
|
+
);
|
|
437
434
|
}
|
|
438
435
|
|
|
439
436
|
export type MessageToolbarProps = ComponentProps<"div">;
|
|
440
437
|
|
|
441
438
|
export const MessageToolbar = ({
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
439
|
+
className,
|
|
440
|
+
children,
|
|
441
|
+
...props
|
|
445
442
|
}: MessageToolbarProps) => (
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
443
|
+
<div
|
|
444
|
+
className={cn(
|
|
445
|
+
"mt-4 flex w-full items-center justify-between gap-4",
|
|
446
|
+
className,
|
|
447
|
+
)}
|
|
448
|
+
{...props}
|
|
449
|
+
>
|
|
450
|
+
{children}
|
|
451
|
+
</div>
|
|
455
452
|
);
|