From 91631aa91aa707c4b67ed132f8f4da15772ae550 Mon Sep 17 00:00:00 2001 From: Jabber Developer Date: Sat, 4 Jul 2026 09:47:28 +0000 Subject: [PATCH] feat(ai): add suport for `/ai set custom` parameters Modify _build_json_payload_from_list to accept an AIProvider parameter and dynamically merge its custom settings into the JSON payload. The settings are serialized as additional key-value pairs alongside the standard model and input fields, enabling per-provider configuration options without hardcoding them. --- src/ai/ai_client.c | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/src/ai/ai_client.c b/src/ai/ai_client.c index 4402975c..5ee3139c 100644 --- a/src/ai/ai_client.c +++ b/src/ai/ai_client.c @@ -1435,13 +1435,17 @@ ai_session_switch(AISession* session, const gchar* provider_name, * This is the thread-safe variant used by _ai_request_thread() which holds * the session lock while calling it. * + * Custom provider settings are merged into the payload as additional JSON + * key-value pairs alongside "model" and "input". + * + * @param provider The AI provider (for custom settings) * @param model The model identifier * @param history GList of AIMessage* (must be held under session lock) * @param prompt The new user prompt to append * @return Newly allocated JSON string (caller must free) */ static gchar* -_build_json_payload_from_list(const gchar* model, GList* history, const gchar* prompt) +_build_json_payload_from_list(AIProvider* provider, const gchar* model, GList* history, const gchar* prompt) { GString* messages_json = g_string_new(""); GList* curr = history; @@ -1468,11 +1472,37 @@ _build_json_payload_from_list(const gchar* model, GList* history, const gchar* p g_string_append_printf(messages_json, "{\"role\":\"user\",\"content\":\"%s\"}", escaped_prompt); auto_gchar gchar* escaped_model = ai_json_escape(model); - gchar* json_payload = g_strdup_printf( - "{\"model\":\"%s\",\"input\":[%s],\"stream\":false,\"store\":false}", - escaped_model, messages_json->str); + + /* Build custom settings JSON fragment */ + GString* custom_json = g_string_new(""); + if (provider && provider->settings) { + GHashTableIter iter; + gpointer key, value; + g_hash_table_iter_init(&iter, provider->settings); + while (g_hash_table_iter_next(&iter, &key, &value)) { + auto_gchar gchar* escaped_key = ai_json_escape((gchar*)key); + auto_gchar gchar* escaped_val = ai_json_escape((gchar*)value); + if (custom_json->len > 0) { + g_string_append_c(custom_json, ','); + } + g_string_append_printf(custom_json, "\"%s\": %s", escaped_key, escaped_val); + } + } + + /* Assemble final payload: model, input, custom settings, then fixed keys */ + gchar* json_payload; + if (custom_json->len > 0) { + json_payload = g_strdup_printf( + "{\"model\":\"%s\",\"input\":[%s],%s,\"stream\":false,\"store\":false}", + escaped_model, messages_json->str, custom_json->str); + } else { + json_payload = g_strdup_printf( + "{\"model\":\"%s\",\"input\":[%s],\"stream\":false,\"store\":false}", + escaped_model, messages_json->str); + } g_string_free(messages_json, TRUE); + g_string_free(custom_json, TRUE); return json_payload; } @@ -1566,7 +1596,7 @@ _ai_request_thread(gpointer data) /* Build JSON payload from history + prompt (under lock), then add user message to history */ log_debug("[AI-THREAD] Building JSON payload..."); pthread_mutex_lock(&session->lock); - auto_gchar gchar* json_payload = _build_json_payload_from_list(local_model, session->history, prompt); + auto_gchar gchar* json_payload = _build_json_payload_from_list(local_provider, local_model, session->history, prompt); /* Add user message to history now (it's in JSON but not yet in history) */ AIMessage* user_msg = g_new0(AIMessage, 1);