From e883e383a540368f26295ce3504d5253f637b294 Mon Sep 17 00:00:00 2001 From: liuk Date: Fri, 4 Oct 2024 18:42:45 +0800 Subject: [PATCH] fix(settings): Test connection failed without applying settings --- .../com/phodal/shirecore/llm/LlmConfig.kt | 3 ++ .../com/phodal/shirecore/llm/LlmProvider.kt | 11 +++++-- .../phodal/shire/llm/OpenAILikeProvider.kt | 7 +++-- .../phodal/shire/settings/ShireSettingUi.kt | 29 ++++++++++--------- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/core/src/main/kotlin/com/phodal/shirecore/llm/LlmConfig.kt b/core/src/main/kotlin/com/phodal/shirecore/llm/LlmConfig.kt index 6ad213a05..addd375b0 100644 --- a/core/src/main/kotlin/com/phodal/shirecore/llm/LlmConfig.kt +++ b/core/src/main/kotlin/com/phodal/shirecore/llm/LlmConfig.kt @@ -16,6 +16,9 @@ class LlmConfig( val responseFormat: String = "\$.choices[0].delta.content", val messageKeys: Map = mapOf(), ) { + + fun checkAvailable(): Boolean = apiKey.isNotBlank() && model.isNotBlank() + companion object { fun fromJson(modelConfig: JsonObject): LlmConfig? { val title = modelConfig.findString("title") ?: return null diff --git a/core/src/main/kotlin/com/phodal/shirecore/llm/LlmProvider.kt b/core/src/main/kotlin/com/phodal/shirecore/llm/LlmProvider.kt index 0990f2ea0..e472009c9 100644 --- a/core/src/main/kotlin/com/phodal/shirecore/llm/LlmProvider.kt +++ b/core/src/main/kotlin/com/phodal/shirecore/llm/LlmProvider.kt @@ -34,9 +34,12 @@ interface LlmProvider { * Checks if the given project is applicable for some operation. * * @param project the project to check for applicability + * @param llmConfig This llmConfig is used to verify if llmProvider is available. + * For example, it may be an unsaved configuration that can be used to test LLM connection. + * * @return true if the project is applicable, false otherwise */ - fun isApplicable(project: Project): Boolean + fun isApplicable(project: Project, llmConfig: LlmConfig? = null): Boolean /** * Streams chat completion responses from the service. @@ -80,10 +83,12 @@ interface LlmProvider { * Returns an instance of LlmProvider based on the given Project. * * @param project the Project for which to find a suitable LlmProvider + * @param llmConfig provide llmConfig as a condition for finding a suitable LlmProvider. + * * @return an instance of LlmProvider if a suitable provider is found, null otherwise */ - fun provider(project: Project): LlmProvider? { - val providers = EP_NAME.extensions.filter { it.isApplicable(project) } + fun provider(project: Project, llmConfig: LlmConfig? = null): LlmProvider? { + val providers = EP_NAME.extensions.filter { it.isApplicable(project, llmConfig) } return if (providers.isEmpty()) { ShirelangNotifications.error(project, ShireCoreBundle.message("shire.llm.notfound")) null diff --git a/src/main/kotlin/com/phodal/shire/llm/OpenAILikeProvider.kt b/src/main/kotlin/com/phodal/shire/llm/OpenAILikeProvider.kt index 51c78c212..cff06889b 100644 --- a/src/main/kotlin/com/phodal/shire/llm/OpenAILikeProvider.kt +++ b/src/main/kotlin/com/phodal/shire/llm/OpenAILikeProvider.kt @@ -43,7 +43,10 @@ class OpenAILikeProvider : CustomSSEHandler(), LlmProvider { override var project: Project? = null override fun clearMessage() = messages.clear() - override fun isApplicable(project: Project): Boolean { + override fun isApplicable(project: Project, llmConfig: LlmConfig?): Boolean { + if (llmConfig != null) return llmConfig.checkAvailable() + // If the configRunLlm configuration exists, it is also available + if (configRunLlm().let { it?.checkAvailable() == true }) return true this.project = project // dynamic check for the API key and model name return ShireSettingsState.getInstance().apiToken.isNotEmpty() @@ -66,7 +69,7 @@ class OpenAILikeProvider : CustomSSEHandler(), LlmProvider { llmConfig: LlmConfig? ): Flow { (llmConfig ?: configRunLlm()).let { - if (it != null) { + if (it != null && it.checkAvailable()) { modelName = it.model temperature = it.temperature.toFloat() key = it.apiKey diff --git a/src/main/kotlin/com/phodal/shire/settings/ShireSettingUi.kt b/src/main/kotlin/com/phodal/shire/settings/ShireSettingUi.kt index dd38b5ede..9a68ec590 100644 --- a/src/main/kotlin/com/phodal/shire/settings/ShireSettingUi.kt +++ b/src/main/kotlin/com/phodal/shire/settings/ShireSettingUi.kt @@ -132,20 +132,23 @@ class ShireSettingUi : ConfigurableUi { testResultField.text = throwable.message ?: "Unknown error" }) { val flowString: Flow = - LlmProvider.provider(project) - ?.stream( - promptText = "hi", - systemPrompt = "", - keepHistory = false, - llmConfig = LlmConfig( - model = modelName.text, - apiKey = engineToken.text, - apiBase = apiHost.text, - temperature = temperatureField.text.toDoubleOrNull() ?: 0.0, - title = modelName.text, + LlmConfig( + model = modelName.text, + apiKey = engineToken.text, + apiBase = apiHost.text, + temperature = temperatureField.text.toDoubleOrNull() ?: 0.0, + title = modelName.text, + ).let { + LlmProvider.provider(project, it) + ?.stream( + promptText = "hi", + systemPrompt = "", + keepHistory = false, + llmConfig = it ) - ) - ?: throw Exception(ShireCoreBundle.message("shire.llm.notfound")) + ?: throw Exception(ShireCoreBundle.message("shire.llm.notfound")) + } + flowString.collect { testResultField.text += it }