mirror of https://github.com/usememos/memos.git
feat: remove API key requirement for local AI services
- Make API key optional for local services like Ollama - Update validation logic to support key-less configurations - Update UI descriptions and localization for optional API key Signed-off-by: ChaoLiu <chaoliu719@gmail.com>
This commit is contained in:
parent
b711e801af
commit
07fe11a3f9
|
|
@ -51,8 +51,8 @@ func LoadConfigFromEnv() *Config {
|
||||||
TimeoutSeconds: timeoutSeconds,
|
TimeoutSeconds: timeoutSeconds,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable AI if all required fields are provided
|
// Enable AI if all required fields are provided (API Key is optional for local services like Ollama)
|
||||||
config.Enabled = config.BaseURL != "" && config.APIKey != "" && config.Model != ""
|
config.Enabled = config.BaseURL != "" && config.Model != ""
|
||||||
|
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
@ -105,15 +105,15 @@ func (c *Config) MergeWithEnv() *Config {
|
||||||
merged.TimeoutSeconds = envConfig.TimeoutSeconds
|
merged.TimeoutSeconds = envConfig.TimeoutSeconds
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable if all required fields are present
|
// Enable if all required fields are present (API Key is optional for local services like Ollama)
|
||||||
merged.Enabled = merged.BaseURL != "" && merged.APIKey != "" && merged.Model != ""
|
merged.Enabled = merged.BaseURL != "" && merged.Model != ""
|
||||||
|
|
||||||
return merged
|
return merged
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsConfigured returns true if AI is properly configured
|
// IsConfigured returns true if AI is properly configured
|
||||||
func (c *Config) IsConfigured() bool {
|
func (c *Config) IsConfigured() bool {
|
||||||
return c.Enabled && c.BaseURL != "" && c.APIKey != "" && c.Model != ""
|
return c.Enabled && c.BaseURL != "" && c.Model != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client wraps OpenAI client with convenience methods
|
// Client wraps OpenAI client with convenience methods
|
||||||
|
|
|
||||||
|
|
@ -397,12 +397,6 @@ func (s *APIV1Service) TestAiConnection(ctx context.Context, request *v1pb.TestA
|
||||||
Message: "Base URL is required",
|
Message: "Base URL is required",
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
if request.ApiKey == "" {
|
|
||||||
return &v1pb.TestAiConnectionResponse{
|
|
||||||
Success: false,
|
|
||||||
Message: "API Key is required",
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
if request.Model == "" {
|
if request.Model == "" {
|
||||||
return &v1pb.TestAiConnectionResponse{
|
return &v1pb.TestAiConnectionResponse{
|
||||||
Success: false,
|
Success: false,
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,8 @@ const AISettings = observer(() => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateSetting = async () => {
|
const updateSetting = async () => {
|
||||||
if (aiSetting.enableAi && (!aiSetting.apiKey || !aiSetting.model)) {
|
if (aiSetting.enableAi && !aiSetting.model) {
|
||||||
toast.error(t("setting.ai-section.api-key-model-required"));
|
toast.error(t("setting.ai-section.model-required"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,7 +65,7 @@ const AISettings = observer(() => {
|
||||||
const resetSetting = () => setAiSetting(originalSetting);
|
const resetSetting = () => setAiSetting(originalSetting);
|
||||||
|
|
||||||
const testConnection = async () => {
|
const testConnection = async () => {
|
||||||
if (!aiSetting.baseUrl || !aiSetting.apiKey || !aiSetting.model) {
|
if (!aiSetting.baseUrl || !aiSetting.model) {
|
||||||
toast.error(t("setting.ai-section.test-connection-incomplete"));
|
toast.error(t("setting.ai-section.test-connection-incomplete"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -222,7 +222,7 @@ const AISettings = observer(() => {
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={testConnection}
|
onClick={testConnection}
|
||||||
disabled={isTestingConnection || !aiSetting.baseUrl || !aiSetting.apiKey || !aiSetting.model}
|
disabled={isTestingConnection || !aiSetting.baseUrl || !aiSetting.model}
|
||||||
>
|
>
|
||||||
{isTestingConnection ? t("setting.ai-section.testing-connection") : t("setting.ai-section.test-connection")}
|
{isTestingConnection ? t("setting.ai-section.testing-connection") : t("setting.ai-section.test-connection")}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -331,7 +331,7 @@
|
||||||
"base-url": "Base URL",
|
"base-url": "Base URL",
|
||||||
"base-url-description": "API endpoint for your AI service (e.g., https://api.openai.com/v1)",
|
"base-url-description": "API endpoint for your AI service (e.g., https://api.openai.com/v1)",
|
||||||
"api-key": "API Key",
|
"api-key": "API Key",
|
||||||
"api-key-description": "Authentication key for your AI service",
|
"api-key-description": "Authentication key for your AI service (optional for local services like Ollama)",
|
||||||
"model": "Model",
|
"model": "Model",
|
||||||
"model-description": "AI model to use for processing requests (e.g., gpt-4o, claude-3-5-sonnet-20241022)",
|
"model-description": "AI model to use for processing requests (e.g., gpt-4o, claude-3-5-sonnet-20241022)",
|
||||||
"timeout": "Timeout (seconds)",
|
"timeout": "Timeout (seconds)",
|
||||||
|
|
@ -341,9 +341,8 @@
|
||||||
"test-connection-description": "Verify that your AI service configuration is working",
|
"test-connection-description": "Verify that your AI service configuration is working",
|
||||||
"test-connection-success": "Connection successful! AI service is properly configured.",
|
"test-connection-success": "Connection successful! AI service is properly configured.",
|
||||||
"test-connection-failed": "Connection failed. Please check your configuration.",
|
"test-connection-failed": "Connection failed. Please check your configuration.",
|
||||||
"test-connection-incomplete": "Please fill in all required fields before testing.",
|
"test-connection-incomplete": "Please fill in Base URL and Model before testing.",
|
||||||
"fields-required": "All fields are required when AI is enabled.",
|
"model-required": "Model is required when AI is enabled."
|
||||||
"api-key-model-required": "API key and model are required when AI is enabled."
|
|
||||||
},
|
},
|
||||||
"tag-recommendation": {
|
"tag-recommendation": {
|
||||||
"title": "Tag Recommendation",
|
"title": "Tag Recommendation",
|
||||||
|
|
|
||||||
|
|
@ -329,7 +329,7 @@
|
||||||
"base-url": "基础 URL",
|
"base-url": "基础 URL",
|
||||||
"base-url-description": "AI 服务的 API 端点(例如:https://api.openai.com/v1)",
|
"base-url-description": "AI 服务的 API 端点(例如:https://api.openai.com/v1)",
|
||||||
"api-key": "API 密钥",
|
"api-key": "API 密钥",
|
||||||
"api-key-description": "AI 服务的身份验证密钥",
|
"api-key-description": "AI 服务的身份验证密钥(本地服务如 Ollama 可选)",
|
||||||
"model": "模型",
|
"model": "模型",
|
||||||
"model-description": "用于处理请求的 AI 模型(例如:gpt-4o, claude-3-5-sonnet-20241022)",
|
"model-description": "用于处理请求的 AI 模型(例如:gpt-4o, claude-3-5-sonnet-20241022)",
|
||||||
"timeout": "超时(秒)",
|
"timeout": "超时(秒)",
|
||||||
|
|
@ -339,9 +339,8 @@
|
||||||
"test-connection-description": "验证您的 AI 服务配置是否正常工作",
|
"test-connection-description": "验证您的 AI 服务配置是否正常工作",
|
||||||
"test-connection-success": "连接成功!AI 服务配置正确。",
|
"test-connection-success": "连接成功!AI 服务配置正确。",
|
||||||
"test-connection-failed": "连接失败。请检查您的配置。",
|
"test-connection-failed": "连接失败。请检查您的配置。",
|
||||||
"test-connection-incomplete": "请在测试前填写所有必填字段。",
|
"test-connection-incomplete": "请在测试前填写基础 URL 和模型。",
|
||||||
"fields-required": "启用 AI 时,所有字段都是必填的。",
|
"model-required": "启用 AI 时,模型是必填的。"
|
||||||
"api-key-model-required": "启用 AI 时,API 密钥和模型是必填的。"
|
|
||||||
},
|
},
|
||||||
"sso": "单点登录",
|
"sso": "单点登录",
|
||||||
"sso-section": {
|
"sso-section": {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue