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:
ChaoLiu 2025-08-18 18:35:37 +08:00
parent b711e801af
commit 07fe11a3f9
5 changed files with 21 additions and 29 deletions

View File

@ -51,8 +51,8 @@ func LoadConfigFromEnv() *Config {
TimeoutSeconds: timeoutSeconds,
}
// Enable AI if all required fields are provided
config.Enabled = config.BaseURL != "" && config.APIKey != "" && config.Model != ""
// Enable AI if all required fields are provided (API Key is optional for local services like Ollama)
config.Enabled = config.BaseURL != "" && config.Model != ""
return config
}
@ -105,15 +105,15 @@ func (c *Config) MergeWithEnv() *Config {
merged.TimeoutSeconds = envConfig.TimeoutSeconds
}
// Enable if all required fields are present
merged.Enabled = merged.BaseURL != "" && merged.APIKey != "" && merged.Model != ""
// Enable if all required fields are present (API Key is optional for local services like Ollama)
merged.Enabled = merged.BaseURL != "" && merged.Model != ""
return merged
}
// IsConfigured returns true if AI is properly configured
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

View File

@ -397,12 +397,6 @@ func (s *APIV1Service) TestAiConnection(ctx context.Context, request *v1pb.TestA
Message: "Base URL is required",
}, nil
}
if request.ApiKey == "" {
return &v1pb.TestAiConnectionResponse{
Success: false,
Message: "API Key is required",
}, nil
}
if request.Model == "" {
return &v1pb.TestAiConnectionResponse{
Success: false,

View File

@ -48,8 +48,8 @@ const AISettings = observer(() => {
};
const updateSetting = async () => {
if (aiSetting.enableAi && (!aiSetting.apiKey || !aiSetting.model)) {
toast.error(t("setting.ai-section.api-key-model-required"));
if (aiSetting.enableAi && !aiSetting.model) {
toast.error(t("setting.ai-section.model-required"));
return;
}
@ -65,7 +65,7 @@ const AISettings = observer(() => {
const resetSetting = () => setAiSetting(originalSetting);
const testConnection = async () => {
if (!aiSetting.baseUrl || !aiSetting.apiKey || !aiSetting.model) {
if (!aiSetting.baseUrl || !aiSetting.model) {
toast.error(t("setting.ai-section.test-connection-incomplete"));
return;
}
@ -222,7 +222,7 @@ const AISettings = observer(() => {
<Button
variant="outline"
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")}
</Button>

View File

@ -331,7 +331,7 @@
"base-url": "Base URL",
"base-url-description": "API endpoint for your AI service (e.g., https://api.openai.com/v1)",
"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-description": "AI model to use for processing requests (e.g., gpt-4o, claude-3-5-sonnet-20241022)",
"timeout": "Timeout (seconds)",
@ -341,9 +341,8 @@
"test-connection-description": "Verify that your AI service configuration is working",
"test-connection-success": "Connection successful! AI service is properly configured.",
"test-connection-failed": "Connection failed. Please check your configuration.",
"test-connection-incomplete": "Please fill in all required fields before testing.",
"fields-required": "All fields are required when AI is enabled.",
"api-key-model-required": "API key and model are required when AI is enabled."
"test-connection-incomplete": "Please fill in Base URL and Model before testing.",
"model-required": "Model is required when AI is enabled."
},
"tag-recommendation": {
"title": "Tag Recommendation",

View File

@ -329,7 +329,7 @@
"base-url": "基础 URL",
"base-url-description": "AI 服务的 API 端点例如https://api.openai.com/v1",
"api-key": "API 密钥",
"api-key-description": "AI 服务的身份验证密钥",
"api-key-description": "AI 服务的身份验证密钥(本地服务如 Ollama 可选)",
"model": "模型",
"model-description": "用于处理请求的 AI 模型例如gpt-4o, claude-3-5-sonnet-20241022",
"timeout": "超时(秒)",
@ -339,9 +339,8 @@
"test-connection-description": "验证您的 AI 服务配置是否正常工作",
"test-connection-success": "连接成功AI 服务配置正确。",
"test-connection-failed": "连接失败。请检查您的配置。",
"test-connection-incomplete": "请在测试前填写所有必填字段。",
"fields-required": "启用 AI 时,所有字段都是必填的。",
"api-key-model-required": "启用 AI 时API 密钥和模型是必填的。"
"test-connection-incomplete": "请在测试前填写基础 URL 和模型。",
"model-required": "启用 AI 时,模型是必填的。"
},
"sso": "单点登录",
"sso-section": {