From 6fe8c370df965085e55f32c021cd7ae0e32c6b0c Mon Sep 17 00:00:00 2001 From: Jabber Developer Date: Mon, 11 May 2026 22:58:39 +0000 Subject: [PATCH] ref(ai): remove org_id from provider configuration The org_id field was removed from AIProvider as it was no longer populated through the command surface. The /ai set org command was previously removed, leaving org_id as dead code. This change removes org_id from: - AIProvider struct definition - ai_provider_new() and ai_provider_unref() - ai_add_provider() API signature - _build_curl_headers() (OpenAI-Organization header) - cmd_ai_set() and cmd_ai_providers() - All unit tests --- src/ai/ai_client.c | 21 +++++------------- src/ai/ai_client.h | 4 +--- src/command/cmd_funcs.c | 5 +---- tests/unittests/test_ai_client.c | 38 ++++++++++++++------------------ 4 files changed, 25 insertions(+), 43 deletions(-) diff --git a/src/ai/ai_client.c b/src/ai/ai_client.c index da891e8d..f36767c2 100644 --- a/src/ai/ai_client.c +++ b/src/ai/ai_client.c @@ -190,12 +190,11 @@ ai_json_escape(const gchar* str) * ======================================================================== */ static AIProvider* -ai_provider_new(const gchar* name, const gchar* api_url, const gchar* org_id) +ai_provider_new(const gchar* name, const gchar* api_url) { AIProvider* provider = g_new0(AIProvider, 1); provider->name = g_strdup(name); provider->api_url = g_strdup(api_url ? api_url : ""); - provider->org_id = g_strdup(org_id); provider->project_id = NULL; provider->default_model = NULL; provider->settings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); @@ -226,7 +225,6 @@ ai_provider_unref(AIProvider* provider) g_free(provider->name); g_free(provider->api_url); - g_free(provider->org_id); g_free(provider->project_id); g_free(provider->default_model); g_hash_table_destroy(provider->settings); @@ -284,8 +282,8 @@ ai_client_init(void) providers_ac = autocomplete_new(); /* Add default providers */ - ai_add_provider("openai", DEFAULT_OPENAI_URL, NULL); - ai_add_provider("perplexity", DEFAULT_PERPLEXITY_URL, NULL); + ai_add_provider("openai", DEFAULT_OPENAI_URL); + ai_add_provider("perplexity", DEFAULT_PERPLEXITY_URL); /* Load saved API keys from config */ ai_load_keys(); @@ -332,7 +330,7 @@ ai_get_provider(const gchar* name) } AIProvider* -ai_add_provider(const gchar* name, const gchar* api_url, const gchar* org_id) +ai_add_provider(const gchar* name, const gchar* api_url) { if (!name || !api_url) return NULL; @@ -347,14 +345,12 @@ ai_add_provider(const gchar* name, const gchar* api_url, const gchar* org_id) /* Update existing provider */ g_free(existing->api_url); existing->api_url = g_strdup(api_url); - g_free(existing->org_id); - existing->org_id = g_strdup(org_id); log_info("Updated provider: %s", name); return ai_provider_ref(existing); } /* Create new provider (ref_count=1 owned by hash table) */ - AIProvider* provider = ai_provider_new(name, api_url, org_id); + AIProvider* provider = ai_provider_new(name, api_url); g_hash_table_insert(providers, g_strdup(name), provider); /* Sync autocomplete */ @@ -567,7 +563,7 @@ typedef struct } ai_request_t; /** - * Build curl headers with auth and optional org header. + * Build curl headers with auth. * Returns headers list (caller must free with curl_slist_free_all). */ static struct curl_slist* @@ -578,11 +574,6 @@ _build_curl_headers(AIProvider* provider, const gchar* api_key) headers = curl_slist_append(headers, "Content-Type: application/json"); headers = curl_slist_append(headers, auth_header); - if (provider && provider->org_id && strlen(provider->org_id) > 0) { - auto_gchar gchar* org_header = g_strdup_printf("OpenAI-Organization: %s", provider->org_id); - headers = curl_slist_append(headers, org_header); - } - return headers; } diff --git a/src/ai/ai_client.h b/src/ai/ai_client.h index eb41bcce..7728b3ab 100644 --- a/src/ai/ai_client.h +++ b/src/ai/ai_client.h @@ -19,7 +19,6 @@ typedef struct ai_provider_t { gchar* name; /* Provider name (e.g., "openai", "perplexity") */ gchar* api_url; /* API endpoint URL */ - gchar* org_id; /* Optional organization ID */ gchar* project_id; /* Optional project ID (for some providers) */ gchar* default_model; /* Default model for this provider */ GHashTable* settings; /* Extensible per-provider settings (e.g., tools=enabled, search=disabled) */ @@ -66,10 +65,9 @@ AIProvider* ai_get_provider(const gchar* name); * Add or update a provider configuration. * @param name The provider name * @param api_url The API endpoint URL - * @param org_id Optional organization ID (can be NULL) * @return New AIProvider* (caller must unref when done) */ -AIProvider* ai_add_provider(const gchar* name, const gchar* api_url, const gchar* org_id); +AIProvider* ai_add_provider(const gchar* name, const gchar* api_url); /** * Remove a provider by name. diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index 79ffc094..9d6678d4 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -10839,7 +10839,7 @@ cmd_ai_set(ProfWin* window, const char* const command, gchar** args) cons_bad_cmd_usage(command); return TRUE; } - if (ai_add_provider(args[2], args[3], NULL)) { + if (ai_add_provider(args[2], args[3])) { cons_show("Provider '%s' configured with URL: %s", args[2], args[3]); } else { cons_show_error("Failed to configure provider '%s'.", args[2]); @@ -11218,9 +11218,6 @@ cmd_ai_providers(ProfWin* window, const char* const command, gchar** args) cons_show(" %s", provider->name); cons_show(" URL: %s", provider->api_url); cons_show(" Key: %s", key ? "configured" : "NOT configured"); - if (provider->org_id && strlen(provider->org_id) > 0) { - cons_show(" Org: %s", provider->org_id); - } cons_show(""); g_free(key); } diff --git a/tests/unittests/test_ai_client.c b/tests/unittests/test_ai_client.c index 7c1cf16c..d482cc01 100644 --- a/tests/unittests/test_ai_client.c +++ b/tests/unittests/test_ai_client.c @@ -44,17 +44,15 @@ void test_ai_add_provider(void** state) { /* Add a custom provider (hash table owns ref; caller gets non-owning pointer) */ - AIProvider* provider = ai_add_provider("custom", "https://custom.api.com/v1", "my-org"); + AIProvider* provider = ai_add_provider("custom", "https://custom.api.com/v1"); assert_non_null(provider); assert_string_equal("custom", provider->name); assert_string_equal("https://custom.api.com/v1", provider->api_url); - assert_string_equal("my-org", provider->org_id); /* Update existing provider (returns ref; caller owns it) */ - AIProvider* updated = ai_add_provider("custom", "https://new.api.com/v1", NULL); + AIProvider* updated = ai_add_provider("custom", "https://new.api.com/v1"); assert_non_null(updated); assert_string_equal("https://new.api.com/v1", updated->api_url); - assert_null(updated->org_id); ai_provider_unref(updated); } @@ -66,7 +64,7 @@ test_ai_remove_provider(void** state) assert_false(ai_remove_provider("nonexistent")); /* Add and remove custom provider */ - ai_add_provider("temp", "https://temp.api.com/v1", NULL); + ai_add_provider("temp", "https://temp.api.com/v1"); assert_true(ai_remove_provider("temp")); assert_null(ai_get_provider("temp")); } @@ -82,7 +80,7 @@ test_ai_list_providers(void** state) g_list_free(providers); /* Add another provider */ - ai_add_provider("test", "https://test.api.com/v1", NULL); + ai_add_provider("test", "https://test.api.com/v1"); providers = ai_list_providers(); assert_int_equal(3, g_list_length(providers)); @@ -301,29 +299,27 @@ void test_ai_add_provider_update_existing(void** state) { /* Add a provider (hash table owns ref) */ - AIProvider* provider = ai_add_provider("custom", "https://first.api.com/v1", "org1"); + AIProvider* provider = ai_add_provider("custom", "https://first.api.com/v1"); assert_non_null(provider); assert_string_equal("https://first.api.com/v1", provider->api_url); - assert_string_equal("org1", provider->org_id); /* Update the same provider (returns ref) */ - provider = ai_add_provider("custom", "https://second.api.com/v1", "org2"); + provider = ai_add_provider("custom", "https://second.api.com/v1"); assert_non_null(provider); assert_string_equal("https://second.api.com/v1", provider->api_url); - assert_string_equal("org2", provider->org_id); ai_provider_unref(provider); } void test_ai_add_provider_null_name_returns_null(void** state) { - assert_null(ai_add_provider(NULL, "https://api.com/v1", NULL)); + assert_null(ai_add_provider(NULL, "https://api.com/v1")); } void test_ai_add_provider_null_url_returns_null(void** state) { - assert_null(ai_add_provider("test", NULL, NULL)); + assert_null(ai_add_provider("test", NULL)); } void @@ -374,7 +370,7 @@ void test_ai_providers_find_forward_custom(void** state) { /* Add a custom provider and test */ - ai_add_provider("custom", "https://custom.api.com/v1", NULL); + ai_add_provider("custom", "https://custom.api.com/v1"); auto_gchar gchar* result = ai_providers_find("c", FALSE, NULL); assert_non_null(result); @@ -484,7 +480,7 @@ test_ai_models_find_null_session(void** state) void test_ai_models_find_null_provider(void** state) { - ai_add_provider("temp", "https://temp.api.com/v1", NULL); + ai_add_provider("temp", "https://temp.api.com/v1"); AISession* session = ai_session_create("temp", "gpt-4"); assert_non_null(session); ai_session_unref(session); @@ -656,7 +652,7 @@ test_ai_parse_models_openai_format(void** state) /* Format: {"object":"list","data":[{"id":"model1",...},...]} */ ai_client_init(); - AIProvider* provider = ai_add_provider("test", "https://test.api.com/v1", NULL); + AIProvider* provider = ai_add_provider("test", "https://test.api.com/v1"); /* JSON response from Perplexity/OpenAI API */ const gchar* json = "{\"object\":\"list\"," @@ -692,7 +688,7 @@ test_ai_parse_models_perplexity_format(void** state) /* Test parsing actual Perplexity API response with all models from curl test */ ai_client_init(); - AIProvider* provider = ai_add_provider("perplexity", "https://api.perplexity.ai/", NULL); + AIProvider* provider = ai_add_provider("perplexity", "https://api.perplexity.ai/"); const gchar* json = "{\"object\":\"list\"," "\"data\":[" @@ -765,7 +761,7 @@ test_ai_parse_models_array_format(void** state) /* Test parsing simple array format: ["model1", "model2", ...] */ ai_client_init(); - AIProvider* provider = ai_add_provider("test", "https://test.api.com/v1", NULL); + AIProvider* provider = ai_add_provider("test", "https://test.api.com/v1"); const gchar* json = "[\"model1\", \"model2\", \"model3\"]"; @@ -790,7 +786,7 @@ test_ai_parse_models_empty_json(void** state) /* Test parsing empty/invalid JSON */ ai_client_init(); - AIProvider* provider = ai_add_provider("test", "https://test.api.com/v1", NULL); + AIProvider* provider = ai_add_provider("test", "https://test.api.com/v1"); ai_parse_models_from_json(provider, ""); assert_null(provider->models); @@ -810,7 +806,7 @@ test_ai_parse_models_null_handling(void** state) /* Test NULL handling */ ai_client_init(); - AIProvider* provider = ai_add_provider("test", "https://test.api.com/v1", NULL); + AIProvider* provider = ai_add_provider("test", "https://test.api.com/v1"); /* NULL json should not crash */ ai_parse_models_from_json(provider, NULL); @@ -826,7 +822,7 @@ test_ai_parse_models_escaped_quotes(void** state) /* Test parsing model IDs with escaped quotes */ ai_client_init(); - AIProvider* provider = ai_add_provider("test", "https://test.api.com/v1", NULL); + AIProvider* provider = ai_add_provider("test", "https://test.api.com/v1"); const gchar* json = "{\"object\":\"list\"," "\"data\":[" @@ -850,7 +846,7 @@ test_ai_parse_models_with_whitespace(void** state) /* Test parsing JSON with whitespace after colons */ ai_client_init(); - AIProvider* provider = ai_add_provider("test", "https://test.api.com/v1", NULL); + AIProvider* provider = ai_add_provider("test", "https://test.api.com/v1"); /* JSON with spaces after colons (common in formatted JSON) */ const gchar* json = "{ \"object\": \"list\", "