Skip to content

Commit ba50600

Browse files
committed
feat(custom): add dynamic field replacement in custom requests #251
Introduce functionality to dynamically replace `$content` placeholders in custom request fields with the content of the first message. This enhances flexibility in custom request formatting. Added a test case to verify the new behavior
1 parent 80bec60 commit ba50600

File tree

2 files changed

+62
-4
lines changed

2 files changed

+62
-4
lines changed

core/src/main/kotlin/cc/unitmesh/devti/llms/custom/CustomSSEProcessor.kt

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,34 @@ fun JsonObject.updateCustomBody(customRequest: String): JsonObject {
187187
return runCatching {
188188
buildJsonObject {
189189
// copy origin object
190-
this@updateCustomBody.forEach { u, v -> put(u, v) }
191-
192190
val customRequestJson = Json.parseToJsonElement(customRequest).jsonObject
191+
customRequestJson["fields"]?.jsonObject?.let { fieldsObj ->
192+
val messages: JsonArray = this@updateCustomBody["messages"]?.jsonArray ?: buildJsonArray {}
193+
val contentOfFirstMessage = if (messages.isNotEmpty()) {
194+
messages.last().jsonObject["content"]?.jsonPrimitive?.content ?: ""
195+
} else ""
196+
fieldsObj.forEach { (fieldKey, fieldValue) ->
197+
if (fieldValue is JsonObject) {
198+
put(fieldKey, buildJsonObject {
199+
fieldValue.forEach { (subKey, subValue) ->
200+
if (subValue is JsonPrimitive && subValue.content == "\$content") {
201+
put(subKey, JsonPrimitive(contentOfFirstMessage))
202+
} else {
203+
put(subKey, subValue)
204+
}
205+
}
206+
})
207+
} else if (fieldValue is JsonPrimitive && fieldValue.content == "\$content") {
208+
put(fieldKey, JsonPrimitive(contentOfFirstMessage))
209+
} else {
210+
put(fieldKey, fieldValue)
211+
}
212+
}
213+
214+
return@buildJsonObject
215+
}
216+
217+
this@updateCustomBody.forEach { u, v -> put(u, v) }
193218
customRequestJson["customFields"]?.let { customFields ->
194219
customFields.jsonObject.forEach { (key, value) ->
195220
put(key, value)
@@ -224,6 +249,17 @@ fun JsonObject.updateCustomBody(customRequest: String): JsonObject {
224249

225250
fun CustomRequest.updateCustomFormat(format: String): String {
226251
val requestContentOri = Json.encodeToString<CustomRequest>(this)
227-
return Json.parseToJsonElement(requestContentOri)
228-
.jsonObject.updateCustomBody(format).toString()
252+
val updateCustomBody = Json.parseToJsonElement(requestContentOri)
253+
.jsonObject.updateCustomBody(format)
254+
255+
return updateCustomBody.toString()
229256
}
257+
258+
fun JsonObject.removeFields(vararg fields: String): JsonObject {
259+
return JsonObject(
260+
toMutableMap()
261+
.apply {
262+
fields.forEach { remove(it) }
263+
}
264+
)
265+
}

core/src/test/kotlin/cc/unitmesh/devti/llms/custom/CustomLLMProviderTest.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,26 @@ class CustomLLMProviderTest {
8282
""".trimIndent(), request)
8383
}
8484

85+
@Test
86+
fun shouldReplaceUserInputToFieldWhenUserUseField() {
87+
val customRequestFormat = """
88+
{
89+
"fields": {
90+
"inputs": {
91+
"feature": "${'$'}content"
92+
},
93+
"response_mode": "streaming"
94+
}
95+
}
96+
""".trimIndent()
97+
98+
val customRequest = CustomRequest(listOf(
99+
Message("robot", "robot-hello")
100+
))
101+
102+
val request = customRequest.updateCustomFormat(customRequestFormat)
103+
assertEquals("""
104+
{"inputs":{"feature":"robot-hello"},"response_mode":"streaming"}
105+
""".trimIndent(), request)
106+
}
85107
}

0 commit comments

Comments
 (0)