ikoncomponents 1.7.0 → 1.7.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/dist/ikoncomponents/assistant-ui/Assistant.d.ts +28 -0
- package/dist/ikoncomponents/assistant-ui/Assistant.js +306 -0
- package/dist/ikoncomponents/assistant-ui/agent-dropdown.d.ts +24 -0
- package/dist/ikoncomponents/assistant-ui/agent-dropdown.js +16 -0
- package/dist/ikoncomponents/assistant-ui/agentTextChatTransport.d.ts +30 -0
- package/dist/ikoncomponents/assistant-ui/agentTextChatTransport.js +208 -0
- package/dist/ikoncomponents/assistant-ui/attachment.d.ts +4 -0
- package/dist/ikoncomponents/assistant-ui/attachment.js +93 -0
- package/dist/ikoncomponents/assistant-ui/markdown-text.d.ts +2 -0
- package/dist/ikoncomponents/assistant-ui/markdown-text.js +126 -0
- package/dist/ikoncomponents/assistant-ui/thread.d.ts +10 -0
- package/dist/ikoncomponents/assistant-ui/thread.js +115 -0
- package/dist/ikoncomponents/assistant-ui/tool-fallback.d.ts +2 -0
- package/dist/ikoncomponents/assistant-ui/tool-fallback.js +18 -0
- package/dist/ikoncomponents/assistant-ui/tooltip-icon-button.d.ts +7 -0
- package/dist/ikoncomponents/assistant-ui/tooltip-icon-button.js +23 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/utils/userType.d.ts +13 -0
- package/dist/utils/userType.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
interface UserData {
|
|
2
|
+
userId: string;
|
|
3
|
+
userName: string;
|
|
4
|
+
userLogin: string;
|
|
5
|
+
password: string;
|
|
6
|
+
userPhone?: string;
|
|
7
|
+
userEmail: string;
|
|
8
|
+
userThumbnail?: string | null;
|
|
9
|
+
userType?: string;
|
|
10
|
+
active?: boolean;
|
|
11
|
+
accountId?: string;
|
|
12
|
+
userDeleted?: boolean;
|
|
13
|
+
}
|
|
14
|
+
interface AssistantComponentProps {
|
|
15
|
+
provider?: string;
|
|
16
|
+
model?: string;
|
|
17
|
+
agentId?: string;
|
|
18
|
+
agentName?: string;
|
|
19
|
+
temperature?: number;
|
|
20
|
+
maxTokens?: number;
|
|
21
|
+
className?: string;
|
|
22
|
+
baseUrl?: string;
|
|
23
|
+
additionalReferenceInfo?: object;
|
|
24
|
+
appId: string;
|
|
25
|
+
currentUserDetails: UserData;
|
|
26
|
+
}
|
|
27
|
+
export declare const AssistantComponent: ({ provider, model, agentId, agentName, temperature, maxTokens, className, baseUrl, additionalReferenceInfo, appId, currentUserDetails, }: AssistantComponentProps) => import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
// "use client";
|
|
2
|
+
// import { Thread } from "./thread";
|
|
3
|
+
// import { AssistantRuntimeProvider } from "@assistant-ui/react";
|
|
4
|
+
// import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
|
|
5
|
+
// import { AgentTextChatTransport } from "./agentTextChatTransport";
|
|
6
|
+
// import { useEffect, useState } from "react";
|
|
7
|
+
// import { getValidAccessToken } from "@/utils/token-management";
|
|
8
|
+
// import { Agent } from "./agent-dropdown";
|
|
9
|
+
// interface UserData {
|
|
10
|
+
// userId: string;
|
|
11
|
+
// userName: string;
|
|
12
|
+
// userLogin: string;
|
|
13
|
+
// password: string;
|
|
14
|
+
// userPhone?: string;
|
|
15
|
+
// userEmail: string;
|
|
16
|
+
// userThumbnail?: string | null;
|
|
17
|
+
// userType?: string;
|
|
18
|
+
// active?: boolean;
|
|
19
|
+
// accountId?: string;
|
|
20
|
+
// userDeleted?: boolean;
|
|
21
|
+
// }
|
|
22
|
+
// interface AssistantComponentProps {
|
|
23
|
+
// provider?: string;
|
|
24
|
+
// model?: string;
|
|
25
|
+
// agentId?: string;
|
|
26
|
+
// agentName?: string;
|
|
27
|
+
// temperature?: number;
|
|
28
|
+
// maxTokens?: number;
|
|
29
|
+
// className?: string;
|
|
30
|
+
// baseUrl?: string;
|
|
31
|
+
// additionalReferenceInfo?: object;
|
|
32
|
+
// appId: string;
|
|
33
|
+
// currentUserDetails: UserData;
|
|
34
|
+
// }
|
|
35
|
+
// export const AssistantComponent = ({
|
|
36
|
+
// provider = "openai",
|
|
37
|
+
// model = "gpt-4o-mini",
|
|
38
|
+
// agentId = "default-agent",
|
|
39
|
+
// agentName = "Default Agent",
|
|
40
|
+
// temperature = 0.7,
|
|
41
|
+
// maxTokens = 2048,
|
|
42
|
+
// className,
|
|
43
|
+
// baseUrl = "http://localhost:3000",
|
|
44
|
+
// additionalReferenceInfo = {},
|
|
45
|
+
// appId = "",
|
|
46
|
+
// currentUserDetails,
|
|
47
|
+
// }: AssistantComponentProps) => {
|
|
48
|
+
// const runtime = useChatRuntime({
|
|
49
|
+
// transport: new AgentTextChatTransport({
|
|
50
|
+
// provider,
|
|
51
|
+
// model,
|
|
52
|
+
// agentId,
|
|
53
|
+
// agentName,
|
|
54
|
+
// temperature,
|
|
55
|
+
// maxTokens,
|
|
56
|
+
// baseUrl,
|
|
57
|
+
// additionalReferenceInfo,
|
|
58
|
+
// }),
|
|
59
|
+
// });
|
|
60
|
+
// const [agentList, setAgentList] = useState([]);
|
|
61
|
+
// const [selectedAgent, setSelectedAgent] = useState<Agent>();
|
|
62
|
+
// const getAgentsByAppId = async () => {
|
|
63
|
+
// try {
|
|
64
|
+
// const accessToken = await getValidAccessToken(
|
|
65
|
+
// "https://ikoncloud-dev.keross.com/ikon-api",
|
|
66
|
+
// );
|
|
67
|
+
// const response = await fetch(`${baseUrl}/api/agent/${appId}`, {
|
|
68
|
+
// method: "GET",
|
|
69
|
+
// headers: {
|
|
70
|
+
// "Content-Type": "application/json",
|
|
71
|
+
// Authorization: `Bearer ${accessToken}`,
|
|
72
|
+
// },
|
|
73
|
+
// });
|
|
74
|
+
// // 1. Check if the response is actually okay
|
|
75
|
+
// if (!response.ok) {
|
|
76
|
+
// throw new Error(`HTTP error! status: ${response.status}`);
|
|
77
|
+
// }
|
|
78
|
+
// // 2. Parse the body as JSON
|
|
79
|
+
// const data = await response.json();
|
|
80
|
+
// // 3. Now you can use it!
|
|
81
|
+
// console.log("Agent Data:", data);
|
|
82
|
+
// setAgentList(data);
|
|
83
|
+
// // setAgentList(response)
|
|
84
|
+
// } catch (error) {
|
|
85
|
+
// console.error(
|
|
86
|
+
// "Error while fetching agents with the specific appId",
|
|
87
|
+
// error,
|
|
88
|
+
// );
|
|
89
|
+
// }
|
|
90
|
+
// };
|
|
91
|
+
// useEffect(() => {
|
|
92
|
+
// getAgentsByAppId();
|
|
93
|
+
// }, [appId, baseUrl]);
|
|
94
|
+
// useEffect(() => {
|
|
95
|
+
// },[selectedAgent])
|
|
96
|
+
// return (
|
|
97
|
+
// <AssistantRuntimeProvider runtime={runtime}>
|
|
98
|
+
// <div className={className}>
|
|
99
|
+
// <div
|
|
100
|
+
// className={`flex flex-col h-full border rounded-lg overflow-hidden ${className}`}
|
|
101
|
+
// >
|
|
102
|
+
// <Thread
|
|
103
|
+
// currentUserDetails={currentUserDetails}
|
|
104
|
+
// agents={agentList}
|
|
105
|
+
// initialAgentId={agentId}
|
|
106
|
+
// initialAgentName={agentName}
|
|
107
|
+
// onAgentChange={(agent) => {
|
|
108
|
+
// // Handle agent change here
|
|
109
|
+
// console.log("Agent changed:", agent);
|
|
110
|
+
// setSelectedAgent(agent);
|
|
111
|
+
// }}
|
|
112
|
+
// />
|
|
113
|
+
// </div>
|
|
114
|
+
// </div>
|
|
115
|
+
// </AssistantRuntimeProvider>
|
|
116
|
+
// );
|
|
117
|
+
// };
|
|
118
|
+
//2nd imperfect change
|
|
119
|
+
// "use client";
|
|
120
|
+
// import { Thread } from "./thread";
|
|
121
|
+
// import { AssistantRuntimeProvider } from "@assistant-ui/react";
|
|
122
|
+
// import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
|
|
123
|
+
// import { AgentTextChatTransport } from "./agentTextChatTransport";
|
|
124
|
+
// import { useEffect, useRef, useState } from "react";
|
|
125
|
+
// import { getValidAccessToken } from "@/utils/token-management";
|
|
126
|
+
// import { Agent } from "./agent-dropdown";
|
|
127
|
+
// interface UserData {
|
|
128
|
+
// userId: string;
|
|
129
|
+
// userName: string;
|
|
130
|
+
// userLogin: string;
|
|
131
|
+
// password: string;
|
|
132
|
+
// userPhone?: string;
|
|
133
|
+
// userEmail: string;
|
|
134
|
+
// userThumbnail?: string | null;
|
|
135
|
+
// userType?: string;
|
|
136
|
+
// active?: boolean;
|
|
137
|
+
// accountId?: string;
|
|
138
|
+
// userDeleted?: boolean;
|
|
139
|
+
// }
|
|
140
|
+
// interface AssistantComponentProps {
|
|
141
|
+
// provider?: string;
|
|
142
|
+
// model?: string;
|
|
143
|
+
// agentId?: string;
|
|
144
|
+
// agentName?: string;
|
|
145
|
+
// temperature?: number;
|
|
146
|
+
// maxTokens?: number;
|
|
147
|
+
// className?: string;
|
|
148
|
+
// baseUrl?: string;
|
|
149
|
+
// additionalReferenceInfo?: object;
|
|
150
|
+
// appId: string;
|
|
151
|
+
// currentUserDetails: UserData;
|
|
152
|
+
// }
|
|
153
|
+
// export const AssistantComponent = ({
|
|
154
|
+
// provider = "openai",
|
|
155
|
+
// model = "gpt-4o-mini",
|
|
156
|
+
// agentId = "default-agent",
|
|
157
|
+
// agentName = "Default Agent",
|
|
158
|
+
// temperature = 0.7,
|
|
159
|
+
// maxTokens = 2048,
|
|
160
|
+
// className,
|
|
161
|
+
// baseUrl = "http://localhost:3000",
|
|
162
|
+
// additionalReferenceInfo = {},
|
|
163
|
+
// appId = "",
|
|
164
|
+
// currentUserDetails,
|
|
165
|
+
// }: AssistantComponentProps) => {
|
|
166
|
+
// const transportRef = useRef<AgentTextChatTransport | null>(null);
|
|
167
|
+
// const transport = new AgentTextChatTransport({
|
|
168
|
+
// provider,
|
|
169
|
+
// model,
|
|
170
|
+
// agentId,
|
|
171
|
+
// agentName,
|
|
172
|
+
// temperature,
|
|
173
|
+
// maxTokens,
|
|
174
|
+
// baseUrl,
|
|
175
|
+
// additionalReferenceInfo,
|
|
176
|
+
// });
|
|
177
|
+
// transportRef.current = transport;
|
|
178
|
+
// const runtime = useChatRuntime({
|
|
179
|
+
// transport,
|
|
180
|
+
// });
|
|
181
|
+
// const [agentList, setAgentList] = useState<Agent[]>([]);
|
|
182
|
+
// const [selectedAgent, setSelectedAgent] = useState<Agent>();
|
|
183
|
+
// const getAgentsByAppId = async () => {
|
|
184
|
+
// try {
|
|
185
|
+
// const accessToken = await getValidAccessToken(
|
|
186
|
+
// "https://ikoncloud-dev.keross.com/ikon-api",
|
|
187
|
+
// );
|
|
188
|
+
// const response = await fetch(`${baseUrl}/api/agent/${appId}`, {
|
|
189
|
+
// method: "GET",
|
|
190
|
+
// headers: {
|
|
191
|
+
// "Content-Type": "application/json",
|
|
192
|
+
// Authorization: `Bearer ${accessToken}`,
|
|
193
|
+
// },
|
|
194
|
+
// });
|
|
195
|
+
// if (!response.ok) {
|
|
196
|
+
// throw new Error(`HTTP error! status: ${response.status}`);
|
|
197
|
+
// }
|
|
198
|
+
// const data = await response.json();
|
|
199
|
+
// console.log("Agent Data:", data);
|
|
200
|
+
// setAgentList(data);
|
|
201
|
+
// } catch (error) {
|
|
202
|
+
// console.error(
|
|
203
|
+
// "Error while fetching agents with the specific appId",
|
|
204
|
+
// error,
|
|
205
|
+
// );
|
|
206
|
+
// }
|
|
207
|
+
// };
|
|
208
|
+
// useEffect(() => {
|
|
209
|
+
// getAgentsByAppId();
|
|
210
|
+
// }, [appId, baseUrl]);
|
|
211
|
+
// const handleAgentChange = (agent: Agent) => {
|
|
212
|
+
// setSelectedAgent(agent);
|
|
213
|
+
// // Update the transport with the new agent configuration
|
|
214
|
+
// if (transportRef.current) {
|
|
215
|
+
// transportRef.current.updateAgentConfig({
|
|
216
|
+
// agentId: agent.agentID,
|
|
217
|
+
// agentName: agent.agentName,
|
|
218
|
+
// });
|
|
219
|
+
// }
|
|
220
|
+
// console.log("Agent changed to:", agent.agentName);
|
|
221
|
+
// };
|
|
222
|
+
// return (
|
|
223
|
+
// <AssistantRuntimeProvider runtime={runtime}>
|
|
224
|
+
// <div className={className}>
|
|
225
|
+
// <div
|
|
226
|
+
// className={`flex flex-col h-full border rounded-lg overflow-hidden ${className}`}
|
|
227
|
+
// >
|
|
228
|
+
// <Thread
|
|
229
|
+
// currentUserDetails={currentUserDetails}
|
|
230
|
+
// agents={agentList}
|
|
231
|
+
// initialAgentId={agentId}
|
|
232
|
+
// initialAgentName={agentName}
|
|
233
|
+
// onAgentChange={handleAgentChange}
|
|
234
|
+
// />
|
|
235
|
+
// </div>
|
|
236
|
+
// </div>
|
|
237
|
+
// </AssistantRuntimeProvider>
|
|
238
|
+
// );
|
|
239
|
+
// };
|
|
240
|
+
//3rd change
|
|
241
|
+
"use client";
|
|
242
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
243
|
+
import { Thread } from "./thread";
|
|
244
|
+
import { AssistantRuntimeProvider } from "@assistant-ui/react";
|
|
245
|
+
import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
|
|
246
|
+
import { AgentTextChatTransport } from "./agentTextChatTransport";
|
|
247
|
+
import { useEffect, useMemo, useState } from "react";
|
|
248
|
+
import { getValidAccessToken } from "../../utils/token-management";
|
|
249
|
+
export const AssistantComponent = ({ provider = "openai", model = "gpt-4o-mini", agentId = "default-agent", agentName = "Default Agent", temperature = 0.7, maxTokens = 2048, className, baseUrl = "http://localhost:3000", additionalReferenceInfo = {}, appId = "", currentUserDetails, }) => {
|
|
250
|
+
const [agentList, setAgentList] = useState([]);
|
|
251
|
+
const [selectedAgent, setSelectedAgent] = useState();
|
|
252
|
+
// Create transport with current agent config - memoized to avoid recreating on every render
|
|
253
|
+
const transport = useMemo(() => new AgentTextChatTransport({
|
|
254
|
+
provider,
|
|
255
|
+
model,
|
|
256
|
+
agentId: selectedAgent ? selectedAgent.agentID : agentId,
|
|
257
|
+
agentName: selectedAgent ? selectedAgent.agentName : agentName,
|
|
258
|
+
temperature,
|
|
259
|
+
maxTokens,
|
|
260
|
+
baseUrl,
|
|
261
|
+
additionalReferenceInfo,
|
|
262
|
+
}), [
|
|
263
|
+
provider,
|
|
264
|
+
model,
|
|
265
|
+
selectedAgent,
|
|
266
|
+
agentId,
|
|
267
|
+
agentName,
|
|
268
|
+
temperature,
|
|
269
|
+
maxTokens,
|
|
270
|
+
baseUrl,
|
|
271
|
+
additionalReferenceInfo,
|
|
272
|
+
]);
|
|
273
|
+
// Create runtime with the transport - will recreate when transport changes
|
|
274
|
+
const runtime = useChatRuntime({
|
|
275
|
+
transport,
|
|
276
|
+
});
|
|
277
|
+
const getAgentsByAppId = async () => {
|
|
278
|
+
try {
|
|
279
|
+
const accessToken = await getValidAccessToken("https://ikoncloud-dev.keross.com/ikon-api");
|
|
280
|
+
const response = await fetch(`${baseUrl}/api/agent/${appId}`, {
|
|
281
|
+
method: "GET",
|
|
282
|
+
headers: {
|
|
283
|
+
"Content-Type": "application/json",
|
|
284
|
+
Authorization: `Bearer ${accessToken}`,
|
|
285
|
+
},
|
|
286
|
+
});
|
|
287
|
+
if (!response.ok) {
|
|
288
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
289
|
+
}
|
|
290
|
+
const data = await response.json();
|
|
291
|
+
console.log("Agent Data:", data);
|
|
292
|
+
setAgentList(data);
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
console.error("Error while fetching agents with the specific appId", error);
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
useEffect(() => {
|
|
299
|
+
getAgentsByAppId();
|
|
300
|
+
}, [appId, baseUrl]);
|
|
301
|
+
const handleAgentChange = (agent) => {
|
|
302
|
+
setSelectedAgent(agent);
|
|
303
|
+
console.log("Agent changed to:", agent.agentName);
|
|
304
|
+
};
|
|
305
|
+
return (_jsx(AssistantRuntimeProvider, { runtime: runtime, children: _jsx("div", { className: className, children: _jsx("div", { className: `flex flex-col h-full border rounded-lg overflow-hidden ${className}`, children: _jsx(Thread, { currentUserDetails: currentUserDetails, agents: agentList, initialAgentId: agentId, initialAgentName: agentName, onAgentChange: handleAgentChange }) }) }) }));
|
|
306
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface Agent {
|
|
2
|
+
agentDescription?: string;
|
|
3
|
+
agentID: string;
|
|
4
|
+
agentName: string;
|
|
5
|
+
agentRoles?: string[];
|
|
6
|
+
agentTasks?: object[];
|
|
7
|
+
appId: string;
|
|
8
|
+
createdAt: string;
|
|
9
|
+
createdBy: string;
|
|
10
|
+
mcpServerIds?: string[];
|
|
11
|
+
systemPrompt: string;
|
|
12
|
+
updatedAt: string;
|
|
13
|
+
updatedBy: string;
|
|
14
|
+
userName?: null | string;
|
|
15
|
+
[key: string]: any;
|
|
16
|
+
}
|
|
17
|
+
export interface AgentDropdownProps {
|
|
18
|
+
agents: Agent[];
|
|
19
|
+
selectedAgent?: Agent;
|
|
20
|
+
onSelectAgent: (agent: Agent) => void;
|
|
21
|
+
className?: string;
|
|
22
|
+
triggerClassName?: string;
|
|
23
|
+
}
|
|
24
|
+
export declare const AgentDropdown: ({ agents, selectedAgent, onSelectAgent, className, triggerClassName, }: AgentDropdownProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { ChevronDownIcon } from "lucide-react";
|
|
5
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "../../shadcn/dropdown-menu";
|
|
6
|
+
import { Button } from "../../shadcn/button";
|
|
7
|
+
import { cn } from "../../utils/cn";
|
|
8
|
+
export const AgentDropdown = ({ agents, selectedAgent, onSelectAgent, className, triggerClassName, }) => {
|
|
9
|
+
const [open, setOpen] = useState(false);
|
|
10
|
+
// const displayAgent = selectedAgent || (agents.length > 0 ? agents[0] : null);
|
|
11
|
+
const displayAgent = selectedAgent || null;
|
|
12
|
+
return (_jsxs(DropdownMenu, { open: open, onOpenChange: setOpen, children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", className: cn("gap-2 px-3 py-2 text-sm font-medium rounded-2xl", triggerClassName), children: [_jsx("span", { className: "truncate", children: (displayAgent === null || displayAgent === void 0 ? void 0 : displayAgent.agentName) || "Select Agent" }), _jsx(ChevronDownIcon, { className: "size-4 shrink-0 opacity-50" })] }) }), _jsx(DropdownMenuContent, { align: "end", className: cn("min-w-[200px]", className), children: agents.length > 0 ? (_jsxs(_Fragment, { children: [_jsx(DropdownMenuLabel, { className: "px-2 py-1.5 text-xs font-semibold text-muted-foreground", children: "Agents" }), _jsx(DropdownMenuSeparator, {}), _jsx(DropdownMenuGroup, { children: agents.map((agent) => (_jsxs(DropdownMenuItem, { onClick: () => {
|
|
13
|
+
onSelectAgent(agent);
|
|
14
|
+
setOpen(false);
|
|
15
|
+
}, className: cn("cursor-pointer flex flex-col gap-1", (displayAgent === null || displayAgent === void 0 ? void 0 : displayAgent.agentID) === agent.agentID && "bg-accent"), children: [_jsx("div", { className: "font-medium text-sm", children: agent.agentName }), agent.agentDescription && (_jsx("div", { className: "text-xs text-muted-foreground truncate", children: agent.agentDescription }))] }, agent.agentID))) })] })) : (_jsx("div", { className: "px-2 py-1.5 text-sm text-muted-foreground text-center", children: "No agents available" })) })] }));
|
|
16
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ChatTransport, UIMessage, UIMessageChunk, ChatRequestOptions } from "ai";
|
|
2
|
+
export interface AgentTextChatTransportOptions {
|
|
3
|
+
provider: string;
|
|
4
|
+
model: string;
|
|
5
|
+
agentId: string;
|
|
6
|
+
agentName?: string;
|
|
7
|
+
temperature?: number;
|
|
8
|
+
maxTokens?: number;
|
|
9
|
+
baseUrl?: string;
|
|
10
|
+
additionalReferenceInfo?: object;
|
|
11
|
+
}
|
|
12
|
+
export declare class AgentTextChatTransport<UI_MESSAGE extends UIMessage = UIMessage> implements ChatTransport<UI_MESSAGE> {
|
|
13
|
+
private agentConfig;
|
|
14
|
+
private baseUrl;
|
|
15
|
+
private chatIdMap;
|
|
16
|
+
constructor(options: AgentTextChatTransportOptions);
|
|
17
|
+
updateAgentConfig(options: Partial<AgentTextChatTransportOptions>): void;
|
|
18
|
+
private getChatId;
|
|
19
|
+
sendMessages(options: {
|
|
20
|
+
trigger: "submit-message" | "regenerate-message";
|
|
21
|
+
chatId: string;
|
|
22
|
+
messageId: string | undefined;
|
|
23
|
+
messages: UI_MESSAGE[];
|
|
24
|
+
abortSignal: AbortSignal | undefined;
|
|
25
|
+
} & ChatRequestOptions): Promise<ReadableStream<UIMessageChunk>>;
|
|
26
|
+
reconnectToStream(options: {
|
|
27
|
+
chatId: string;
|
|
28
|
+
} & ChatRequestOptions): Promise<ReadableStream<UIMessageChunk> | null>;
|
|
29
|
+
private processResponseStream;
|
|
30
|
+
}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { getValidAccessToken } from "../../utils/token-management";
|
|
2
|
+
import { v4 as uuidv4 } from "uuid";
|
|
3
|
+
export class AgentTextChatTransport {
|
|
4
|
+
constructor(options) {
|
|
5
|
+
this.chatIdMap = new Map();
|
|
6
|
+
this.agentConfig = options;
|
|
7
|
+
this.baseUrl = options.baseUrl || "";
|
|
8
|
+
}
|
|
9
|
+
updateAgentConfig(options) {
|
|
10
|
+
this.agentConfig = Object.assign(Object.assign({}, this.agentConfig), options);
|
|
11
|
+
}
|
|
12
|
+
getChatId(chatId) {
|
|
13
|
+
if (this.chatIdMap.has(chatId)) {
|
|
14
|
+
return this.chatIdMap.get(chatId);
|
|
15
|
+
}
|
|
16
|
+
return uuidv4();
|
|
17
|
+
}
|
|
18
|
+
async sendMessages(options) {
|
|
19
|
+
var _a, _b;
|
|
20
|
+
const { messages, chatId, abortSignal, headers, body } = options;
|
|
21
|
+
console.log("sendMessages called with chatId:", chatId, "trigger:", options.trigger);
|
|
22
|
+
const serverChatId = this.getChatId(chatId);
|
|
23
|
+
console.log("Using server chatId:", serverChatId);
|
|
24
|
+
// Convert UIMessage[] to LangChain AIMessage format
|
|
25
|
+
const convertedMessages = messages.map((msg) => {
|
|
26
|
+
const content = msg.parts
|
|
27
|
+
.filter((part) => part.type === "text")
|
|
28
|
+
.map((part) => part.text)
|
|
29
|
+
.join("");
|
|
30
|
+
return {
|
|
31
|
+
role: msg.role,
|
|
32
|
+
content: msg.role === "user" &&
|
|
33
|
+
this.agentConfig.additionalReferenceInfo &&
|
|
34
|
+
Object.keys(this.agentConfig.additionalReferenceInfo).length > 0
|
|
35
|
+
? content + JSON.stringify(this.agentConfig.additionalReferenceInfo)
|
|
36
|
+
: content,
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
const requestBody = Object.assign({ messages: convertedMessages, provider: this.agentConfig.provider, model: this.agentConfig.model, agentId: this.agentConfig.agentId, agentName: this.agentConfig.agentName, temperature: (_a = this.agentConfig.temperature) !== null && _a !== void 0 ? _a : 0.7, maxTokens: (_b = this.agentConfig.maxTokens) !== null && _b !== void 0 ? _b : 2048, stream: true, useVoice: false }, body);
|
|
40
|
+
//adding code to fetch the token and pass it
|
|
41
|
+
const accessToken = await getValidAccessToken(this.baseUrl);
|
|
42
|
+
const mergedHeaders = Object.assign({ "Content-Type": "application/json", "Authorization": `Bearer ${accessToken}` }, (headers instanceof Headers
|
|
43
|
+
? Object.fromEntries(headers.entries())
|
|
44
|
+
: headers || {}));
|
|
45
|
+
try {
|
|
46
|
+
const response = await fetch(`${this.baseUrl}/api/chat/completions/${serverChatId}`, {
|
|
47
|
+
method: "POST",
|
|
48
|
+
headers: mergedHeaders,
|
|
49
|
+
body: JSON.stringify(requestBody),
|
|
50
|
+
signal: abortSignal,
|
|
51
|
+
cache: "no-store",
|
|
52
|
+
});
|
|
53
|
+
if (!response.ok) {
|
|
54
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
55
|
+
}
|
|
56
|
+
if (!response.body) {
|
|
57
|
+
throw new Error("Response body is null");
|
|
58
|
+
}
|
|
59
|
+
return this.processResponseStream(response.body);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
console.error("Error in sendMessages:", error);
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async reconnectToStream(options) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
processResponseStream(stream) {
|
|
70
|
+
const decoder = new TextDecoder();
|
|
71
|
+
let buffer = "";
|
|
72
|
+
let reader = null;
|
|
73
|
+
let isClosed = false;
|
|
74
|
+
let pendingChunks = [];
|
|
75
|
+
let hasStarted = false;
|
|
76
|
+
let messageId = "";
|
|
77
|
+
let textStarted = false;
|
|
78
|
+
let textPartId = "";
|
|
79
|
+
return new ReadableStream({
|
|
80
|
+
async start(controller) {
|
|
81
|
+
reader = stream.getReader();
|
|
82
|
+
},
|
|
83
|
+
async pull(controller) {
|
|
84
|
+
var _a;
|
|
85
|
+
if (!reader || isClosed) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
// First, deliver any pending chunks one at a time
|
|
89
|
+
if (pendingChunks.length > 0) {
|
|
90
|
+
controller.enqueue(pendingChunks.shift());
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
const { done, value } = await reader.read();
|
|
95
|
+
if (done) {
|
|
96
|
+
// Send text-end and finish chunks before closing
|
|
97
|
+
if (hasStarted && messageId) {
|
|
98
|
+
if (textStarted && textPartId) {
|
|
99
|
+
pendingChunks.push({
|
|
100
|
+
type: "text-end",
|
|
101
|
+
id: textPartId,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
pendingChunks.push({
|
|
105
|
+
type: "finish",
|
|
106
|
+
finishReason: "stop",
|
|
107
|
+
});
|
|
108
|
+
// Enqueue pending chunks before closing
|
|
109
|
+
while (pendingChunks.length > 0) {
|
|
110
|
+
controller.enqueue(pendingChunks.shift());
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (!isClosed) {
|
|
114
|
+
isClosed = true;
|
|
115
|
+
controller.close();
|
|
116
|
+
}
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
buffer += decoder.decode(value, { stream: true });
|
|
120
|
+
const lines = buffer.split("\n");
|
|
121
|
+
buffer = lines.pop() || "";
|
|
122
|
+
for (const line of lines) {
|
|
123
|
+
const trimmedLine = line.trim();
|
|
124
|
+
if (!trimmedLine)
|
|
125
|
+
continue;
|
|
126
|
+
if (trimmedLine.startsWith("data:")) {
|
|
127
|
+
const data = trimmedLine.slice(5).trim();
|
|
128
|
+
if (!data)
|
|
129
|
+
continue;
|
|
130
|
+
try {
|
|
131
|
+
const parsed = JSON.parse(data);
|
|
132
|
+
if (isClosed) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
// Track message ID and send start chunk once
|
|
136
|
+
if (parsed.id && !messageId) {
|
|
137
|
+
messageId = parsed.id;
|
|
138
|
+
hasStarted = true;
|
|
139
|
+
pendingChunks.push({
|
|
140
|
+
type: "start",
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
let chunk = null;
|
|
144
|
+
if (parsed.type === "ai") {
|
|
145
|
+
const message = (_a = parsed.messages) === null || _a === void 0 ? void 0 : _a[0];
|
|
146
|
+
if (message === null || message === void 0 ? void 0 : message.content) {
|
|
147
|
+
// Generate text part ID once
|
|
148
|
+
if (!textPartId) {
|
|
149
|
+
textPartId = uuidv4();
|
|
150
|
+
}
|
|
151
|
+
// Send text-start before first delta
|
|
152
|
+
if (!textStarted) {
|
|
153
|
+
textStarted = true;
|
|
154
|
+
pendingChunks.push({
|
|
155
|
+
type: "text-start",
|
|
156
|
+
id: textPartId,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
chunk = {
|
|
160
|
+
type: "text-delta",
|
|
161
|
+
delta: message.content,
|
|
162
|
+
id: textPartId,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
else if (parsed.type === "tool") {
|
|
167
|
+
const toolCall = parsed.toolCall;
|
|
168
|
+
if (toolCall) {
|
|
169
|
+
chunk = {
|
|
170
|
+
type: "tool-input-available",
|
|
171
|
+
toolCallId: toolCall.callId,
|
|
172
|
+
toolName: toolCall.name,
|
|
173
|
+
input: toolCall.result,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (chunk) {
|
|
178
|
+
pendingChunks.push(chunk);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
catch (e) {
|
|
182
|
+
// Ignore parse errors
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// Enqueue the first chunk if we have any
|
|
187
|
+
if (pendingChunks.length > 0) {
|
|
188
|
+
controller.enqueue(pendingChunks.shift());
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
if (!isClosed) {
|
|
193
|
+
isClosed = true;
|
|
194
|
+
controller.error(error);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
cancel() {
|
|
199
|
+
isClosed = true;
|
|
200
|
+
pendingChunks = [];
|
|
201
|
+
if (reader) {
|
|
202
|
+
reader.releaseLock();
|
|
203
|
+
reader = null;
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import Image from "next/image";
|
|
5
|
+
import { XIcon, PlusIcon, FileText } from "lucide-react";
|
|
6
|
+
import { AttachmentPrimitive, ComposerPrimitive, MessagePrimitive, useAssistantState, useAssistantApi, } from "@assistant-ui/react";
|
|
7
|
+
import { useShallow } from "zustand/shallow";
|
|
8
|
+
import { Tooltip, TooltipContent, TooltipTrigger, } from "../../shadcn/tooltip";
|
|
9
|
+
import { Dialog, DialogTitle, DialogContent, DialogTrigger, } from "../../shadcn/dialog";
|
|
10
|
+
import { Avatar, AvatarImage, AvatarFallback } from "../../shadcn/avatar";
|
|
11
|
+
import { TooltipIconButton } from "./tooltip-icon-button";
|
|
12
|
+
import { cn } from "../../utils/cn";
|
|
13
|
+
const useFileSrc = (file) => {
|
|
14
|
+
const [src, setSrc] = useState(undefined);
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (!file) {
|
|
17
|
+
setSrc(undefined);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const objectUrl = URL.createObjectURL(file);
|
|
21
|
+
setSrc(objectUrl);
|
|
22
|
+
return () => {
|
|
23
|
+
URL.revokeObjectURL(objectUrl);
|
|
24
|
+
};
|
|
25
|
+
}, [file]);
|
|
26
|
+
return src;
|
|
27
|
+
};
|
|
28
|
+
const useAttachmentSrc = () => {
|
|
29
|
+
var _a;
|
|
30
|
+
const { file, src } = useAssistantState(useShallow(({ attachment }) => {
|
|
31
|
+
var _a, _b;
|
|
32
|
+
if (attachment.type !== "image")
|
|
33
|
+
return {};
|
|
34
|
+
if (attachment.file)
|
|
35
|
+
return { file: attachment.file };
|
|
36
|
+
const src = (_b = (_a = attachment.content) === null || _a === void 0 ? void 0 : _a.filter((c) => c.type === "image")[0]) === null || _b === void 0 ? void 0 : _b.image;
|
|
37
|
+
if (!src)
|
|
38
|
+
return {};
|
|
39
|
+
return { src };
|
|
40
|
+
}));
|
|
41
|
+
return (_a = useFileSrc(file)) !== null && _a !== void 0 ? _a : src;
|
|
42
|
+
};
|
|
43
|
+
const AttachmentPreview = ({ src }) => {
|
|
44
|
+
const [isLoaded, setIsLoaded] = useState(false);
|
|
45
|
+
return (_jsx(Image, { src: src, alt: "Image Preview", width: 1, height: 1, className: isLoaded
|
|
46
|
+
? "aui-attachment-preview-image-loaded block h-auto max-h-[80vh] w-auto max-w-full object-contain"
|
|
47
|
+
: "aui-attachment-preview-image-loading hidden", onLoadingComplete: () => setIsLoaded(true), priority: false }));
|
|
48
|
+
};
|
|
49
|
+
const AttachmentPreviewDialog = ({ children }) => {
|
|
50
|
+
const src = useAttachmentSrc();
|
|
51
|
+
if (!src)
|
|
52
|
+
return children;
|
|
53
|
+
return (_jsxs(Dialog, { children: [_jsx(DialogTrigger, { className: "aui-attachment-preview-trigger cursor-pointer transition-colors hover:bg-accent/50", asChild: true, children: children }), _jsxs(DialogContent, { className: "aui-attachment-preview-dialog-content p-2 sm:max-w-3xl [&>button]:rounded-full [&>button]:bg-foreground/60 [&>button]:p-1 [&>button]:opacity-100 [&>button]:ring-0! [&_svg]:text-background [&>button]:hover:[&_svg]:text-destructive", children: [_jsx(DialogTitle, { className: "aui-sr-only sr-only", children: "Image Attachment Preview" }), _jsx("div", { className: "aui-attachment-preview relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden bg-background", children: _jsx(AttachmentPreview, { src: src }) })] })] }));
|
|
54
|
+
};
|
|
55
|
+
const AttachmentThumb = () => {
|
|
56
|
+
const isImage = useAssistantState(({ attachment }) => attachment.type === "image");
|
|
57
|
+
const src = useAttachmentSrc();
|
|
58
|
+
return (_jsxs(Avatar, { className: "aui-attachment-tile-avatar h-full w-full rounded-none", children: [_jsx(AvatarImage, { src: src, alt: "Attachment preview", className: "aui-attachment-tile-image object-cover" }), _jsx(AvatarFallback, { delayMs: isImage ? 200 : 0, children: _jsx(FileText, { className: "aui-attachment-tile-fallback-icon size-8 text-muted-foreground" }) })] }));
|
|
59
|
+
};
|
|
60
|
+
const AttachmentUI = () => {
|
|
61
|
+
const api = useAssistantApi();
|
|
62
|
+
const isComposer = api.attachment.source === "composer";
|
|
63
|
+
const isImage = useAssistantState(({ attachment }) => attachment.type === "image");
|
|
64
|
+
const typeLabel = useAssistantState(({ attachment }) => {
|
|
65
|
+
const type = attachment.type;
|
|
66
|
+
switch (type) {
|
|
67
|
+
case "image":
|
|
68
|
+
return "Image";
|
|
69
|
+
case "document":
|
|
70
|
+
return "Document";
|
|
71
|
+
case "file":
|
|
72
|
+
return "File";
|
|
73
|
+
default:
|
|
74
|
+
const _exhaustiveCheck = type;
|
|
75
|
+
throw new Error(`Unknown attachment type: ${_exhaustiveCheck}`);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
return (_jsxs(Tooltip, { children: [_jsxs(AttachmentPrimitive.Root, { className: cn("aui-attachment-root relative", isImage &&
|
|
79
|
+
"aui-attachment-root-composer only:[&>#attachment-tile]:size-24"), children: [_jsx(AttachmentPreviewDialog, { children: _jsx(TooltipTrigger, { asChild: true, children: _jsx("div", { className: cn("aui-attachment-tile size-14 cursor-pointer overflow-hidden rounded-[14px] border bg-muted transition-opacity hover:opacity-75", isComposer &&
|
|
80
|
+
"aui-attachment-tile-composer border-foreground/20"), role: "button", id: "attachment-tile", "aria-label": `${typeLabel} attachment`, children: _jsx(AttachmentThumb, {}) }) }) }), isComposer && _jsx(AttachmentRemove, {})] }), _jsx(TooltipContent, { side: "top", children: _jsx(AttachmentPrimitive.Name, {}) })] }));
|
|
81
|
+
};
|
|
82
|
+
const AttachmentRemove = () => {
|
|
83
|
+
return (_jsx(AttachmentPrimitive.Remove, { asChild: true, children: _jsx(TooltipIconButton, { tooltip: "Remove file", className: "aui-attachment-tile-remove absolute top-1.5 right-1.5 size-3.5 rounded-full bg-white text-muted-foreground opacity-100 shadow-sm hover:bg-white! [&_svg]:text-black hover:[&_svg]:text-destructive", side: "top", children: _jsx(XIcon, { className: "aui-attachment-remove-icon size-3 dark:stroke-[2.5px]" }) }) }));
|
|
84
|
+
};
|
|
85
|
+
export const UserMessageAttachments = () => {
|
|
86
|
+
return (_jsx("div", { className: "aui-user-message-attachments-end col-span-full col-start-1 row-start-1 flex w-full flex-row justify-end gap-2", children: _jsx(MessagePrimitive.Attachments, { components: { Attachment: AttachmentUI } }) }));
|
|
87
|
+
};
|
|
88
|
+
export const ComposerAttachments = () => {
|
|
89
|
+
return (_jsx("div", { className: "aui-composer-attachments mb-2 flex w-full flex-row items-center gap-2 overflow-x-auto px-1.5 pt-0.5 pb-1 empty:hidden", children: _jsx(ComposerPrimitive.Attachments, { components: { Attachment: AttachmentUI } }) }));
|
|
90
|
+
};
|
|
91
|
+
export const ComposerAddAttachment = () => {
|
|
92
|
+
return (_jsx(ComposerPrimitive.AddAttachment, { asChild: true, children: _jsx(TooltipIconButton, { tooltip: "Add Attachment", side: "bottom", variant: "ghost", size: "icon", className: "aui-composer-add-attachment size-8.5 rounded-full p-1 font-semibold text-xs hover:bg-muted-foreground/15 dark:border-muted-foreground/15 dark:hover:bg-muted-foreground/30", "aria-label": "Add Attachment", children: _jsx(PlusIcon, { className: "aui-attachment-add-icon size-5 stroke-[1.5px]" }) }) }));
|
|
93
|
+
};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
+
import "@assistant-ui/react-markdown";
|
|
15
|
+
import { MarkdownTextPrimitive, unstable_memoizeMarkdownComponents as memoizeMarkdownComponents, useIsMarkdownCodeBlock, } from "@assistant-ui/react-markdown";
|
|
16
|
+
import remarkGfm from "remark-gfm";
|
|
17
|
+
import { memo, useState } from "react";
|
|
18
|
+
import { CheckIcon, CopyIcon } from "lucide-react";
|
|
19
|
+
import { TooltipIconButton } from "../assistant-ui/tooltip-icon-button";
|
|
20
|
+
import { cn } from "../../utils/cn";
|
|
21
|
+
const MarkdownTextImpl = () => {
|
|
22
|
+
return (_jsx(MarkdownTextPrimitive, { remarkPlugins: [remarkGfm], className: "aui-md", components: defaultComponents }));
|
|
23
|
+
};
|
|
24
|
+
export const MarkdownText = memo(MarkdownTextImpl);
|
|
25
|
+
const CodeHeader = ({ language, code }) => {
|
|
26
|
+
const { isCopied, copyToClipboard } = useCopyToClipboard();
|
|
27
|
+
const onCopy = () => {
|
|
28
|
+
if (!code || isCopied)
|
|
29
|
+
return;
|
|
30
|
+
copyToClipboard(code);
|
|
31
|
+
};
|
|
32
|
+
return (_jsxs("div", { className: "aui-code-header-root mt-4 flex items-center justify-between gap-4 rounded-t-lg bg-muted-foreground/15 px-4 py-2 font-semibold text-foreground text-sm dark:bg-muted-foreground/20", children: [_jsx("span", { className: "aui-code-header-language lowercase [&>span]:text-xs", children: language }), _jsxs(TooltipIconButton, { tooltip: "Copy", onClick: onCopy, children: [!isCopied && _jsx(CopyIcon, {}), isCopied && _jsx(CheckIcon, {})] })] }));
|
|
33
|
+
};
|
|
34
|
+
const useCopyToClipboard = ({ copiedDuration = 3000, } = {}) => {
|
|
35
|
+
const [isCopied, setIsCopied] = useState(false);
|
|
36
|
+
const copyToClipboard = (value) => {
|
|
37
|
+
if (!value)
|
|
38
|
+
return;
|
|
39
|
+
navigator.clipboard.writeText(value).then(() => {
|
|
40
|
+
setIsCopied(true);
|
|
41
|
+
setTimeout(() => setIsCopied(false), copiedDuration);
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
return { isCopied, copyToClipboard };
|
|
45
|
+
};
|
|
46
|
+
const defaultComponents = memoizeMarkdownComponents({
|
|
47
|
+
h1: (_a) => {
|
|
48
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
49
|
+
return (_jsx("h1", Object.assign({ className: cn("aui-md-h1 mb-8 scroll-m-20 font-extrabold text-4xl tracking-tight last:mb-0", className) }, props)));
|
|
50
|
+
},
|
|
51
|
+
h2: (_a) => {
|
|
52
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
53
|
+
return (_jsx("h2", Object.assign({ className: cn("aui-md-h2 mt-8 mb-4 scroll-m-20 font-semibold text-3xl tracking-tight first:mt-0 last:mb-0", className) }, props)));
|
|
54
|
+
},
|
|
55
|
+
h3: (_a) => {
|
|
56
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
57
|
+
return (_jsx("h3", Object.assign({ className: cn("aui-md-h3 mt-6 mb-4 scroll-m-20 font-semibold text-2xl tracking-tight first:mt-0 last:mb-0", className) }, props)));
|
|
58
|
+
},
|
|
59
|
+
h4: (_a) => {
|
|
60
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
61
|
+
return (_jsx("h4", Object.assign({ className: cn("aui-md-h4 mt-6 mb-4 scroll-m-20 font-semibold text-xl tracking-tight first:mt-0 last:mb-0", className) }, props)));
|
|
62
|
+
},
|
|
63
|
+
h5: (_a) => {
|
|
64
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
65
|
+
return (_jsx("h5", Object.assign({ className: cn("aui-md-h5 my-4 font-semibold text-lg first:mt-0 last:mb-0", className) }, props)));
|
|
66
|
+
},
|
|
67
|
+
h6: (_a) => {
|
|
68
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
69
|
+
return (_jsx("h6", Object.assign({ className: cn("aui-md-h6 my-4 font-semibold first:mt-0 last:mb-0", className) }, props)));
|
|
70
|
+
},
|
|
71
|
+
p: (_a) => {
|
|
72
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
73
|
+
return (_jsx("p", Object.assign({ className: cn("aui-md-p mt-5 mb-5 leading-7 first:mt-0 last:mb-0", className) }, props)));
|
|
74
|
+
},
|
|
75
|
+
a: (_a) => {
|
|
76
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
77
|
+
return (_jsx("a", Object.assign({ className: cn("aui-md-a font-medium text-primary underline underline-offset-4", className) }, props)));
|
|
78
|
+
},
|
|
79
|
+
blockquote: (_a) => {
|
|
80
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
81
|
+
return (_jsx("blockquote", Object.assign({ className: cn("aui-md-blockquote border-l-2 pl-6 italic", className) }, props)));
|
|
82
|
+
},
|
|
83
|
+
ul: (_a) => {
|
|
84
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
85
|
+
return (_jsx("ul", Object.assign({ className: cn("aui-md-ul my-5 ml-6 list-disc [&>li]:mt-2", className) }, props)));
|
|
86
|
+
},
|
|
87
|
+
ol: (_a) => {
|
|
88
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
89
|
+
return (_jsx("ol", Object.assign({ className: cn("aui-md-ol my-5 ml-6 list-decimal [&>li]:mt-2", className) }, props)));
|
|
90
|
+
},
|
|
91
|
+
hr: (_a) => {
|
|
92
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
93
|
+
return (_jsx("hr", Object.assign({ className: cn("aui-md-hr my-5 border-b", className) }, props)));
|
|
94
|
+
},
|
|
95
|
+
table: (_a) => {
|
|
96
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
97
|
+
return (_jsx("table", Object.assign({ className: cn("aui-md-table my-5 w-full border-separate border-spacing-0 overflow-y-auto", className) }, props)));
|
|
98
|
+
},
|
|
99
|
+
th: (_a) => {
|
|
100
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
101
|
+
return (_jsx("th", Object.assign({ className: cn("aui-md-th bg-muted px-4 py-2 text-left font-bold first:rounded-tl-lg last:rounded-tr-lg [[align=center]]:text-center [[align=right]]:text-right", className) }, props)));
|
|
102
|
+
},
|
|
103
|
+
td: (_a) => {
|
|
104
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
105
|
+
return (_jsx("td", Object.assign({ className: cn("aui-md-td border-b border-l px-4 py-2 text-left last:border-r [[align=center]]:text-center [[align=right]]:text-right", className) }, props)));
|
|
106
|
+
},
|
|
107
|
+
tr: (_a) => {
|
|
108
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
109
|
+
return (_jsx("tr", Object.assign({ className: cn("aui-md-tr m-0 border-b p-0 first:border-t [&:last-child>td:first-child]:rounded-bl-lg [&:last-child>td:last-child]:rounded-br-lg", className) }, props)));
|
|
110
|
+
},
|
|
111
|
+
sup: (_a) => {
|
|
112
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
113
|
+
return (_jsx("sup", Object.assign({ className: cn("aui-md-sup [&>a]:text-xs [&>a]:no-underline", className) }, props)));
|
|
114
|
+
},
|
|
115
|
+
pre: (_a) => {
|
|
116
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
117
|
+
return (_jsx("pre", Object.assign({ className: cn("aui-md-pre overflow-x-auto rounded-t-none!rounded-b-lg bg-black p-4 text-white", className) }, props)));
|
|
118
|
+
},
|
|
119
|
+
code: function Code(_a) {
|
|
120
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
121
|
+
const isCodeBlock = useIsMarkdownCodeBlock();
|
|
122
|
+
return (_jsx("code", Object.assign({ className: cn(!isCodeBlock &&
|
|
123
|
+
"aui-md-inline-code rounded border bg-muted font-semibold", className) }, props)));
|
|
124
|
+
},
|
|
125
|
+
CodeHeader,
|
|
126
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type FC } from "react";
|
|
2
|
+
import { UserData } from "../../utils/userType";
|
|
3
|
+
import { Agent } from "./agent-dropdown";
|
|
4
|
+
export declare const Thread: FC<{
|
|
5
|
+
currentUserDetails: UserData;
|
|
6
|
+
agents?: Agent[];
|
|
7
|
+
initialAgentId?: string;
|
|
8
|
+
initialAgentName?: string;
|
|
9
|
+
onAgentChange?: (agent: Agent) => void;
|
|
10
|
+
}>;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
+
import { ArrowDownIcon, ArrowUpIcon, CheckIcon, ChevronLeftIcon, ChevronRightIcon, CopyIcon, PencilIcon, RefreshCwIcon, Square, } from "lucide-react";
|
|
15
|
+
import { ActionBarPrimitive, BranchPickerPrimitive, ComposerPrimitive, ErrorPrimitive, MessagePrimitive, ThreadPrimitive, } from "@assistant-ui/react";
|
|
16
|
+
import { useState } from "react";
|
|
17
|
+
import { LazyMotion, MotionConfig, domAnimation } from "motion/react";
|
|
18
|
+
import * as m from "motion/react-m";
|
|
19
|
+
import { Button } from "../../shadcn/button";
|
|
20
|
+
import { MarkdownText } from "../assistant-ui/markdown-text";
|
|
21
|
+
import { ToolFallback } from "../assistant-ui/tool-fallback";
|
|
22
|
+
import { TooltipIconButton } from "../assistant-ui/tooltip-icon-button";
|
|
23
|
+
import { ComposerAddAttachment, ComposerAttachments, UserMessageAttachments, } from "../assistant-ui/attachment";
|
|
24
|
+
import { cn } from "../../utils/cn";
|
|
25
|
+
import { AgentDropdown } from "./agent-dropdown";
|
|
26
|
+
export const Thread = ({ currentUserDetails, agents = [], initialAgentId = "default-agent", initialAgentName = "Default Agent", onAgentChange, }) => {
|
|
27
|
+
const [selectedAgent, setSelectedAgent] = useState(agents.find((a) => a.agentID === initialAgentId));
|
|
28
|
+
return (_jsx(LazyMotion, { features: domAnimation, children: _jsx(MotionConfig, { reducedMotion: "user", children: _jsx(ThreadPrimitive.Root, { className: "aui-root aui-thread-root @container flex h-full flex-col bg-background", style: {
|
|
29
|
+
["--thread-max-width"]: "44rem",
|
|
30
|
+
}, children: _jsxs(ThreadPrimitive.Viewport, { turnAnchor: "top", className: "aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll scroll-smooth px-4 pt-4", children: [_jsx(ThreadPrimitive.If, { empty: true, children: _jsx(ThreadWelcome, { currentUserDetails: currentUserDetails }) }), _jsx(ThreadPrimitive.Messages, { components: {
|
|
31
|
+
UserMessage,
|
|
32
|
+
EditComposer,
|
|
33
|
+
AssistantMessage,
|
|
34
|
+
} }), _jsxs(ThreadPrimitive.ViewportFooter, { className: "aui-thread-viewport-footer sticky bottom-0 mx-auto mt-4 flex w-full max-w-[var(--thread-max-width)] flex-col gap-4 overflow-visible rounded-t-3xl bg-background pb-4 md:pb-6", children: [_jsx(ThreadScrollToBottom, {}), _jsx(Composer, { agents: agents, selectedAgent: selectedAgent, onSelectAgent: (agent) => {
|
|
35
|
+
setSelectedAgent(agent);
|
|
36
|
+
onAgentChange === null || onAgentChange === void 0 ? void 0 : onAgentChange(agent);
|
|
37
|
+
} })] })] }) }) }) }));
|
|
38
|
+
};
|
|
39
|
+
const ThreadScrollToBottom = () => {
|
|
40
|
+
return (_jsx(ThreadPrimitive.ScrollToBottom, { asChild: true, children: _jsx(TooltipIconButton, { tooltip: "Scroll to bottom", variant: "outline", className: "aui-thread-scroll-to-bottom absolute -top-12 z-10 self-center rounded-full p-4 disabled:invisible dark:bg-background dark:hover:bg-accent", children: _jsx(ArrowDownIcon, {}) }) }));
|
|
41
|
+
};
|
|
42
|
+
const ThreadWelcome = ({ currentUserDetails, }) => {
|
|
43
|
+
const now = new Date();
|
|
44
|
+
const hours = now.getHours();
|
|
45
|
+
let greeting = "";
|
|
46
|
+
if (hours >= 5 && hours < 12) {
|
|
47
|
+
greeting = "Good Morning";
|
|
48
|
+
}
|
|
49
|
+
else if (hours >= 12 && hours < 17) {
|
|
50
|
+
greeting = "Good Afternoon";
|
|
51
|
+
}
|
|
52
|
+
else if (hours >= 17 && hours < 21) {
|
|
53
|
+
greeting = "Good Evening";
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
greeting = "Good Night";
|
|
57
|
+
}
|
|
58
|
+
console.log(greeting);
|
|
59
|
+
return (_jsxs("div", { className: "aui-thread-welcome-root mx-auto my-auto flex w-full max-w-[var(--thread-max-width)] flex-grow flex-col", children: [_jsx("div", { className: "aui-thread-welcome-center flex w-full flex-grow flex-col items-center justify-center", children: _jsxs("div", { className: "aui-thread-welcome-message flex size-full flex-col justify-center px-8", children: [_jsx(m.div, { initial: { opacity: 0, y: 10 }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: 10 }, className: "aui-thread-welcome-message-motion-1 text-2xl font-semibold", children: `${greeting} ${currentUserDetails.userName.split(" ")[0]}` }), _jsx(m.div, { initial: { opacity: 0, y: 10 }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: 10 }, transition: { delay: 0.1 }, className: "aui-thread-welcome-message-motion-2 text-2xl text-muted-foreground/65", children: "How can I help you today?" })] }) }), _jsx(ThreadSuggestions, {})] }));
|
|
60
|
+
};
|
|
61
|
+
const ThreadSuggestions = () => {
|
|
62
|
+
return (_jsx("div", { className: "aui-thread-welcome-suggestions grid w-full gap-2 pb-4 @md:grid-cols-2", children: [
|
|
63
|
+
{
|
|
64
|
+
title: "What's the weather",
|
|
65
|
+
label: "in San Francisco?",
|
|
66
|
+
action: "What's the weather in San Francisco?",
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
title: "Explain React hooks",
|
|
70
|
+
label: "like useState and useEffect",
|
|
71
|
+
action: "Explain React hooks like useState and useEffect",
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
title: "Write a SQL query",
|
|
75
|
+
label: "to find top customers",
|
|
76
|
+
action: "Write a SQL query to find top customers",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
title: "Create a meal plan",
|
|
80
|
+
label: "for healthy weight loss",
|
|
81
|
+
action: "Create a meal plan for healthy weight loss",
|
|
82
|
+
},
|
|
83
|
+
].map((suggestedAction, index) => (_jsx(m.div, { initial: { opacity: 0, y: 20 }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: 20 }, transition: { delay: 0.05 * index }, className: "aui-thread-welcome-suggestion-display [&:nth-child(n+3)]:hidden @md:[&:nth-child(n+3)]:block", children: _jsx(ThreadPrimitive.Suggestion, { prompt: suggestedAction.action, send: true, asChild: true, children: _jsxs(Button, { variant: "ghost", className: "aui-thread-welcome-suggestion h-auto w-full flex-1 flex-wrap items-start justify-start gap-1 rounded-3xl border px-5 py-4 text-left text-sm @md:flex-col dark:hover:bg-accent/60", "aria-label": suggestedAction.action, children: [_jsx("span", { className: "aui-thread-welcome-suggestion-text-1 font-medium", children: suggestedAction.title }), _jsx("span", { className: "aui-thread-welcome-suggestion-text-2 text-muted-foreground", children: suggestedAction.label })] }) }) }, `suggested-action-${suggestedAction.title}-${index}`))) }));
|
|
84
|
+
};
|
|
85
|
+
const Composer = ({ agents = [], selectedAgent, onSelectAgent }) => {
|
|
86
|
+
return (_jsx(ComposerPrimitive.Root, { className: "aui-composer-root relative flex w-full flex-col", children: _jsxs(ComposerPrimitive.AttachmentDropzone, { className: "aui-composer-attachment-dropzone group/input-group flex w-full flex-col rounded-3xl border border-input bg-background px-1 pt-2 shadow-xs transition-[color,box-shadow] outline-none has-[textarea:focus-visible]:border-ring has-[textarea:focus-visible]:ring-[3px] has-[textarea:focus-visible]:ring-ring/50 data-[dragging=true]:border-dashed data-[dragging=true]:border-ring data-[dragging=true]:bg-accent/50 dark:bg-background", children: [_jsx(ComposerAttachments, {}), _jsx(ComposerPrimitive.Input, { placeholder: "Send a message...", className: "aui-composer-input mb-1 max-h-32 min-h-16 w-full resize-none bg-transparent px-3.5 pt-1.5 pb-3 text-base outline-none placeholder:text-muted-foreground focus-visible:ring-0", rows: 1, autoFocus: true, "aria-label": "Message input" }), _jsx(ComposerAction, { agents: agents, selectedAgent: selectedAgent, onSelectAgent: onSelectAgent })] }) }));
|
|
87
|
+
};
|
|
88
|
+
const ComposerAction = ({ agents = [], selectedAgent, onSelectAgent }) => {
|
|
89
|
+
return (_jsxs("div", { className: "aui-composer-action-wrapper relative mx-1 mt-2 mb-2 flex items-center justify-between", children: [_jsx(ComposerAddAttachment, {}), _jsxs("div", { className: "flex gap-3", children: [agents.length > 0 && (_jsx(AgentDropdown, { agents: agents, selectedAgent: selectedAgent, onSelectAgent: onSelectAgent !== null && onSelectAgent !== void 0 ? onSelectAgent : (() => { }), triggerClassName: "h-9 text-xs" })), _jsx(ThreadPrimitive.If, { running: false, children: _jsx(ComposerPrimitive.Send, { asChild: true, children: _jsx(TooltipIconButton, { tooltip: "Send message", side: "bottom", type: "submit", variant: "default", size: "icon", className: "aui-composer-send size-[34px] rounded-full p-1", "aria-label": "Send message", children: _jsx(ArrowUpIcon, { className: "aui-composer-send-icon size-5" }) }) }) }), _jsx(ThreadPrimitive.If, { running: true, children: _jsx(ComposerPrimitive.Cancel, { asChild: true, children: _jsx(Button, { type: "button", variant: "default", size: "icon", className: "aui-composer-cancel size-[34px] rounded-full border border-muted-foreground/60 hover:bg-primary/75 dark:border-muted-foreground/90", "aria-label": "Stop generating", children: _jsx(Square, { className: "aui-composer-cancel-icon size-3.5 fill-white dark:fill-black" }) }) }) })] })] }));
|
|
90
|
+
};
|
|
91
|
+
const MessageError = () => {
|
|
92
|
+
return (_jsx(MessagePrimitive.Error, { children: _jsx(ErrorPrimitive.Root, { className: "aui-message-error-root mt-2 rounded-md border border-destructive bg-destructive/10 p-3 text-sm text-destructive dark:bg-destructive/5 dark:text-red-200", children: _jsx(ErrorPrimitive.Message, { className: "aui-message-error-message line-clamp-2" }) }) }));
|
|
93
|
+
};
|
|
94
|
+
const AssistantMessage = () => {
|
|
95
|
+
return (_jsxs(MessagePrimitive.Root, { className: "aui-assistant-message-root relative mx-auto w-full max-w-[var(--thread-max-width)] animate-in py-4 duration-150 ease-out fade-in slide-in-from-bottom-1", "data-role": "assistant", children: [_jsxs("div", { className: "aui-assistant-message-content mx-2 leading-7 break-words text-foreground", children: [_jsx(MessagePrimitive.Parts, { components: {
|
|
96
|
+
Text: MarkdownText,
|
|
97
|
+
tools: { Fallback: ToolFallback },
|
|
98
|
+
} }), _jsx(MessageError, {})] }), _jsxs("div", { className: "aui-assistant-message-footer mt-2 ml-2 flex", children: [_jsx(BranchPicker, {}), _jsx(AssistantActionBar, {})] })] }));
|
|
99
|
+
};
|
|
100
|
+
const AssistantActionBar = () => {
|
|
101
|
+
return (_jsxs(ActionBarPrimitive.Root, { hideWhenRunning: true, autohide: "not-last", autohideFloat: "single-branch", className: "aui-assistant-action-bar-root col-start-3 row-start-2 -ml-1 flex gap-1 text-muted-foreground data-floating:absolute data-floating:rounded-md data-floating:border data-floating:bg-background data-floating:p-1 data-floating:shadow-sm", children: [_jsx(ActionBarPrimitive.Copy, { asChild: true, children: _jsxs(TooltipIconButton, { tooltip: "Copy", children: [_jsx(MessagePrimitive.If, { copied: true, children: _jsx(CheckIcon, {}) }), _jsx(MessagePrimitive.If, { copied: false, children: _jsx(CopyIcon, {}) })] }) }), _jsx(ActionBarPrimitive.Reload, { asChild: true, children: _jsx(TooltipIconButton, { tooltip: "Refresh", children: _jsx(RefreshCwIcon, {}) }) })] }));
|
|
102
|
+
};
|
|
103
|
+
const UserMessage = () => {
|
|
104
|
+
return (_jsxs(MessagePrimitive.Root, { className: "aui-user-message-root mx-auto grid w-full max-w-[var(--thread-max-width)] animate-in auto-rows-auto grid-cols-[minmax(72px,1fr)_auto] content-start gap-y-2 px-2 py-4 duration-150 ease-out fade-in slide-in-from-bottom-1 [&:where(>*)]:col-start-2", "data-role": "user", children: [_jsx(UserMessageAttachments, {}), _jsxs("div", { className: "aui-user-message-content-wrapper relative col-start-2 min-w-0", children: [_jsx("div", { className: "aui-user-message-content rounded-3xl bg-muted px-5 py-2.5 break-words text-foreground", children: _jsx(MessagePrimitive.Parts, {}) }), _jsx("div", { className: "aui-user-action-bar-wrapper absolute top-1/2 left-0 -translate-x-full -translate-y-1/2 pr-2", children: _jsx(UserActionBar, {}) })] }), _jsx(BranchPicker, { className: "aui-user-branch-picker col-span-full col-start-1 row-start-3 -mr-1 justify-end" })] }));
|
|
105
|
+
};
|
|
106
|
+
const UserActionBar = () => {
|
|
107
|
+
return (_jsx(ActionBarPrimitive.Root, { hideWhenRunning: true, autohide: "not-last", className: "aui-user-action-bar-root flex flex-col items-end", children: _jsx(ActionBarPrimitive.Edit, { asChild: true, children: _jsx(TooltipIconButton, { tooltip: "Edit", className: "aui-user-action-edit p-4", children: _jsx(PencilIcon, {}) }) }) }));
|
|
108
|
+
};
|
|
109
|
+
const EditComposer = () => {
|
|
110
|
+
return (_jsx(MessagePrimitive.Root, { className: "aui-edit-composer-wrapper mx-auto flex w-full max-w-[var(--thread-max-width)] flex-col gap-4 px-2", children: _jsxs(ComposerPrimitive.Root, { className: "aui-edit-composer-root ml-auto flex w-full max-w-7/8 flex-col rounded-xl bg-muted", children: [_jsx(ComposerPrimitive.Input, { className: "aui-edit-composer-input flex min-h-[60px] w-full resize-none bg-transparent p-4 text-foreground outline-none", autoFocus: true }), _jsxs("div", { className: "aui-edit-composer-footer mx-3 mb-3 flex items-center justify-center gap-2 self-end", children: [_jsx(ComposerPrimitive.Cancel, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "sm", "aria-label": "Cancel edit", children: "Cancel" }) }), _jsx(ComposerPrimitive.Send, { asChild: true, children: _jsx(Button, { size: "sm", "aria-label": "Update message", children: "Update" }) })] })] }) }));
|
|
111
|
+
};
|
|
112
|
+
const BranchPicker = (_a) => {
|
|
113
|
+
var { className } = _a, rest = __rest(_a, ["className"]);
|
|
114
|
+
return (_jsxs(BranchPickerPrimitive.Root, Object.assign({ hideWhenSingleBranch: true, className: cn("aui-branch-picker-root mr-2 -ml-2 inline-flex items-center text-xs text-muted-foreground", className) }, rest, { children: [_jsx(BranchPickerPrimitive.Previous, { asChild: true, children: _jsx(TooltipIconButton, { tooltip: "Previous", children: _jsx(ChevronLeftIcon, {}) }) }), _jsxs("span", { className: "aui-branch-picker-state font-medium", children: [_jsx(BranchPickerPrimitive.Number, {}), " / ", _jsx(BranchPickerPrimitive.Count, {})] }), _jsx(BranchPickerPrimitive.Next, { asChild: true, children: _jsx(TooltipIconButton, { tooltip: "Next", children: _jsx(ChevronRightIcon, {}) }) })] })));
|
|
115
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { CheckIcon, ChevronDownIcon, ChevronUpIcon, XCircleIcon, } from "lucide-react";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { Button } from "../../shadcn/button";
|
|
6
|
+
import { cn } from "../../utils/cn";
|
|
7
|
+
export const ToolFallback = ({ toolName, argsText, result, status, }) => {
|
|
8
|
+
const [isCollapsed, setIsCollapsed] = useState(true);
|
|
9
|
+
const isCancelled = (status === null || status === void 0 ? void 0 : status.type) === "incomplete" && status.reason === "cancelled";
|
|
10
|
+
const cancelledReason = isCancelled && status.error
|
|
11
|
+
? typeof status.error === "string"
|
|
12
|
+
? status.error
|
|
13
|
+
: JSON.stringify(status.error)
|
|
14
|
+
: null;
|
|
15
|
+
return (_jsxs("div", { className: cn("aui-tool-fallback-root mb-4 flex w-full flex-col gap-3 rounded-lg border py-3", isCancelled && "border-muted-foreground/30 bg-muted/30"), children: [_jsxs("div", { className: "aui-tool-fallback-header flex items-center gap-2 px-4", children: [isCancelled ? (_jsx(XCircleIcon, { className: "aui-tool-fallback-icon size-4 text-muted-foreground" })) : (_jsx(CheckIcon, { className: "aui-tool-fallback-icon size-4" })), _jsxs("p", { className: cn("aui-tool-fallback-title grow", isCancelled && "text-muted-foreground line-through"), children: [isCancelled ? "Cancelled tool: " : "Used tool: ", _jsx("b", { children: toolName })] }), _jsx(Button, { onClick: () => setIsCollapsed(!isCollapsed), children: isCollapsed ? _jsx(ChevronUpIcon, {}) : _jsx(ChevronDownIcon, {}) })] }), !isCollapsed && (_jsxs("div", { className: "aui-tool-fallback-content flex flex-col gap-2 border-t pt-2", children: [cancelledReason && (_jsxs("div", { className: "aui-tool-fallback-cancelled-root px-4", children: [_jsx("p", { className: "aui-tool-fallback-cancelled-header font-semibold text-muted-foreground", children: "Cancelled reason:" }), _jsx("p", { className: "aui-tool-fallback-cancelled-reason text-muted-foreground", children: cancelledReason })] })), _jsx("div", { className: cn("aui-tool-fallback-args-root px-4", isCancelled && "opacity-60"), children: _jsx("pre", { className: "aui-tool-fallback-args-value whitespace-pre-wrap", children: argsText }) }), !isCancelled && result !== undefined && (_jsxs("div", { className: "aui-tool-fallback-result-root border-t border-dashed px-4 pt-2", children: [_jsx("p", { className: "aui-tool-fallback-result-header font-semibold", children: "Result:" }), _jsx("pre", { className: "aui-tool-fallback-result-content whitespace-pre-wrap", children: typeof result === "string"
|
|
16
|
+
? result
|
|
17
|
+
: JSON.stringify(result, null, 2) })] }))] }))] }));
|
|
18
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ComponentPropsWithRef } from "react";
|
|
2
|
+
import { Button } from "../../shadcn/button";
|
|
3
|
+
export type TooltipIconButtonProps = ComponentPropsWithRef<typeof Button> & {
|
|
4
|
+
tooltip: string;
|
|
5
|
+
side?: "top" | "bottom" | "left" | "right";
|
|
6
|
+
};
|
|
7
|
+
export declare const TooltipIconButton: import("react").ForwardRefExoticComponent<Omit<TooltipIconButtonProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
+
import { forwardRef } from "react";
|
|
15
|
+
import { Slottable } from "@radix-ui/react-slot";
|
|
16
|
+
import { Tooltip, TooltipContent, TooltipTrigger, } from "../../shadcn/tooltip";
|
|
17
|
+
import { Button } from "../../shadcn/button";
|
|
18
|
+
import { cn } from "../../utils/cn";
|
|
19
|
+
export const TooltipIconButton = forwardRef((_a, ref) => {
|
|
20
|
+
var { children, tooltip, side = "bottom", className } = _a, rest = __rest(_a, ["children", "tooltip", "side", "className"]);
|
|
21
|
+
return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs(Button, Object.assign({ variant: "ghost", size: "icon" }, rest, { className: cn("aui-button-icon size-6 p-1", className), ref: ref, children: [_jsx(Slottable, { children: children }), _jsx("span", { className: "aui-sr-only sr-only", children: tooltip })] })) }), _jsx(TooltipContent, { side: side, children: tooltip })] }));
|
|
22
|
+
});
|
|
23
|
+
TooltipIconButton.displayName = "TooltipIconButton";
|
package/dist/index.d.ts
CHANGED
|
@@ -127,6 +127,7 @@ export { NewImageForm } from "./ikoncomponents/image-cropper-upload/components/n
|
|
|
127
127
|
export type { ImageFormProps } from "./ikoncomponents/image-cropper-upload/components/newImageUploadForm";
|
|
128
128
|
export { WorkInProgress } from "./ikoncomponents/work-in-progress";
|
|
129
129
|
export { CustomComboboxInput } from "./ikoncomponents/custom-combo-dropdown";
|
|
130
|
+
export { AssistantComponent } from "./ikoncomponents/assistant-ui/Assistant";
|
|
130
131
|
export { ThemeProvider } from "./utils/theme-provider";
|
|
131
132
|
export { RadiusProvider, useRadius } from "./utils/border-radius-provider";
|
|
132
133
|
export { FontProvider, useFont } from "./utils/font-provider";
|
package/dist/index.js
CHANGED
|
@@ -107,7 +107,7 @@ export { NewCropperImg } from "./ikoncomponents/image-cropper-upload/components/
|
|
|
107
107
|
export { NewImageForm } from "./ikoncomponents/image-cropper-upload/components/newImageUploadForm";
|
|
108
108
|
export { WorkInProgress } from "./ikoncomponents/work-in-progress";
|
|
109
109
|
export { CustomComboboxInput } from "./ikoncomponents/custom-combo-dropdown";
|
|
110
|
-
|
|
110
|
+
export { AssistantComponent } from "./ikoncomponents/assistant-ui/Assistant";
|
|
111
111
|
export { ThemeProvider } from "./utils/theme-provider";
|
|
112
112
|
export { RadiusProvider, useRadius } from "./utils/border-radius-provider";
|
|
113
113
|
export { FontProvider, useFont } from "./utils/font-provider";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface UserData {
|
|
2
|
+
userId: string;
|
|
3
|
+
userName: string;
|
|
4
|
+
userLogin: string;
|
|
5
|
+
password: string;
|
|
6
|
+
userPhone?: string;
|
|
7
|
+
userEmail: string;
|
|
8
|
+
userThumbnail?: string | null;
|
|
9
|
+
userType?: string;
|
|
10
|
+
active?: boolean;
|
|
11
|
+
accountId?: string;
|
|
12
|
+
userDeleted?: boolean;
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|