@dr33m/react-native-litert-lm 0.6.3 → 0.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -800,7 +800,7 @@ class HybridLiteRTLM : HybridLiteRTLMSpec() {
|
|
|
800
800
|
}
|
|
801
801
|
conversation = null
|
|
802
802
|
}
|
|
803
|
-
// Map tools
|
|
803
|
+
// Map tools. The engine only parses calls; JS runs them (see `automaticToolCalling`).
|
|
804
804
|
val lmTools: List<ToolProvider>? = tools?.map { toolDef ->
|
|
805
805
|
val apiTool = object : OpenApiTool {
|
|
806
806
|
override fun getToolDescriptionJsonString(): String {
|
|
@@ -812,12 +812,9 @@ class HybridLiteRTLM : HybridLiteRTLMSpec() {
|
|
|
812
812
|
return fullDesc.toString()
|
|
813
813
|
}
|
|
814
814
|
override fun execute(paramsJsonString: String): String {
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
argumentsJson = paramsJsonString
|
|
819
|
-
))
|
|
820
|
-
return "{\"status\": \"pending\", \"message\": \"Tool execution delegated to application\"}"
|
|
815
|
+
// Never invoked: automatic tool calling is off, so tool
|
|
816
|
+
// execution happens on the JS side.
|
|
817
|
+
return "{}"
|
|
821
818
|
}
|
|
822
819
|
}
|
|
823
820
|
tool(apiTool)
|
|
@@ -834,6 +831,17 @@ class HybridLiteRTLM : HybridLiteRTLMSpec() {
|
|
|
834
831
|
systemInstruction = systemPrompt?.let { Contents.of(Content.Text(it)) },
|
|
835
832
|
initialMessages = initialMessages,
|
|
836
833
|
tools = lmTools ?: emptyList(),
|
|
834
|
+
/*
|
|
835
|
+
* Off, ported from upstream (hung-yueh 2cc938a). The SDK default runs
|
|
836
|
+
* each parsed call against `execute()` above, which was a stub, and
|
|
837
|
+
* feeds that stub's reply straight back to the model in the same
|
|
838
|
+
* turn. The model then answered the stub: prose claiming a result it
|
|
839
|
+
* never had ("I have removed it…"), streamed to the reader, then
|
|
840
|
+
* discarded once JS ran the real tool and generated again. A wasted
|
|
841
|
+
* generation per call, and its tokens stayed in the KV cache.
|
|
842
|
+
* With it off, calls arrive on `Message.toolCalls` instead.
|
|
843
|
+
*/
|
|
844
|
+
automaticToolCalling = false,
|
|
837
845
|
// Available since LiteRT-LM 0.15.0; before that the Kotlin SDK had no
|
|
838
846
|
// way to express it and every Android reply ran to the engine default.
|
|
839
847
|
maxOutputToken = maxOutputTokens,
|
|
@@ -1023,7 +1031,8 @@ class HybridLiteRTLM : HybridLiteRTLMSpec() {
|
|
|
1023
1031
|
history = history,
|
|
1024
1032
|
userMessage = userTextRepresentation,
|
|
1025
1033
|
onStatsReady = { stats -> lastStats = stats },
|
|
1026
|
-
onFailure = { e -> errorRef.set(e) }
|
|
1034
|
+
onFailure = { e -> errorRef.set(e) },
|
|
1035
|
+
onToolCalls = { calls -> captureToolCalls(calls) }
|
|
1027
1036
|
)
|
|
1028
1037
|
|
|
1029
1038
|
try {
|
|
@@ -1061,6 +1070,7 @@ class HybridLiteRTLM : HybridLiteRTLMSpec() {
|
|
|
1061
1070
|
.joinToString("") { it.text }
|
|
1062
1071
|
|
|
1063
1072
|
val thinkingText = responseMsg.channels["thought"] ?: ""
|
|
1073
|
+
captureToolCalls(responseMsg.toolCalls)
|
|
1064
1074
|
|
|
1065
1075
|
history.add(Message(Role.MODEL, response))
|
|
1066
1076
|
|
|
@@ -1094,6 +1104,15 @@ class HybridLiteRTLM : HybridLiteRTLMSpec() {
|
|
|
1094
1104
|
}
|
|
1095
1105
|
}
|
|
1096
1106
|
|
|
1107
|
+
/** Records SDK-parsed calls in the shape JS receives on `ExecuteResult.toolCalls`. */
|
|
1108
|
+
private fun captureToolCalls(calls: List<com.google.ai.edge.litertlm.ToolCall>?) {
|
|
1109
|
+
for (call in calls.orEmpty()) {
|
|
1110
|
+
val argumentsJson = org.json.JSONObject(call.arguments).toString()
|
|
1111
|
+
Log.d(TAG, "Tool called: ${call.name} with args: $argumentsJson")
|
|
1112
|
+
pendingToolCalls.add(ToolCall(name = call.name, argumentsJson = argumentsJson))
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1097
1116
|
override fun sendToolResponse(
|
|
1098
1117
|
responses: Array<ToolResponse>,
|
|
1099
1118
|
onToken: ((token: String, done: Boolean) -> Unit)?
|
package/android/src/main/java/com/margelo/nitro/dev/litert/litertlm/StreamingCallbackListener.kt
CHANGED
|
@@ -18,6 +18,8 @@ internal class StreamingCallbackListener(
|
|
|
18
18
|
private val onStatsReady: (GenerationStats) -> Unit,
|
|
19
19
|
private val onFailure: ((Throwable) -> Unit)? = null,
|
|
20
20
|
private val onThinkingToken: ((String) -> Unit)? = null,
|
|
21
|
+
/** Tool calls the engine parsed out of this reply. They arrive on the final message. */
|
|
22
|
+
private val onToolCalls: ((List<com.google.ai.edge.litertlm.ToolCall>) -> Unit)? = null,
|
|
21
23
|
) : com.google.ai.edge.litertlm.MessageCallback {
|
|
22
24
|
|
|
23
25
|
private val startTime = System.nanoTime()
|
|
@@ -29,6 +31,8 @@ internal class StreamingCallbackListener(
|
|
|
29
31
|
.filterIsInstance<Content.Text>()
|
|
30
32
|
.joinToString("") { it.text }
|
|
31
33
|
|
|
34
|
+
if (message.toolCalls.isNotEmpty()) onToolCalls?.invoke(message.toolCalls)
|
|
35
|
+
|
|
32
36
|
// Capture thinking from the "thought" channel
|
|
33
37
|
val thinkingChunk = message.channels["thought"]
|
|
34
38
|
if (!thinkingChunk.isNullOrEmpty()) {
|
package/ios/HybridLiteRTLM.swift
CHANGED
|
@@ -431,15 +431,16 @@ public class HybridLiteRTLM: HybridLiteRTLMSpec_base, HybridLiteRTLMSpec_protoco
|
|
|
431
431
|
|
|
432
432
|
litert_lm_session_config_set_max_output_tokens(sessionConfig, Int32(self.maxOutputTokens))
|
|
433
433
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
sampler
|
|
438
|
-
|
|
439
|
-
sampler.
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
434
|
+
// v0.15: sampler params are opaque — built through create/setters
|
|
435
|
+
// instead of a stack struct. set_sampler_params copies the values into
|
|
436
|
+
// the session config, so the params can be freed when this scope ends.
|
|
437
|
+
guard let sampler = litert_lm_sampler_params_create(kLiteRtLmSamplerTypeTopP) else { return }
|
|
438
|
+
defer { litert_lm_sampler_params_delete(sampler) }
|
|
439
|
+
litert_lm_sampler_params_set_top_k(sampler, Int32(self.topK))
|
|
440
|
+
litert_lm_sampler_params_set_top_p(sampler, Float(self.topP))
|
|
441
|
+
litert_lm_sampler_params_set_temperature(sampler, Float(self.temperature))
|
|
442
|
+
litert_lm_sampler_params_set_seed(sampler, 0)
|
|
443
|
+
litert_lm_session_config_set_sampler_params(sessionConfig, sampler)
|
|
443
444
|
|
|
444
445
|
litert_lm_conversation_config_set_session_config(convConfig, sessionConfig)
|
|
445
446
|
|