Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,6 @@ class ChatCodingPanel(private val chatCodingService: ChatCodingService, val disp
}.catch {
it.printStackTrace()
}.collect {
println("got message $it")
text += it

// 以下两个 API 设计不合理,如果必须要同时调用,那就只提供一个就好了
Expand Down
9 changes: 5 additions & 4 deletions src/main/kotlin/cc/unitmesh/devti/gui/chat/MessageView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,10 @@ class MessageView(private val message: String, val role: ChatRole, private val d
MessageWorker(content).execute()
}

fun updateSourceContent(source: String?) {
component.text = source

private var answer: String = ""
fun updateSourceContent(source: String) {
answer = source
}

fun scrollToBottom() {
Expand All @@ -117,15 +119,14 @@ class MessageView(private val message: String, val role: ChatRole, private val d

fun reRenderAssistantOutput() {
ApplicationManager.getApplication().invokeLater {
val displayText = component.text

centerPanel.remove(component)
centerPanel.updateUI()

centerPanel.add(myNameLabel)
centerPanel.add(createTitlePanel())

val message = SimpleMessage(displayText, displayText, ChatRole.Assistant)
val message = SimpleMessage(answer, answer, ChatRole.Assistant)
renderInPartView(message)

centerPanel.revalidate()
Expand Down
17 changes: 5 additions & 12 deletions src/main/kotlin/cc/unitmesh/devti/llms/custom/CustomLLMProvider.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
import com.intellij.openapi.components.Service
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.project.Project
import com.nfeld.jsonpathkt.JsonPath
import com.nfeld.jsonpathkt.extension.read
import com.jayway.jsonpath.JsonPath
import com.theokanning.openai.completion.chat.ChatCompletionResult
import com.theokanning.openai.service.SSE
import io.reactivex.BackpressureStrategy
Expand All @@ -19,7 +18,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.withContext
import kotlinx.serialization.Serializable
Expand Down Expand Up @@ -49,7 +47,7 @@ class CustomLLMProvider(val project: Project) : LLMProvider {
private val requestFormat: String
get() = autoDevSettingsState.customEngineRequestFormat
private val responseFormat
get() = autoDevSettingsState.customEngineResponseType
get() = autoDevSettingsState.customEngineResponseFormat

private var client = OkHttpClient()
private val timeout = Duration.ofSeconds(600)
Expand Down Expand Up @@ -99,8 +97,6 @@ class CustomLLMProvider(val project: Project) : LLMProvider {
}


private val _responseFlow = MutableSharedFlow<String>()

@OptIn(ExperimentalCoroutinesApi::class)
private fun streamJson(call: Call): Flow<String> = callbackFlow {
call.enqueue(JSONBodyResponseCallback(responseFormat) {
Expand All @@ -114,11 +110,9 @@ class CustomLLMProvider(val project: Project) : LLMProvider {

@OptIn(ExperimentalCoroutinesApi::class)
private fun streamSSE(call: Call): Flow<String> {
val emitDone = false

val sseFlowable = Flowable
.create({ emitter: FlowableEmitter<SSE> ->
call.enqueue(cc.unitmesh.devti.llms.azure.ResponseBodyCallback(emitter, emitDone))
call.enqueue(cc.unitmesh.devti.llms.azure.ResponseBodyCallback(emitter, true))
}, BackpressureStrategy.BUFFER)

try {
Expand All @@ -132,8 +126,7 @@ class CustomLLMProvider(val project: Project) : LLMProvider {
.blockingForEach { sse ->
if (responseFormat.isNotEmpty()) {
val chunk: String = JsonPath.parse(sse!!.data)?.read(responseFormat)
?: throw Exception("Failed to parse chunk")
logger.warn("got msg: $chunk")
?: throw Exception("Failed to parse chunk: ${sse.data}")
trySend(chunk)
} else {
val result: ChatCompletionResult =
Expand Down Expand Up @@ -215,7 +208,7 @@ fun JsonObject.updateCustomBody(customRequest: String): JsonObject {

customRequestJson["customFields"]?.let { customFields ->
customFields.jsonObject.forEach { (key, value) ->
put(key, value.jsonPrimitive.content)
put(key, value.jsonPrimitive)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class JSONBodyResponseCallback(private val responseFormat: String,private val ca
}

override fun onResponse(call: Call, response: Response) {
println("got response ${response.body?.string()}")
val responseContent: String = JsonPath.parse(response.body?.string())?.read(responseFormat) ?: ""

runBlocking() {
Expand Down
8 changes: 0 additions & 8 deletions src/main/kotlin/cc/unitmesh/devti/settings/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,6 @@ enum class XingHuoApiVersion(val value: Int) {

enum class ResponseType {
SSE, JSON;

companion object {
fun of(str: String): ResponseType = when (str) {
"SSE" -> SSE
"JSON" -> JSON
else -> JSON
}
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class LLMSettingComponent(private val settings: AutoDevSettingsState) {
private val xingHuoApiKeyParam by LLMParam.creating { Password(settings.xingHuoApiKey) }
private val xingHuoApiSecretParam by LLMParam.creating { Password(settings.xingHuoApiSecrect) }

private val customEngineResponseTypeParam by LLMParam.creating { ComboBox(ResponseType.of(settings.customEngineResponseType).name, ResponseType.values().map { it.name }.toList()) }
private val customEngineResponseTypeParam by LLMParam.creating { ComboBox(settings.customEngineResponseType, ResponseType.values().map { it.name }.toList()) }
private val customEngineResponseFormatParam by LLMParam.creating { Editable(settings.customEngineResponseFormat) }
private val customEngineRequestBodyFormatParam by LLMParam.creating { Editable(settings.customEngineRequestFormat) }

Expand Down Expand Up @@ -224,7 +224,7 @@ class LLMSettingComponent(private val settings: AutoDevSettingsState) {
customEngineToken = customEngineTokenParam.value
customPrompts = customEnginePrompt.text
openAiModel = openAIModelsParam.value
customEngineResponseType = customEngineResponseFormatParam.value
customEngineResponseFormat = customEngineResponseFormatParam.value
customEngineRequestFormat = customEngineRequestBodyFormatParam.value
delaySeconds = delaySecondsParam.value
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cc.unitmesh.devti.settings

import org.junit.Assert.*
import com.jayway.jsonpath.JsonPath
import org.junit.Assert.assertEquals
import org.junit.Test

class LLMSettingComponentKtTest {
Expand Down Expand Up @@ -88,6 +89,14 @@ class LLMSettingComponentKtTest {
s = 2
assertEquals("callback should be called", 1, count)
assertEquals("s should be changed to 2", 2, s)
}

@Test
fun testJsonPath() {
val content = """
{"id":"chatcmpl-8Vf3lDVkktbu4v1SYXGt0LTzCVgdC","object":"chat.completion.chunk","created":1702556693,"model":"gpt-35-turbo-16k","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"abc"},"finish_reason":null}]}
"""
val result = JsonPath.parse(content)?.read<String>("\$.choices[0].delta.content")
println("result is $result")
}
}