Merge pull request #7 from ConnectAI-E/feature/plugin-artifact

Feature/plugin artifact
This commit is contained in:
Lloyd Zhou 2024-09-05 14:54:01 +08:00 committed by GitHub
commit f32dd69acf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 42 additions and 43 deletions

View File

@ -91,8 +91,7 @@ For enterprise inquiries, please contact: **business@nextchat.dev**
- [x] Desktop App with tauri - [x] Desktop App with tauri
- [x] Self-host Model: Fully compatible with [RWKV-Runner](https://github.com/josStorer/RWKV-Runner), as well as server deployment of [LocalAI](https://github.com/go-skynet/LocalAI): llama/gpt4all/rwkv/vicuna/koala/gpt4all-j/cerebras/falcon/dolly etc. - [x] Self-host Model: Fully compatible with [RWKV-Runner](https://github.com/josStorer/RWKV-Runner), as well as server deployment of [LocalAI](https://github.com/go-skynet/LocalAI): llama/gpt4all/rwkv/vicuna/koala/gpt4all-j/cerebras/falcon/dolly etc.
- [x] Artifacts: Easily preview, copy and share generated content/webpages through a separate window [#5092](https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web/pull/5092) - [x] Artifacts: Easily preview, copy and share generated content/webpages through a separate window [#5092](https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web/pull/5092)
- [x] Plugins: support artifacts, network search, calculator, any other apis etc. [#165](https://github.com/Yidadaa/ChatGPT-Next-Web/issues/165) [#5353](https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web/issues/5353) - [x] Plugins: support network search, calculator, any other apis etc. [#165](https://github.com/Yidadaa/ChatGPT-Next-Web/issues/165) [#5353](https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web/issues/5353)
- [x] artifacts
- [x] network search, calculator, any other apis etc. [#165](https://github.com/Yidadaa/ChatGPT-Next-Web/issues/165) [#5353](https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web/issues/5353) - [x] network search, calculator, any other apis etc. [#165](https://github.com/Yidadaa/ChatGPT-Next-Web/issues/165) [#5353](https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web/issues/5353)
- [ ] local knowledge base - [ ] local knowledge base
@ -129,8 +128,7 @@ For enterprise inquiries, please contact: **business@nextchat.dev**
- [x] 使用 tauri 打包桌面应用 - [x] 使用 tauri 打包桌面应用
- [x] 支持自部署的大语言模型:开箱即用 [RWKV-Runner](https://github.com/josStorer/RWKV-Runner) ,服务端部署 [LocalAI 项目](https://github.com/go-skynet/LocalAI) llama / gpt4all / rwkv / vicuna / koala / gpt4all-j / cerebras / falcon / dolly 等等,或者使用 [api-for-open-llm](https://github.com/xusenlinzy/api-for-open-llm) - [x] 支持自部署的大语言模型:开箱即用 [RWKV-Runner](https://github.com/josStorer/RWKV-Runner) ,服务端部署 [LocalAI 项目](https://github.com/go-skynet/LocalAI) llama / gpt4all / rwkv / vicuna / koala / gpt4all-j / cerebras / falcon / dolly 等等,或者使用 [api-for-open-llm](https://github.com/xusenlinzy/api-for-open-llm)
- [x] Artifacts: 通过独立窗口,轻松预览、复制和分享生成的内容/可交互网页 [#5092](https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web/pull/5092) - [x] Artifacts: 通过独立窗口,轻松预览、复制和分享生成的内容/可交互网页 [#5092](https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web/pull/5092)
- [x] 插件机制,支持 artifacts联网搜索、计算器、调用其他平台 api [#165](https://github.com/Yidadaa/ChatGPT-Next-Web/issues/165) [#5353](https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web/issues/5353) - [x] 插件机制,支持`联网搜索`、`计算器`、调用其他平台 api [#165](https://github.com/Yidadaa/ChatGPT-Next-Web/issues/165) [#5353](https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web/issues/5353)
- [x] artifacts
- [x] 支持联网搜索、计算器、调用其他平台 api [#165](https://github.com/Yidadaa/ChatGPT-Next-Web/issues/165) [#5353](https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web/issues/5353) - [x] 支持联网搜索、计算器、调用其他平台 api [#165](https://github.com/Yidadaa/ChatGPT-Next-Web/issues/165) [#5353](https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web/issues/5353)
- [ ] 本地知识库 - [ ] 本地知识库

View File

@ -98,7 +98,6 @@ import {
REQUEST_TIMEOUT_MS, REQUEST_TIMEOUT_MS,
UNFINISHED_INPUT, UNFINISHED_INPUT,
ServiceProvider, ServiceProvider,
ArtifactsPlugin,
} from "../constant"; } from "../constant";
import { Avatar } from "./emoji"; import { Avatar } from "./emoji";
import { ContextPrompts, MaskAvatar, MaskConfig } from "./mask"; import { ContextPrompts, MaskAvatar, MaskConfig } from "./mask";
@ -727,38 +726,26 @@ export function ChatActions(props: {
/> />
)} )}
{showPlugins(currentProviderName, currentModel) && (
<ChatAction <ChatAction
onClick={() => setShowPluginSelector(true)} onClick={() => setShowPluginSelector(true)}
text={Locale.Plugin.Name} text={Locale.Plugin.Name}
icon={<PluginIcon />} icon={<PluginIcon />}
/> />
{showPluginSelector && ( )}
{showPluginSelector && showPlugins(currentProviderName, currentModel) && (
<Selector <Selector
multiple multiple
defaultSelectedValue={chatStore.currentSession().mask?.plugin} defaultSelectedValue={chatStore.currentSession().mask?.plugin}
items={[ items={pluginStore.getAll().map((item) => ({
{
title: Locale.Plugin.Artifacts,
value: ArtifactsPlugin.Artifacts as string,
},
].concat(
showPlugins(currentProviderName, currentModel)
? pluginStore.getAll().map((item) => ({
// @ts-ignore
title: `${item?.title}@${item?.version}`, title: `${item?.title}@${item?.version}`,
// @ts-ignore
value: item?.id, value: item?.id,
})) }))}
: [],
)}
onClose={() => setShowPluginSelector(false)} onClose={() => setShowPluginSelector(false)}
onSelection={(s) => { onSelection={(s) => {
chatStore.updateCurrentSession((session) => { chatStore.updateCurrentSession((session) => {
session.mask.plugin = s as string[]; session.mask.plugin = s as string[];
}); });
if (s.includes(ArtifactsPlugin.Artifacts)) {
showToast(ArtifactsPlugin.Artifacts);
}
}} }}
/> />
)} )}

View File

@ -19,7 +19,6 @@ import {
HTMLPreview, HTMLPreview,
HTMLPreviewHander, HTMLPreviewHander,
} from "./artifacts"; } from "./artifacts";
import { ArtifactsPlugin } from "../constant";
import { useChatStore } from "../store"; import { useChatStore } from "../store";
import { IconButton } from "./button"; import { IconButton } from "./button";
@ -77,7 +76,6 @@ export function PreCode(props: { children: any }) {
const { height } = useWindowSize(); const { height } = useWindowSize();
const chatStore = useChatStore(); const chatStore = useChatStore();
const session = chatStore.currentSession(); const session = chatStore.currentSession();
const plugins = session.mask?.plugin;
const renderArtifacts = useDebouncedCallback(() => { const renderArtifacts = useDebouncedCallback(() => {
if (!ref.current) return; if (!ref.current) return;
@ -94,10 +92,7 @@ export function PreCode(props: { children: any }) {
} }
}, 600); }, 600);
const enableArtifacts = useMemo( const enableArtifacts = session.mask?.enableArtifacts !== false;
() => plugins?.includes(ArtifactsPlugin.Artifacts),
[plugins],
);
//Wrap the paragraph for plain-text //Wrap the paragraph for plain-text
useEffect(() => { useEffect(() => {

View File

@ -167,6 +167,22 @@ export function MaskConfig(props: {
></input> ></input>
</ListItem> </ListItem>
<ListItem
title={Locale.Mask.Config.Artifacts.Title}
subTitle={Locale.Mask.Config.Artifacts.SubTitle}
>
<input
aria-label={Locale.Mask.Config.Artifacts.Title}
type="checkbox"
checked={props.mask.enableArtifacts}
onChange={(e) => {
props.updateMask((mask) => {
mask.enableArtifacts = e.currentTarget.checked;
});
}}
></input>
</ListItem>
{!props.shouldSyncFromGlobal ? ( {!props.shouldSyncFromGlobal ? (
<ListItem <ListItem
title={Locale.Mask.Config.Share.Title} title={Locale.Mask.Config.Share.Title}

View File

@ -73,10 +73,6 @@ export enum FileName {
Prompts = "prompts.json", Prompts = "prompts.json",
} }
export enum ArtifactsPlugin {
Artifacts = "artifacts",
}
export enum StoreKey { export enum StoreKey {
Chat = "chat-next-web-store", Chat = "chat-next-web-store",
Plugin = "chat-next-web-plugin", Plugin = "chat-next-web-plugin",

View File

@ -532,7 +532,6 @@ const cn = {
}, },
Plugin: { Plugin: {
Name: "插件", Name: "插件",
Artifacts: "Artifacts",
Page: { Page: {
Title: "插件", Title: "插件",
SubTitle: (count: number) => `${count} 个插件`, SubTitle: (count: number) => `${count} 个插件`,
@ -604,6 +603,10 @@ const cn = {
Title: "隐藏预设对话", Title: "隐藏预设对话",
SubTitle: "隐藏后预设对话不会出现在聊天界面", SubTitle: "隐藏后预设对话不会出现在聊天界面",
}, },
Artifacts: {
Title: "启用Artifacts",
SubTitle: "启用之后可以直接渲染HTML页面",
},
Share: { Share: {
Title: "分享此面具", Title: "分享此面具",
SubTitle: "生成此面具的直达链接", SubTitle: "生成此面具的直达链接",

View File

@ -540,7 +540,6 @@ const en: LocaleType = {
}, },
Plugin: { Plugin: {
Name: "Plugin", Name: "Plugin",
Artifacts: "Artifacts",
Page: { Page: {
Title: "Plugins", Title: "Plugins",
SubTitle: (count: number) => `${count} plugins`, SubTitle: (count: number) => `${count} plugins`,
@ -613,6 +612,10 @@ const en: LocaleType = {
Title: "Hide Context Prompts", Title: "Hide Context Prompts",
SubTitle: "Do not show in-context prompts in chat", SubTitle: "Do not show in-context prompts in chat",
}, },
Artifacts: {
Title: "Enable Artifacts",
SubTitle: "Can render HTML page when enable artifacts.",
},
Share: { Share: {
Title: "Share This Mask", Title: "Share This Mask",
SubTitle: "Generate a link to this mask", SubTitle: "Generate a link to this mask",

View File

@ -2,7 +2,7 @@ import { BUILTIN_MASKS } from "../masks";
import { getLang, Lang } from "../locales"; import { getLang, Lang } from "../locales";
import { DEFAULT_TOPIC, ChatMessage } from "./chat"; import { DEFAULT_TOPIC, ChatMessage } from "./chat";
import { ModelConfig, useAppConfig } from "./config"; import { ModelConfig, useAppConfig } from "./config";
import { StoreKey, ArtifactsPlugin } from "../constant"; import { StoreKey } from "../constant";
import { nanoid } from "nanoid"; import { nanoid } from "nanoid";
import { createPersistStore } from "../utils/store"; import { createPersistStore } from "../utils/store";
@ -18,6 +18,7 @@ export type Mask = {
lang: Lang; lang: Lang;
builtin: boolean; builtin: boolean;
plugin?: string[]; plugin?: string[];
enableArtifacts?: boolean;
}; };
export const DEFAULT_MASK_STATE = { export const DEFAULT_MASK_STATE = {
@ -38,7 +39,7 @@ export const createEmptyMask = () =>
lang: getLang(), lang: getLang(),
builtin: false, builtin: false,
createdAt: Date.now(), createdAt: Date.now(),
plugin: [ArtifactsPlugin.Artifacts as string], plugin: [],
}) as Mask; }) as Mask;
export const useMaskStore = createPersistStore( export const useMaskStore = createPersistStore(