mirror of
https://github.com/usememos/memos.git
synced 2025-06-05 22:09:59 +02:00
refactor: openAI config system setting (#1333)
This commit is contained in:
@ -19,6 +19,4 @@ type SystemStatus struct {
|
||||
// Customized server profile, including server name and external url.
|
||||
CustomizedProfile CustomizedProfile `json:"customizedProfile"`
|
||||
StorageServiceID int `json:"storageServiceId"`
|
||||
// OpenAI API Host
|
||||
OpenAIAPIHost string `json:"openAIApiHost"`
|
||||
}
|
||||
|
@ -27,10 +27,8 @@ const (
|
||||
SystemSettingCustomizedProfileName SystemSettingName = "customizedProfile"
|
||||
// SystemSettingStorageServiceIDName is the key type of storage service ID.
|
||||
SystemSettingStorageServiceIDName SystemSettingName = "storageServiceId"
|
||||
// SystemSettingOpenAIAPIKeyName is the key type of OpenAI API key.
|
||||
SystemSettingOpenAIAPIKeyName SystemSettingName = "openAIApiKey"
|
||||
// SystemSettingOpenAIAPIHost is the key type of OpenAI API path.
|
||||
SystemSettingOpenAIAPIHost SystemSettingName = "openAIApiHost"
|
||||
// SystemSettingOpenAIConfigName is the key type of OpenAI config.
|
||||
SystemSettingOpenAIConfigName SystemSettingName = "openAIConfig"
|
||||
)
|
||||
|
||||
// CustomizedProfile is the struct definition for SystemSettingCustomizedProfileName system setting item.
|
||||
@ -49,6 +47,11 @@ type CustomizedProfile struct {
|
||||
ExternalURL string `json:"externalUrl"`
|
||||
}
|
||||
|
||||
type OpenAIConfig struct {
|
||||
Key string `json:"key"`
|
||||
Host string `json:"host"`
|
||||
}
|
||||
|
||||
func (key SystemSettingName) String() string {
|
||||
switch key {
|
||||
case SystemSettingServerID:
|
||||
@ -67,24 +70,17 @@ func (key SystemSettingName) String() string {
|
||||
return "customizedProfile"
|
||||
case SystemSettingStorageServiceIDName:
|
||||
return "storageServiceId"
|
||||
case SystemSettingOpenAIAPIKeyName:
|
||||
return "openAIApiKey"
|
||||
case SystemSettingOpenAIAPIHost:
|
||||
return "openAIApiHost"
|
||||
case SystemSettingOpenAIConfigName:
|
||||
return "openAIConfig"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var (
|
||||
SystemSettingAllowSignUpValue = []bool{true, false}
|
||||
SystemSettingDisablePublicMemosValue = []bool{true, false}
|
||||
)
|
||||
|
||||
type SystemSetting struct {
|
||||
Name SystemSettingName
|
||||
Name SystemSettingName `json:"name"`
|
||||
// Value is a JSON string with basic value.
|
||||
Value string
|
||||
Description string
|
||||
Value string `json:"value"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type SystemSettingUpsert struct {
|
||||
@ -102,35 +98,12 @@ func (upsert SystemSettingUpsert) Validate() error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unmarshal system setting allow signup value")
|
||||
}
|
||||
|
||||
invalid := true
|
||||
for _, v := range SystemSettingAllowSignUpValue {
|
||||
if value == v {
|
||||
invalid = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if invalid {
|
||||
return fmt.Errorf("invalid system setting allow signup value")
|
||||
}
|
||||
} else if upsert.Name == SystemSettingDisablePublicMemosName {
|
||||
value := false
|
||||
err := json.Unmarshal([]byte(upsert.Value), &value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unmarshal system setting disable public memos value")
|
||||
}
|
||||
|
||||
invalid := true
|
||||
for _, v := range SystemSettingDisablePublicMemosValue {
|
||||
if value == v {
|
||||
invalid = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if invalid {
|
||||
return fmt.Errorf("invalid system setting disable public memos value")
|
||||
}
|
||||
} else if upsert.Name == SystemSettingAdditionalStyleName {
|
||||
value := ""
|
||||
err := json.Unmarshal([]byte(upsert.Value), &value)
|
||||
@ -169,17 +142,11 @@ func (upsert SystemSettingUpsert) Validate() error {
|
||||
return fmt.Errorf("failed to unmarshal system setting storage service id value")
|
||||
}
|
||||
return nil
|
||||
} else if upsert.Name == SystemSettingOpenAIAPIKeyName {
|
||||
value := ""
|
||||
} else if upsert.Name == SystemSettingOpenAIConfigName {
|
||||
value := OpenAIConfig{}
|
||||
err := json.Unmarshal([]byte(upsert.Value), &value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unmarshal system setting openai api key value")
|
||||
}
|
||||
} else if upsert.Name == SystemSettingOpenAIAPIHost {
|
||||
value := ""
|
||||
err := json.Unmarshal([]byte(upsert.Value), &value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unmarshal system setting openai api host value")
|
||||
return fmt.Errorf("failed to unmarshal system setting openai api config value")
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("invalid system setting name")
|
||||
|
@ -13,39 +13,24 @@ import (
|
||||
func (s *Server) registerOpenAIRoutes(g *echo.Group) {
|
||||
g.POST("/openai/chat-completion", func(c echo.Context) error {
|
||||
ctx := c.Request().Context()
|
||||
openAIApiKeySetting, err := s.Store.FindSystemSetting(ctx, &api.SystemSettingFind{
|
||||
Name: api.SystemSettingOpenAIAPIKeyName,
|
||||
openAIConfigSetting, err := s.Store.FindSystemSetting(ctx, &api.SystemSettingFind{
|
||||
Name: api.SystemSettingOpenAIConfigName,
|
||||
})
|
||||
if err != nil && common.ErrorCode(err) != common.NotFound {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find openai api key").SetInternal(err)
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find openai key").SetInternal(err)
|
||||
}
|
||||
|
||||
openAIApiHostSetting, err := s.Store.FindSystemSetting(ctx, &api.SystemSettingFind{
|
||||
Name: api.SystemSettingOpenAIAPIHost,
|
||||
})
|
||||
if err != nil && common.ErrorCode(err) != common.NotFound {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find openai api host").SetInternal(err)
|
||||
}
|
||||
|
||||
openAIApiKey := ""
|
||||
if openAIApiKeySetting != nil {
|
||||
err = json.Unmarshal([]byte(openAIApiKeySetting.Value), &openAIApiKey)
|
||||
openAIConfig := api.OpenAIConfig{}
|
||||
if openAIConfigSetting != nil {
|
||||
err = json.Unmarshal([]byte(openAIConfigSetting.Value), &openAIConfig)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to unmarshal system setting value").SetInternal(err)
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to unmarshal openai system setting value").SetInternal(err)
|
||||
}
|
||||
}
|
||||
if openAIApiKey == "" {
|
||||
if openAIConfig.Key == "" {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "OpenAI API key not set")
|
||||
}
|
||||
|
||||
openAIApiHost := ""
|
||||
if openAIApiHostSetting != nil {
|
||||
err = json.Unmarshal([]byte(openAIApiHostSetting.Value), &openAIApiHost)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to unmarshal system setting value").SetInternal(err)
|
||||
}
|
||||
}
|
||||
|
||||
completionRequest := api.OpenAICompletionRequest{}
|
||||
if err := json.NewDecoder(c.Request().Body).Decode(&completionRequest); err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted post chat completion request").SetInternal(err)
|
||||
@ -54,7 +39,7 @@ func (s *Server) registerOpenAIRoutes(g *echo.Group) {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "Prompt is required")
|
||||
}
|
||||
|
||||
result, err := openai.PostChatCompletion(completionRequest.Prompt, openAIApiKey, openAIApiHost)
|
||||
result, err := openai.PostChatCompletion(completionRequest.Prompt, openAIConfig.Key, openAIConfig.Host)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to post chat completion").SetInternal(err)
|
||||
}
|
||||
@ -64,39 +49,24 @@ func (s *Server) registerOpenAIRoutes(g *echo.Group) {
|
||||
|
||||
g.POST("/openai/text-completion", func(c echo.Context) error {
|
||||
ctx := c.Request().Context()
|
||||
openAIApiKeySetting, err := s.Store.FindSystemSetting(ctx, &api.SystemSettingFind{
|
||||
Name: api.SystemSettingOpenAIAPIKeyName,
|
||||
openAIConfigSetting, err := s.Store.FindSystemSetting(ctx, &api.SystemSettingFind{
|
||||
Name: api.SystemSettingOpenAIConfigName,
|
||||
})
|
||||
if err != nil && common.ErrorCode(err) != common.NotFound {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find openai api key").SetInternal(err)
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find openai key").SetInternal(err)
|
||||
}
|
||||
|
||||
openAIApiHostSetting, err := s.Store.FindSystemSetting(ctx, &api.SystemSettingFind{
|
||||
Name: api.SystemSettingOpenAIAPIHost,
|
||||
})
|
||||
if err != nil && common.ErrorCode(err) != common.NotFound {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find openai api host").SetInternal(err)
|
||||
}
|
||||
|
||||
openAIApiKey := ""
|
||||
if openAIApiKeySetting != nil {
|
||||
err = json.Unmarshal([]byte(openAIApiKeySetting.Value), &openAIApiKey)
|
||||
openAIConfig := api.OpenAIConfig{}
|
||||
if openAIConfigSetting != nil {
|
||||
err = json.Unmarshal([]byte(openAIConfigSetting.Value), &openAIConfig)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to unmarshal system setting value").SetInternal(err)
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to unmarshal openai system setting value").SetInternal(err)
|
||||
}
|
||||
}
|
||||
if openAIApiKey == "" {
|
||||
if openAIConfig.Key == "" {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "OpenAI API key not set")
|
||||
}
|
||||
|
||||
openAIApiHost := ""
|
||||
if openAIApiHostSetting != nil {
|
||||
err = json.Unmarshal([]byte(openAIApiHostSetting.Value), &openAIApiHost)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to unmarshal system setting value").SetInternal(err)
|
||||
}
|
||||
}
|
||||
|
||||
textCompletion := api.OpenAICompletionRequest{}
|
||||
if err := json.NewDecoder(c.Request().Body).Decode(&textCompletion); err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted post text completion request").SetInternal(err)
|
||||
@ -105,7 +75,7 @@ func (s *Server) registerOpenAIRoutes(g *echo.Group) {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "Prompt is required")
|
||||
}
|
||||
|
||||
result, err := openai.PostTextCompletion(textCompletion.Prompt, openAIApiKey, openAIApiHost)
|
||||
result, err := openai.PostTextCompletion(textCompletion.Prompt, openAIConfig.Key, openAIConfig.Host)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to post text completion").SetInternal(err)
|
||||
}
|
||||
@ -115,21 +85,24 @@ func (s *Server) registerOpenAIRoutes(g *echo.Group) {
|
||||
|
||||
g.GET("/openai/enabled", func(c echo.Context) error {
|
||||
ctx := c.Request().Context()
|
||||
openAIApiKeySetting, err := s.Store.FindSystemSetting(ctx, &api.SystemSettingFind{
|
||||
Name: api.SystemSettingOpenAIAPIKeyName,
|
||||
openAIConfigSetting, err := s.Store.FindSystemSetting(ctx, &api.SystemSettingFind{
|
||||
Name: api.SystemSettingOpenAIConfigName,
|
||||
})
|
||||
if err != nil && common.ErrorCode(err) != common.NotFound {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find openai api key").SetInternal(err)
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find openai key").SetInternal(err)
|
||||
}
|
||||
|
||||
openAIApiKey := ""
|
||||
if openAIApiKeySetting != nil {
|
||||
err = json.Unmarshal([]byte(openAIApiKeySetting.Value), &openAIApiKey)
|
||||
openAIConfig := api.OpenAIConfig{}
|
||||
if openAIConfigSetting != nil {
|
||||
err = json.Unmarshal([]byte(openAIConfigSetting.Value), &openAIConfig)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to unmarshal system setting value").SetInternal(err)
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to unmarshal openai system setting value").SetInternal(err)
|
||||
}
|
||||
}
|
||||
if openAIConfig.Key == "" {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "OpenAI API key not set")
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, composeResponse(openAIApiKey != ""))
|
||||
return c.JSON(http.StatusOK, composeResponse(openAIConfig.Key != ""))
|
||||
})
|
||||
}
|
||||
|
@ -52,7 +52,6 @@ func (s *Server) registerSystemRoutes(g *echo.Group) {
|
||||
ExternalURL: "",
|
||||
},
|
||||
StorageServiceID: 0,
|
||||
OpenAIAPIHost: "",
|
||||
}
|
||||
|
||||
systemSettingList, err := s.Store.FindSystemSettingList(ctx, &api.SystemSettingFind{})
|
||||
@ -60,49 +59,33 @@ func (s *Server) registerSystemRoutes(g *echo.Group) {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find system setting list").SetInternal(err)
|
||||
}
|
||||
for _, systemSetting := range systemSettingList {
|
||||
if systemSetting.Name == api.SystemSettingServerID || systemSetting.Name == api.SystemSettingSecretSessionName || systemSetting.Name == api.SystemSettingOpenAIAPIKeyName {
|
||||
if systemSetting.Name == api.SystemSettingServerID || systemSetting.Name == api.SystemSettingSecretSessionName || systemSetting.Name == api.SystemSettingOpenAIConfigName {
|
||||
continue
|
||||
}
|
||||
|
||||
var value interface{}
|
||||
err := json.Unmarshal([]byte(systemSetting.Value), &value)
|
||||
var baseValue interface{}
|
||||
err := json.Unmarshal([]byte(systemSetting.Value), &baseValue)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to unmarshal system setting value").SetInternal(err)
|
||||
}
|
||||
|
||||
if systemSetting.Name == api.SystemSettingAllowSignUpName {
|
||||
systemStatus.AllowSignUp = value.(bool)
|
||||
systemStatus.AllowSignUp = baseValue.(bool)
|
||||
} else if systemSetting.Name == api.SystemSettingDisablePublicMemosName {
|
||||
systemStatus.DisablePublicMemos = value.(bool)
|
||||
systemStatus.DisablePublicMemos = baseValue.(bool)
|
||||
} else if systemSetting.Name == api.SystemSettingAdditionalStyleName {
|
||||
systemStatus.AdditionalStyle = value.(string)
|
||||
systemStatus.AdditionalStyle = baseValue.(string)
|
||||
} else if systemSetting.Name == api.SystemSettingAdditionalScriptName {
|
||||
systemStatus.AdditionalScript = value.(string)
|
||||
systemStatus.AdditionalScript = baseValue.(string)
|
||||
} else if systemSetting.Name == api.SystemSettingCustomizedProfileName {
|
||||
valueMap := value.(map[string]interface{})
|
||||
systemStatus.CustomizedProfile = api.CustomizedProfile{}
|
||||
if v := valueMap["name"]; v != nil {
|
||||
systemStatus.CustomizedProfile.Name = v.(string)
|
||||
}
|
||||
if v := valueMap["logoUrl"]; v != nil {
|
||||
systemStatus.CustomizedProfile.LogoURL = v.(string)
|
||||
}
|
||||
if v := valueMap["description"]; v != nil {
|
||||
systemStatus.CustomizedProfile.Description = v.(string)
|
||||
}
|
||||
if v := valueMap["locale"]; v != nil {
|
||||
systemStatus.CustomizedProfile.Locale = v.(string)
|
||||
}
|
||||
if v := valueMap["appearance"]; v != nil {
|
||||
systemStatus.CustomizedProfile.Appearance = v.(string)
|
||||
}
|
||||
if v := valueMap["externalUrl"]; v != nil {
|
||||
systemStatus.CustomizedProfile.ExternalURL = v.(string)
|
||||
customizedProfile := api.CustomizedProfile{}
|
||||
err := json.Unmarshal([]byte(systemSetting.Value), &customizedProfile)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to unmarshal system setting customized profile value").SetInternal(err)
|
||||
}
|
||||
systemStatus.CustomizedProfile = customizedProfile
|
||||
} else if systemSetting.Name == api.SystemSettingStorageServiceIDName {
|
||||
systemStatus.StorageServiceID = int(value.(float64))
|
||||
} else if systemSetting.Name == api.SystemSettingOpenAIAPIHost {
|
||||
systemStatus.OpenAIAPIHost = value.(string)
|
||||
systemStatus.StorageServiceID = int(baseValue.(float64))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,16 +5,12 @@ import { Button, Divider, Input, Switch, Textarea } from "@mui/joy";
|
||||
import { useGlobalStore } from "../../store/module";
|
||||
import * as api from "../../helpers/api";
|
||||
import showUpdateCustomizedProfileDialog from "../UpdateCustomizedProfileDialog";
|
||||
import { useAppDispatch } from "../../store";
|
||||
import { setGlobalState } from "../../store/reducer/global";
|
||||
import "@/less/settings/system-section.less";
|
||||
|
||||
interface State {
|
||||
dbSize: number;
|
||||
allowSignUp: boolean;
|
||||
disablePublicMemos: boolean;
|
||||
openAIApiKey: string;
|
||||
openAIApiHost: string;
|
||||
additionalStyle: string;
|
||||
additionalScript: string;
|
||||
}
|
||||
@ -36,13 +32,13 @@ const SystemSection = () => {
|
||||
dbSize: systemStatus.dbSize,
|
||||
allowSignUp: systemStatus.allowSignUp,
|
||||
additionalStyle: systemStatus.additionalStyle,
|
||||
openAIApiKey: "",
|
||||
openAIApiHost: systemStatus.openAIApiHost,
|
||||
additionalScript: systemStatus.additionalScript,
|
||||
disablePublicMemos: systemStatus.disablePublicMemos,
|
||||
});
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const [openAIConfig, setOpenAIConfig] = useState<OpenAIConfig>({
|
||||
key: "",
|
||||
host: "",
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
globalStore.fetchSystemStatus();
|
||||
@ -50,16 +46,24 @@ const SystemSection = () => {
|
||||
|
||||
useEffect(() => {
|
||||
setState({
|
||||
...state,
|
||||
dbSize: systemStatus.dbSize,
|
||||
allowSignUp: systemStatus.allowSignUp,
|
||||
additionalStyle: systemStatus.additionalStyle,
|
||||
openAIApiKey: "",
|
||||
openAIApiHost: systemStatus.openAIApiHost,
|
||||
additionalScript: systemStatus.additionalScript,
|
||||
disablePublicMemos: systemStatus.disablePublicMemos,
|
||||
});
|
||||
}, [systemStatus]);
|
||||
|
||||
useEffect(() => {
|
||||
api.getSystemSetting().then(({ data: { data: systemSettings } }) => {
|
||||
const openAIConfigSetting = systemSettings.find((setting) => setting.name === "openAIConfig");
|
||||
if (openAIConfigSetting) {
|
||||
setOpenAIConfig(JSON.parse(openAIConfigSetting.value));
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
const handleAllowSignUpChanged = async (value: boolean) => {
|
||||
setState({
|
||||
...state,
|
||||
@ -86,46 +90,33 @@ const SystemSection = () => {
|
||||
toast.success(t("message.succeed-vacuum-database"));
|
||||
};
|
||||
|
||||
const handleOpenAIApiKeyChanged = (value: string) => {
|
||||
setState({
|
||||
...state,
|
||||
openAIApiKey: value,
|
||||
const handleOpenAIConfigKeyChanged = (value: string) => {
|
||||
setOpenAIConfig({
|
||||
...openAIConfig,
|
||||
key: value,
|
||||
});
|
||||
};
|
||||
|
||||
const handleSaveOpenAIApiKey = async () => {
|
||||
const handleSaveOpenAIConfig = async () => {
|
||||
try {
|
||||
await api.upsertSystemSetting({
|
||||
name: "openAIApiKey",
|
||||
value: JSON.stringify(state.openAIApiKey),
|
||||
name: "openAIConfig",
|
||||
value: JSON.stringify(openAIConfig),
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return;
|
||||
}
|
||||
toast.success("OpenAI Api Key updated");
|
||||
toast.success("OpenAI Config updated");
|
||||
};
|
||||
|
||||
const handleOpenAIApiHostChanged = (value: string) => {
|
||||
setState({
|
||||
...state,
|
||||
openAIApiHost: value,
|
||||
const handleOpenAIConfigHostChanged = (value: string) => {
|
||||
setOpenAIConfig({
|
||||
...openAIConfig,
|
||||
host: value,
|
||||
});
|
||||
};
|
||||
|
||||
const handleSaveOpenAIApiHost = async () => {
|
||||
try {
|
||||
await api.upsertSystemSetting({
|
||||
name: "openAIApiHost",
|
||||
value: JSON.stringify(state.openAIApiHost),
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return;
|
||||
}
|
||||
toast.success("OpenAI Api Host updated");
|
||||
};
|
||||
|
||||
const handleAdditionalStyleChanged = (value: string) => {
|
||||
setState({
|
||||
...state,
|
||||
@ -171,8 +162,7 @@ const SystemSection = () => {
|
||||
...state,
|
||||
disablePublicMemos: value,
|
||||
});
|
||||
// Update global store immediately as MemoEditor/Selector is dependent on this value.
|
||||
dispatch(setGlobalState({ systemStatus: { ...systemStatus, disablePublicMemos: value } }));
|
||||
globalStore.setSystemStatus({ disablePublicMemos: value });
|
||||
await api.upsertSystemSetting({
|
||||
name: "disablePublicMemos",
|
||||
value: JSON.stringify(value),
|
||||
@ -206,7 +196,7 @@ const SystemSection = () => {
|
||||
<Divider className="!mt-3 !my-4" />
|
||||
<div className="form-label">
|
||||
<span className="normal-text">OpenAI API Key</span>
|
||||
<Button onClick={handleSaveOpenAIApiKey}>{t("common.save")}</Button>
|
||||
<Button onClick={handleSaveOpenAIConfig}>{t("common.save")}</Button>
|
||||
</div>
|
||||
<Input
|
||||
className="w-full"
|
||||
@ -215,12 +205,11 @@ const SystemSection = () => {
|
||||
fontSize: "14px",
|
||||
}}
|
||||
placeholder="Write only"
|
||||
value={state.openAIApiKey}
|
||||
onChange={(event) => handleOpenAIApiKeyChanged(event.target.value)}
|
||||
value={openAIConfig.key}
|
||||
onChange={(event) => handleOpenAIConfigKeyChanged(event.target.value)}
|
||||
/>
|
||||
<div className="form-label mt-2">
|
||||
<span className="normal-text">OpenAI API Host</span>
|
||||
<Button onClick={handleSaveOpenAIApiHost}>{t("common.save")}</Button>
|
||||
</div>
|
||||
<Input
|
||||
className="w-full"
|
||||
@ -229,8 +218,8 @@ const SystemSection = () => {
|
||||
fontSize: "14px",
|
||||
}}
|
||||
placeholder="OpenAI Host. Default: https://api.openai.com"
|
||||
value={state.openAIApiHost}
|
||||
onChange={(event) => handleOpenAIApiHostChanged(event.target.value)}
|
||||
value={openAIConfig.host}
|
||||
onChange={(event) => handleOpenAIConfigHostChanged(event.target.value)}
|
||||
/>
|
||||
<Divider className="!mt-3 !my-4" />
|
||||
<div className="form-label">
|
||||
|
@ -10,6 +10,10 @@ export function getSystemStatus() {
|
||||
return axios.get<ResponseObject<SystemStatus>>("/api/status");
|
||||
}
|
||||
|
||||
export function getSystemSetting() {
|
||||
return axios.get<ResponseObject<SystemSetting[]>>("/api/system/setting");
|
||||
}
|
||||
|
||||
export function upsertSystemSetting(systemSetting: SystemSetting) {
|
||||
return axios.post<ResponseObject<SystemSetting>>("/api/system/setting", systemSetting);
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ export const initialGlobalState = async () => {
|
||||
appearance: "system",
|
||||
externalUrl: "",
|
||||
},
|
||||
openAIApiHost: "",
|
||||
} as SystemStatus,
|
||||
};
|
||||
|
||||
@ -75,6 +74,16 @@ export const useGlobalStore = () => {
|
||||
store.dispatch(setGlobalState({ systemStatus: systemStatus }));
|
||||
return systemStatus;
|
||||
},
|
||||
setSystemStatus: (systemStatus: Partial<SystemStatus>) => {
|
||||
store.dispatch(
|
||||
setGlobalState({
|
||||
systemStatus: {
|
||||
...state.systemStatus,
|
||||
...systemStatus,
|
||||
},
|
||||
})
|
||||
);
|
||||
},
|
||||
setLocale: (locale: Locale) => {
|
||||
store.dispatch(setLocale(locale));
|
||||
},
|
||||
|
6
web/src/types/modules/system.d.ts
vendored
6
web/src/types/modules/system.d.ts
vendored
@ -12,6 +12,11 @@ interface CustomizedProfile {
|
||||
externalUrl: string;
|
||||
}
|
||||
|
||||
interface OpenAIConfig {
|
||||
key: string;
|
||||
host: string;
|
||||
}
|
||||
|
||||
interface SystemStatus {
|
||||
host?: User;
|
||||
profile: Profile;
|
||||
@ -23,7 +28,6 @@ interface SystemStatus {
|
||||
additionalScript: string;
|
||||
customizedProfile: CustomizedProfile;
|
||||
storageServiceId: number;
|
||||
openAIApiHost: string;
|
||||
}
|
||||
|
||||
interface SystemSetting {
|
||||
|
Reference in New Issue
Block a user