Skip to content

Commit

Permalink
Integration with SiliconFlow (#1)
Browse files Browse the repository at this point in the history
* SiliconCloud support
  • Loading branch information
jackalcooper committed Oct 8, 2024
1 parent 8ad63a6 commit 2273a83
Show file tree
Hide file tree
Showing 12 changed files with 534 additions and 6 deletions.
38 changes: 38 additions & 0 deletions .github/workflows/auto-rebase.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Auto Rebase

on:
schedule:
- cron: '0 * * * *' # This will run every hour
push:
branches:
- main # Change this to the branch you want to watch for updates
workflow_dispatch: # Allows manual triggering of the action

permissions:
id-token: write
contents: write

jobs:
rebase:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
fetch-depth: 0 # Fetch all history for all branches and tags

- name: Add upstream remote
run: git remote add upstream https://github.com/comfyanonymous/ComfyUI.git

- name: Fetch upstream changes
run: git fetch upstream

- name: Rebase branch
run: |
git config --global user.email jackalcooper@gmail.com
git config --global user.name tsai
git checkout master
git rebase upstream/master
- name: Push changes
run: git push origin master --force
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ For enterprise inquiries, please contact: **business@nextchat.dev**
- I18n: English, 简体中文, 繁体中文, 日本語, Français, Español, Italiano, Türkçe, Deutsch, Tiếng Việt, Русский, Čeština, 한국어, Indonesia

<div align="center">

![主界面](./docs/images/cover.png)

</div>
Expand All @@ -101,7 +101,7 @@ For enterprise inquiries, please contact: **business@nextchat.dev**
## What's New

- 🚀 v2.15.0 Now supports Plugins! Read this: [NextChat-Awesome-Plugins](https://github.com/ChatGPTNextWeb/NextChat-Awesome-Plugins)
- 🚀 v2.14.0 Now supports Artifacts & SD
- 🚀 v2.14.0 Now supports Artifacts & SD
- 🚀 v2.10.1 support Google Gemini Pro model.
- 🚀 v2.9.11 you can use azure endpoint now.
- 🚀 v2.8 now we have a client that runs across all platforms!
Expand Down Expand Up @@ -152,7 +152,7 @@ For enterprise inquiries, please contact: **business@nextchat.dev**
1. Get [OpenAI API Key](https://platform.openai.com/account/api-keys);
2. Click
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgit.luolix.top%2FYidadaa%2FChatGPT-Next-Web&env=OPENAI_API_KEY&env=CODE&project-name=chatgpt-next-web&repository-name=ChatGPT-Next-Web), remember that `CODE` is your page password;
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgit.luolix.top%2Fsiliconflow%2FChatGPT-Next-Web&env=NEXT_PUBLIC_SF_NEXT_CHAT_CLIENT_ID&env=SF_NEXT_CHAT_SECRET&project-name=chatgpt-next-web&repository-name=ChatGPT-Next-Web), remember that `CODE` is your page password;
3. Enjoy :)

## FAQ
Expand Down Expand Up @@ -346,7 +346,7 @@ Change default model
### `WHITE_WEBDAV_ENDPOINTS` (optional)

You can use this option if you want to increase the number of webdav service addresses you are allowed to access, as required by the format:
- Each address must be a complete endpoint
- Each address must be a complete endpoint
> `https://xxxx/yyy`
- Multiple addresses are connected by ', '

Expand Down
3 changes: 3 additions & 0 deletions app/api/[provider]/[...path]/route.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { handle as oauthHandler } from "../../oauth_callback";
import { ApiPath } from "@/app/constant";
import { NextRequest } from "next/server";
import { handle as openaiHandler } from "../../openai";
Expand All @@ -19,6 +20,8 @@ async function handle(
const apiPath = `/api/${params.provider}`;
console.log(`[${params.provider} Route] params `, params);
switch (apiPath) {
case ApiPath.OAuth:
return oauthHandler(req, { params });
case ApiPath.Azure:
return azureHandler(req, { params });
case ApiPath.Google:
Expand Down
70 changes: 70 additions & 0 deletions app/api/oauth_callback.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { NextRequest, NextResponse } from "next/server";
import { redirect } from "next/navigation";
import { cookies } from "next/headers";

export async function handle(
req: NextRequest,
{ params }: { params: { path: string[] } },
) {
console.log("[SF] params ", params);

if (req.method === "OPTIONS") {
return NextResponse.json({ body: "OK" }, { status: 200 });
}
const url = new URL(req.url);
const queryParams = new URLSearchParams(url.search);
const code = queryParams.get("code");
let sfak = "";
console.log("[SF] code ", code);
try {
const tokenFetch = await fetch(
`${
process.env.NEXT_PUBLIC_SF_NEXT_CHAT_SF_ACCOUNT_ENDPOINT ||
"https://account.siliconflow.cn"
}/oauth?client_id=${
process.env.NEXT_PUBLIC_SF_NEXT_CHAT_CLIENT_ID
}/api/open/oauth`,
{
method: "POST",
body: JSON.stringify({
clientId: process.env.NEXT_PUBLIC_SF_NEXT_CHAT_CLIENT_ID,
secret: process.env.SF_NEXT_CHAT_SECRET,
code,
}),
},
);
if (!tokenFetch.ok)
return Response.json(
{ status: false, message: "fetch error" },
{ status: 500 },
);
const tokenJson = await tokenFetch.json();
const access_token = tokenJson.status ? tokenJson.data?.access_token : null;
console.log("access_token", access_token);
// uat https://cloud-uat.siliconflow.cn
// prod https://cloud.siliconflow.cn
const apiKey = await fetch(
`${
process.env.NEXT_PUBLIC_SF_NEXT_CHAT_SF_CLOUD_ENDPOINT ||
"https://cloud.siliconflow.cn"
}/api/oauth/apikeys`,
{
method: "POST",
headers: {
Authorization: `token ${access_token}`,
},
},
);
const apiKeysData = await apiKey.json();
console.log("apiKeysData", apiKeysData);
sfak = apiKeysData.data[0].secretKey;
} catch (error) {
console.log("error", error);
return Response.json(
{ status: false, message: "fetch error" },
{ status: 500 },
);
}
cookies().set("sfak", sfak);
redirect(`/`);
}
95 changes: 95 additions & 0 deletions app/components/chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import {
DEFAULT_TOPIC,
ModelType,
usePluginStore,
DEFAULT_CONFIG,
} from "../store";

import {
Expand Down Expand Up @@ -114,6 +115,7 @@ import { ExportMessageModal } from "./exporter";
import { getClientConfig } from "../config/client";
import { useAllModels } from "../utils/hooks";
import { MultimodalContent } from "../client/api";
import { useCookies } from "react-cookie";

const localStorage = safeLocalStorage();
import { ClientApi } from "../client/api";
Expand Down Expand Up @@ -1244,6 +1246,99 @@ function _Chat() {
return session.mask.hideContext ? [] : session.mask.context.slice();
}, [session.mask.context, session.mask.hideContext]);

const [cookies, setCookie, removeCookie] = useCookies(["sfak"], {
doNotParse: true,
});

useEffect(() => {
const sfakValue = cookies.sfak;

const model = "Qwen/Qwen2-7B-Instruct";
config.update((config) => {
const ids = [
"stabilityai/stable-diffusion-xl-base-1.0",
"TencentARC/PhotoMaker",
"InstantX/InstantID",
"stabilityai/stable-diffusion-2-1",
"stabilityai/sd-turbo",
"stabilityai/sdxl-turbo",
"ByteDance/SDXL-Lightning",
"deepseek-ai/deepseek-llm-67b-chat",
"Qwen/Qwen1.5-14B-Chat",
"Qwen/Qwen1.5-7B-Chat",
"Qwen/Qwen1.5-110B-Chat",
"Qwen/Qwen1.5-32B-Chat",
"01-ai/Yi-1.5-6B-Chat",
"01-ai/Yi-1.5-9B-Chat-16K",
"01-ai/Yi-1.5-34B-Chat-16K",
"THUDM/chatglm3-6b",
"deepseek-ai/DeepSeek-V2-Chat",
"THUDM/glm-4-9b-chat",
"Qwen/Qwen2-72B-Instruct",
"Qwen/Qwen2-7B-Instruct",
"Qwen/Qwen2-57B-A14B-Instruct",
"stabilityai/stable-diffusion-3-medium",
"deepseek-ai/DeepSeek-Coder-V2-Instruct",
"Qwen/Qwen2-1.5B-Instruct",
"internlm/internlm2_5-7b-chat",
"BAAI/bge-large-en-v1.5",
"BAAI/bge-large-zh-v1.5",
"Pro/Qwen/Qwen2-7B-Instruct",
"Pro/Qwen/Qwen2-1.5B-Instruct",
"Pro/Qwen/Qwen1.5-7B-Chat",
"Pro/THUDM/glm-4-9b-chat",
"Pro/THUDM/chatglm3-6b",
"Pro/01-ai/Yi-1.5-9B-Chat-16K",
"Pro/01-ai/Yi-1.5-6B-Chat",
"Pro/internlm/internlm2_5-7b-chat",
"black-forest-labs/FLUX.1-schnell",
"FunAudioLLM/SenseVoiceSmall",
"netease-youdao/bce-embedding-base_v1",
"BAAI/bge-m3",
"internlm/internlm2_5-20b-chat",
"Qwen/Qwen2-Math-72B-Instruct",
"netease-youdao/bce-reranker-base_v1",
"BAAI/bge-reranker-v2-m3",
"deepseek-ai/DeepSeek-V2.5",
"Ascend/Qwen/Qwen2-72B-Instruct",
];
config.customModels = ids
.sort()
.filter(
(id) =>
!id.toLowerCase().includes("voice") &&
!id.toLowerCase().includes("flux") &&
!id.toLowerCase().includes("stability") &&
!id.toLowerCase().includes("sdxl") &&
!id.toLowerCase().includes("photomaker") &&
!id.toLowerCase().includes("instantid") &&
!id.toLowerCase().includes("bge") &&
!id.toLowerCase().includes("bce"),
)
.join(","); // Filter out unwanted ids;
config.modelConfig.model = model as ModelType;
config.modelConfig.providerName = model as ServiceProvider;
});
if (sfakValue) {
chatStore.updateCurrentSession((session) => {
if (
session.mask.modelConfig.model == DEFAULT_CONFIG.modelConfig.model
) {
session.mask.modelConfig.model = model as ModelType;
session.mask.modelConfig.providerName = model as ServiceProvider;
}
});
accessStore.update((access) => {
console.log("update access store with SF API key");
access.useCustomConfig = true;
access.openaiApiKey = sfakValue;
access.openaiUrl =
process.env.NEXT_PUBLIC_SF_NEXT_CHAT_SF_API_ENDPOINT!;
});
removeCookie("sfak");
}
}, []);

if (
context.length === 0 &&
session.messages.at(0)?.content !== BOT_HELLO.content
Expand Down
61 changes: 60 additions & 1 deletion app/components/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import styles from "./home.module.scss";
import { IconButton } from "./button";
import SettingsIcon from "../icons/settings.svg";
import GithubIcon from "../icons/github.svg";
import SiliconFlowIcon from "../icons/sf.svg";
import SiliconFlowActiveIcon from "../icons/sf.active.svg";
import ChatGptIcon from "../icons/chatgpt.svg";
import AddIcon from "../icons/add.svg";
import DeleteIcon from "../icons/delete.svg";
Expand All @@ -14,7 +16,12 @@ import DiscoveryIcon from "../icons/discovery.svg";

import Locale from "../locales";

import { useAppConfig, useChatStore } from "../store";
import {
DEFAULT_CONFIG,
useAccessStore,
useAppConfig,
useChatStore,
} from "../store";

import {
DEFAULT_SIDEBAR_WIDTH,
Expand All @@ -30,6 +37,7 @@ import { Link, useNavigate } from "react-router-dom";
import { isIOS, useMobileScreen } from "../utils";
import dynamic from "next/dynamic";
import { showConfirm, Selector } from "./ui-lib";
import { useCookies } from "react-cookie";

const ChatList = dynamic(async () => (await import("./chat-list")).ChatList, {
loading: () => null,
Expand Down Expand Up @@ -216,6 +224,10 @@ export function SideBar(props: { className?: string }) {
const navigate = useNavigate();
const config = useAppConfig();
const chatStore = useChatStore();
const accessStore = useAccessStore();
const [cookies, setCookie, removeCookie] = useCookies(["sfak"], {
doNotParse: true,
});

return (
<SideBarContainer
Expand Down Expand Up @@ -307,6 +319,53 @@ export function SideBar(props: { className?: string }) {
/>
</a>
</div>
<div className={styles["sidebar-action"]}>
<a
rel="noopener noreferrer"
onClick={() => {
if (accessStore.useCustomConfig && accessStore.openaiApiKey) {
const confirmLogout = window.confirm(
"Are you sure you want to log out?",
);
if (confirmLogout) {
chatStore.updateCurrentSession((session) => {
session.mask.modelConfig.model =
DEFAULT_CONFIG.modelConfig.model;
session.mask.modelConfig.providerName =
DEFAULT_CONFIG.modelConfig.providerName;
accessStore.update((access) => {
removeCookie("sfak");
access.openaiApiKey = "";
access.useCustomConfig = false;
window.location.href = "/";
});
});
}
} else {
window.location.href = `${
process.env
.NEXT_PUBLIC_SF_NEXT_CHAT_SF_ACCOUNT_ENDPOINT ||
"https://account.siliconflow.cn"
}/oauth?client_id=${
process.env.NEXT_PUBLIC_SF_NEXT_CHAT_CLIENT_ID
}`;
}
}}
>
<IconButton
aria={Locale.Export.MessageFromChatGPT}
key={accessStore.openaiApiKey + accessStore.openaiUrl}
icon={
accessStore.useCustomConfig && accessStore.openaiApiKey ? (
<SiliconFlowActiveIcon />
) : (
<SiliconFlowIcon />
)
}
shadow
/>
</a>
</div>
</>
}
secondaryAction={
Expand Down
3 changes: 2 additions & 1 deletion app/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export enum ApiPath {
Iflytek = "/api/iflytek",
Stability = "/api/stability",
Artifacts = "/api/artifacts",
OAuth = "/api/oauth_callback",
}

export enum SlotID {
Expand Down Expand Up @@ -230,7 +231,7 @@ You are ChatGPT, a large language model trained by {{ServiceProvider}}.
Knowledge cutoff: {{cutoff}}
Current model: {{model}}
Current time: {{time}}
Latex inline: \\(x^2\\)
Latex inline: \\(x^2\\)
Latex block: $$e=mc^2$$
`;

Expand Down
3 changes: 3 additions & 0 deletions app/icons/sf.active.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions app/icons/sf.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 2273a83

Please sign in to comment.