Compare commits

...

23 Commits

Author SHA1 Message Date
孙高猛
571b6fdef7 test 2024-01-25 11:20:40 +08:00
孙高猛
3bc771a0d9 add workflow_dispatch 2024-01-24 22:03:47 +08:00
孙高猛
bdc25adb41 add delete preview scripts 2024-01-24 20:49:30 +08:00
孙高猛
7ec29c2eea add workflows/deploy preview 2024-01-24 20:19:39 +08:00
Fred Liang
b9995e7f70 feat: update dependencies 2024-01-22 15:12:21 +08:00
Fred Liang
31d9d2efcd feat: support setting up GTM 2024-01-22 15:12:21 +08:00
Yifei Zhang
0cf6614186 Merge pull request #3813 from ChatGPTNextWeb/update-cn-qq-info
Update README_CN.md
2024-01-11 01:27:43 +08:00
Yifei Zhang
ddc16cc2be Update README_CN.md 2024-01-11 01:27:31 +08:00
Yifei Zhang
616f0b3e73 Merge pull request #3812 from ChatGPTNextWeb/update-twitter-info
doc: update twitter & QQ group info
2024-01-11 01:26:30 +08:00
Yifei Zhang
bd1056b13f Update README.md 2024-01-11 01:25:20 +08:00
Fred Liang
cc86923fd5 fix: import typing error 2024-01-05 21:19:51 +08:00
Fred Liang
916d764477 fix: import language issue 2024-01-05 21:17:26 +08:00
levidius
4a21a8fdae Added Slovak language support
Slovak language was added app/locales/sk.ts and also the language was added to app/locales/index.ts
2024-01-05 21:05:17 +08:00
H0llyW00dzZ
49df5bd590 Chore [Tauri Desktop] Update icons
- [+] chore(icons): update icon files in src-tauri/icons directory
2024-01-05 21:03:44 +08:00
Fred Liang
9eaf492d5b chore: low the google safety setting to avoid unexpected blocking 2023-12-31 19:49:22 +08:00
Fred Liang
a80502f7db fix: fix gemini pro streaming api duplicated issue (#3721)
* fix: streaming duplicated issue

* chore: remove debug logs

* chore: add types defination
2023-12-31 19:08:16 +08:00
Fred Liang
eade013138 fix: update google url description (#3719)
* feat: update new logo & cover image

* fix: update google url description
2023-12-31 18:02:04 +08:00
Fred Liang
912254751a feat: update new logo & cover image (#3716) 2023-12-31 13:24:36 +08:00
Tashvik Srivastava
c3c6f7f7ae update readme (#3715) 2023-12-31 01:43:29 +08:00
Fred Liang
5cf58d9446 feat: support streaming for Gemini Pro (#3688)
* feat: support streaming for Gemini Pro

* feat: display texts smoothly

* chore: remove comments
2023-12-29 03:42:45 +08:00
reece00
3ba598633c Non -GPT model disable system prompt (#3684) 2023-12-28 23:52:45 +08:00
Fred Liang
406530ca69 feat: support vercel speed insight (#3686) 2023-12-28 23:10:19 +08:00
Fred Liang
f8b963df6d chore(docs): update readme for Gemini Pro (#3685)
* chore: update auth value logic

* chore: bump version 2.10.1

* Chore [Package] Downgrade Tauri Builder Version (#3656)

- [+] chore(package.json): update @tauri-apps/cli devDependency to version 1.5.7
- [+] chore(yarn.lock): update @tauri-apps/cli versions to 1.5.7

* chore: update README.md

---------

Co-authored-by: H0llyW00dzZ <priv8@btz.pm>
2023-12-28 22:56:01 +08:00
41 changed files with 789 additions and 95 deletions

View File

@@ -14,8 +14,8 @@ PROXY_URL=http://localhost:7890
GOOGLE_API_KEY=
# (optional)
# Default: https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent
# Googel Gemini Pro API url, set if you want to customize Google Gemini Pro API url.
# Default: https://generativelanguage.googleapis.com/
# Googel Gemini Pro API url without pathname, set if you want to customize Google Gemini Pro API url.
GOOGLE_URL=
# Override openai api request base url. (optional)

85
.github/workflows/deploy_preview.yml vendored Normal file
View File

@@ -0,0 +1,85 @@
name: VercelPreviewDeployment
on:
workflow_dispatch:
inputs:
branchName:
description: 'Branch to deploy'
required: true
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
VERCEL_DOMAIN_SUFFIX: ".pr.nextchat.dev"
permissions:
contents: read
statuses: write
pull-requests: write
jobs:
deploy-preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: ${{ github.event.inputs.branchName }}
- name: Extract branch name
shell: bash
run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> "$GITHUB_OUTPUT"
id: extract_branch
- name: Hash branch name
uses: pplanel/hash-calculator-action@v1.3.1
id: hash_branch
with:
input: ${{ steps.extract_branch.outputs.branch }}
method: MD5
- name: Set Environment Variables
id: set_env
if: github.event_name == 'pull_request'
run: |
echo "VERCEL_ALIAS_DOMAIN=${{ github.event.pull_request.number }}-${{ github.workflow }}.${VERCEL_DOMAIN_SUFFIX}" >> $GITHUB_OUTPUT
- name: Install Vercel CLI
run: npm install --global vercel@latest
- name: Cache dependencies
uses: actions/cache@v2
id: cache-npm
with:
path: ~/.npm
key: npm-${{ hashFiles('package-lock.json') }}
restore-keys: npm-
- name: Pull Vercel Environment Information
run: vercel pull --yes --environment=preview --token=${VERCEL_TOKEN}
- name: Deploy Project Artifacts to Vercel
id: vercel
env:
META_TAG: ${{ steps.hash_branch.outputs.digest }}-${{ github.run_number }}-${{ github.run_attempt}}
run: |
env
vercel pull --yes --environment=preview --token=${VERCEL_TOKEN}
vercel build --token=${VERCEL_TOKEN}
vercel deploy --prebuilt --archive=tgz --token=${VERCEL_TOKEN} --meta base_hash=${{ env.META_TAG }}
vercel ls --token=${VERCEL_TOKEN} --meta base_hash=${{ env.META_TAG }} &> vercel-output
DEFAULT_URL=$(cat vercel-output | grep http | awk '{print $2}')
ALIAS_URL=$(vercel alias set ${DEFAULT_URL} ${{ steps.set_env.outputs.VERCEL_ALIAS_DOMAIN }} --token=${VERCEL_TOKEN} | awk '{print $3}')
echo "New preview URL: ${DEFAULT_URL}"
echo "New alias URL: ${ALIAS_URL}"
echo "META_TAG=${META_TAG}"
echo "VERCEL_URL=${ALIAS_URL}" >> "$GITHUB_OUTPUT"
- uses: mshick/add-pr-comment@v2
with:
message: |
Your build has completed!
[Preview deployment](${{ steps.vercel.outputs.VERCEL_URL }})

View File

@@ -0,0 +1,40 @@
name: Removedeploypreview
permissions:
contents: read
statuses: write
pull-requests: write
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
on:
pull_request:
types:
- closed
jobs:
delete-deployments:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Extract branch name
shell: bash
run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
id: extract_branch
- name: Hash branch name
uses: pplanel/hash-calculator-action@v1.3.1
id: hash_branch
with:
input: ${{ steps.extract_branch.outputs.branch }}
method: MD5
- name: Call the delete-deployment-preview.sh script
env:
META_TAG: ${{ steps.hash_branch.outputs.digest }}
run: |
bash ./scripts/delete-deployment-preview.sh

View File

@@ -1,5 +1,6 @@
<div align="center">
<img src="./docs/images/icon.svg" alt="icon"/>
<img src="./docs/images/head-cover.png" alt="icon"/>
<h1 align="center">NextChat (ChatGPT Next Web)</h1>
@@ -14,9 +15,9 @@ One-Click to get a well-designed cross-platform ChatGPT web UI, with GPT3, GPT4
[![MacOS][MacOS-image]][download-url]
[![Linux][Linux-image]][download-url]
[Web App](https://app.nextchat.dev/) / [Desktop App](https://github.com/Yidadaa/ChatGPT-Next-Web/releases) / [Discord](https://discord.gg/YCkeafCafC) / [Twitter](https://twitter.com/mortiest_ricky) / [Buy Me a Coffee](https://www.buymeacoffee.com/yidadaa)
[Web App](https://app.nextchat.dev/) / [Desktop App](https://github.com/Yidadaa/ChatGPT-Next-Web/releases) / [Discord](https://discord.gg/YCkeafCafC) / [Twitter](https://twitter.com/NextChatDev)
[网页版](https://app.nextchat.dev/) / [客户端](https://github.com/Yidadaa/ChatGPT-Next-Web/releases) / [反馈](https://github.com/Yidadaa/ChatGPT-Next-Web/issues) / [QQ 群](https://github.com/Yidadaa/ChatGPT-Next-Web/discussions/1724) / [打赏开发者](https://user-images.githubusercontent.com/16968934/227772541-5bcd52d8-61b7-488c-a203-0330d8006e2b.jpg)
[网页版](https://app.nextchat.dev/) / [客户端](https://github.com/Yidadaa/ChatGPT-Next-Web/releases) / [反馈](https://github.com/Yidadaa/ChatGPT-Next-Web/issues)
[web-url]: https://chatgpt.nextweb.fun
[download-url]: https://github.com/Yidadaa/ChatGPT-Next-Web/releases
@@ -61,10 +62,11 @@ One-Click to get a well-designed cross-platform ChatGPT web UI, with GPT3, GPT4
## What's New
- 🚀 v2.0 is released, now you can create prompt templates, turn your ideas into reality! Read this: [ChatGPT Prompt Engineering Tips: Zero, One and Few Shot Prompting](https://www.allabtai.com/prompt-engineering-tips-zero-one-and-few-shot-prompting/).
- 🚀 v2.7 let's share conversations as image, or share to ShareGPT!
- 🚀 v2.8 now we have a client that runs across all platforms!
- 🚀 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!
- 🚀 v2.7 let's share conversations as image, or share to ShareGPT!
- 🚀 v2.0 is released, now you can create prompt templates, turn your ideas into reality! Read this: [ChatGPT Prompt Engineering Tips: Zero, One and Few Shot Prompting](https://www.allabtai.com/prompt-engineering-tips-zero-one-and-few-shot-prompting/).
## 主要功能
@@ -360,9 +362,11 @@ If you want to add a new translation, read this [document](./docs/translation.md
[@Licoy](https://github.com/Licoy)
[@shangmin2009](https://github.com/shangmin2009)
### Contributor
### Contributors
[Contributors](https://github.com/Yidadaa/ChatGPT-Next-Web/graphs/contributors)
<a href="https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web/graphs/contributors">
<img src="https://contrib.rocks/image?repo=ChatGPTNextWeb/ChatGPT-Next-Web" />
</a>
## LICENSE

View File

@@ -5,7 +5,7 @@
一键免费部署你的私人 ChatGPT 网页应用,支持 GPT3, GPT4 & Gemini Pro 模型。
[演示 Demo](https://chat-gpt-next-web.vercel.app/) / [反馈 Issues](https://github.com/Yidadaa/ChatGPT-Next-Web/issues) / [加入 Discord](https://discord.gg/zrhvHCr79N) / [QQ 群](https://user-images.githubusercontent.com/16968934/228190818-7dd00845-e9b9-4363-97e5-44c507ac76da.jpeg) / [打赏开发者](https://user-images.githubusercontent.com/16968934/227772541-5bcd52d8-61b7-488c-a203-0330d8006e2b.jpg) / [Donate](#捐赠-donate-usdt)
[演示 Demo](https://chat-gpt-next-web.vercel.app/) / [反馈 Issues](https://github.com/Yidadaa/ChatGPT-Next-Web/issues) / [加入 Discord](https://discord.gg/zrhvHCr79N)
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FYidadaa%2FChatGPT-Next-Web&env=OPENAI_API_KEY&env=CODE&project-name=chatgpt-next-web&repository-name=ChatGPT-Next-Web)

View File

@@ -9,6 +9,7 @@ import { prettyObject } from "@/app/utils/format";
import { getClientConfig } from "@/app/config/client";
import Locale from "../../locales";
import { getServerSideConfig } from "@/app/config/server";
import de from "@/app/locales/de";
export class GeminiProApi implements LLMApi {
extractMessage(res: any) {
console.log("[Response] gemini-pro response: ", res);
@@ -20,6 +21,7 @@ export class GeminiProApi implements LLMApi {
);
}
async chat(options: ChatOptions): Promise<void> {
const apiClient = this;
const messages = options.messages.map((v) => ({
role: v.role.replace("assistant", "model").replace("system", "user"),
parts: [{ text: v.content }],
@@ -57,12 +59,29 @@ export class GeminiProApi implements LLMApi {
topP: modelConfig.top_p,
// "topK": modelConfig.top_k,
},
safetySettings: [
{
category: "HARM_CATEGORY_HARASSMENT",
threshold: "BLOCK_ONLY_HIGH",
},
{
category: "HARM_CATEGORY_HATE_SPEECH",
threshold: "BLOCK_ONLY_HIGH",
},
{
category: "HARM_CATEGORY_SEXUALLY_EXPLICIT",
threshold: "BLOCK_ONLY_HIGH",
},
{
category: "HARM_CATEGORY_DANGEROUS_CONTENT",
threshold: "BLOCK_ONLY_HIGH",
},
],
};
console.log("[Request] google payload: ", requestPayload);
// todo: support stream later
const shouldStream = false;
const shouldStream = !!options.config.stream;
const controller = new AbortController();
options.onController?.(controller);
try {
@@ -82,13 +101,23 @@ export class GeminiProApi implements LLMApi {
if (shouldStream) {
let responseText = "";
let remainText = "";
let streamChatPath = chatPath.replace(
"generateContent",
"streamGenerateContent",
);
let finished = false;
let existingTexts: string[] = [];
const finish = () => {
finished = true;
options.onFinish(existingTexts.join(""));
};
// animate response to make it looks smooth
function animateResponseText() {
if (finished || controller.signal.aborted) {
responseText += remainText;
console.log("[Response Animation] finished");
finish();
return;
}
@@ -105,88 +134,56 @@ export class GeminiProApi implements LLMApi {
// start animaion
animateResponseText();
fetch(streamChatPath, chatPayload)
.then((response) => {
const reader = response?.body?.getReader();
const decoder = new TextDecoder();
let partialData = "";
const finish = () => {
if (!finished) {
finished = true;
options.onFinish(responseText + remainText);
}
};
return reader?.read().then(function processText({
done,
value,
}): Promise<any> {
if (done) {
console.log("Stream complete");
// options.onFinish(responseText + remainText);
finished = true;
return Promise.resolve();
}
controller.signal.onabort = finish;
partialData += decoder.decode(value, { stream: true });
fetchEventSource(chatPath, {
...chatPayload,
async onopen(res) {
clearTimeout(requestTimeoutId);
const contentType = res.headers.get("content-type");
console.log(
"[OpenAI] request response content type: ",
contentType,
);
if (contentType?.startsWith("text/plain")) {
responseText = await res.clone().text();
return finish();
}
if (
!res.ok ||
!res.headers
.get("content-type")
?.startsWith(EventStreamContentType) ||
res.status !== 200
) {
const responseTexts = [responseText];
let extraInfo = await res.clone().text();
try {
const resJson = await res.clone().json();
extraInfo = prettyObject(resJson);
} catch {}
let data = JSON.parse(ensureProperEnding(partialData));
if (res.status === 401) {
responseTexts.push(Locale.Error.Unauthorized);
const textArray = data.reduce(
(acc: string[], item: { candidates: any[] }) => {
const texts = item.candidates.map((candidate) =>
candidate.content.parts
.map((part: { text: any }) => part.text)
.join(""),
);
return acc.concat(texts);
},
[],
);
if (textArray.length > existingTexts.length) {
const deltaArray = textArray.slice(existingTexts.length);
existingTexts = textArray;
remainText += deltaArray.join("");
}
} catch (error) {
// console.log("[Response Animation] error: ", error,partialData);
// skip error message when parsing json
}
if (extraInfo) {
responseTexts.push(extraInfo);
}
responseText = responseTexts.join("\n\n");
return finish();
}
},
onmessage(msg) {
if (msg.data === "[DONE]" || finished) {
return finish();
}
const text = msg.data;
try {
const json = JSON.parse(text) as {
choices: Array<{
delta: {
content: string;
};
}>;
};
const delta = json.choices[0]?.delta?.content;
if (delta) {
remainText += delta;
}
} catch (e) {
console.error("[Request] parse error", text);
}
},
onclose() {
finish();
},
onerror(e) {
options.onError?.(e);
throw e;
},
openWhenHidden: true,
});
return reader.read().then(processText);
});
})
.catch((error) => {
console.error("Error:", error);
});
} else {
const res = await fetch(chatPath, chatPayload);
clearTimeout(requestTimeoutId);
@@ -220,3 +217,10 @@ export class GeminiProApi implements LLMApi {
return "/api/google/" + path;
}
}
function ensureProperEnding(str: string) {
if (str.startsWith("[") && !str.endsWith("]")) {
return str + "]";
}
return str;
}

View File

@@ -89,6 +89,8 @@ export const getServerSideConfig = () => {
googleApiKey: process.env.GOOGLE_API_KEY,
googleUrl: process.env.GOOGLE_URL,
gtmId: process.env.GTM_ID,
needCode: ACCESS_CODES.size > 0,
code: process.env.CODE,
codes: ACCESS_CODES,

View File

@@ -87,8 +87,7 @@ export const Azure = {
};
export const Google = {
ExampleEndpoint:
"https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent",
ExampleEndpoint: "https://generativelanguage.googleapis.com/",
ChatPath: "v1beta/models/gemini-pro:generateContent",
// /api/openai/v1/chat/completions

View File

@@ -4,6 +4,10 @@ import "./styles/markdown.scss";
import "./styles/highlight.scss";
import { getClientConfig } from "./config/client";
import { type Metadata } from "next";
import { SpeedInsights } from "@vercel/speed-insights/next";
import { getServerSideConfig } from "./config/server";
import { GoogleTagManager } from "@next/third-parties/google";
const serverConfig = getServerSideConfig();
export const metadata: Metadata = {
title: "NextChat",
@@ -35,7 +39,19 @@ export default function RootLayout({
<link rel="manifest" href="/site.webmanifest"></link>
<script src="/serviceWorkerRegister.js" defer></script>
</head>
<body>{children}</body>
<body>
{children}
{serverConfig?.isVercel && (
<>
<SpeedInsights />
</>
)}
{serverConfig?.gtmId && (
<>
<GoogleTagManager gtmId={serverConfig.gtmId} />
</>
)}
</body>
</html>
);
}

View File

@@ -321,7 +321,7 @@ const cn = {
Endpoint: {
Title: "接口地址",
SubTitle: "样例:",
SubTitle: "不包含请求路径,样例:",
},
ApiVerion: {

View File

@@ -16,6 +16,7 @@ import cs from "./cs";
import ko from "./ko";
import ar from "./ar";
import bn from "./bn";
import sk from "./sk";
import { merge } from "../utils/merge";
import type { LocaleType } from "./cn";
@@ -40,6 +41,7 @@ const ALL_LANGS = {
no,
ar,
bn,
sk,
};
export type Lang = keyof typeof ALL_LANGS;
@@ -65,6 +67,7 @@ export const ALL_LANG_OPTIONS: Record<Lang, string> = {
no: "Nynorsk",
ar: "العربية",
bn: "বাংলা",
sk: "Slovensky",
};
const LANG_KEY = "lang";

482
app/locales/sk.ts Normal file
View File

@@ -0,0 +1,482 @@
import { getClientConfig } from "../config/client";
import { SubmitKey } from "../store/config";
import { LocaleType } from "./index";
import type { PartialLocaleType } from "./index";
// if you are adding a new translation, please use PartialLocaleType instead of LocaleType
const isApp = !!getClientConfig()?.isApp;
const sk: PartialLocaleType = {
WIP: "Už čoskoro...",
Error: {
Unauthorized: isApp
? "Neplatný API kľúč, prosím skontrolujte ho na stránke [Nastavenia](/#/settings)."
: "Neoprávnený prístup, prosím zadajte prístupový kód na stránke [auth](/#/auth), alebo zadajte váš OpenAI API kľúč.",
},
Auth: {
Title: "Potrebný prístupový kód",
Tips: "Prosím, zadajte prístupový kód nižšie",
SubTips: "Alebo zadajte váš OpenAI alebo Google API kľúč",
Input: "prístupový kód",
Confirm: "Potvrdiť",
Later: "Neskôr",
},
ChatItem: {
ChatItemCount: (count: number) => `${count} správ`,
},
Chat: {
SubTitle: (count: number) => `${count} správ`,
EditMessage: {
Title: "Upraviť všetky správy",
Topic: {
Title: "Téma",
SubTitle: "Zmeniť aktuálnu tému",
},
},
Actions: {
ChatList: "Prejsť na zoznam chatov",
CompressedHistory: "Komprimovaná história výziev",
Export: "Exportovať všetky správy ako Markdown",
Copy: "Kopírovať",
Stop: "Zastaviť",
Retry: "Skúsiť znova",
Pin: "Pripnúť",
PinToastContent: "Pripnuté 1 správy do kontextových výziev",
PinToastAction: "Zobraziť",
Delete: "Vymazať",
Edit: "Upraviť",
},
Commands: {
new: "Začať nový chat",
newm: "Začať nový chat s maskou",
next: "Ďalší Chat",
prev: "Predchádzajúci Chat",
clear: "Vymazať kontext",
del: "Vymazať Chat",
},
InputActions: {
Stop: "Zastaviť",
ToBottom: "Na najnovšie",
Theme: {
auto: "Automaticky",
light: "Svetlý motív",
dark: "Tmavý motív",
},
Prompt: "Výzvy",
Masks: "Masky",
Clear: "Vymazať kontext",
Settings: "Nastavenia",
},
Rename: "Premenovať Chat",
Typing: "Písanie…",
Input: (submitKey: string) => {
var inputHints = `${submitKey} na odoslanie`;
if (submitKey === String(SubmitKey.Enter)) {
inputHints += ", Shift + Enter na zalomenie";
}
return inputHints + ", / na vyhľadávanie výziev, : na použitie príkazov";
},
Send: "Odoslať",
Config: {
Reset: "Resetovať na predvolené",
SaveAs: "Uložiť ako masku",
},
IsContext: "Kontextová výzva",
},
Export: {
Title: "Export správ",
Copy: "Kopírovať všetko",
Download: "Stiahnuť",
MessageFromYou: "Správa od vás",
MessageFromChatGPT: "Správa od ChatGPT",
Share: "Zdieľať na ShareGPT",
Format: {
Title: "Formát exportu",
SubTitle: "Markdown alebo PNG obrázok",
},
IncludeContext: {
Title: "Vrátane kontextu",
SubTitle: "Exportovať kontextové výzvy v maske alebo nie",
},
Steps: {
Select: "Vybrať",
Preview: "Náhľad",
},
Image: {
Toast: "Snímanie obrázka...",
Modal:
"Dlhým stlačením alebo kliknutím pravým tlačidlom myši uložte obrázok",
},
},
Select: {
Search: "Hľadať",
All: "Vybrať všetko",
Latest: "Vybrať najnovšie",
Clear: "Vymazať",
},
Memory: {
Title: "Výzva pamäti",
EmptyContent: "Zatiaľ nič.",
Send: "Odoslať pamäť",
Copy: "Kopírovať pamäť",
Reset: "Resetovať reláciu",
ResetConfirm:
"Resetovaním sa vymaže aktuálna história konverzácie a historická pamäť. Ste si istí, že chcete resetovať?",
},
Home: {
NewChat: "Nový Chat",
DeleteChat: "Potvrdiť vymazanie vybranej konverzácie?",
DeleteToast: "Chat vymazaný",
Revert: "Vrátiť späť",
},
Settings: {
Title: "Nastavenia",
SubTitle: "Všetky nastavenia",
Danger: {
Reset: {
Title: "Resetovať všetky nastavenia",
SubTitle: "Resetovať všetky položky nastavení na predvolené",
Action: "Resetovať",
Confirm: "Potvrdiť resetovanie všetkých nastavení na predvolené?",
},
Clear: {
Title: "Vymazať všetky údaje",
SubTitle: "Vymazať všetky správy a nastavenia",
Action: "Vymazať",
Confirm: "Potvrdiť vymazanie všetkých správ a nastavení?",
},
},
Lang: {
Name: "Jazyk", // POZOR: ak pridávate nový preklad, prosím neprekladajte túto hodnotu, nechajte ju ako "Jazyk"
All: "Všetky jazyky",
},
Avatar: "Avatar",
FontSize: {
Title: "Veľkosť písma",
SubTitle: "Nastaviť veľkosť písma obsahu chatu",
},
InjectSystemPrompts: {
Title: "Vložiť systémové výzvy",
SubTitle: "Vložiť globálnu systémovú výzvu pre každú požiadavku",
},
InputTemplate: {
Title: "Šablóna vstupu",
SubTitle: "Najnovšia správa bude vyplnená do tejto šablóny",
},
Update: {
Version: (x: string) => `Verzia: ${x}`,
IsLatest: "Najnovšia verzia",
CheckUpdate: "Skontrolovať aktualizácie",
IsChecking: "Kontrola aktualizácií...",
FoundUpdate: (x: string) => `Nájdená nová verzia: ${x}`,
GoToUpdate: "Aktualizovať",
},
SendKey: "Odoslať kľúč",
Theme: "Motív",
TightBorder: "Tesný okraj",
SendPreviewBubble: {
Title: "Bublina náhľadu odoslania",
SubTitle: "Náhľad markdownu v bubline",
},
AutoGenerateTitle: {
Title: "Automaticky generovať názov",
SubTitle: "Generovať vhodný názov na základe obsahu konverzácie",
},
Sync: {
CloudState: "Posledná aktualizácia",
NotSyncYet: "Zatiaľ nesynchronizované",
Success: "Synchronizácia úspešná",
Fail: "Synchronizácia zlyhala",
Config: {
Modal: {
Title: "Konfigurácia synchronizácie",
Check: "Skontrolovať pripojenie",
},
SyncType: {
Title: "Typ synchronizácie",
SubTitle: "Vyberte svoju obľúbenú službu synchronizácie",
},
Proxy: {
Title: "Povoliť CORS Proxy",
SubTitle: "Povoliť proxy na obídenie obmedzení cross-origin",
},
ProxyUrl: {
Title: "Koncový bod Proxy",
SubTitle: "Platné len pre vstavaný CORS proxy tohto projektu",
},
WebDav: {
Endpoint: "Koncový bod WebDAV",
UserName: "Meno používateľa",
Password: "Heslo",
},
UpStash: {
Endpoint: "URL REST služby UpStash Redis",
UserName: "Názov zálohy",
Password: "Token REST služby UpStash Redis",
},
},
LocalState: "Lokálne údaje",
Overview: (overview: any) => {
return `${overview.chat} chaty, ${overview.message} správy, ${overview.prompt} výzvy, ${overview.mask} masky`;
},
ImportFailed: "Import z súboru zlyhal",
},
Mask: {
Splash: {
Title: "Úvodná obrazovka masky",
SubTitle: "Zobraziť úvodnú obrazovku masky pred začatím nového chatu",
},
Builtin: {
Title: "Skryť vstavané masky",
SubTitle: "Skryť vstavané masky v zozname masiek",
},
},
Prompt: {
Disable: {
Title: "Zakázať automatické dopĺňanie",
SubTitle: "Zadajte / na spustenie automatického dopĺňania",
},
List: "Zoznam výziev",
ListCount: (builtin: number, custom: number) =>
`${builtin} vstavaných, ${custom} užívateľsky definovaných`,
Edit: "Upraviť",
Modal: {
Title: "Zoznam výziev",
Add: "Pridať jednu",
Search: "Hľadať výzvy",
},
EditModal: {
Title: "Upraviť výzvu",
},
},
HistoryCount: {
Title: "Počet pripojených správ",
SubTitle: "Počet odoslaných správ pripojených na požiadavku",
},
CompressThreshold: {
Title: "Práh kompresie histórie",
SubTitle:
"Bude komprimované, ak dĺžka nekomprimovaných správ presiahne túto hodnotu",
},
Usage: {
Title: "Stav účtu",
SubTitle(used: any, total: any) {
return `Tento mesiac použité ${used}, predplatné ${total}`;
},
IsChecking: "Kontroluje sa...",
Check: "Skontrolovať",
NoAccess: "Zadajte API kľúč na skontrolovanie zostatku",
},
Access: {
AccessCode: {
Title: "Prístupový kód",
SubTitle: "Povolený prístupový kód",
Placeholder: "Zadajte kód",
},
CustomEndpoint: {
Title: "Vlastný koncový bod",
SubTitle: "Použiť vlastnú službu Azure alebo OpenAI",
},
Provider: {
Title: "Poskytovateľ modelu",
SubTitle: "Vyberte Azure alebo OpenAI",
},
OpenAI: {
ApiKey: {
Title: "API kľúč OpenAI",
SubTitle: "Použiť vlastný API kľúč OpenAI",
Placeholder: "sk-xxx",
},
Endpoint: {
Title: "Koncový bod OpenAI",
SubTitle:
"Musí začínať http(s):// alebo použiť /api/openai ako predvolený",
},
},
Azure: {
ApiKey: {
Title: "API kľúč Azure",
SubTitle: "Skontrolujte svoj API kľúč v Azure konzole",
Placeholder: "API kľúč Azure",
},
Endpoint: {
Title: "Koncový bod Azure",
SubTitle: "Príklad: ",
},
ApiVerion: {
Title: "Verzia API Azure",
SubTitle: "Skontrolujte svoju verziu API v Azure konzole",
},
},
CustomModel: {
Title: "Vlastné modely",
SubTitle: "Možnosti vlastného modelu, oddelené čiarkou",
},
Google: {
ApiKey: {
Title: "API kľúč",
SubTitle:
"Obísť obmedzenia prístupu heslom pomocou vlastného API kľúča Google AI Studio",
Placeholder: "API kľúč Google AI Studio",
},
Endpoint: {
Title: "Adresa koncového bodu",
SubTitle: "Príklad:",
},
ApiVerion: {
Title: "Verzia API (gemini-pro verzia API)",
SubTitle: "Vyberte špecifickú verziu časti",
},
},
},
Model: "Model",
Temperature: {
Title: "Teplota",
SubTitle: "Vyššia hodnota robí výstup náhodnejším",
},
TopP: {
Title: "Top P",
SubTitle: "Neupravujte túto hodnotu spolu s teplotou",
},
MaxTokens: {
Title: "Maximálny počet tokenov",
SubTitle: "Maximálna dĺžka vstupných tokenov a generovaných tokenov",
},
PresencePenalty: {
Title: "Penalizácia za prítomnosť",
SubTitle:
"Vyššia hodnota zvyšuje pravdepodobnosť hovorenia o nových témach",
},
FrequencyPenalty: {
Title: "Penalizácia za frekvenciu",
SubTitle:
"Vyššia hodnota znižuje pravdepodobnosť opakovania rovnakej línie",
},
},
Store: {
DefaultTopic: "Nová konverzácia",
BotHello: "Ahoj! Ako vám dnes môžem pomôcť?",
Error: "Niečo sa pokazilo, skúste to prosím neskôr znova.",
Prompt: {
History: (content: string) =>
"Toto je zhrnutie histórie chatu ako rekapitulácia: " + content,
Topic:
"Prosím, vygenerujte štvor- až päťslovný titul, ktorý zhrnie našu konverzáciu bez akéhokoľvek úvodu, interpunkcie, úvodzoviek, bodiek, symbolov, tučného textu alebo ďalšieho textu. Odstráňte uzatváracie úvodzovky.",
Summarize:
"Stručne zhrňte diskusiu na menej ako 200 slov, aby ste ju mohli použiť ako výzvu pre budúci kontext.",
},
},
Copy: {
Success: "Skopírované do schránky",
Failed:
"Kopírovanie zlyhalo, prosím udeľte povolenie na prístup k schránke",
},
Download: {
Success: "Obsah stiahnutý do vášho adresára.",
Failed: "Stiahnutie zlyhalo.",
},
Context: {
Toast: (x: any) => `S ${x} kontextovými výzvami`,
Edit: "Aktuálne nastavenia chatu",
Add: "Pridať výzvu",
Clear: "Kontext vyčistený",
Revert: "Vrátiť späť",
},
Plugin: {
Name: "Plugin",
},
FineTuned: {
Sysmessage: "Ste asistent, ktorý",
},
Mask: {
Name: "Maska",
Page: {
Title: "Šablóna výziev",
SubTitle: (count: number) => `${count} šablón výziev`,
Search: "Hľadať šablóny",
Create: "Vytvoriť",
},
Item: {
Info: (count: number) => `${count} výziev`,
Chat: "Chat",
View: "Zobraziť",
Edit: "Upraviť",
Delete: "Vymazať",
DeleteConfirm: "Potvrdiť vymazanie?",
},
EditModal: {
Title: (readonly: boolean) =>
`Upraviť šablónu výziev ${readonly ? "(iba na čítanie)" : ""}`,
Download: "Stiahnuť",
Clone: "Klonovať",
},
Config: {
Avatar: "Avatar robota",
Name: "Meno robota",
Sync: {
Title: "Použiť globálne nastavenia",
SubTitle: "Použiť globálne nastavenia v tomto chate",
Confirm: "Potvrdiť prepísanie vlastného nastavenia globálnym?",
},
HideContext: {
Title: "Skryť kontextové výzvy",
SubTitle: "Nezobrazovať kontextové výzvy v chate",
},
Share: {
Title: "Zdieľať túto masku",
SubTitle: "Vygenerovať odkaz na túto masku",
Action: "Kopírovať odkaz",
},
},
},
NewChat: {
Return: "Vrátiť sa",
Skip: "Len začať",
Title: "Vybrať masku",
SubTitle: "Chatovať s dušou za maskou",
More: "Nájsť viac",
NotShow: "Už nezobrazovať",
ConfirmNoShow:
"Potvrdiť deaktiváciu? Môžete ju neskôr znova povoliť v nastaveniach.",
},
UI: {
Confirm: "Potvrdiť",
Cancel: "Zrušiť",
Close: "Zavrieť",
Create: "Vytvoriť",
Edit: "Upraviť",
Export: "Exportovať",
Import: "Importovať",
Sync: "Synchronizovať",
Config: "Konfigurácia",
},
Exporter: {
Description: {
Title: "Zobrazia sa len správy po vyčistení kontextu",
},
Model: "Model",
Messages: "Správy",
Topic: "Téma",
Time: "Čas",
},
URLCommand: {
Code: "Zistený prístupový kód z URL, potvrdiť na aplikovanie?",
Settings: "Zistené nastavenia z URL, potvrdiť na aplikovanie?",
},
};
export default sk;

View File

@@ -10,7 +10,11 @@ export default async function App() {
return (
<>
<Home />
{serverConfig?.isVercel && <Analytics />}
{serverConfig?.isVercel && (
<>
<Analytics />
</>
)}
</>
);
}

View File

@@ -386,7 +386,9 @@ export const useChatStore = createPersistStore(
const contextPrompts = session.mask.context.slice();
// system prompts, to get close to OpenAI Web ChatGPT
const shouldInjectSystemPrompts = modelConfig.enableInjectSystemPrompts;
const shouldInjectSystemPrompts =
modelConfig.enableInjectSystemPrompts &&
session.mask.modelConfig.model.startsWith("gpt-");
var systemPrompts: ChatMessage[] = [];
systemPrompts = shouldInjectSystemPrompts

BIN
docs/images/head-cover.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@@ -18,8 +18,10 @@
"dependencies": {
"@fortaine/fetch-event-source": "^3.0.6",
"@hello-pangea/dnd": "^16.5.0",
"@next/third-parties": "^14.1.0",
"@svgr/webpack": "^6.5.1",
"@vercel/analytics": "^0.1.11",
"@vercel/speed-insights": "^1.0.2",
"emoji-picker-react": "^4.5.15",
"fuse.js": "^7.0.0",
"html-to-image": "^1.11.11",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 633 B

After

Width:  |  Height:  |  Size: 719 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 74 KiB

View File

@@ -0,0 +1,34 @@
#!/bin/bash
# Set the pipefail option.
set -o pipefail
# Get the Vercel API endpoints.
GET_DEPLOYMENTS_ENDPOINT="https://api.vercel.com/v6/deployments"
DELETE_DEPLOYMENTS_ENDPOINT="https://api.vercel.com/v13/deployments"
# Create a list of deployments.
# deployments=$(curl -s -X GET "$GET_DEPLOYMENTS_ENDPOINT/?projectId=$VERCEL_PROJECT_ID&teamId=$VERCEL_ORG_ID" -H "Authorization: Bearer $VERCEL_TOKEN ")
deployments=$(curl -s -X GET "$GET_DEPLOYMENTS_ENDPOINT/?projectId=$VERCEL_PROJECT_ID" -H "Authorization: Bearer $VERCEL_TOKEN ")
# Filter the deployments list by meta.base_hash === meta tag.
filtered_deployments=$(echo $deployments | jq --arg META_TAG "$META_TAG" '[.deployments[] | select(.meta.base_hash | type == "string" and contains($META_TAG)) | .uid] | join(",")')
filtered_deployments="${filtered_deployments//\"/}" # Remove double quotes
# Clears the values from filtered_deployments
IFS=',' read -ra values <<<"$filtered_deployments"
echo "META_TAG ${META_TAG}"
echo "Filtered deployments ${filtered_deployments}"
# Iterate over the filtered deployments list.
for uid in "${values[@]}"; do
echo "Deleting ${uid}"
delete_url=${DELETE_DEPLOYMENTS_ENDPOINT}/${uid}
echo $delete_url
# Make DELETE a request to the /v13/deployments/{id} endpoint.
curl -X DELETE $delete_url -H "Authorization: Bearer $VERCEL_TOKEN"
echo "Deleted!"
done

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 82 KiB

View File

@@ -1275,6 +1275,13 @@
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.9.tgz#0c2758164cccd61bc5a1c6cd8284fe66173e4a2b"
integrity sha512-QbT03FXRNdpuL+e9pLnu+XajZdm/TtIXVYY4lA9t+9l0fLZbHXDYEKitAqxrOj37o3Vx5ufxiRAniaIebYDCgw==
"@next/third-parties@^14.1.0":
version "14.1.0"
resolved "https://registry.yarnpkg.com/@next/third-parties/-/third-parties-14.1.0.tgz#d9604fff8880e05d3804d2cf7ab42eb5430aec69"
integrity sha512-f55SdvQ1WWxi4mb5QqtYQh5wRzbm1XaeP7s39DPn4ks3re+n9VlFccbMxBRHqkE62zAyIKmvkUB2cByT/gugGA==
dependencies:
third-party-capital "1.0.20"
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
@@ -1704,6 +1711,11 @@
resolved "https://registry.yarnpkg.com/@vercel/analytics/-/analytics-0.1.11.tgz#727a0ac655a4a89104cdea3e6925476470299428"
integrity sha512-mj5CPR02y0BRs1tN3oZcBNAX9a8NxsIUl9vElDPcqxnMfP0RbRc9fI9Ud7+QDg/1Izvt5uMumsr+6YsmVHcyuw==
"@vercel/speed-insights@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@vercel/speed-insights/-/speed-insights-1.0.2.tgz#1bebf3e7c7046b6a911721233b263b69214ddb3e"
integrity sha512-y5HWeB6RmlyVYxJAMrjiDEz8qAIy2cit0fhBq+MD78WaUwQvuBnQlX4+5MuwVTWi46bV3klaRMq83u9zUy1KOg==
"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5":
version "1.11.6"
resolved "https://registry.npmmirror.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24"
@@ -5775,6 +5787,11 @@ text-table@^0.2.0:
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
third-party-capital@1.0.20:
version "1.0.20"
resolved "https://registry.yarnpkg.com/third-party-capital/-/third-party-capital-1.0.20.tgz#e218a929a35bf4d2245da9addb8ab978d2f41685"
integrity sha512-oB7yIimd8SuGptespDAZnNkzIz+NWaJCu2RMsbs4Wmp9zSDUM8Nhi3s2OOcqYuv3mN4hitXc8DVx+LyUmbUDiA==
through@^2.3.8:
version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"