@@ -45,7 +45,10 @@ struct rac_llm_component {
4545 /* * Mutex for thread safety */
4646 std::mutex mtx;
4747
48- rac_llm_component () : lifecycle(nullptr ) {
48+ /* * Resolved inference framework (defaults to LlamaCPP, the primary LLM backend) */
49+ rac_inference_framework_t actual_framework;
50+
51+ rac_llm_component () : lifecycle(nullptr ), actual_framework(RAC_FRAMEWORK_LLAMACPP) {
4952 // Initialize with defaults - matches rac_llm_types.h rac_llm_config_t
5053 config = RAC_LLM_CONFIG_DEFAULT;
5154
@@ -178,6 +181,13 @@ extern "C" rac_result_t rac_llm_component_configure(rac_handle_t handle,
178181 // Mirrors Swift's: self.config = config
179182 component->config = *config;
180183
184+ // Resolve actual framework: if caller explicitly set one (not UNKNOWN=99), use it;
185+ // otherwise keep the default (RAC_FRAMEWORK_LLAMACPP for LLM components)
186+ if (config->preferred_framework != static_cast <int32_t >(RAC_FRAMEWORK_UNKNOWN)) {
187+ component->actual_framework =
188+ static_cast <rac_inference_framework_t >(config->preferred_framework );
189+ }
190+
181191 // Update default options based on config
182192 if (config->max_tokens > 0 ) {
183193 component->default_options .max_tokens = config->max_tokens ;
@@ -235,9 +245,51 @@ extern "C" rac_result_t rac_llm_component_load_model(rac_handle_t handle, const
235245 auto * component = reinterpret_cast <rac_llm_component*>(handle);
236246 std::lock_guard<std::mutex> lock (component->mtx );
237247
248+ // Emit model load started event
249+ {
250+ rac_analytics_event_data_t event = {};
251+ event.type = RAC_EVENT_LLM_MODEL_LOAD_STARTED;
252+ event.data .llm_model .model_id = model_id;
253+ event.data .llm_model .model_name = model_name;
254+ event.data .llm_model .framework = component->actual_framework ;
255+ event.data .llm_model .error_code = RAC_SUCCESS;
256+ rac_analytics_event_emit (RAC_EVENT_LLM_MODEL_LOAD_STARTED, &event);
257+ }
258+
259+ auto load_start = std::chrono::steady_clock::now ();
260+
238261 // Delegate to lifecycle manager with separate path, model_id, and model_name
239262 rac_handle_t service = nullptr ;
240- return rac_lifecycle_load (component->lifecycle , model_path, model_id, model_name, &service);
263+ rac_result_t result =
264+ rac_lifecycle_load (component->lifecycle , model_path, model_id, model_name, &service);
265+
266+ double load_duration_ms = static_cast <double >(
267+ std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now () -
268+ load_start)
269+ .count ());
270+
271+ if (result != RAC_SUCCESS) {
272+ rac_analytics_event_data_t event = {};
273+ event.type = RAC_EVENT_LLM_MODEL_LOAD_FAILED;
274+ event.data .llm_model .model_id = model_id;
275+ event.data .llm_model .model_name = model_name;
276+ event.data .llm_model .framework = component->actual_framework ;
277+ event.data .llm_model .duration_ms = load_duration_ms;
278+ event.data .llm_model .error_code = result;
279+ event.data .llm_model .error_message = " Model load failed" ;
280+ rac_analytics_event_emit (RAC_EVENT_LLM_MODEL_LOAD_FAILED, &event);
281+ } else {
282+ rac_analytics_event_data_t event = {};
283+ event.type = RAC_EVENT_LLM_MODEL_LOAD_COMPLETED;
284+ event.data .llm_model .model_id = model_id;
285+ event.data .llm_model .model_name = model_name;
286+ event.data .llm_model .framework = component->actual_framework ;
287+ event.data .llm_model .duration_ms = load_duration_ms;
288+ event.data .llm_model .error_code = RAC_SUCCESS;
289+ rac_analytics_event_emit (RAC_EVENT_LLM_MODEL_LOAD_COMPLETED, &event);
290+ }
291+
292+ return result;
241293}
242294
243295extern " C" rac_result_t rac_llm_component_unload (rac_handle_t handle) {
@@ -324,8 +376,7 @@ extern "C" rac_result_t rac_llm_component_generate(rac_handle_t handle, const ch
324376 event.data .llm_generation .model_id = model_id;
325377 event.data .llm_generation .model_name = model_name;
326378 event.data .llm_generation .is_streaming = RAC_FALSE;
327- event.data .llm_generation .framework =
328- static_cast <rac_inference_framework_t >(component->config .preferred_framework );
379+ event.data .llm_generation .framework = component->actual_framework ;
329380 event.data .llm_generation .temperature = effective_options->temperature ;
330381 event.data .llm_generation .max_tokens = effective_options->max_tokens ;
331382 event.data .llm_generation .context_length = context_length;
@@ -402,8 +453,7 @@ extern "C" rac_result_t rac_llm_component_generate(rac_handle_t handle, const ch
402453 event.data .llm_generation .tokens_per_second = tokens_per_second;
403454 event.data .llm_generation .is_streaming = RAC_FALSE;
404455 event.data .llm_generation .time_to_first_token_ms = 0 ;
405- event.data .llm_generation .framework =
406- static_cast <rac_inference_framework_t >(component->config .preferred_framework );
456+ event.data .llm_generation .framework = component->actual_framework ;
407457 event.data .llm_generation .temperature = effective_options->temperature ;
408458 event.data .llm_generation .max_tokens = effective_options->max_tokens ;
409459 event.data .llm_generation .context_length = context_length;
@@ -594,8 +644,7 @@ extern "C" rac_result_t rac_llm_component_generate_stream(
594644 event.data .llm_generation .model_id = model_id;
595645 event.data .llm_generation .model_name = model_name;
596646 event.data .llm_generation .is_streaming = RAC_TRUE;
597- event.data .llm_generation .framework =
598- static_cast <rac_inference_framework_t >(component->config .preferred_framework );
647+ event.data .llm_generation .framework = component->actual_framework ;
599648 event.data .llm_generation .temperature = effective_options->temperature ;
600649 event.data .llm_generation .max_tokens = effective_options->max_tokens ;
601650 event.data .llm_generation .context_length = context_length;
@@ -614,7 +663,7 @@ extern "C" rac_result_t rac_llm_component_generate_stream(
614663 ctx.generation_id = generation_id;
615664 ctx.model_id = model_id;
616665 ctx.model_name = model_name;
617- ctx.framework = static_cast < rac_inference_framework_t >( component->config . preferred_framework ) ;
666+ ctx.framework = component->actual_framework ;
618667 ctx.temperature = effective_options->temperature ;
619668 ctx.max_tokens = effective_options->max_tokens ;
620669 ctx.token_count = 0 ;
@@ -691,8 +740,7 @@ extern "C" rac_result_t rac_llm_component_generate_stream(
691740 event.data .llm_generation .tokens_per_second = tokens_per_second;
692741 event.data .llm_generation .is_streaming = RAC_TRUE;
693742 event.data .llm_generation .time_to_first_token_ms = ttft_ms;
694- event.data .llm_generation .framework =
695- static_cast <rac_inference_framework_t >(component->config .preferred_framework );
743+ event.data .llm_generation .framework = component->actual_framework ;
696744 event.data .llm_generation .temperature = effective_options->temperature ;
697745 event.data .llm_generation .max_tokens = effective_options->max_tokens ;
698746 event.data .llm_generation .context_length = context_length;
0 commit comments