@@ -86,18 +86,21 @@ class Conversation(
8686 * [RECURRING_TOOL_CALL_LIMIT] times.
8787 *
8888 * @param message The message to send to the model.
89+ * @param extraContext Optional context used for prompt template rendering.
8990 * @return The model's response message.
9091 * @throws IllegalStateException if the conversation is not alive, if the native layer returns an
9192 * invalid response, or if the tool call limit is exceeded.
9293 * @throws LiteRtLmJniException if an error occurs during the native call.
9394 */
94- fun sendMessage (message : Message ): Message {
95+ fun sendMessage (message : Message , extraContext : Map < String , Any > = emptyMap() ): Message {
9596 checkIsAlive()
9697
9798 var currentMessageJson = message.toJson()
99+ var extraContextJsonString = extraContext.toJsonObject().toString()
98100
99101 for (i in 0 .. <RECURRING_TOOL_CALL_LIMIT ) {
100- val responseJsonString = LiteRtLmJni .nativeSendMessage(handle, currentMessageJson.toString())
102+ val responseJsonString =
103+ LiteRtLmJni .nativeSendMessage(handle, currentMessageJson.toString(), extraContextJsonString)
101104 val responseJsonObject = JsonParser .parseString(responseJsonString).asJsonObject
102105
103106 if (responseJsonObject.has("tool_calls")) {
@@ -124,13 +127,14 @@ class Conversation(
124127 * [RECURRING_TOOL_CALL_LIMIT ] times.
125128 *
126129 * @param contents The list of contents to send to the model.
130+ * @param extraContext Optional context used for prompt template rendering.
127131 * @return The model's response message.
128132 * @throws IllegalStateException if the conversation is not alive, if the native layer returns an
129133 * invalid response, or if the tool call limit is exceeded.
130134 * @throws LiteRtLmJniException if an error occurs during the native call.
131135 * /
132- fun sendMessage(contents: Contents ): Message {
133- return sendMessage(Message .user(contents))
136+ fun sendMessage(contents: Contents , extraContext : Map < String , Any > = emptyMap() ): Message {
137+ return sendMessage(Message .user(contents), extraContext )
134138 }
135139
136140 /* *
@@ -142,12 +146,14 @@ class Conversation(
142146 * [RECURRING_TOOL_CALL_LIMIT] times.
143147 *
144148 * @param text The text to send to the model.
149+ * @param extraContext Optional context used for prompt template rendering.
145150 * @return The model's response message.
146151 * @throws IllegalStateException if the conversation is not alive, if the native layer returns an
147152 * invalid response, or if the tool call limit is exceeded.
148153 * @throws LiteRtLmJniException if an error occurs during the native call.
149154 */
150- fun sendMessage(text: String ): Message = sendMessage(Contents .of(text))
155+ fun sendMessage (text : String , extraContext : Map <String , Any > = emptyMap()): Message =
156+ sendMessage(Contents .of(text), extraContext)
151157
152158 /* *
153159 * Send a message to the model and returns the response async with a callback.
@@ -159,14 +165,26 @@ class Conversation(
159165 *
160166 * @param message The message to send to the model.
161167 * @param callback The callback to receive the streaming responses.
168+ * @param extraContext Optional context used for prompt template rendering.
162169 * @throws IllegalStateException if the conversation has already been closed or the content is
163170 * empty.
164171 */
165- fun sendMessageAsync(message: Message , callback: MessageCallback ) {
172+ fun sendMessageAsync (
173+ message : Message ,
174+ callback : MessageCallback ,
175+ extraContext : Map <String , Any > = emptyMap(),
176+ ) {
166177 checkIsAlive()
167178
179+ val extraContextJsonString = extraContext.toJsonObject().toString()
180+
168181 val jniCallback = JniMessageCallbackImpl (callback)
169- LiteRtLmJni .nativeSendMessageAsync(handle, message.toJson().toString(), jniCallback)
182+ LiteRtLmJni .nativeSendMessageAsync(
183+ handle,
184+ message.toJson().toString(),
185+ extraContextJsonString,
186+ jniCallback,
187+ )
170188 }
171189
172190 /* *
@@ -179,11 +197,15 @@ class Conversation(
179197 *
180198 * @param contents The list of contents to send to the model.
181199 * @param callback The callback to receive the streaming responses.
200+ * @param extraContext Optional context used for prompt template rendering.
182201 * @throws IllegalStateException if the conversation has already been closed or the content is
183202 * empty.
184203 */
185- fun sendMessageAsync(contents: Contents , callback: MessageCallback ) =
186- sendMessageAsync(Message .user(contents), callback)
204+ fun sendMessageAsync (
205+ contents : Contents ,
206+ callback : MessageCallback ,
207+ extraContext : Map <String , Any > = emptyMap(),
208+ ) = sendMessageAsync(Message .user(contents), callback, extraContext)
187209
188210 /* *
189211 * Send a text to the model and returns the response async with a callback.
@@ -195,11 +217,15 @@ class Conversation(
195217 *
196218 * @param text The text to send to the model.
197219 * @param callback The callback to receive the streaming responses.
220+ * @param extraContext Optional context used for prompt template rendering.
198221 * @throws IllegalStateException if the conversation has already been closed or the content is
199222 * empty.
200223 */
201- fun sendMessageAsync(text: String , callback: MessageCallback ) =
202- sendMessageAsync(Contents .of(text), callback)
224+ fun sendMessageAsync (
225+ text : String ,
226+ callback : MessageCallback ,
227+ extraContext : Map <String , Any > = emptyMap(),
228+ ) = sendMessageAsync(Contents .of(text), callback, extraContext)
203229
204230 /* *
205231 * Sends a message to the model and returns the response async as a [Flow].
@@ -210,11 +236,15 @@ class Conversation(
210236 * [RECURRING_TOOL_CALL_LIMIT] times.
211237 *
212238 * @param message The message to send to the model.
239+ * @param extraContext Optional context used for prompt template rendering.
213240 * @return A Flow of messages representing the model's response.
214241 * @throws IllegalStateException if the conversation has already been closed or the content is
215242 * empty.
216243 */
217- fun sendMessageAsync(message: Message ): Flow <Message > = callbackFlow {
244+ fun sendMessageAsync (
245+ message : Message ,
246+ extraContext : Map <String , Any > = emptyMap(),
247+ ): Flow <Message > = callbackFlow {
218248 sendMessageAsync(
219249 message,
220250 object : MessageCallback {
@@ -230,6 +260,7 @@ class Conversation(
230260 close(throwable)
231261 }
232262 },
263+ extraContext,
233264 )
234265 awaitClose {}
235266 }
@@ -243,11 +274,15 @@ class Conversation(
243274 * [RECURRING_TOOL_CALL_LIMIT] times.
244275 *
245276 * @param contents The list of contents to send to the model.
277+ * @param extraContext Optional context used for prompt template rendering.
246278 * @return A Flow of messages representing the model's response.
247279 * @throws IllegalStateException if the conversation has already been closed or the content is
248280 * empty.
249281 */
250- fun sendMessageAsync (contents : Contents ): Flow <Message > = sendMessageAsync(Message .user(contents))
282+ fun sendMessageAsync (
283+ contents : Contents ,
284+ extraContext : Map <String , Any > = emptyMap(),
285+ ): Flow <Message > = sendMessageAsync(Message .user(contents), extraContext)
251286
252287 /* *
253288 * Sends a text to the model and returns the response async as a [Flow].
@@ -258,11 +293,13 @@ class Conversation(
258293 * [RECURRING_TOOL_CALL_LIMIT] times.
259294 *
260295 * @param text The text to send to the model.
296+ * @param extraContext Optional context used for prompt template rendering.
261297 * @return A Flow of messages representing the model's response.
262298 * @throws IllegalStateException if the conversation has already been closed or the content is
263299 * empty.
264300 */
265- fun sendMessageAsync (text : String ): Flow <Message > = sendMessageAsync(Contents .of(text))
301+ fun sendMessageAsync (text : String , extraContext : Map <String , Any > = emptyMap()): Flow <Message > =
302+ sendMessageAsync(Contents .of(text), extraContext)
266303
267304 private fun handleToolCalls (toolCallsJsonObject : JsonObject ): JsonObject {
268305 val toolCallsJSONArray = toolCallsJsonObject.getAsJsonArray(" tool_calls" )
@@ -328,6 +365,7 @@ class Conversation(
328365 LiteRtLmJni .nativeSendMessageAsync(
329366 handle,
330367 localToolResponse.toString(),
368+ " {}" ,
331369 this @JniMessageCallbackImpl,
332370 )
333371 pendingToolResponseJSONMessage = null // Clear after sending
0 commit comments