Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
399 changes: 347 additions & 52 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"lodash": "^4.17.21",
"nanoid": "^4.0.1",
"next": "13.2.4",
"openai": "^3.2.1",
"openai": "^4.28.4",
"openai-ext": "^1.2.6",
"prism-react-renderer": "^1.3.1",
"prismjs": "^1.29.0",
Expand Down
4 changes: 2 additions & 2 deletions src/components/ChatItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ export function ChatItem({ chat, isActive }: { chat: Chat, isActive: boolean })
chat.pinned = !chat.pinned;
});
} catch (error: any) {
if (error.toJSON().message === "Network Error") {
const message = error.message;
if (message === "Network Error") {
notifications.show({
title: "Error",
color: "red",
message: "No internet connection.",
});
}
const message = error.response?.data?.error?.message;
if (message) {
notifications.show({
title: "Error",
Expand Down
4 changes: 2 additions & 2 deletions src/components/CreatePromptModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ export function CreatePromptModal({ content }: { content?: string }) {
});
close();
} catch (error: any) {
if (error.toJSON().message === "Network Error") {
const message = error.message;
if (message === "Network Error") {
notifications.show({
title: "Error",
color: "red",
message: "No internet connection.",
});
}
const message = error.response?.data?.error?.message;
if (message) {
notifications.show({
title: "Error",
Expand Down
2 changes: 1 addition & 1 deletion src/components/DeleteChatModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export function DeleteChatModal({
message: "Chat deleted.",
});
} catch (error: any) {
if (error.toJSON().message === "Network Error") {
if (error.message === "Network Error") {
notifications.show({
title: "Error",
color: "red",
Expand Down
2 changes: 1 addition & 1 deletion src/components/DeletePromptModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function DeletePromptModal({ prompt }: { prompt: Prompt }) {
message: "Chat deleted.",
});
} catch (error: any) {
if (error.toJSON().message === "Network Error") {
if (error.message === "Network Error") {
notifications.show({
title: "Error",
color: "red",
Expand Down
4 changes: 2 additions & 2 deletions src/components/EditChatModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ export function EditChatModal({
});
close();
} catch (error: any) {
if (error.toJSON().message === "Network Error") {
if (error.message === "Network Error") {
notifications.show({
title: "Error",
color: "red",
message: "No internet connection.",
});
}
const message = error.response?.data?.error?.message;
const message = error.message;
if (message) {
notifications.show({
title: "Error",
Expand Down
4 changes: 2 additions & 2 deletions src/components/EditPromptModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ export function EditPromptModal({ prompt }: { prompt: Prompt }) {
message: "Prompt updated",
});
} catch (error: any) {
if (error.toJSON().message === "Network Error") {
if (error.message === "Network Error") {
notifications.show({
title: "Error",
color: "red",
message: "No internet connection.",
});
}
const message = error.response?.data?.error?.message;
const message = error.message;
if (message) {
notifications.show({
title: "Error",
Expand Down
22 changes: 11 additions & 11 deletions src/components/SettingsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,14 @@ export function SettingsModal({ children }: { children: ReactElement }) {
message: "Your OpenAI Key has been saved.",
});
} catch (error: any) {
if (error.toJSON().message === "Network Error") {
const message = error.message;
if (message === "Network Error") {
notifications.show({
title: "Error",
color: "red",
message: "No internet connection.",
});
}
const message = error.response?.data?.error?.message;
if (message) {
notifications.show({
title: "Error",
Expand Down Expand Up @@ -141,7 +141,7 @@ export function SettingsModal({ children }: { children: ReactElement }) {
message: "Your OpenAI Type has been saved.",
});
} catch (error: any) {
if (error.toJSON().message === "Network Error") {
if (error.message === "Network Error") {
notifications.show({
title: "Error",
color: "red",
Expand Down Expand Up @@ -177,14 +177,14 @@ export function SettingsModal({ children }: { children: ReactElement }) {
message: "Your OpenAI Model has been saved.",
});
} catch (error: any) {
if (error.toJSON().message === "Network Error") {
if (error.message === "Network Error") {
notifications.show({
title: "Error",
color: "red",
message: "No internet connection.",
});
}
const message = error.response?.data?.error?.message;
const message = error.message;
if (message) {
notifications.show({
title: "Error",
Expand Down Expand Up @@ -217,14 +217,14 @@ export function SettingsModal({ children }: { children: ReactElement }) {
message: "Your OpenAI Auth has been saved.",
});
} catch (error: any) {
if (error.toJSON().message === "Network Error") {
if (error.message === "Network Error") {
notifications.show({
title: "Error",
color: "red",
message: "No internet connection.",
});
}
const message = error.response?.data?.error?.message;
const message = error.message;
if (message) {
notifications.show({
title: "Error",
Expand Down Expand Up @@ -253,14 +253,14 @@ export function SettingsModal({ children }: { children: ReactElement }) {
message: "Your OpenAI Base has been saved.",
});
} catch (error: any) {
if (error.toJSON().message === "Network Error") {
if (error.message === "Network Error") {
notifications.show({
title: "Error",
color: "red",
message: "No internet connection.",
});
}
const message = error.response?.data?.error?.message;
const message = error.message;
if (message) {
notifications.show({
title: "Error",
Expand Down Expand Up @@ -301,14 +301,14 @@ export function SettingsModal({ children }: { children: ReactElement }) {
message: "Your OpenAI Version has been saved.",
});
} catch (error: any) {
if (error.toJSON().message === "Network Error") {
if (error.message === "Network Error") {
notifications.show({
title: "Error",
color: "red",
message: "No internet connection.",
});
}
const message = error.response?.data?.error?.message;
const message = error.message;
if (message) {
notifications.show({
title: "Error",
Expand Down
19 changes: 11 additions & 8 deletions src/routes/ChatRoute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ export function ChatRoute() {
if (!chatId) return [];
return db.messages.where("chatId").equals(chatId).sortBy("createdAt");
}, [chatId]);
const baseUrl = useLiveQuery(async () => {
return (await db.settings.where({ id: "general" }).first())?.openAiApiBase;
});
const userMessages =
messages
?.filter((message) => message.role === "user")
Expand Down Expand Up @@ -159,29 +162,29 @@ export function ChatRoute() {
},
]);
const chatDescription =
createChatDescription.data.choices[0].message?.content;
createChatDescription.choices[0].message?.content;

if (createChatDescription.data.usage) {
if (createChatDescription.usage) {
await db.chats.where({ id: chatId }).modify((chat) => {
chat.description = chatDescription ?? "New Chat";
if (chat.totalTokens) {
chat.totalTokens +=
createChatDescription.data.usage!.total_tokens;
createChatDescription.usage!.total_tokens;
} else {
chat.totalTokens = createChatDescription.data.usage!.total_tokens;
chat.totalTokens = createChatDescription.usage!.total_tokens;
}
});
}
}
} catch (error: any) {
if (error.toJSON().message === "Network Error") {
if (error.message === "Network Error") {
notifications.show({
title: "Error",
color: "red",
message: "No internet connection.",
});
}
const message = error.response?.data?.error?.message;
const message = error.message;
if (message) {
notifications.show({
title: "Error",
Expand Down Expand Up @@ -288,14 +291,14 @@ export function ChatRoute() {
message: "Your OpenAI Model has been saved.",
});
} catch (error: any) {
if (error.toJSON().message === "Network Error") {
if (error.message === "Network Error") {
notifications.show({
title: "Error",
color: "red",
message: "No internet connection.",
});
}
const message = error.response?.data?.error?.message;
const message = error.message;
if (message) {
notifications.show({
title: "Error",
Expand Down
80 changes: 37 additions & 43 deletions src/utils/openai.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,52 @@
import { encode } from "gpt-token-utils";
import { ChatCompletionRequestMessage, Configuration, OpenAIApi } from "openai";
import { OpenAIExt } from "openai-ext";
import OpenAI from 'openai';
import { db } from "../db";
import { config } from "./config";

function getClient(
apiKey: string,
apiType: string,
apiAuth: string,
basePath: string
) {
const configuration = new Configuration({
...((apiType === "openai" ||
(apiType === "custom" && apiAuth === "bearer-token")) && {
function getClient(apiKey: string, apiType: string, apiAuth: string, basePath: string, version: string) {
var openai
if (apiType === "openai" || (apiType === "custom" && apiAuth === "bearer-token")) {
openai = new OpenAI({apiKey: apiKey, dangerouslyAllowBrowser: true});
}
else {
openai = new OpenAI({
apiKey: apiKey,
}),
...(apiType === "custom" && { basePath: basePath }),
});
return new OpenAIApi(configuration);
baseURL: basePath,
dangerouslyAllowBrowser: true,
defaultQuery: { 'api-version': version },
defaultHeaders: { 'api-key': apiKey }
});
}
return openai;
}

export async function createStreamChatCompletion(
apiKey: string,
messages: ChatCompletionRequestMessage[],
messages: Array<{ role: string; content: string; }>,
chatId: string,
messageId: string
) {
const settings = await db.settings.get("general");
const type = settings?.openAiApiType ?? config.defaultType;
const auth = settings?.openAiApiAuth ?? config.defaultAuth;
const base = settings?.openAiApiBase ?? config.defaultBase;
const version = settings?.openAiApiVersion ?? config.defaultVersion;
const model = settings?.openAiModel ?? config.defaultModel;
const client = getClient(apiKey, type, auth, base, version);
const stream = await client.beta.chat.completions.stream({
model: 'gpt-4',
messages,
stream: true,
});
var full = "";
stream.on('content', (delta, snapshot) => {
full += delta;
setStreamContent(messageId, full, false);
});

return OpenAIExt.streamClientChatCompletion(
{
model,
messages,
},
{
apiKey: apiKey,
handler: {
onContent(content, isFinal, stream) {
setStreamContent(messageId, content, isFinal);
if (isFinal) {
setTotalTokens(chatId, content);
}
},
onDone(stream) {},
onError(error, stream) {
console.error(error);
},
},
}
);
const chatCompletion = await stream.finalChatCompletion();
setStreamContent(messageId, full, true);
setTotalTokens(chatId, full);
}

function setStreamContent(
Expand All @@ -72,19 +69,16 @@ function setTotalTokens(chatId: string, content: string) {
});
}

export async function createChatCompletion(
apiKey: string,
messages: ChatCompletionRequestMessage[]
) {
export async function createChatCompletion(apiKey: string, messages: Array<{ role: string; content: string; }>) {
const settings = await db.settings.get("general");
const model = settings?.openAiModel ?? config.defaultModel;
const type = settings?.openAiApiType ?? config.defaultType;
const auth = settings?.openAiApiAuth ?? config.defaultAuth;
const base = settings?.openAiApiBase ?? config.defaultBase;
const version = settings?.openAiApiVersion ?? config.defaultVersion;

const client = getClient(apiKey, type, auth, base);
return client.createChatCompletion(
const client = getClient(apiKey, type, auth, base, version);
return client.chat.completions.create(
{
model,
stream: false,
Expand Down
Loading