mtxuilib 0.1.107 → 0.1.109
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/common/markdown.d.ts +3 -0
- package/dist/common/markdown.js +4 -0
- package/dist/common/table/cells/string.js +2 -2
- package/dist/components/bloggenBot/BlogGenBot.d.ts +8 -0
- package/dist/components/bloggenBot/BlogGenBot.js +43 -0
- package/dist/components/bloggenBot/BlogGenBotActions.d.ts +20 -0
- package/dist/components/bloggenBot/BlogGenBotActions.js +179 -0
- package/dist/components/bloggenBot/chat-panel.d.ts +9 -0
- package/dist/components/bloggenBot/chat-panel.js +41 -0
- package/dist/components/button-scroll-to-bottom.d.ts +7 -0
- package/dist/components/button-scroll-to-bottom.js +8 -0
- package/dist/components/chat-list.d.ts +8 -0
- package/dist/components/chat-list.js +10 -0
- package/dist/components/chat-panel.d.ts +9 -0
- package/dist/components/chat-panel.js +41 -0
- package/dist/components/chat-share-dialog.d.ts +9 -0
- package/dist/components/chat-share-dialog.js +33 -0
- package/dist/components/chat.d.ts +8 -0
- package/dist/components/chat.js +48 -0
- package/dist/components/dev-bot/DevBot.d.ts +8 -0
- package/dist/components/dev-bot/DevBot.js +43 -0
- package/dist/components/dev-bot/DevBotActions.d.ts +8 -0
- package/dist/components/dev-bot/DevBotActions.js +143 -0
- package/dist/components/dev-bot/actions.d.ts +2 -0
- package/dist/components/dev-bot/actions.js +9 -0
- package/dist/components/dev-bot/chat-panel.d.ts +9 -0
- package/dist/components/dev-bot/chat-panel.js +41 -0
- package/dist/components/empty-screen.d.ts +1 -0
- package/dist/components/empty-screen.js +4 -0
- package/dist/components/external-link.d.ts +4 -0
- package/dist/components/external-link.js +4 -0
- package/dist/components/footer.d.ts +2 -0
- package/dist/components/footer.js +6 -0
- package/dist/components/prompt-form.d.ts +4 -0
- package/dist/components/prompt-form.js +45 -0
- package/dist/components/stocks/events-skeleton.d.ts +1 -0
- package/dist/components/stocks/events-skeleton.js +11 -0
- package/dist/components/stocks/events.d.ts +9 -0
- package/dist/components/stocks/events.js +5 -0
- package/dist/components/stocks/index.js +25 -0
- package/dist/components/stocks/message.d.ts +16 -0
- package/dist/components/stocks/message.js +43 -0
- package/dist/components/stocks/spinner.d.ts +1 -0
- package/dist/components/stocks/spinner.js +3 -0
- package/dist/components/stocks/stock-purchase.d.ts +10 -0
- package/dist/components/stocks/stock-purchase.js +35 -0
- package/dist/components/stocks/stock-skeleton.d.ts +1 -0
- package/dist/components/stocks/stock-skeleton.js +4 -0
- package/dist/components/stocks/stock.d.ts +9 -0
- package/dist/components/stocks/stock.js +90 -0
- package/dist/components/stocks/stocks-skeleton.d.ts +1 -0
- package/dist/components/stocks/stocks-skeleton.js +4 -0
- package/dist/components/stocks/stocks.d.ts +9 -0
- package/dist/components/stocks/stocks.js +11 -0
- package/dist/components/testingBot/TestingBot.d.ts +8 -0
- package/dist/components/testingBot/TestingBot.js +43 -0
- package/dist/components/testingBot/TestingBotActions.d.ts +16 -0
- package/dist/components/testingBot/TestingBotActions.js +122 -0
- package/dist/components/testingBot/chat-panel.d.ts +9 -0
- package/dist/components/testingBot/chat-panel.js +41 -0
- package/dist/components/testingBot/empty-screen.d.ts +1 -0
- package/dist/components/testingBot/empty-screen.js +4 -0
- package/dist/components/tool-ui/BlogHomePage.d.ts +5 -0
- package/dist/components/tool-ui/BlogHomePage.js +8 -0
- package/dist/components/tool-ui/BlogHomePage.z.d.ts +60 -0
- package/dist/components/tool-ui/BlogHomePage.z.js +20 -0
- package/dist/components/tool-ui/DemoCategoryGen.d.ts +3 -0
- package/dist/components/tool-ui/DemoCategoryGen.js +8 -0
- package/dist/components/tool-ui/DpCfWorker.d.ts +1 -0
- package/dist/components/tool-ui/DpCfWorker.js +12 -0
- package/dist/components/tool-ui/DpMtxEdge.d.ts +1 -0
- package/dist/components/tool-ui/DpMtxEdge.js +12 -0
- package/dist/components/tool-ui/ExtractArticle.d.ts +1 -0
- package/dist/components/tool-ui/ExtractArticle.js +30 -0
- package/dist/components/tool-ui/OpenBrowser.d.ts +1 -0
- package/dist/components/tool-ui/OpenBrowser.js +30 -0
- package/dist/components/tool-ui/vcDeploy.d.ts +1 -0
- package/dist/components/tool-ui/vcDeploy.js +12 -0
- package/dist/form/EditFormToolbar.js +1 -1
- package/dist/form/ZodForm.js +11 -13
- package/dist/hooks/use-copy-to-clipboard.d.ts +7 -0
- package/dist/hooks/use-copy-to-clipboard.js +20 -0
- package/dist/hooks/use-enter-submit.d.ts +5 -0
- package/dist/hooks/use-enter-submit.js +11 -0
- package/dist/hooks/use-local-storage.d.ts +1 -2
- package/dist/hooks/use-local-storage.js +1 -2
- package/dist/hooks/use-scroll-anchor.d.ts +8 -0
- package/dist/hooks/use-scroll-anchor.js +70 -0
- package/dist/hooks/use-streamable-text.d.ts +2 -0
- package/dist/hooks/use-streamable-text.js +19 -0
- package/dist/icons/icons-ai.d.ts +31 -0
- package/dist/icons/icons-ai.js +87 -0
- package/dist/lib/auth/auth.config.js +35 -0
- package/dist/lib/auth/auth.js +38 -0
- package/dist/lib/auth/authActions.d.ts +9 -0
- package/dist/lib/auth/authActions.js +58 -0
- package/dist/lib/chat/actions.d.ts +20 -0
- package/dist/lib/chat/actions.js +136 -0
- package/dist/lib/chat/chatActions.d.ts +27 -0
- package/dist/lib/chat/chatActions.js +118 -0
- package/dist/lib/reactqueryGraphql/query-utils.d.ts +3 -3
- package/dist/lib/selectPath.d.ts +1 -1
- package/dist/lib/types.d.ts +32 -0
- package/dist/lib/types.js +1 -0
- package/dist/lib/utils.d.ts +14 -0
- package/dist/lib/utils.js +52 -0
- package/dist/misc/MtErrorBoundary.d.ts +1 -1
- package/dist/tools/countDown.d.ts +32 -0
- package/dist/tools/countDown.js +36 -0
- package/dist/tools/devTools/clean.d.ts +8 -0
- package/dist/tools/devTools/clean.js +28 -0
- package/dist/tools/devTools/docker-compose.d.ts +8 -0
- package/dist/tools/devTools/docker-compose.js +17 -0
- package/dist/tools/devTools/dockerBuildMtm.d.ts +8 -0
- package/dist/tools/devTools/dockerBuildMtm.js +34 -0
- package/dist/tools/devTools/dpMtCfWorkerTool.d.ts +8 -0
- package/dist/tools/devTools/dpMtCfWorkerTool.js +15 -0
- package/dist/tools/devTools/dpMtxedge.d.ts +8 -0
- package/dist/tools/devTools/dpMtxedge.js +80 -0
- package/dist/tools/devTools/packageRelease.d.ts +8 -0
- package/dist/tools/devTools/packageRelease.js +52 -0
- package/dist/tools/devTools/vcDeploytool.d.ts +8 -0
- package/dist/tools/devTools/vcDeploytool.js +63 -0
- package/dist/tools/genSiteHeaderBarsTool.d.ts +14 -0
- package/dist/tools/genSiteHeaderBarsTool.js +17 -0
- package/dist/tools/hello1Tool.d.ts +8 -0
- package/dist/tools/hello1Tool.js +15 -0
- package/dist/tools/ui/Hello1.d.ts +1 -0
- package/dist/tools/ui/Hello1.js +17 -0
- package/dist/tools/welcomeAdminTool.d.ts +8 -0
- package/dist/tools/welcomeAdminTool.js +14 -0
- package/dist/ui/codeblock.d.ts +12 -0
- package/dist/ui/codeblock.js +85 -0
- package/dist/ui-mt/WithLinkIf.d.ts +1 -1
- package/dist/ui-mt/inputs/TaskStatusInput.js +4 -4
- package/dist/ui-vamp/button.d.ts +1 -1
- package/dist/ui-vamp/dropdown.d.ts +1 -1
- package/package.json +23 -20
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import React from "react";
|
|
4
4
|
import { CellWrapper } from "./container/cellWrapper";
|
|
@@ -11,5 +11,5 @@ export const StringCell = (info) => {
|
|
|
11
11
|
React.useEffect(() => {
|
|
12
12
|
setValue(initialValue);
|
|
13
13
|
}, [initialValue]);
|
|
14
|
-
return _jsx(CellWrapper, { children: value });
|
|
14
|
+
return (_jsx(CellWrapper, { children: value }));
|
|
15
15
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Session } from "../../lib/types";
|
|
2
|
+
export interface ChatProps extends React.ComponentProps<"div"> {
|
|
3
|
+
initialMessages?: Message[];
|
|
4
|
+
id?: string;
|
|
5
|
+
session?: Session;
|
|
6
|
+
missingKeys: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function BlogGenBot({ id, className, session, missingKeys }: ChatProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useAIState, useUIState } from "ai/rsc";
|
|
4
|
+
import { useEffect, useState } from "react";
|
|
5
|
+
import { ChatList } from "../chat-list";
|
|
6
|
+
import { usePathname, useRouter } from "next/navigation";
|
|
7
|
+
import { toast } from "sonner";
|
|
8
|
+
import { useLocalStorage } from "usehooks-ts";
|
|
9
|
+
import { useScrollAnchor } from "../../hooks/use-scroll-anchor";
|
|
10
|
+
import { cn } from "../../lib/utils";
|
|
11
|
+
import { EmptyScreen } from "../empty-screen";
|
|
12
|
+
import { BlogGenChatPanel } from "./chat-panel";
|
|
13
|
+
export function BlogGenBot({ id, className, session, missingKeys }) {
|
|
14
|
+
const router = useRouter();
|
|
15
|
+
const path = usePathname();
|
|
16
|
+
const [input, setInput] = useState("");
|
|
17
|
+
const [messages] = useUIState();
|
|
18
|
+
const [aiState] = useAIState();
|
|
19
|
+
const [_, setNewChatId] = useLocalStorage("newChatId", id);
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (session?.user) {
|
|
22
|
+
if (!path.includes("chat") && messages.length === 1) {
|
|
23
|
+
window.history.replaceState({}, "", `/chat/${id}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}, [id, path, session?.user, messages]);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const messagesLength = aiState.messages?.length;
|
|
29
|
+
if (messagesLength === 2) {
|
|
30
|
+
router.refresh();
|
|
31
|
+
}
|
|
32
|
+
}, [aiState.messages, router]);
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
setNewChatId(id);
|
|
35
|
+
});
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
missingKeys.map((key) => {
|
|
38
|
+
toast.error(`Missing ${key} environment variable!`);
|
|
39
|
+
});
|
|
40
|
+
}, [missingKeys]);
|
|
41
|
+
const { messagesRef, scrollRef, visibilityRef, isAtBottom, scrollToBottom } = useScrollAnchor();
|
|
42
|
+
return (_jsxs("div", { className: "group w-full overflow-auto pl-0 peer-[[data-state=open]]:lg:pl-[250px] peer-[[data-state=open]]:xl:pl-[300px]", ref: scrollRef, children: [_jsxs("div", { className: cn("pb-[200px] pt-4 md:pt-10", className), ref: messagesRef, children: [messages.length ? (_jsx(ChatList, { messages: messages, isShared: false, session: session })) : (_jsx(EmptyScreen, {})), _jsx("div", { className: "w-full h-px", ref: visibilityRef })] }), _jsx(BlogGenChatPanel, { id: id, input: input, setInput: setInput, isAtBottom: isAtBottom, scrollToBottom: scrollToBottom })] }));
|
|
43
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import "server-only";
|
|
2
|
+
import { Chat, Message } from "mtxuilib/lib/types";
|
|
3
|
+
export type AIState = {
|
|
4
|
+
chatId: string;
|
|
5
|
+
messages: Message[];
|
|
6
|
+
};
|
|
7
|
+
export type UIState = {
|
|
8
|
+
id: string;
|
|
9
|
+
display: React.ReactNode;
|
|
10
|
+
}[];
|
|
11
|
+
export declare const AIBlogGen: (props: {
|
|
12
|
+
children: React.ReactNode;
|
|
13
|
+
initialAIState?: AIState | undefined;
|
|
14
|
+
initialUIState?: UIState | undefined;
|
|
15
|
+
$ActionTypes?: {} | undefined;
|
|
16
|
+
}) => Promise<React.ReactElement>;
|
|
17
|
+
export declare const getUIStateFromAIState: (aiState: Chat) => {
|
|
18
|
+
id: string;
|
|
19
|
+
display: import("react/jsx-runtime").JSX.Element | (import("react/jsx-runtime").JSX.Element | null)[] | null;
|
|
20
|
+
}[];
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import "server-only";
|
|
3
|
+
import { createOpenAI } from "@ai-sdk/openai";
|
|
4
|
+
import { createAI, createStreamableUI, createStreamableValue, getAIState, getMutableAIState, streamUI, } from "ai/rsc";
|
|
5
|
+
import { Events } from "mtxuilib/components/stocks/events";
|
|
6
|
+
import { BotCard, BotMessage, SpinnerMessage, SystemMessage, UserMessage, } from "mtxuilib/components/stocks/message";
|
|
7
|
+
import { Stocks } from "mtxuilib/components/stocks/stocks";
|
|
8
|
+
import { StocksSkeleton } from "mtxuilib/components/stocks/stocks-skeleton";
|
|
9
|
+
import { formatNumber, nanoid, runAsyncFnWithoutBlocking, sleep } from "mtxuilib/lib/utils";
|
|
10
|
+
import { auth } from "../../lib/auth/auth";
|
|
11
|
+
import { saveChat } from "../../lib/chat/chatActions";
|
|
12
|
+
import { Purchase, Stock, spinner } from "../stocks";
|
|
13
|
+
import BlogHomePage from "../tool-ui/BlogHomePage";
|
|
14
|
+
import { homePageSchema } from "../tool-ui/BlogHomePage.z";
|
|
15
|
+
async function confirmPurchase(symbol, price, amount) {
|
|
16
|
+
"use server";
|
|
17
|
+
const aiState = getMutableAIState();
|
|
18
|
+
const purchasing = createStreamableUI(_jsxs("div", { className: "inline-flex items-start gap-1 md:items-center", children: [spinner, _jsxs("p", { className: "mb-2", children: ["Purchasing ", amount, " $", symbol, "..."] })] }));
|
|
19
|
+
const systemMessage = createStreamableUI(null);
|
|
20
|
+
runAsyncFnWithoutBlocking(async () => {
|
|
21
|
+
purchasing.update(_jsxs("div", { className: "inline-flex items-start gap-1 md:items-center", children: [spinner, _jsxs("p", { className: "mb-2", children: ["Purchasing ", amount, " $", symbol, "... working on it..."] })] }));
|
|
22
|
+
await sleep(1000);
|
|
23
|
+
purchasing.done(_jsx("div", { children: _jsxs("p", { className: "mb-2", children: ["You have successfully purchased ", amount, " $", symbol, ". Total cost: ", formatNumber(amount * price)] }) }));
|
|
24
|
+
systemMessage.done(_jsxs(SystemMessage, { children: ["You have purchased ", amount, " shares of ", symbol, " at $", price, ". Total cost =", " ", formatNumber(amount * price), "."] }));
|
|
25
|
+
aiState.done({
|
|
26
|
+
...aiState.get(),
|
|
27
|
+
messages: [
|
|
28
|
+
...aiState.get().messages,
|
|
29
|
+
{
|
|
30
|
+
id: nanoid(),
|
|
31
|
+
role: "system",
|
|
32
|
+
content: `[User has purchased ${amount} shares of ${symbol} at ${price}. Total cost = ${amount * price}]`,
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
purchasingUI: purchasing.value,
|
|
39
|
+
newMessage: {
|
|
40
|
+
id: nanoid(),
|
|
41
|
+
display: systemMessage.value,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
async function submitUserMessage(content) {
|
|
46
|
+
"use server";
|
|
47
|
+
const aiState = getMutableAIState();
|
|
48
|
+
aiState.update({
|
|
49
|
+
...aiState.get(),
|
|
50
|
+
messages: [
|
|
51
|
+
...aiState.get().messages,
|
|
52
|
+
{
|
|
53
|
+
id: nanoid(),
|
|
54
|
+
role: "user",
|
|
55
|
+
content,
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
});
|
|
59
|
+
let textStream;
|
|
60
|
+
let textNode;
|
|
61
|
+
const groq = createOpenAI({
|
|
62
|
+
baseURL: "https://api.groq.com/openai/v1",
|
|
63
|
+
apiKey: process.env.GROQ_API_KEY,
|
|
64
|
+
});
|
|
65
|
+
const result = await streamUI({
|
|
66
|
+
model: groq("llama3-8b-8192"),
|
|
67
|
+
initial: _jsx(SpinnerMessage, {}),
|
|
68
|
+
system: `\
|
|
69
|
+
# 你是博客网站生成助手,有很丰富的SEO经验,
|
|
70
|
+
# 用户会通过对话的方式告诉你他需要的页面的样子
|
|
71
|
+
# 在任何情况下都不要回复文字,仅仅调用对应的tool即可
|
|
72
|
+
# 网站页面生成 使用工具: genHomePage
|
|
73
|
+
# 第一次调用应该传入基本的数据,让页面看起来充实
|
|
74
|
+
# 用户会多次描述补充新的想法,应该尽量保持之前的json数据状态,仅根据用户新的补充对页面的json数据进行变更
|
|
75
|
+
|
|
76
|
+
`,
|
|
77
|
+
messages: [
|
|
78
|
+
...aiState.get().messages.map((message) => ({
|
|
79
|
+
role: message.role,
|
|
80
|
+
content: message.content,
|
|
81
|
+
name: message.name,
|
|
82
|
+
})),
|
|
83
|
+
],
|
|
84
|
+
text: ({ content, done, delta }) => {
|
|
85
|
+
if (!textStream) {
|
|
86
|
+
textStream = createStreamableValue("");
|
|
87
|
+
textNode = _jsx(BotMessage, { content: textStream.value });
|
|
88
|
+
}
|
|
89
|
+
if (done) {
|
|
90
|
+
textStream.done();
|
|
91
|
+
aiState.done({
|
|
92
|
+
...aiState.get(),
|
|
93
|
+
messages: [
|
|
94
|
+
...aiState.get().messages,
|
|
95
|
+
{
|
|
96
|
+
id: nanoid(),
|
|
97
|
+
role: "assistant",
|
|
98
|
+
content,
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
textStream.update(delta);
|
|
105
|
+
}
|
|
106
|
+
return textNode;
|
|
107
|
+
},
|
|
108
|
+
tools: {
|
|
109
|
+
genHomePage: {
|
|
110
|
+
description: "基于json数据,生成博客网站首页,只要正确传入json数据,后端会根据json约定的字段渲染出页面",
|
|
111
|
+
parameters: homePageSchema,
|
|
112
|
+
generate: async function* (params) {
|
|
113
|
+
yield (_jsx(BotCard, { children: _jsx(StocksSkeleton, {}) }));
|
|
114
|
+
return (_jsx(BotCard, { children: _jsx(BlogHomePage, { params: params }) }));
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
return {
|
|
120
|
+
id: nanoid(),
|
|
121
|
+
display: result.value,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
export const AIBlogGen = createAI({
|
|
125
|
+
actions: {
|
|
126
|
+
submitUserMessage,
|
|
127
|
+
confirmPurchase,
|
|
128
|
+
},
|
|
129
|
+
initialUIState: [],
|
|
130
|
+
initialAIState: { chatId: nanoid(), messages: [] },
|
|
131
|
+
onGetUIState: async () => {
|
|
132
|
+
"use server";
|
|
133
|
+
const session = await auth();
|
|
134
|
+
if (session && session.user) {
|
|
135
|
+
const aiState = getAIState();
|
|
136
|
+
if (aiState) {
|
|
137
|
+
const uiState = getUIStateFromAIState(aiState);
|
|
138
|
+
return uiState;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
onSetAIState: async ({ state }) => {
|
|
146
|
+
"use server";
|
|
147
|
+
const session = await auth();
|
|
148
|
+
if (session && session.user) {
|
|
149
|
+
const { chatId, messages } = state;
|
|
150
|
+
const createdAt = new Date();
|
|
151
|
+
const userId = session.user.id;
|
|
152
|
+
const path = `/chat/${chatId}`;
|
|
153
|
+
const firstMessageContent = messages[0].content;
|
|
154
|
+
const title = firstMessageContent.substring(0, 100);
|
|
155
|
+
const chat = {
|
|
156
|
+
id: chatId,
|
|
157
|
+
title,
|
|
158
|
+
userId,
|
|
159
|
+
createdAt,
|
|
160
|
+
messages,
|
|
161
|
+
path,
|
|
162
|
+
};
|
|
163
|
+
await saveChat(chat);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
export const getUIStateFromAIState = (aiState) => {
|
|
171
|
+
return aiState.messages
|
|
172
|
+
.filter((message) => message.role !== "system")
|
|
173
|
+
.map((message, index) => ({
|
|
174
|
+
id: `${aiState.chatId}-${index}`,
|
|
175
|
+
display: message.role === "tool" ? (message.content.map((tool) => {
|
|
176
|
+
return tool.toolName === "listStocks" ? (_jsx(BotCard, { children: _jsx(Stocks, { props: tool.result }) })) : tool.toolName === "showStockPrice" ? (_jsx(BotCard, { children: _jsx(Stock, { props: tool.result }) })) : tool.toolName === "showStockPurchase" ? (_jsx(BotCard, { children: _jsx(Purchase, { props: tool.result }) })) : tool.toolName === "getEvents" ? (_jsx(BotCard, { children: _jsx(Events, { props: tool.result }) })) : null;
|
|
177
|
+
})) : message.role === "user" ? (_jsx(UserMessage, { children: message.content })) : message.role === "assistant" && typeof message.content === "string" ? (_jsx(BotMessage, { content: message.content })) : null,
|
|
178
|
+
}));
|
|
179
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface ChatPanelProps {
|
|
2
|
+
id?: string;
|
|
3
|
+
title?: string;
|
|
4
|
+
input: string;
|
|
5
|
+
setInput: (value: string) => void;
|
|
6
|
+
isAtBottom: boolean;
|
|
7
|
+
scrollToBottom: () => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function BlogGenChatPanel({ id, title, input, setInput, isAtBottom, scrollToBottom }: ChatPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useAIState, useActions, useUIState } from "ai/rsc";
|
|
3
|
+
import { nanoid } from "nanoid";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { IconShare } from "../../icons/icons-ai";
|
|
6
|
+
import { shareChat } from "../../lib/chat/chatActions";
|
|
7
|
+
import { Button } from "../../ui/button";
|
|
8
|
+
import { ButtonScrollToBottom } from "../button-scroll-to-bottom";
|
|
9
|
+
import { ChatShareDialog } from "../chat-share-dialog";
|
|
10
|
+
import { FooterText } from "../footer";
|
|
11
|
+
import { PromptForm } from "../prompt-form";
|
|
12
|
+
import { UserMessage } from "../stocks/message";
|
|
13
|
+
export function BlogGenChatPanel({ id, title, input, setInput, isAtBottom, scrollToBottom }) {
|
|
14
|
+
const [aiState] = useAIState();
|
|
15
|
+
const [messages, setMessages] = useUIState();
|
|
16
|
+
const { submitUserMessage } = useActions();
|
|
17
|
+
const [shareDialogOpen, setShareDialogOpen] = React.useState(false);
|
|
18
|
+
const exampleMessages = [
|
|
19
|
+
{
|
|
20
|
+
heading: "生成导航栏",
|
|
21
|
+
subheading: "分别用7个水果命名",
|
|
22
|
+
message: `生成导航栏,分别用7个水果命名`,
|
|
23
|
+
},
|
|
24
|
+
];
|
|
25
|
+
return (_jsxs("div", { className: "fixed inset-x-0 bottom-0 w-full bg-gradient-to-b from-muted/30 from-0% to-muted/30 to-50% duration-300 ease-in-out animate-in dark:from-background/10 dark:from-10% dark:to-background/80 peer-[[data-state=open]]:group-[]:lg:pl-[250px] peer-[[data-state=open]]:group-[]:xl:pl-[300px]", children: [_jsx(ButtonScrollToBottom, { isAtBottom: isAtBottom, scrollToBottom: scrollToBottom }), _jsxs("div", { className: "mx-auto sm:max-w-2xl sm:px-4", children: [_jsx("div", { className: "mb-4 grid grid-cols-2 gap-2 px-4 sm:px-0", children: messages.length === 0 &&
|
|
26
|
+
exampleMessages.map((example, index) => (_jsxs("div", { className: `cursor-pointer rounded-lg border bg-white p-4 hover:bg-zinc-50 dark:bg-zinc-950 dark:hover:bg-zinc-900 ${index > 1 && "hidden md:block"}`, onClick: async () => {
|
|
27
|
+
setMessages((currentMessages) => [
|
|
28
|
+
...currentMessages,
|
|
29
|
+
{
|
|
30
|
+
id: nanoid(),
|
|
31
|
+
display: _jsx(UserMessage, { children: example.message }),
|
|
32
|
+
},
|
|
33
|
+
]);
|
|
34
|
+
const responseMessage = await submitUserMessage(example.message);
|
|
35
|
+
setMessages((currentMessages) => [...currentMessages, responseMessage]);
|
|
36
|
+
}, children: [_jsx("div", { className: "text-sm font-semibold", children: example.heading }), _jsx("div", { className: "text-sm text-zinc-600", children: example.subheading })] }, example.heading))) }), messages?.length >= 2 ? (_jsx("div", { className: "flex h-12 items-center justify-center", children: _jsx("div", { className: "flex space-x-2", children: id && title ? (_jsxs(_Fragment, { children: [_jsxs(Button, { variant: "outline", onClick: () => setShareDialogOpen(true), children: [_jsx(IconShare, { className: "mr-2" }), "Share"] }), _jsx(ChatShareDialog, { open: shareDialogOpen, onOpenChange: setShareDialogOpen, onCopy: () => setShareDialogOpen(false), shareChat: shareChat, chat: {
|
|
37
|
+
id,
|
|
38
|
+
title,
|
|
39
|
+
messages: aiState.messages,
|
|
40
|
+
} })] })) : null }) })) : null, _jsxs("div", { className: "space-y-4 border-t bg-background px-4 py-2 shadow-lg sm:rounded-t-xl sm:border md:py-4", children: [_jsx(PromptForm, { input: input, setInput: setInput }), _jsx(FooterText, { className: "hidden sm:block" })] })] })] }));
|
|
41
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ButtonProps } from "../ui/button";
|
|
2
|
+
interface ButtonScrollToBottomProps extends ButtonProps {
|
|
3
|
+
isAtBottom: boolean;
|
|
4
|
+
scrollToBottom: () => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function ButtonScrollToBottom({ className, isAtBottom, scrollToBottom, ...props }: ButtonScrollToBottomProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { IconArrowDown } from "../icons/icons-ai";
|
|
4
|
+
import { cn } from "../lib/utils";
|
|
5
|
+
import { Button } from "../ui/button";
|
|
6
|
+
export function ButtonScrollToBottom({ className, isAtBottom, scrollToBottom, ...props }) {
|
|
7
|
+
return (_jsxs(Button, { variant: "outline", size: "icon", className: cn("absolute right-4 top-1 z-10 bg-background transition-opacity duration-300 sm:right-8 md:top-2", isAtBottom ? "opacity-0" : "opacity-100", className), onClick: () => scrollToBottom(), ...props, children: [_jsx(IconArrowDown, {}), _jsx("span", { className: "sr-only", children: "Scroll to bottom" })] }));
|
|
8
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { UIState } from "../lib/chat/actions";
|
|
2
|
+
import { Session } from "../lib/types";
|
|
3
|
+
export interface ChatList {
|
|
4
|
+
messages: UIState;
|
|
5
|
+
session?: Session;
|
|
6
|
+
isShared: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function ChatList({ messages, session, isShared }: ChatList): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { ExclamationTriangleIcon } from "@radix-ui/react-icons";
|
|
3
|
+
import { Separator } from "@radix-ui/react-select";
|
|
4
|
+
import Link from "next/link";
|
|
5
|
+
export function ChatList({ messages, session, isShared }) {
|
|
6
|
+
if (!messages.length) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
return (_jsxs("div", { className: "relative mx-auto max-w-2xl px-4", children: [!isShared && !session ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "group relative mb-4 flex items-start md:-ml-12", children: [_jsx("div", { className: "bg-background flex size-[25px] shrink-0 select-none items-center justify-center rounded-md border shadow-sm", children: _jsx(ExclamationTriangleIcon, {}) }), _jsx("div", { className: "ml-4 flex-1 space-y-2 overflow-hidden px-1", children: _jsxs("p", { className: "text-muted-foreground leading-normal", children: ["Please", " ", _jsx(Link, { href: "/login", className: "underline", children: "log in" }), " ", "or", " ", _jsx(Link, { href: "/signup", className: "underline", children: "sign up" }), " ", "to save and revisit your chat history!"] }) })] }), _jsx(Separator, { className: "my-4" })] })) : null, messages.map((message, index) => (_jsxs("div", { children: [message.display, index < messages.length - 1 && _jsx(Separator, { className: "my-4" })] }, message.id)))] }));
|
|
10
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface ChatPanelProps {
|
|
2
|
+
id?: string;
|
|
3
|
+
title?: string;
|
|
4
|
+
input: string;
|
|
5
|
+
setInput: (value: string) => void;
|
|
6
|
+
isAtBottom: boolean;
|
|
7
|
+
scrollToBottom: () => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function ChatPanel({ id, title, input, setInput, isAtBottom, scrollToBottom }: ChatPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useAIState, useActions, useUIState } from "ai/rsc";
|
|
3
|
+
import { nanoid } from "nanoid";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { IconShare } from "../icons/icons-ai";
|
|
6
|
+
import { shareChat } from "../lib/chat/chatActions";
|
|
7
|
+
import { Button } from "../ui/button";
|
|
8
|
+
import { ButtonScrollToBottom } from "./button-scroll-to-bottom";
|
|
9
|
+
import { ChatShareDialog } from "./chat-share-dialog";
|
|
10
|
+
import { FooterText } from "./footer";
|
|
11
|
+
import { PromptForm } from "./prompt-form";
|
|
12
|
+
import { UserMessage } from "./stocks/message";
|
|
13
|
+
export function ChatPanel({ id, title, input, setInput, isAtBottom, scrollToBottom }) {
|
|
14
|
+
const [aiState] = useAIState();
|
|
15
|
+
const [messages, setMessages] = useUIState();
|
|
16
|
+
const { submitUserMessage } = useActions();
|
|
17
|
+
const [shareDialogOpen, setShareDialogOpen] = React.useState(false);
|
|
18
|
+
const exampleMessages = [
|
|
19
|
+
{
|
|
20
|
+
heading: "部署前端到vercel",
|
|
21
|
+
subheading: "",
|
|
22
|
+
message: `调用工具中的 dpMtxcli 函数`,
|
|
23
|
+
},
|
|
24
|
+
];
|
|
25
|
+
return (_jsxs("div", { className: "fixed inset-x-0 bottom-0 w-full bg-gradient-to-b from-muted/30 from-0% to-muted/30 to-50% duration-300 ease-in-out animate-in dark:from-background/10 dark:from-10% dark:to-background/80 peer-[[data-state=open]]:group-[]:lg:pl-[250px] peer-[[data-state=open]]:group-[]:xl:pl-[300px]", children: [_jsx(ButtonScrollToBottom, { isAtBottom: isAtBottom, scrollToBottom: scrollToBottom }), _jsxs("div", { className: "mx-auto sm:max-w-2xl sm:px-4", children: [_jsx("div", { className: "mb-4 grid grid-cols-2 gap-2 px-4 sm:px-0", children: messages.length === 0 &&
|
|
26
|
+
exampleMessages.map((example, index) => (_jsxs("div", { className: `cursor-pointer rounded-lg border bg-white p-4 hover:bg-zinc-50 dark:bg-zinc-950 dark:hover:bg-zinc-900 ${index > 1 && "hidden md:block"}`, onClick: async () => {
|
|
27
|
+
setMessages((currentMessages) => [
|
|
28
|
+
...currentMessages,
|
|
29
|
+
{
|
|
30
|
+
id: nanoid(),
|
|
31
|
+
display: _jsx(UserMessage, { children: example.message }),
|
|
32
|
+
},
|
|
33
|
+
]);
|
|
34
|
+
const responseMessage = await submitUserMessage(example.message);
|
|
35
|
+
setMessages((currentMessages) => [...currentMessages, responseMessage]);
|
|
36
|
+
}, children: [_jsx("div", { className: "text-sm font-semibold", children: example.heading }), _jsx("div", { className: "text-sm text-zinc-600", children: example.subheading })] }, example.heading))) }), messages?.length >= 2 ? (_jsx("div", { className: "flex h-12 items-center justify-center", children: _jsx("div", { className: "flex space-x-2", children: id && title ? (_jsxs(_Fragment, { children: [_jsxs(Button, { variant: "outline", onClick: () => setShareDialogOpen(true), children: [_jsx(IconShare, { className: "mr-2" }), "Share"] }), _jsx(ChatShareDialog, { open: shareDialogOpen, onOpenChange: setShareDialogOpen, onCopy: () => setShareDialogOpen(false), shareChat: shareChat, chat: {
|
|
37
|
+
id,
|
|
38
|
+
title,
|
|
39
|
+
messages: aiState.messages,
|
|
40
|
+
} })] })) : null }) })) : null, _jsxs("div", { className: "space-y-4 border-t bg-background px-4 py-2 shadow-lg sm:rounded-t-xl sm:border md:py-4", children: [_jsx(PromptForm, { input: input, setInput: setInput }), _jsx(FooterText, { className: "hidden sm:block" })] })] })] }));
|
|
41
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type DialogProps } from "@radix-ui/react-dialog";
|
|
2
|
+
import { type Chat, ServerActionResult } from "../lib/types";
|
|
3
|
+
interface ChatShareDialogProps extends DialogProps {
|
|
4
|
+
chat: Pick<Chat, "id" | "title" | "messages">;
|
|
5
|
+
shareChat: (id: string) => ServerActionResult<Chat>;
|
|
6
|
+
onCopy: () => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function ChatShareDialog({ chat, shareChat, onCopy, ...props }: ChatShareDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Dialog, DialogContent, DialogDescription, DialogTitle, } from "@radix-ui/react-dialog";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { Button } from "react-day-picker";
|
|
6
|
+
import { toast } from "sonner";
|
|
7
|
+
import { useCopyToClipboard } from "../hooks/use-copy-to-clipboard";
|
|
8
|
+
import { IconSpinner } from "../icons/icons-ai";
|
|
9
|
+
import { DialogFooter, DialogHeader } from "../ui/dialog";
|
|
10
|
+
export function ChatShareDialog({ chat, shareChat, onCopy, ...props }) {
|
|
11
|
+
const { copyToClipboard } = useCopyToClipboard({ timeout: 1000 });
|
|
12
|
+
const [isSharePending, startShareTransition] = React.useTransition();
|
|
13
|
+
const copyShareLink = React.useCallback(async (chat) => {
|
|
14
|
+
if (!chat.sharePath) {
|
|
15
|
+
return toast.error("Could not copy share link to clipboard");
|
|
16
|
+
}
|
|
17
|
+
const url = new URL(window.location.href);
|
|
18
|
+
url.pathname = chat.sharePath;
|
|
19
|
+
copyToClipboard(url.toString());
|
|
20
|
+
onCopy();
|
|
21
|
+
toast.success("Share link copied to clipboard");
|
|
22
|
+
}, [copyToClipboard, onCopy]);
|
|
23
|
+
return (_jsx(Dialog, { ...props, children: _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Share link to chat" }), _jsx(DialogDescription, { children: "Anyone with the URL will be able to view the shared chat." })] }), _jsxs("div", { className: "p-4 space-y-1 text-sm border rounded-md", children: [_jsx("div", { className: "font-medium", children: chat.title }), _jsxs("div", { className: "text-muted-foreground", children: [chat.messages.length, " messages"] })] }), _jsx(DialogFooter, { className: "items-center", children: _jsx(Button, { disabled: isSharePending, onClick: () => {
|
|
24
|
+
startShareTransition(async () => {
|
|
25
|
+
const result = await shareChat(chat.id);
|
|
26
|
+
if (result && "error" in result) {
|
|
27
|
+
toast.error(result.error);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
copyShareLink(result);
|
|
31
|
+
});
|
|
32
|
+
}, children: isSharePending ? (_jsxs(_Fragment, { children: [_jsx(IconSpinner, { className: "mr-2 animate-spin" }), "Copying..."] })) : (_jsx(_Fragment, { children: "Copy link" })) }) })] }) }));
|
|
33
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Session } from "../lib/types";
|
|
2
|
+
export interface ChatProps extends React.ComponentProps<"div"> {
|
|
3
|
+
initialMessages?: Message[];
|
|
4
|
+
id?: string;
|
|
5
|
+
session?: Session;
|
|
6
|
+
missingKeys: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function Chat({ id, className, session, missingKeys }: ChatProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useAIState, useUIState } from "ai/rsc";
|
|
4
|
+
import { useEffect, useState } from "react";
|
|
5
|
+
import dynamic from "next/dynamic";
|
|
6
|
+
import { usePathname, useRouter } from "next/navigation";
|
|
7
|
+
import { toast } from "sonner";
|
|
8
|
+
import { useLocalStorage } from "usehooks-ts";
|
|
9
|
+
import { useScrollAnchor } from "../hooks/use-scroll-anchor";
|
|
10
|
+
import { cn } from "../lib/utils";
|
|
11
|
+
import { EmptyScreen } from "./empty-screen";
|
|
12
|
+
const LzChatPanel = dynamic(() => import("./chat-panel").then((x) => x.ChatPanel), {
|
|
13
|
+
ssr: false,
|
|
14
|
+
});
|
|
15
|
+
const LzChatList = dynamic(() => import("./chat-list").then((x) => x.ChatList), {
|
|
16
|
+
ssr: false,
|
|
17
|
+
});
|
|
18
|
+
export function Chat({ id, className, session, missingKeys }) {
|
|
19
|
+
const router = useRouter();
|
|
20
|
+
const path = usePathname();
|
|
21
|
+
const [input, setInput] = useState("");
|
|
22
|
+
const [messages] = useUIState();
|
|
23
|
+
const [aiState] = useAIState();
|
|
24
|
+
const [_, setNewChatId] = useLocalStorage("newChatId", id);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (session?.user) {
|
|
27
|
+
if (!path.includes("chat") && messages.length === 1) {
|
|
28
|
+
window.history.replaceState({}, "", `/chat/${id}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}, [id, path, session?.user, messages]);
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
const messagesLength = aiState.messages?.length;
|
|
34
|
+
if (messagesLength === 2) {
|
|
35
|
+
router.refresh();
|
|
36
|
+
}
|
|
37
|
+
}, [aiState.messages, router]);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
setNewChatId(id);
|
|
40
|
+
});
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
missingKeys.map((key) => {
|
|
43
|
+
toast.error(`Missing ${key} environment variable!`);
|
|
44
|
+
});
|
|
45
|
+
}, [missingKeys]);
|
|
46
|
+
const { messagesRef, scrollRef, visibilityRef, isAtBottom, scrollToBottom } = useScrollAnchor();
|
|
47
|
+
return (_jsxs("div", { className: "group w-full overflow-auto pl-0 peer-[[data-state=open]]:lg:pl-[250px] peer-[[data-state=open]]:xl:pl-[300px]", ref: scrollRef, children: [_jsxs("div", { className: cn("pb-[200px] pt-4 md:pt-10", className), ref: messagesRef, children: [messages.length ? (_jsx(LzChatList, { messages: messages, isShared: false, session: session })) : (_jsx(EmptyScreen, {})), _jsx("div", { className: "w-full h-px", ref: visibilityRef })] }), _jsx(LzChatPanel, { id: id, input: input, setInput: setInput, isAtBottom: isAtBottom, scrollToBottom: scrollToBottom })] }));
|
|
48
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Session } from "../../lib/types";
|
|
2
|
+
export interface ChatProps extends React.ComponentProps<"div"> {
|
|
3
|
+
initialMessages?: Message[];
|
|
4
|
+
id?: string;
|
|
5
|
+
session?: Session;
|
|
6
|
+
missingKeys: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function DevBot({ id, className, session, missingKeys }: ChatProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useAIState, useUIState } from "ai/rsc";
|
|
4
|
+
import { useEffect, useState } from "react";
|
|
5
|
+
import { ChatList } from "../chat-list";
|
|
6
|
+
import { usePathname, useRouter } from "next/navigation";
|
|
7
|
+
import { toast } from "sonner";
|
|
8
|
+
import { useLocalStorage } from "usehooks-ts";
|
|
9
|
+
import { useScrollAnchor } from "../../hooks/use-scroll-anchor";
|
|
10
|
+
import { cn } from "../../lib/utils";
|
|
11
|
+
import { EmptyScreen } from "../empty-screen";
|
|
12
|
+
import { DevChatPanel } from "./chat-panel";
|
|
13
|
+
export function DevBot({ id, className, session, missingKeys }) {
|
|
14
|
+
const router = useRouter();
|
|
15
|
+
const path = usePathname();
|
|
16
|
+
const [input, setInput] = useState("");
|
|
17
|
+
const [messages] = useUIState();
|
|
18
|
+
const [aiState] = useAIState();
|
|
19
|
+
const [_, setNewChatId] = useLocalStorage("newChatId", id);
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (session?.user) {
|
|
22
|
+
if (!path.includes("chat") && messages.length === 1) {
|
|
23
|
+
window.history.replaceState({}, "", `/chat/${id}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}, [id, path, session?.user, messages]);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const messagesLength = aiState.messages?.length;
|
|
29
|
+
if (messagesLength === 2) {
|
|
30
|
+
router.refresh();
|
|
31
|
+
}
|
|
32
|
+
}, [aiState.messages, router]);
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
setNewChatId(id);
|
|
35
|
+
});
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
missingKeys.map((key) => {
|
|
38
|
+
toast.error(`Missing ${key} environment variable!`);
|
|
39
|
+
});
|
|
40
|
+
}, [missingKeys]);
|
|
41
|
+
const { messagesRef, scrollRef, visibilityRef, isAtBottom, scrollToBottom } = useScrollAnchor();
|
|
42
|
+
return (_jsxs("div", { className: "group w-full overflow-auto pl-0 peer-[[data-state=open]]:lg:pl-[250px] peer-[[data-state=open]]:xl:pl-[300px]", ref: scrollRef, children: [_jsxs("div", { className: cn("pb-[200px] pt-4 md:pt-10", className), ref: messagesRef, children: [messages.length ? (_jsx(ChatList, { messages: messages, isShared: false, session: session })) : (_jsx(EmptyScreen, {})), _jsx("div", { className: "w-full h-px", ref: visibilityRef })] }), _jsx(DevChatPanel, { id: id, input: input, setInput: setInput, isAtBottom: isAtBottom, scrollToBottom: scrollToBottom })] }));
|
|
43
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import "server-only";
|
|
2
|
+
import { AIState, UIState } from "../../lib/chat/actions";
|
|
3
|
+
export declare const AIDev: (props: {
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
initialAIState?: AIState | undefined;
|
|
6
|
+
initialUIState?: UIState | undefined;
|
|
7
|
+
$ActionTypes?: {} | undefined;
|
|
8
|
+
}) => Promise<React.ReactElement>;
|