feat(ai): add AI client with multi-provider support and UI
Some checks failed
CI Code / Check coding style (pull_request) Successful in 47s
CI Code / Check spelling (pull_request) Successful in 59s
CI Code / Code Coverage (pull_request) Failing after 1m8s
CI Code / Linux (debian) (pull_request) Failing after 2m28s
CI Code / Linux (ubuntu) (pull_request) Failing after 2m41s
CI Code / Linux (arch) (pull_request) Failing after 3m15s

Add an AI client module that integrates with OpenAI-compatible API
providers (OpenAI, Perplexity, and custom providers) to provide
AI-assisted responses within the profanity client.

The implementation includes:

- src/ai/ai_client.c/h: Core AI client with provider management,
  session handling, and async HTTP request handling via libcurl.
  Supports per-provider API keys stored in preferences, reference-
  counted sessions, and conversation history tracking.

- src/ui/window.c/window_list.c: New AI window type (ProfAiWin) for
  displaying AI conversations, with response streaming and error
  display capabilities.

- Command integration: New `/ai` command (cmd_defs.c, cmd_funcs.c)
  for creating sessions, sending prompts, and managing providers.
  Provider autocomplete support in cmd_ac.c.

- Preferences integration: API keys for providers are persisted in
  the preferences system (config/preferences.c).

- Unit tests: 472 lines of comprehensive tests covering provider
  management, session lifecycle, JSON escaping, and autocomplete
  (tests/unittests/test_ai_client.c).

Architecture decisions:
- Asynchronous design: HTTP requests run on a separate thread to
  avoid blocking the main UI loop. Callbacks are invoked on the main
  thread via direct function call (profanity uses ncurses, not GLib
  main loop).
- Reference counting: Both AIProvider and AISession use ref counting
  for safe shared ownership.
- Response size limit: 10MB cap on HTTP responses to prevent OOM.
This commit is contained in:
2026-04-29 19:23:33 +00:00
parent 0feacbc9da
commit e43e8378b0
20 changed files with 2399 additions and 6 deletions

View File

@@ -74,7 +74,8 @@ core_sources = \
src/plugins/themes.c src/plugins/themes.h \
src/plugins/settings.c src/plugins/settings.h \
src/plugins/disco.c src/plugins/disco.h \
src/ui/tray.h src/ui/tray.c
src/ui/tray.h src/ui/tray.c \
src/ai/ai_client.h src/ai/ai_client.c
unittest_sources = \
src/xmpp/contact.c src/xmpp/contact.h src/common.c \
@@ -85,6 +86,7 @@ unittest_sources = \
src/xmpp/chat_state.h src/xmpp/chat_state.c \
src/xmpp/roster_list.c src/xmpp/roster_list.h \
src/xmpp/xmpp.h src/xmpp/form.c \
src/ai/ai_client.h src/ai/ai_client.c \
src/ui/ui.h \
src/otr/otr.h \
src/pgp/gpg.h \
@@ -132,6 +134,7 @@ unittest_sources = \
tests/unittests/xmpp/stub_message.c \
tests/unittests/ui/stub_ui.c tests/unittests/ui/stub_ui.h \
tests/unittests/ui/stub_vcardwin.c \
tests/unittests/ui/stub_ai.c \
tests/unittests/log/stub_log.c \
tests/unittests/chatlog/stub_chatlog.c \
tests/unittests/database/stub_database.c \
@@ -168,6 +171,7 @@ unittest_sources = \
tests/unittests/test_callbacks.c tests/unittests/test_callbacks.h \
tests/unittests/test_plugins_disco.c tests/unittests/test_plugins_disco.h \
tests/unittests/test_forced_encryption.c tests/unittests/test_forced_encryption.h \
tests/unittests/test_ai_client.c tests/unittests/test_ai_client.h \
tests/unittests/unittests.c
functionaltest_sources = \