createConversation method
void
createConversation({})
Create a new conversation with optional system message and tools.
Implementation
void createConversation({
String? systemMessage,
String? toolsJson,
double temperature = 0.8,
int topK = 40,
double? topP,
int seed = 1,
}) {
_assertInitialized();
final b = _bindings!;
// Close existing conversation if any
if (_conversation != null && _conversation != nullptr) {
b.litert_lm_conversation_delete(_conversation!);
_conversation = null;
}
// Always build a sessionConfig with the caller's sampler params — even
// when there's no systemMessage/tools. Otherwise temperature, topK,
// topP, and seed get silently dropped on the floor and the model
// falls back to its baked-in defaults (typically greedy), making
// every call ignore stochastic decoding requests.
//
// This requires a patched libLiteRtLm.{so,dylib,dll} where
// litert_lm_conversation_config_create accepts the 6-arg overload
// and applies session_config via the upstream setter chain. See
// native/litert_lm/patch_c_api.sh ("PATCH: 6-arg overload").
final sessionConfig = b.litert_lm_session_config_create();
final samplerParams = calloc<LiteRtLmSamplerParams>();
// Upstream LiteRT-LM (commit 5e0d86b) only implements TopP sampling at
// engine level — sampler type 1 (TopK) and 3 (Greedy) are rejected with
// "UNIMPLEMENTED: Sampler type: N not implemented yet." Use TopP (=2)
// unconditionally and pass top_k as a hint; native respects both fields
// even though it's gated by the type tag.
samplerParams.ref.typeAsInt = 2; // always TopP
samplerParams.ref.top_k = topK;
samplerParams.ref.top_p = topP ?? 0.95;
samplerParams.ref.temperature = temperature;
samplerParams.ref.seed = seed;
b.litert_lm_session_config_set_sampler_params(sessionConfig, samplerParams);
calloc.free(samplerParams);
final systemPtr = systemMessage?.toNativeUtf8();
final toolsPtr = toolsJson?.toNativeUtf8();
final Pointer<LiteRtLmConversationConfig> convConfig =
b.litert_lm_conversation_config_create(
_engine!,
sessionConfig,
systemPtr?.cast() ?? nullptr,
toolsPtr?.cast() ?? nullptr,
nullptr,
toolsJson != null,
);
b.litert_lm_session_config_delete(sessionConfig);
if (systemPtr != null) calloc.free(systemPtr);
if (toolsPtr != null) calloc.free(toolsPtr);
if (convConfig == nullptr) {
throw Exception(
'litert_lm_conversation_config_create returned null '
'(systemMessage=${systemMessage != null}, tools=${toolsJson != null}, '
'temperature=$temperature, topK=$topK, topP=$topP)',
);
}
_conversation = b.litert_lm_conversation_create(_engine!, convConfig);
b.litert_lm_conversation_config_delete(convConfig);
if (_conversation == null || _conversation == nullptr) {
_dumpNativeLog();
throw Exception('Failed to create conversation');
}
debugPrint('[LiteRtLmFfi] Conversation created');
}