diff --git a/src/app.tsx b/src/app.tsx
index df7e5a7..c1870f1 100644
--- a/src/app.tsx
+++ b/src/app.tsx
@@ -43,7 +43,11 @@ export interface ChatStore {
develop_mode: boolean;
whisper_api: string;
whisper_key: string;
- audioDeviceID: string;
+ tts_api: string;
+ tts_key: string;
+ tts_voice: string;
+ tts_speed: number;
+ tts_speed_enabled: boolean;
}
const _defaultAPIEndpoint = "https://api.openai.com/v1/chat/completions";
@@ -56,7 +60,11 @@ const newChatStore = (
temperature = 0.7,
dev = false,
whisper_api = "",
- whisper_key = ""
+ whisper_key = "",
+ tts_api = "",
+ tts_key = "",
+ tts_speed = 1.0,
+ tts_speed_enabled = false
): ChatStore => {
return {
chatgpt_api_web_version: CHATGPT_API_WEB_VERSION,
@@ -81,7 +89,11 @@ const newChatStore = (
develop_mode: getDefaultParams("dev", dev),
whisper_api: getDefaultParams("whisper-api", whisper_api),
whisper_key: getDefaultParams("whisper-key", whisper_key),
- audioDeviceID: "",
+ tts_api: getDefaultParams("tts-api", tts_api),
+ tts_key: getDefaultParams("tts-key", tts_key),
+ tts_voice: "alloy",
+ tts_speed: tts_speed,
+ tts_speed_enabled: tts_speed_enabled,
};
};
@@ -215,7 +227,11 @@ export function App() {
chatStore.temperature,
!!chatStore.develop_mode,
chatStore.whisper_api,
- chatStore.whisper_key
+ chatStore.whisper_key,
+ chatStore.tts_api,
+ chatStore.tts_key,
+ chatStore.tts_speed,
+ chatStore.tts_speed_enabled
)
)
);
@@ -296,7 +312,15 @@ export function App() {
chatStore.systemMessageContent,
chatStore.apiEndpoint,
chatStore.streamMode,
- chatStore.model
+ chatStore.model,
+ chatStore.temperature,
+ !!chatStore.develop_mode,
+ chatStore.whisper_api,
+ chatStore.whisper_key,
+ chatStore.tts_api,
+ chatStore.tts_key,
+ chatStore.tts_speed,
+ chatStore.tts_speed_enabled
)
);
}
diff --git a/src/message.tsx b/src/message.tsx
index 0baec80..3779cd4 100644
--- a/src/message.tsx
+++ b/src/message.tsx
@@ -3,6 +3,7 @@ import { useState, useEffect, StateUpdater } from "preact/hooks";
import { ChatStore, ChatStoreMessage } from "./app";
import { calculate_token_length } from "./chatgpt";
import Markdown from "preact-markdown";
+import TTSButton from "./tts";
interface EditMessageProps {
chat: ChatStoreMessage;
@@ -163,6 +164,13 @@ export default function Message(props: Props) {
+ {chatStore.tts_api && chatStore.tts_key && (
+
+ )}
diff --git a/src/settings.tsx b/src/settings.tsx
index ecd9cb6..b35c6b0 100644
--- a/src/settings.tsx
+++ b/src/settings.tsx
@@ -6,6 +6,15 @@ import { TemplateChatStore } from "./chatbox";
import { tr, Tr, langCodeContext, LANG_OPTIONS } from "./translate";
import p from "preact-markdown";
+const TTS_VOICES: string[] = [
+ "alloy",
+ "echo",
+ "fable",
+ "onyx",
+ "nova",
+ "shimmer",
+];
+
const Help = (props: { children: any; help: string }) => {
return (
@@ -71,7 +80,13 @@ const LongInput = (props: {
const Input = (props: {
chatStore: ChatStore;
setChatStore: (cs: ChatStore) => void;
- field: "apiKey" | "apiEndpoint" | "whisper_api" | "whisper_key";
+ field:
+ | "apiKey"
+ | "apiEndpoint"
+ | "whisper_api"
+ | "whisper_key"
+ | "tts_api"
+ | "tts_key";
help: string;
}) => {
const [hideInput, setHideInput] = useState(true);
@@ -101,8 +116,10 @@ const Input = (props: {
const Slicer = (props: {
chatStore: ChatStore;
setChatStore: (cs: ChatStore) => void;
- field: "temperature" | "top_p";
+ field: "temperature" | "top_p" | "tts_speed";
help: string;
+ min: number;
+ max: number;
}) => {
const enable_filed_name: "temperature_enabled" | "top_p_enabled" =
`${props.field}_enabled` as any;
@@ -139,8 +156,8 @@ const Slicer = (props: {
disabled={!enabled}
className="m-2 p-2 border rounded focus w-28"
type="range"
- min="0"
- max="1"
+ min={props.min}
+ max={props.max}
step="0.01"
value={props.chatStore[props.field]}
onChange={(event: any) => {
@@ -387,8 +404,8 @@ export default (props: {
readOnly={true}
{...props}
/>
-
-
+
+
-
+
+
-
-
- {devices.length === 0 && (
-
- )}
- {devices.length > 0 && (
-
- )}
-
+
+
+
+
+
+
+
diff --git a/src/tts.tsx b/src/tts.tsx
new file mode 100644
index 0000000..bbfe79e
--- /dev/null
+++ b/src/tts.tsx
@@ -0,0 +1,53 @@
+import { ChatStore, addTotalCost } from "./app";
+
+interface TTSProps {
+ chatStore: ChatStore;
+ setChatStore: (cs: ChatStore) => void;
+ text: string;
+}
+export default function TTSButton(props: TTSProps) {
+ return (
+
+ );
+}