ZcAILib
May 21, 2026 ยท View on GitHub
Qt-based AI client library for chat completion APIs.
It currently provides:
- OpenAI / DeepSeek service switching
- model list fetching
- system prompt support
- non-streaming reply callbacks
- streaming reply callbacks based on SSE
Requirements
- Qt 6
- CMake 3.16+
- C++17
This project links against:
Qt6::CoreQt6::NetworkQt6::Widgetsfor the example app
Build
cmake -S . -B build
cmake --build build --config Debug
The example executable will be generated as:
build/Debug/ZcAiLib-Example.exeon Windows with Visual Studio generators
Add To Your Project
If you use this repository directly, the simplest way is:
add_subdirectory(path/to/ZcAiLib)
target_link_libraries(YourApp PRIVATE
ZcAiLib
Qt6::Widgets
)
Then include:
#include "AiProvider.h"
Basic Usage
AiProvider *ai = new AiProvider(this);
ai->setServiceType(AiProvider::DeepSeek);
ai->setApiKey("YOUR_API_KEY");
ai->setModel("deepseek-chat");
ai->setSystemPrompt("You are a helpful assistant.");
connect(ai, &AiProvider::replyReceived, this, [](const QString &reply) {
qDebug() << "AI reply:" << reply;
});
connect(ai, &AiProvider::errorOccurred, this, [](const QString &error) {
qWarning() << "AI error:" << error;
});
ai->chat("Hello");
Streaming Usage
Streaming is disabled by default. Enable it explicitly before calling chat().
AiProvider *ai = new AiProvider(this);
ai->setServiceType(AiProvider::OpenAI);
ai->setApiKey("YOUR_API_KEY");
ai->setModel("gpt-3.5-turbo");
ai->setStreamEnabled(true);
connect(ai, &AiProvider::replyChunkReceived, this, [](const QString &chunk) {
qDebug().noquote() << chunk;
});
connect(ai, &AiProvider::replyReceived, this, [](const QString &fullReply) {
qDebug() << "stream finished:" << fullReply;
});
connect(ai, &AiProvider::errorOccurred, this, [](const QString &error) {
qWarning() << error;
});
ai->chat("Write a short poem about Qt.");
Streaming behavior
replyChunkReceived(...)is emitted for every parsed content chunkreplyReceived(...)is emitted once after the full streamed reply is completeerrorOccurred(...)is emitted on HTTP or API errors
This means existing code that only listens to replyReceived(...) still works after streaming is added.
Fetch Available Models
connect(ai, &AiProvider::modelsReceived, this, [](const QList<AiProvider::ModelInfo> &models) {
for (const auto &model : models) {
qDebug() << model.id << model.ownedBy << model.created;
}
});
ai->fetchModels();
ModelInfo contains:
idcreatedownedBypermissions
Service Configuration
Built-in service types:
AiProvider::OpenAIAiProvider::DeepSeekAiProvider::Custom
For custom services:
ai->setServiceType(AiProvider::Custom);
ai->setBaseUrl("https://your-domain/v1");
ai->setApiKey("YOUR_API_KEY");
ai->setModel("your-model-id");
If you need to point at a fully custom chat endpoint:
ai->setServiceType(AiProvider::Custom);
ai->setApiUrl("https://your-domain/v1/chat/completions");
ai->setApiKey("YOUR_API_KEY");
ai->setModel("your-model-id");
Public API Summary
Main methods:
setServiceType(AiProvider::ServiceType type)setApiKey(const QString &apiKey)setApiUrl(const QString &url)setBaseUrl(const QString &baseUrl)setModel(const QString &model)setStreamEnabled(bool enabled)setSystemPrompt(const QString &prompt)fetchModels()chat(const QString &message)
Main signals:
replyReceived(const QString &reply)replyChunkReceived(const QString &chunk)modelsReceived(const QList<ModelInfo> &models)errorOccurred(const QString &error)
Example
The example UI is in example/mainwindow.cpp.
It demonstrates:
- switching between OpenAI and DeepSeek
- fetching model lists from the API
- setting a system prompt
- enabling/disabling stream output
- rendering streamed output incrementally in a
QTextEdit
Notes
- Streaming support depends on the upstream API supporting SSE chat completion responses.
- The library currently targets chat-completions style APIs.
replyReceived(...)remains the final completion signal for both streaming and non-streaming requests.