Skip to content

Commit 10c4b0f

Browse files
Copilotphodal
andcommitted
Fix stream parameter handling for custom LLM providers
- Support numeric stream values (0/1) in addition to boolean (true/false) - Preserve stream parameter in Additional request body when explicitly set - Allow stream in Additional request body to override checkbox value - Fix stream parameter parsing in LlmConfig.fromLegacyFormat() Co-authored-by: phodal <472311+phodal@users.noreply.github.com>
1 parent 69f5973 commit 10c4b0f

File tree

2 files changed

+45
-5
lines changed

2 files changed

+45
-5
lines changed

core/src/main/kotlin/cc/unitmesh/devti/llm2/model/LlmConfig.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ data class CustomRequest(
4747
when {
4848
streamValue.booleanOrNull != null -> streamValue.boolean
4949
streamValue.isString -> streamValue.content.toBoolean()
50+
// Handle numeric values: 0 = false, 1 (or any other number) = true
51+
streamValue.intOrNull != null -> streamValue.int != 0
52+
streamValue.longOrNull != null -> streamValue.long != 0L
5053
else -> true
5154
}
5255
}

core/src/main/kotlin/cc/unitmesh/devti/settings/dialog/LLMDialog.kt

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,9 @@ class LLMDialog(
115115
headersField.text = headersJson
116116

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

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

279+
// Determine actual stream value (from body if set, otherwise from checkbox)
280+
val actualStream = when (val streamValue = body["stream"]) {
281+
is JsonPrimitive -> {
282+
when {
283+
streamValue.booleanOrNull != null -> streamValue.boolean
284+
streamValue.isString -> streamValue.content.toBoolean()
285+
// Handle numeric values: 0 = false, any other number = true
286+
streamValue.intOrNull != null -> streamValue.int != 0
287+
streamValue.longOrNull != null -> streamValue.long != 0L
288+
else -> streamCheckbox.isSelected
289+
}
290+
}
291+
else -> streamCheckbox.isSelected
292+
}
293+
275294
// Create a temporary LLM config for testing
276295
val customRequest = CustomRequest(
277296
headers = headers,
278297
body = body,
279-
stream = streamCheckbox.isSelected
298+
stream = actualStream
280299
)
281300

282301
// Get response resolver, use default if empty
283302
val responseResolver = responseResolverField.text.trim().ifEmpty {
284-
if (streamCheckbox.isSelected) {
303+
if (actualStream) {
285304
"\$.choices[0].delta.content"
286305
} else {
287306
"\$.choices[0].message.content"
@@ -382,13 +401,31 @@ class LLMDialog(
382401
}
383402

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

414+
// Determine actual stream value (from body if set, otherwise from checkbox)
415+
val actualStream = when (val streamValue = body["stream"]) {
416+
is JsonPrimitive -> {
417+
when {
418+
streamValue.booleanOrNull != null -> streamValue.boolean
419+
streamValue.isString -> streamValue.content.toBoolean()
420+
// Handle numeric values: 0 = false, any other number = true
421+
streamValue.intOrNull != null -> streamValue.int != 0
422+
streamValue.longOrNull != null -> streamValue.long != 0L
423+
else -> streamCheckbox.isSelected
424+
}
425+
}
426+
else -> streamCheckbox.isSelected
427+
}
428+
392429
// Get existing LLMs
393430
val existingLlms = try {
394431
LlmConfig.load().toMutableList()
@@ -405,12 +442,12 @@ class LLMDialog(
405442
val customRequest = CustomRequest(
406443
headers = headers,
407444
body = body,
408-
stream = streamCheckbox.isSelected
445+
stream = actualStream
409446
)
410447

411448
// Get response resolver, use default if empty
412449
val responseResolver = responseResolverField.text.trim().ifEmpty {
413-
if (streamCheckbox.isSelected) {
450+
if (actualStream) {
414451
"\$.choices[0].delta.content"
415452
} else {
416453
"\$.choices[0].message.content"

0 commit comments

Comments
 (0)