feat: support deepseek and openai-compatible providers
This commit is contained in:
@@ -8,18 +8,35 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class SettingsService {
|
||||
public static final String PROVIDER_DEEPSEEK = "deepseek";
|
||||
public static final String PROVIDER_OPENAI_COMPATIBLE = "openai-compatible";
|
||||
|
||||
// 启动默认 API Key(仅作为本地默认值,可在设置页覆盖)
|
||||
private static final String BOOTSTRAP_API_KEY = "sk-48c59012c93b43a08fecbaf3e74799e7";
|
||||
private static final String DEFAULT_OPENAI_BASE_URL = "http://127.0.0.1:5001/v1";
|
||||
private static final String DEFAULT_OPENAI_API_KEY = "sk-f8b3f43e1fdd4f50b287050f08a6c7ed";
|
||||
private static final String DEFAULT_OPENAI_STAGE_ONE_MODEL = "deepseek-v4-flash";
|
||||
private static final String DEFAULT_OPENAI_STAGE_TWO_MODEL = "deepseek-v4-pro";
|
||||
|
||||
private final OutputFileService outputFileService;
|
||||
private final SvnPresetService svnPresetService;
|
||||
private volatile String runtimeApiKey;
|
||||
private volatile String runtimeProvider;
|
||||
private volatile String runtimeOpenaiBaseUrl;
|
||||
private volatile String runtimeOpenaiApiKey;
|
||||
private volatile String runtimeOpenaiStageOneModel;
|
||||
private volatile String runtimeOpenaiStageTwoModel;
|
||||
private volatile String defaultSvnPresetId;
|
||||
|
||||
public SettingsService(OutputFileService outputFileService, SvnPresetService svnPresetService) {
|
||||
this.outputFileService = outputFileService;
|
||||
this.svnPresetService = svnPresetService;
|
||||
this.runtimeApiKey = initStartupApiKey();
|
||||
this.runtimeProvider = PROVIDER_DEEPSEEK;
|
||||
this.runtimeOpenaiBaseUrl = DEFAULT_OPENAI_BASE_URL;
|
||||
this.runtimeOpenaiApiKey = DEFAULT_OPENAI_API_KEY;
|
||||
this.runtimeOpenaiStageOneModel = DEFAULT_OPENAI_STAGE_ONE_MODEL;
|
||||
this.runtimeOpenaiStageTwoModel = DEFAULT_OPENAI_STAGE_TWO_MODEL;
|
||||
this.defaultSvnPresetId = svnPresetService.configuredDefaultPresetId();
|
||||
}
|
||||
|
||||
@@ -28,17 +45,43 @@ public class SettingsService {
|
||||
final String envKey = System.getenv("DEEPSEEK_API_KEY");
|
||||
final String activeKey = pickActiveKey(null);
|
||||
|
||||
result.put("provider", getProvider());
|
||||
result.put("apiKeyConfigured", activeKey != null && !activeKey.trim().isEmpty());
|
||||
result.put("apiKeySource", detectApiKeySource(envKey));
|
||||
result.put("openaiBaseUrl", getOpenaiBaseUrl());
|
||||
result.put("openaiApiKey", getOpenaiApiKey());
|
||||
result.put("openaiApiKeyConfigured", isConfigured(getOpenaiApiKey()));
|
||||
result.put("openaiStageOneModel", getOpenaiStageOneModel());
|
||||
result.put("openaiStageTwoModel", getOpenaiStageTwoModel());
|
||||
result.put("outputDir", outputFileService.getOutputRoot().toString());
|
||||
result.put("defaultSvnPresetId", getDefaultSvnPresetId());
|
||||
return result;
|
||||
}
|
||||
|
||||
public void updateSettings(String apiKey, String outputDir, String newDefaultSvnPresetId) {
|
||||
public void updateSettings(String apiKey,
|
||||
String provider,
|
||||
String openaiBaseUrl,
|
||||
String openaiApiKey,
|
||||
String openaiStageOneModel,
|
||||
String openaiStageTwoModel,
|
||||
String outputDir,
|
||||
String newDefaultSvnPresetId) {
|
||||
if (apiKey != null && !apiKey.trim().isEmpty()) {
|
||||
this.runtimeApiKey = apiKey.trim();
|
||||
}
|
||||
this.runtimeProvider = normalizeProvider(provider);
|
||||
if (openaiBaseUrl != null && !openaiBaseUrl.trim().isEmpty()) {
|
||||
this.runtimeOpenaiBaseUrl = openaiBaseUrl.trim();
|
||||
}
|
||||
if (openaiApiKey != null && !openaiApiKey.trim().isEmpty()) {
|
||||
this.runtimeOpenaiApiKey = openaiApiKey.trim();
|
||||
}
|
||||
if (openaiStageOneModel != null && !openaiStageOneModel.trim().isEmpty()) {
|
||||
this.runtimeOpenaiStageOneModel = openaiStageOneModel.trim();
|
||||
}
|
||||
if (openaiStageTwoModel != null && !openaiStageTwoModel.trim().isEmpty()) {
|
||||
this.runtimeOpenaiStageTwoModel = openaiStageTwoModel.trim();
|
||||
}
|
||||
if (outputDir != null && !outputDir.trim().isEmpty()) {
|
||||
outputFileService.setOutputRoot(outputDir);
|
||||
}
|
||||
@@ -92,4 +135,44 @@ public class SettingsService {
|
||||
}
|
||||
return svnPresetService.firstPresetId();
|
||||
}
|
||||
|
||||
public String getProvider() {
|
||||
return normalizeProvider(runtimeProvider);
|
||||
}
|
||||
|
||||
public String getOpenaiBaseUrl() {
|
||||
return trimOrDefault(runtimeOpenaiBaseUrl, DEFAULT_OPENAI_BASE_URL);
|
||||
}
|
||||
|
||||
public String getOpenaiApiKey() {
|
||||
return trimOrDefault(runtimeOpenaiApiKey, DEFAULT_OPENAI_API_KEY);
|
||||
}
|
||||
|
||||
public String getOpenaiStageOneModel() {
|
||||
return trimOrDefault(runtimeOpenaiStageOneModel, DEFAULT_OPENAI_STAGE_ONE_MODEL);
|
||||
}
|
||||
|
||||
public String getOpenaiStageTwoModel() {
|
||||
return trimOrDefault(runtimeOpenaiStageTwoModel, DEFAULT_OPENAI_STAGE_TWO_MODEL);
|
||||
}
|
||||
|
||||
private String normalizeProvider(String provider) {
|
||||
if (PROVIDER_OPENAI_COMPATIBLE.equalsIgnoreCase(trim(provider))) {
|
||||
return PROVIDER_OPENAI_COMPATIBLE;
|
||||
}
|
||||
return PROVIDER_DEEPSEEK;
|
||||
}
|
||||
|
||||
private String trimOrDefault(String value, String defaultValue) {
|
||||
final String trimmed = trim(value);
|
||||
return trimmed.isEmpty() ? defaultValue : trimmed;
|
||||
}
|
||||
|
||||
private boolean isConfigured(String value) {
|
||||
return value != null && !value.trim().isEmpty();
|
||||
}
|
||||
|
||||
private String trim(String value) {
|
||||
return value == null ? "" : value.trim();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user