ref(ai): remove org_id from provider configuration
Some checks failed
CI Code / Code Coverage (pull_request) Failing after 10m47s
CI Code / Check spelling (pull_request) Failing after 10m58s
CI Code / Check coding style (pull_request) Failing after 11m10s
CI Code / Linux (ubuntu) (pull_request) Failing after 11m30s
CI Code / Linux (debian) (pull_request) Failing after 11m42s
CI Code / Linux (arch) (pull_request) Failing after 11m54s

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
This commit is contained in:
2026-05-11 22:58:39 +00:00
parent b1dbe714e8
commit 6fe8c370df
4 changed files with 25 additions and 43 deletions

View File

@@ -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;
}

View File

@@ -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.

View File

@@ -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);
}

View File

@@ -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\", "