#ifndef AI_CLIENT_H #define AI_CLIENT_H #include /** * @brief AI message structure for conversation history. */ typedef struct ai_message_t { gchar* role; /* "user" or "assistant" */ gchar* content; /* Message content */ } AIMessage; /** * @brief AI provider configuration. */ typedef struct ai_provider_t { gchar* name; /* Provider name (e.g., "openai", "perplexity") */ gchar* api_url; /* API endpoint URL */ 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) */ GList* models; /* Cached models (gchar*) */ gboolean models_fresh; /* Whether models cache is current */ gint32 ref_count; /* Reference count (atomic) */ } AIProvider; /** * @brief AI chat session structure. */ typedef struct ai_session_t { gchar* provider_name; /* Provider name */ AIProvider* provider; /* Provider configuration */ gchar* model; /* Model identifier (e.g., "gpt-4", "sonar") */ gchar* api_key; /* API key for this session */ GList* history; /* Conversation history (GList of AIMessage*) */ gint32 ref_count; /* Reference count (atomic) */ } AISession; /* ======================================================================== * Provider Management * ======================================================================== */ /** * Initialize the AI client and load default providers. */ void ai_client_init(void); /** * Shutdown the AI client and free resources. */ void ai_client_shutdown(void); /** * Get a provider by name. * @param name The provider name (e.g., "openai", "perplexity") * @return AIProvider*, or NULL if not found */ 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 * @return New AIProvider* (caller must unref when done) */ AIProvider* ai_add_provider(const gchar* name, const gchar* api_url); /** * Remove a provider by name. * @param name The provider name * @return TRUE if provider was removed, FALSE if not found */ gboolean ai_remove_provider(const gchar* name); /** * Increment the reference count of a provider. * @param provider The provider to reference * @return The same provider pointer */ AIProvider* ai_provider_ref(AIProvider* provider); /** * Decrement the reference count of a provider. * @param provider The provider to unreference */ void ai_provider_unref(AIProvider* provider); /** * List all configured providers. * @return GList of AIProvider* (caller must not free the list or providers, * and must not unref the returned providers) */ GList* ai_list_providers(void); /** * Find a provider name for autocomplete. * @param search_str The search string * @param previous Whether to go to previous match * @param context Unused * @return Provider name, or NULL if not found */ gchar* ai_providers_find(const char* const search_str, gboolean previous, void* context); /** * Find a model name for autocomplete. * @param search_str The search string * @param previous Whether to go to previous match * @param context ProfAiWin* for the current session * @return Model name, or NULL if not found */ gchar* ai_models_find(const char* const search_str, gboolean previous, void* context); /** * Get the API key for a provider. * @param provider_name The provider name * @return The API key, or NULL if not set (caller must free) */ gchar* ai_get_provider_key(const gchar* provider_name); /** * Set the API key for a provider. * @param provider_name The provider name * @param api_key The API key to set */ void ai_set_provider_key(const gchar* provider_name, const gchar* api_key); /** * Set the default model for a provider. * @param provider_name The provider name * @param model The default model name */ void ai_set_provider_default_model(const gchar* provider_name, const gchar* model); /** * Get the default model for a provider. * @param provider_name The provider name * @return The default model name (caller must not free), or NULL if not set */ const gchar* ai_get_provider_default_model(const gchar* provider_name); /** * Set a custom setting for a provider. * @param provider_name The provider name * @param setting The setting key (e.g., "tools", "search") * @param value The setting value */ void ai_set_provider_setting(const gchar* provider_name, const gchar* setting, const gchar* value); /** * Get a custom setting for a provider. * @param provider_name The provider name * @param setting The setting key * @return The setting value (caller must free), or NULL if not set */ gchar* ai_get_provider_setting(const gchar* provider_name, const gchar* setting); /** * Fetch available models from a provider's API. * @param provider_name The provider name * @param user_data User data (ProfAiWin* for UI display) * @return TRUE if the request was successfully queued, FALSE otherwise */ gboolean ai_fetch_models(const gchar* provider_name, gpointer user_data); /** * Check if models cache is fresh for a provider. * @param provider_name The provider name * @return TRUE if models are fresh, FALSE otherwise */ gboolean ai_models_are_fresh(const gchar* provider_name); /* ======================================================================== * Model Parsing (for testing) * ======================================================================== */ /** * Parse model IDs from an OpenAI-compatible API response. * Expected format: {"object":"list","data":[{"id":"model1",...},...]} * @param provider The provider to add models to * @param json The JSON response from the API */ void ai_parse_models_from_json(AIProvider* provider, const gchar* json); /* ======================================================================== * Session Management * ======================================================================== */ /** * Create a new AI session with the specified provider and model. * @param provider_name The provider name (e.g., "openai") * @param model The model identifier (e.g., "gpt-4") * @return New AISession*, or NULL on failure */ AISession* ai_session_create(const gchar* provider_name, const gchar* model); /** * Increment the reference count of an AI session. * @param session The session to reference * @return The same session pointer */ AISession* ai_session_ref(AISession* session); /** * Decrement the reference count and free the session when it reaches zero. * @param session The session to unreference */ void ai_session_unref(AISession* session); /** * Add a message to the session history. * @param session The session * @param role The message role ("user" or "assistant") * @param content The message content */ void ai_session_add_message(AISession* session, const gchar* role, const gchar* content); /** * Clear the conversation history. * @param session The session */ void ai_session_clear_history(AISession* session); /** * Get the current model for a session. * @param session The session * @return The model name (caller must not free) */ const gchar* ai_session_get_model(AISession* session); /** * Set the model for a session. * @param session The session * @param model The model name */ void ai_session_set_model(AISession* session, const gchar* model); /* ======================================================================== * Request Handling * ======================================================================== */ /** * Send a prompt to the AI provider asynchronously. * @param session The AI session containing provider and model * @param prompt The prompt to send * @param user_data User data (ProfAiWin* for UI display) * @return TRUE if the request was successfully queued, FALSE otherwise */ gboolean ai_send_prompt(AISession* session, const gchar* prompt, gpointer user_data); /** * Escape a string for JSON embedding. * @param str The string to escape * @return Newly allocated escaped string (caller must free) */ gchar* ai_json_escape(const gchar* str); #endif /* AI_CLIENT_H */