add old lci module
This commit is contained in:
1 parent
38a6e815f0
commit
8499631091
171 files changed
+25562
No files matched your search
@@ -0,0 +1,106 @@
|
||||
#ifndef PMC_LLM_CLIENT_HPP
|
||||
#define PMC_LLM_CLIENT_HPP
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/json.hpp>
|
||||
|
||||
#include "net/HttpClient.hpp"
|
||||
|
||||
namespace pmc::llm {
|
||||
|
||||
class LLMClient {
|
||||
public:
|
||||
LLMClient(const std::string& api_key) : api_key_(api_key) {}
|
||||
|
||||
// 流式请求(使用同步版本避免线程死锁)
|
||||
void stream_request(const std::vector<std::pair<std::string, std::string>>& messages,
|
||||
std::function<void(const std::string&)> callback) {
|
||||
// 使用智能指针确保HttpClient在回调期间保持存活
|
||||
auto http_client = std::make_shared<pmc::net::HttpClient>();
|
||||
|
||||
// 设置请求头
|
||||
http_client->set_header("Authorization: Bearer " + api_key_);
|
||||
http_client->set_header("Content-Type: application/json");
|
||||
http_client->set_header("Accept: text/event-stream");
|
||||
|
||||
// 构建请求JSON
|
||||
boost::json::object request;
|
||||
request["model"] = "deepseek-chat";
|
||||
request["stream"] = true;
|
||||
|
||||
// 构建消息数组,添加系统消息要求返回Markdown格式
|
||||
boost::json::array messages_array;
|
||||
|
||||
// 添加系统消息,要求使用Markdown格式回复
|
||||
boost::json::object system_message;
|
||||
system_message["role"] = "system";
|
||||
system_message["content"] = "请使用Markdown格式回复。使用**粗体**表示重要概念,*斜体*表示强调,`代码`表示代码片段,使用列表、标题等Markdown元素来组织内容。";
|
||||
messages_array.push_back(system_message);
|
||||
|
||||
// 添加用户消息
|
||||
for (const auto& msg : messages) {
|
||||
boost::json::object message_obj;
|
||||
message_obj["role"] = msg.first;
|
||||
message_obj["content"] = msg.second;
|
||||
messages_array.push_back(message_obj);
|
||||
}
|
||||
request["messages"] = messages_array;
|
||||
|
||||
// 转换为字符串
|
||||
std::string request_body = boost::json::serialize(request);
|
||||
|
||||
// 创建包装回调,解析JSON并提取文本内容
|
||||
auto wrapped_callback = [callback](const std::string& json_str) {
|
||||
try {
|
||||
// 解析JSON
|
||||
boost::json::value json_value = boost::json::parse(json_str);
|
||||
|
||||
// 检查是否是有效的响应
|
||||
if (json_value.is_object()) {
|
||||
const auto& obj = json_value.as_object();
|
||||
|
||||
// 检查是否有choices数组
|
||||
if (obj.contains("choices") && obj.at("choices").is_array()) {
|
||||
const auto& choices = obj.at("choices").as_array();
|
||||
if (!choices.empty() && choices[0].is_object()) {
|
||||
const auto& choice = choices[0].as_object();
|
||||
|
||||
// 检查是否有delta对象
|
||||
if (choice.contains("delta") && choice.at("delta").is_object()) {
|
||||
const auto& delta = choice.at("delta").as_object();
|
||||
|
||||
// 检查是否有content字段
|
||||
if (delta.contains("content") && delta.at("content").is_string()) {
|
||||
const std::string& content = delta.at("content").as_string().c_str();
|
||||
callback(content);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果JSON解析失败或没有有效内容,发送原始字符串(用于调试)
|
||||
callback("[" + json_str + "]");
|
||||
} catch (const std::exception& e) {
|
||||
// JSON解析失败,发送原始字符串
|
||||
callback("[" + json_str + "]");
|
||||
}
|
||||
};
|
||||
|
||||
// 发送POST请求 - 使用post_stream_sync方法
|
||||
http_client->post_stream_sync("https://api.deepseek.com/v1/chat/completions", request_body, wrapped_callback);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string api_key_;
|
||||
};
|
||||
|
||||
} // namespace pmc::llm
|
||||
|
||||
#endif // PMC_LLM_CLIENT_HPP
|
||||
@@ -0,0 +1,133 @@
|
||||
#ifndef PMC_LLM_WEBSOCKET_SERVER_HPP
|
||||
#define PMC_LLM_WEBSOCKET_SERVER_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <atomic>
|
||||
|
||||
#include "LLMClient.hpp"
|
||||
#include "net/WebSocketServer.hpp"
|
||||
|
||||
namespace pmc::llm {
|
||||
|
||||
class LLMWebSocketServer {
|
||||
public:
|
||||
LLMWebSocketServer(const std::string& api_key, unsigned short port = 8080)
|
||||
: api_key_(api_key)
|
||||
, port_(port)
|
||||
, running_(false) {
|
||||
|
||||
// 创建WebSocket服务器
|
||||
ws_server_ = std::make_unique<pmc::net::WebSocketServer>(port);
|
||||
}
|
||||
|
||||
~LLMWebSocketServer() {
|
||||
stop();
|
||||
}
|
||||
|
||||
void start() {
|
||||
if (running_) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "启动LLM WebSocket服务器,端口: " << port_ << std::endl;
|
||||
std::cout << "API密钥: " << (api_key_.empty() ? "未设置" : "已设置") << std::endl;
|
||||
|
||||
// 设置WebSocket回调
|
||||
ws_server_->onConnect([this](const std::string& client_id, const std::string& remote_address) {
|
||||
handle_connect(client_id, remote_address);
|
||||
});
|
||||
|
||||
ws_server_->onMessage("/", [this](const std::string& client_id,
|
||||
const std::string& message,
|
||||
std::function<void(const std::string&)> send_callback) {
|
||||
// 这里我们使用异步发送,所以忽略send_callback参数
|
||||
handle_message(client_id, message);
|
||||
});
|
||||
|
||||
ws_server_->onDisconnect([this](const std::string& client_id) {
|
||||
handle_disconnect(client_id);
|
||||
});
|
||||
|
||||
// 启动WebSocket服务器
|
||||
ws_server_->start();
|
||||
|
||||
running_ = true;
|
||||
|
||||
std::cout << "服务器已启动,等待客户端连接..." << std::endl;
|
||||
std::cout << "按Ctrl+C停止服务器" << std::endl;
|
||||
}
|
||||
|
||||
void stop() {
|
||||
if (!running_) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "正在停止服务器..." << std::endl;
|
||||
ws_server_->stop();
|
||||
running_ = false;
|
||||
}
|
||||
|
||||
bool is_running() const {
|
||||
return running_;
|
||||
}
|
||||
|
||||
private:
|
||||
// 处理连接
|
||||
void handle_connect(const std::string& client_id, const std::string& remote_address) {
|
||||
std::cout << "客户端连接: " << client_id << " (" << remote_address << ")" << std::endl;
|
||||
|
||||
// 使用异步线程发送欢迎消息,确保客户端已准备好
|
||||
std::thread([this, client_id]() {
|
||||
// 等待一小段时间,确保客户端连接完全建立
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
// 发送欢迎消息
|
||||
ws_server_->sendToClient(client_id, "欢迎连接到LLM WebSocket服务器!");
|
||||
ws_server_->sendToClient(client_id, "请发送您的消息,我将为您提供AI助手服务。");
|
||||
}).detach();
|
||||
}
|
||||
|
||||
// 处理断开连接
|
||||
void handle_disconnect(const std::string& client_id) {
|
||||
std::cout << "客户端断开: " << client_id << std::endl;
|
||||
}
|
||||
|
||||
// 处理消息
|
||||
void handle_message(const std::string& client_id, const std::string& message) {
|
||||
std::cout << "收到来自客户端 " << client_id << " 的消息: " << message << std::endl;
|
||||
|
||||
// 创建LLM客户端
|
||||
LLMClient llm_client(api_key_);
|
||||
|
||||
// 构建消息历史
|
||||
std::vector<std::pair<std::string, std::string>> messages = {
|
||||
{"user", message}
|
||||
};
|
||||
|
||||
// 发送流式请求
|
||||
llm_client.stream_request(messages, [this, client_id](const std::string& chunk) {
|
||||
// 将每个数据块发送给客户端
|
||||
ws_server_->sendToClient(client_id, chunk);
|
||||
});
|
||||
|
||||
// 发送处理完成标记
|
||||
ws_server_->sendToClient(client_id, "[处理完成]");
|
||||
}
|
||||
|
||||
private:
|
||||
std::string api_key_;
|
||||
unsigned short port_;
|
||||
bool running_;
|
||||
std::unique_ptr<pmc::net::WebSocketServer> ws_server_;
|
||||
};
|
||||
|
||||
} // namespace pmc::llm
|
||||
|
||||
#endif // PMC_LLM_WEBSOCKET_SERVER_HPP
|
||||
Reference in new issue
Block a user