refactor(ai): remove default command and enforce strict window context
Some checks failed
CI Code / Check spelling (pull_request) Successful in 23s
CI Code / Check coding style (pull_request) Successful in 37s
CI Code / Code Coverage (pull_request) Failing after 1m8s
CI Code / Linux (ubuntu) (pull_request) Failing after 3m5s
CI Code / Linux (arch) (pull_request) Failing after 3m51s
CI Code / Linux (debian) (pull_request) Failing after 5m58s
Some checks failed
CI Code / Check spelling (pull_request) Successful in 23s
CI Code / Check coding style (pull_request) Successful in 37s
CI Code / Code Coverage (pull_request) Failing after 1m8s
CI Code / Linux (ubuntu) (pull_request) Failing after 3m5s
CI Code / Linux (arch) (pull_request) Failing after 3m51s
CI Code / Linux (debian) (pull_request) Failing after 5m58s
- Remove `/ai set default-provider` command and related autocomplete logic - Remove global `wins_get_ai()` window accessor function - Enforce strict requirement that `/ai model`, `/ai switch`, `/ai models`, and `/ai clear` commands must be executed from within an active AI chat window - Update `/ai start` to require `<provider>` argument BREAKING CHANGE: `/ai model`, `/ai switch`, `/ai models`, and `/ai clear` commands now require an active AI window context. The `/ai set default-provider` command has been removed.
This commit is contained in:
@@ -1192,7 +1192,6 @@ cmd_ac_init(void)
|
|||||||
|
|
||||||
autocomplete_add_unsorted(ai_set_subcommands_ac, "provider", FALSE);
|
autocomplete_add_unsorted(ai_set_subcommands_ac, "provider", FALSE);
|
||||||
autocomplete_add_unsorted(ai_set_subcommands_ac, "token", FALSE);
|
autocomplete_add_unsorted(ai_set_subcommands_ac, "token", FALSE);
|
||||||
autocomplete_add_unsorted(ai_set_subcommands_ac, "default-provider", FALSE);
|
|
||||||
autocomplete_add_unsorted(ai_set_subcommands_ac, "default-model", FALSE);
|
autocomplete_add_unsorted(ai_set_subcommands_ac, "default-model", FALSE);
|
||||||
autocomplete_add_unsorted(ai_set_subcommands_ac, "custom", FALSE);
|
autocomplete_add_unsorted(ai_set_subcommands_ac, "custom", FALSE);
|
||||||
|
|
||||||
@@ -4511,12 +4510,6 @@ _ai_autocomplete(ProfWin* window, const char* const input, gboolean previous)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /ai set default-provider <provider> - autocomplete provider names
|
|
||||||
result = autocomplete_param_with_func(input, "/ai set default-provider", ai_providers_find, previous, NULL);
|
|
||||||
if (result) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// /ai set default-model <provider> <model> - autocomplete provider names
|
// /ai set default-model <provider> <model> - autocomplete provider names
|
||||||
result = autocomplete_param_with_func(input, "/ai set default-model", ai_providers_find, previous, NULL);
|
result = autocomplete_param_with_func(input, "/ai set default-model", ai_providers_find, previous, NULL);
|
||||||
if (result) {
|
if (result) {
|
||||||
@@ -4584,7 +4577,7 @@ _ai_autocomplete(ProfWin* window, const char* const input, gboolean previous)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// /ai switch <model> - autocomplete model names from current session's provider
|
// /ai switch <model> - autocomplete model names from current session's provider
|
||||||
ProfAiWin* aiwin = (window && window->type == WIN_AI) ? (ProfAiWin*)window : wins_get_ai();
|
ProfAiWin* aiwin = (window && window->type == WIN_AI) ? (ProfAiWin*)window : NULL;
|
||||||
result = autocomplete_param_with_func(input, "/ai switch", ai_models_find, previous, aiwin);
|
result = autocomplete_param_with_func(input, "/ai switch", ai_models_find, previous, aiwin);
|
||||||
if (result) {
|
if (result) {
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -2804,7 +2804,6 @@ static const struct cmd_t command_defs[] = {
|
|||||||
"/ai",
|
"/ai",
|
||||||
"/ai set provider <name> <url>",
|
"/ai set provider <name> <url>",
|
||||||
"/ai set token <provider> <token>",
|
"/ai set token <provider> <token>",
|
||||||
"/ai set default-provider <provider>",
|
|
||||||
"/ai set default-model <provider> <model>",
|
"/ai set default-model <provider> <model>",
|
||||||
"/ai set custom <provider> <setting> <value>",
|
"/ai set custom <provider> <setting> <value>",
|
||||||
"/ai remove provider <name>",
|
"/ai remove provider <name>",
|
||||||
@@ -2823,14 +2822,12 @@ static const struct cmd_t command_defs[] = {
|
|||||||
{ "", "Display current AI settings and configured providers" },
|
{ "", "Display current AI settings and configured providers" },
|
||||||
{ "set provider <name> <url>", "Add or update a provider with custom API endpoint" },
|
{ "set provider <name> <url>", "Add or update a provider with custom API endpoint" },
|
||||||
{ "set token <provider> <token>", "Set API token for a provider (e.g., openai, perplexity)" },
|
{ "set token <provider> <token>", "Set API token for a provider (e.g., openai, perplexity)" },
|
||||||
{ "set default-provider <provider>", "Set global default provider for /ai start" },
|
|
||||||
{ "set default-model <provider> <model>", "Set default model for a provider" },
|
{ "set default-model <provider> <model>", "Set default model for a provider" },
|
||||||
{ "set custom <provider> <setting> <value>", "Set provider-level setting (e.g., tools, search)" },
|
{ "set custom <provider> <setting> <value>", "Set provider-level setting (e.g., tools, search)" },
|
||||||
{ "remove provider <name>", "Remove a custom provider" },
|
{ "remove provider <name>", "Remove a custom provider" },
|
||||||
{ "providers", "List configured providers with full details" },
|
{ "providers", "List configured providers with full details" },
|
||||||
{ "start [<provider>] [<model>]", "Start new AI chat (space-separated, uses defaults if omitted)" },
|
{ "start <provider> [<model>]", "Start new AI chat (space-separated, uses defaults if omitted)" },
|
||||||
{ "switch <provider> [<model>]", "Switch to different provider (and optionally model)" },
|
{ "switch <provider> [<model>]", "Switch to different provider (and optionally model)" },
|
||||||
{ "switch <model>", "Change model in current session (keeps provider)" },
|
|
||||||
{ "models <provider>", "Fetch and display available models for provider" },
|
{ "models <provider>", "Fetch and display available models for provider" },
|
||||||
{ "clear", "Clear current chat history" })
|
{ "clear", "Clear current chat history" })
|
||||||
CMD_EXAMPLES(
|
CMD_EXAMPLES(
|
||||||
@@ -2838,7 +2835,6 @@ static const struct cmd_t command_defs[] = {
|
|||||||
"/ai set token openai sk-xxx",
|
"/ai set token openai sk-xxx",
|
||||||
"/ai set token perplexity pplx-xxx",
|
"/ai set token perplexity pplx-xxx",
|
||||||
"/ai set provider custom https://my-api.com/v1/chat/completions",
|
"/ai set provider custom https://my-api.com/v1/chat/completions",
|
||||||
"/ai set default-provider perplexity",
|
|
||||||
"/ai set default-model perplexity sonar",
|
"/ai set default-model perplexity sonar",
|
||||||
"/ai set custom perplexity tools enabled",
|
"/ai set custom perplexity tools enabled",
|
||||||
"/ai remove provider custom",
|
"/ai remove provider custom",
|
||||||
|
|||||||
@@ -10876,23 +10876,6 @@ cmd_ai_set(ProfWin* window, const char* const command, gchar** args)
|
|||||||
cons_show("Setting '%s' for provider '%s' set to: %s", args[3], args[2], args[4]);
|
cons_show("Setting '%s' for provider '%s' set to: %s", args[3], args[2], args[4]);
|
||||||
cons_show("");
|
cons_show("");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} else if (g_strcmp0(args[1], "default-provider") == 0) {
|
|
||||||
// /ai set default-provider <provider>
|
|
||||||
if (g_strv_length(args) < 3) {
|
|
||||||
cons_bad_cmd_usage(command);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
const gchar* provider_name = args[2];
|
|
||||||
AIProvider* provider = ai_get_provider(provider_name);
|
|
||||||
if (!provider) {
|
|
||||||
cons_show_error("Provider '%s' not found. Use '/ai set provider %s <url>' to add it.",
|
|
||||||
provider_name, provider_name);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
prefs_set_string(PREF_AI_PROVIDER, provider_name);
|
|
||||||
cons_show("Default provider set to: %s", provider_name);
|
|
||||||
cons_show("");
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cons_bad_cmd_usage(command);
|
cons_bad_cmd_usage(command);
|
||||||
@@ -11024,12 +11007,12 @@ cmd_ai_model(ProfWin* window, const char* const command, gchar** args)
|
|||||||
|
|
||||||
const gchar* model = args[1];
|
const gchar* model = args[1];
|
||||||
|
|
||||||
// Get current AI window
|
// Must be in an AI window to use this command
|
||||||
ProfAiWin* aiwin = (window && window->type == WIN_AI) ? (ProfAiWin*)window : wins_get_ai();
|
if (!window || window->type != WIN_AI) {
|
||||||
if (!aiwin) {
|
cons_show_error("Must be in an AI chat window to use this command.");
|
||||||
cons_show("No active AI chat window. Use '/ai start' first.");
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
ProfAiWin* aiwin = (ProfAiWin*)window;
|
||||||
|
|
||||||
assert(aiwin->memcheck == PROFAIWIN_MEMCHECK);
|
assert(aiwin->memcheck == PROFAIWIN_MEMCHECK);
|
||||||
|
|
||||||
@@ -11055,12 +11038,12 @@ cmd_ai_switch(ProfWin* window, const char* const command, gchar** args)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get current AI window
|
// Must be in an AI window to use this command
|
||||||
ProfAiWin* aiwin = (window && window->type == WIN_AI) ? (ProfAiWin*)window : wins_get_ai();
|
if (!window || window->type != WIN_AI) {
|
||||||
if (!aiwin) {
|
cons_show_error("Must be in an AI chat window to use this command.");
|
||||||
cons_show("No active AI chat window. Use '/ai start' first.");
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
ProfAiWin* aiwin = (ProfAiWin*)window;
|
||||||
|
|
||||||
assert(aiwin->memcheck == PROFAIWIN_MEMCHECK);
|
assert(aiwin->memcheck == PROFAIWIN_MEMCHECK);
|
||||||
|
|
||||||
@@ -11158,7 +11141,11 @@ cmd_ai_models(ProfWin* window, const char* const command, gchar** args)
|
|||||||
cons_show("Use '/ai models %s' to fetch fresh models from the API.", provider_name);
|
cons_show("Use '/ai models %s' to fetch fresh models from the API.", provider_name);
|
||||||
} else {
|
} else {
|
||||||
// Default: fetch fresh models from API
|
// Default: fetch fresh models from API
|
||||||
ProfAiWin* aiwin = (window && window->type == WIN_AI) ? (ProfAiWin*)window : wins_get_ai();
|
if (!window || window->type != WIN_AI) {
|
||||||
|
cons_show_error("Must be in an AI chat window to fetch models.");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
ProfAiWin* aiwin = (ProfAiWin*)window;
|
||||||
ai_fetch_models(provider_name, aiwin);
|
ai_fetch_models(provider_name, aiwin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11169,18 +11156,20 @@ gboolean
|
|||||||
cmd_ai_clear(ProfWin* window, const char* const command, gchar** args)
|
cmd_ai_clear(ProfWin* window, const char* const command, gchar** args)
|
||||||
{
|
{
|
||||||
// /ai clear
|
// /ai clear
|
||||||
ProfAiWin* aiwin = (window && window->type == WIN_AI) ? (ProfAiWin*)window : wins_get_ai();
|
// Must be in an AI window to use this command
|
||||||
|
if (!window || window->type != WIN_AI) {
|
||||||
if (aiwin) {
|
cons_show_error("Must be in an AI chat window to use this command.");
|
||||||
assert(aiwin->memcheck == PROFAIWIN_MEMCHECK);
|
return TRUE;
|
||||||
if (aiwin->session) {
|
|
||||||
ai_session_clear_history(aiwin->session);
|
|
||||||
}
|
|
||||||
cons_show("Chat history cleared.");
|
|
||||||
} else {
|
|
||||||
cons_show("No active AI chat window to clear.");
|
|
||||||
}
|
}
|
||||||
cons_show("");
|
ProfAiWin* aiwin = (ProfAiWin*)window;
|
||||||
|
|
||||||
|
assert(aiwin->memcheck == PROFAIWIN_MEMCHECK);
|
||||||
|
if (aiwin->session) {
|
||||||
|
ai_session_clear_history(aiwin->session);
|
||||||
|
}
|
||||||
|
|
||||||
|
win_clear(window);
|
||||||
|
cons_show("AI Chat history cleared.");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -867,24 +867,6 @@ wins_get_prune_wins(void)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfAiWin*
|
|
||||||
wins_get_ai(void)
|
|
||||||
{
|
|
||||||
GList* curr = values;
|
|
||||||
|
|
||||||
while (curr) {
|
|
||||||
ProfWin* window = curr->data;
|
|
||||||
if (window->type == WIN_AI) {
|
|
||||||
ProfAiWin* aiwin = (ProfAiWin*)window;
|
|
||||||
assert(aiwin->memcheck == PROFAIWIN_MEMCHECK);
|
|
||||||
return aiwin;
|
|
||||||
}
|
|
||||||
curr = g_list_next(curr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
wins_ai_exists(ProfAiWin* const aiwin)
|
wins_ai_exists(ProfAiWin* const aiwin)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -63,7 +63,6 @@ ProfPrivateWin* wins_get_private(const char* const fulljid);
|
|||||||
ProfPluginWin* wins_get_plugin(const char* const tag);
|
ProfPluginWin* wins_get_plugin(const char* const tag);
|
||||||
ProfXMLWin* wins_get_xmlconsole(void);
|
ProfXMLWin* wins_get_xmlconsole(void);
|
||||||
ProfVcardWin* wins_get_vcard(void);
|
ProfVcardWin* wins_get_vcard(void);
|
||||||
ProfAiWin* wins_get_ai(void);
|
|
||||||
gboolean wins_ai_exists(ProfAiWin* const aiwin);
|
gboolean wins_ai_exists(ProfAiWin* const aiwin);
|
||||||
|
|
||||||
void wins_close_plugin(char* tag);
|
void wins_close_plugin(char* tag);
|
||||||
|
|||||||
Reference in New Issue
Block a user