Skip to content
Open
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 @@ -47,6 +47,9 @@ data class CustomRequest(
when {
streamValue.booleanOrNull != null -> streamValue.boolean
streamValue.isString -> streamValue.content.toBoolean()
// Handle numeric values: 0 = false, 1 (or any other number) = true
streamValue.intOrNull != null -> streamValue.int != 0
streamValue.longOrNull != null -> streamValue.long != 0L
else -> true
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,9 @@ class LLMDialog(
headersField.text = headersJson

// Body without model and temperature (they are now explicit fields)
// Also keep stream if it was explicitly set in body (to support numeric values like 0/1)
val bodyWithoutModelTemp = existingLlm.customRequest.body.filterKeys {
it != "model" && it != "temperature" && it != "stream"
it != "model" && it != "temperature"
}
val bodyJson = if (bodyWithoutModelTemp.isNotEmpty()) {
buildJsonObject {
Expand Down Expand Up @@ -265,23 +266,41 @@ class LLMDialog(
}

// Combine explicit parameters with additional body
// If stream is explicitly set in additional body, use that value
val body = mutableMapOf<String, JsonElement>().apply {
put("model", JsonPrimitive(modelField.text))
put("temperature", JsonPrimitive(temperature))
// Use checkbox value as default
put("stream", JsonPrimitive(streamCheckbox.isSelected))
// Additional body can override stream if explicitly set
putAll(additionalBody)
}

// Determine actual stream value (from body if set, otherwise from checkbox)
val actualStream = when (val streamValue = body["stream"]) {
is JsonPrimitive -> {
when {
streamValue.booleanOrNull != null -> streamValue.boolean
streamValue.isString -> streamValue.content.toBoolean()
// Handle numeric values: 0 = false, any other number = true
streamValue.intOrNull != null -> streamValue.int != 0
streamValue.longOrNull != null -> streamValue.long != 0L
else -> streamCheckbox.isSelected
}
}
else -> streamCheckbox.isSelected
}

// Create a temporary LLM config for testing
val customRequest = CustomRequest(
headers = headers,
body = body,
stream = streamCheckbox.isSelected
stream = actualStream
)

// Get response resolver, use default if empty
val responseResolver = responseResolverField.text.trim().ifEmpty {
if (streamCheckbox.isSelected) {
if (actualStream) {
"\$.choices[0].delta.content"
} else {
"\$.choices[0].message.content"
Expand Down Expand Up @@ -382,13 +401,31 @@ class LLMDialog(
}

// Combine explicit parameters with additional body
// If stream is explicitly set in additional body, use that value
val body = mutableMapOf<String, JsonElement>().apply {
put("model", JsonPrimitive(modelField.text))
put("temperature", JsonPrimitive(temperature))
// Use checkbox value as default
put("stream", JsonPrimitive(streamCheckbox.isSelected))
// Additional body can override stream if explicitly set
putAll(additionalBody)
}

// Determine actual stream value (from body if set, otherwise from checkbox)
val actualStream = when (val streamValue = body["stream"]) {
is JsonPrimitive -> {
when {
streamValue.booleanOrNull != null -> streamValue.boolean
streamValue.isString -> streamValue.content.toBoolean()
// Handle numeric values: 0 = false, any other number = true
streamValue.intOrNull != null -> streamValue.int != 0
streamValue.longOrNull != null -> streamValue.long != 0L
else -> streamCheckbox.isSelected
}
}
else -> streamCheckbox.isSelected
}

// Get existing LLMs
val existingLlms = try {
LlmConfig.load().toMutableList()
Expand All @@ -405,12 +442,12 @@ class LLMDialog(
val customRequest = CustomRequest(
headers = headers,
body = body,
stream = streamCheckbox.isSelected
stream = actualStream
)

// Get response resolver, use default if empty
val responseResolver = responseResolverField.text.trim().ifEmpty {
if (streamCheckbox.isSelected) {
if (actualStream) {
"\$.choices[0].delta.content"
} else {
"\$.choices[0].message.content"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package cc.unitmesh.devti.llm2.model

import kotlinx.serialization.json.JsonPrimitive
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test

class CustomRequestTest {

@Test
fun `should parse boolean stream value true`() {
val requestFormat = """{"customFields": {"model": "test-model", "stream": true}}"""
val result = CustomRequest.fromLegacyFormat(requestFormat)

assertTrue(result.stream)
assertEquals(JsonPrimitive(true), result.body["stream"])
}

@Test
fun `should parse boolean stream value false`() {
val requestFormat = """{"customFields": {"model": "test-model", "stream": false}}"""
val result = CustomRequest.fromLegacyFormat(requestFormat)

assertFalse(result.stream)
assertEquals(JsonPrimitive(false), result.body["stream"])
}

@Test
fun `should parse numeric stream value 1 as true`() {
val requestFormat = """{"customFields": {"model": "test-model", "stream": 1}}"""
val result = CustomRequest.fromLegacyFormat(requestFormat)

assertTrue(result.stream)
assertEquals(JsonPrimitive(1), result.body["stream"])
}

@Test
fun `should parse numeric stream value 0 as false`() {
val requestFormat = """{"customFields": {"model": "test-model", "stream": 0}}"""
val result = CustomRequest.fromLegacyFormat(requestFormat)

assertFalse(result.stream)
assertEquals(JsonPrimitive(0), result.body["stream"])
}

@Test
fun `should parse string stream value true`() {
val requestFormat = """{"customFields": {"model": "test-model", "stream": "true"}}"""
val result = CustomRequest.fromLegacyFormat(requestFormat)

assertTrue(result.stream)
assertEquals(JsonPrimitive("true"), result.body["stream"])
}

@Test
fun `should parse string stream value false`() {
val requestFormat = """{"customFields": {"model": "test-model", "stream": "false"}}"""
val result = CustomRequest.fromLegacyFormat(requestFormat)

assertFalse(result.stream)
assertEquals(JsonPrimitive("false"), result.body["stream"])
}

@Test
fun `should default to true when stream is missing`() {
val requestFormat = """{"customFields": {"model": "test-model"}}"""
val result = CustomRequest.fromLegacyFormat(requestFormat)

assertTrue(result.stream)
}

@Test
fun `should parse custom headers correctly`() {
val requestFormat = """{"customHeaders": {"X-Custom": "value"}, "customFields": {"model": "test"}}"""
val result = CustomRequest.fromLegacyFormat(requestFormat)

assertEquals("value", result.headers["X-Custom"])
}
}
Loading