diff --git a/src/ai/ai_client.c b/src/ai/ai_client.c index b5adde4f..3d6f41b8 100644 --- a/src/ai/ai_client.c +++ b/src/ai/ai_client.c @@ -1419,10 +1419,10 @@ _ai_request_thread(gpointer data) * list modifications). We must snapshot all fields atomically. * ===================================================================== */ pthread_mutex_lock(&session->lock); - gchar* local_provider_name = g_strdup(session->provider_name); + auto_gchar gchar* local_provider_name = g_strdup(session->provider_name); AIProvider* local_provider = ai_provider_ref(session->provider); - gchar* local_model = g_strdup(session->model); - gchar* local_api_key = g_strdup(session->api_key ? session->api_key : ""); + auto_gchar gchar* local_model = g_strdup(session->model); + auto_gchar gchar* local_api_key = g_strdup(session->api_key ? session->api_key : ""); pthread_mutex_unlock(&session->lock); log_debug("[AI-THREAD] Session: %s/%s", local_provider_name, local_model); @@ -1434,6 +1434,8 @@ _ai_request_thread(gpointer data) local_provider_name, local_provider_name); log_error("AI request failed for %s/%s: %s", local_provider_name, local_model, error_msg); _aiwin_display_error(user_data, error_msg); + ai_provider_unref(local_provider); + ai_session_unref(session); g_free(args); return NULL; } @@ -1444,6 +1446,8 @@ _ai_request_thread(gpointer data) log_error("AI request failed for %s/%s: Failed to initialize curl", local_provider_name, local_model); _aiwin_display_error(user_data, "Failed to initialize curl."); + ai_provider_unref(local_provider); + ai_session_unref(session); g_free(args); return NULL; } @@ -1492,6 +1496,7 @@ _ai_request_thread(gpointer data) long http_code = 0; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); log_debug("[AI-THREAD] HTTP response code: %ld", http_code); + auto_gchar gchar* response_data = g_steal_pointer(&response.data); if (res != CURLE_OK) { auto_gchar gchar* error_msg = g_strdup(curl_easy_strerror(res)); @@ -1500,17 +1505,14 @@ _ai_request_thread(gpointer data) } else if (http_code >= 400) { /* Handle HTTP errors */ log_debug("[AI-THREAD] HTTP error response body (%zu bytes): %s", - response.size, response.data ? response.data : "NULL"); + response.size, response_data); /* Try to extract the actual error message from the JSON response */ - auto_gchar gchar* parsed_error = ai_parse_error_message(response.data); - auto_gchar gchar* error_msg = parsed_error ? g_strdup_printf("HTTP %ld: %s", http_code, parsed_error) : g_strdup_printf("HTTP %ld: %s", http_code, response.data && strlen(response.data) > 0 ? response.data : "Unknown error"); + auto_gchar gchar* parsed_error = ai_parse_error_message(response_data); + auto_gchar gchar* error_msg = parsed_error ? g_strdup_printf("HTTP %ld: %s", http_code, parsed_error) : g_strdup_printf("HTTP %ld: %s", http_code, response_data && strlen(response_data) > 0 ? response_data : "Unknown error"); log_error("AI request failed for %s/%s: %s", local_provider_name, local_model, error_msg); _aiwin_display_error(user_data, error_msg); } else { - /* Parse response - transfer ownership to auto_gchar for cleanup */ - log_debug("[AI-THREAD] Raw API response (%zu bytes): %s", response.size, response.data ? response.data : "NULL"); - auto_gchar gchar* response_data = response.data; - response.data = NULL; + log_debug("[AI-THREAD] Raw API response (%zu bytes): %s", response.size, response_data); auto_gchar gchar* content = ai_parse_response(response_data); if (content) { /* Add assistant response to history (under lock) */ @@ -1531,12 +1533,9 @@ _ai_request_thread(gpointer data) curl_slist_free_all(headers); curl_easy_cleanup(curl); - /* Cleanup local copies */ - g_free(local_provider_name); ai_provider_unref(local_provider); - g_free(local_model); - g_free(local_api_key); + ai_session_unref(session); g_free(args); return NULL; diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index 184b88b9..1600078c 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -8516,7 +8516,8 @@ _cmd_execute_default(ProfWin* window, const char* inp) case WIN_AI: { ProfAiWin* aiwin = (ProfAiWin*)window; - cl_ev_send_ai_msg(aiwin, inp, connection_create_stanza_id()); + auto_gchar gchar* stanza_id = connection_create_stanza_id(); + cl_ev_send_ai_msg(aiwin, inp, stanza_id); break; } default: @@ -10980,6 +10981,9 @@ cmd_ai_start(ProfWin* window, const char* const command, gchar** args) } log_debug("[AI-CMD] wins_new_ai() returned successfully, window type: %d", ai_win->type); + // Release the reference held by cmd_ai_start, since the window now holds one + ai_session_unref(session); + // Add welcome message to the AI window log_debug("[AI-CMD] Adding welcome messages..."); win_println(ai_win, THEME_DEFAULT, "-", "AI Chat: %s/%s", provider_name, model);