acp-ws
Version:
基于 WebSocket 的智能体通信库,提供智能体身份管理和实时通信功能
169 lines (168 loc) • 5.66 kB
JavaScript
import { getPublicKeyPem, isPemValid, preloadCrypto } from "./cert";
import { CertAndKeyStore } from "./datamanager";
import { getEntryPointConfig, getGuestAid, signIn } from "./api";
import { createAid, getDecryptKey } from "./utils";
class AgentCP {
constructor(apiUrl, seedPassword = "") {
this.activeAid = '';
if (!apiUrl) {
this.handleError("参数缺失:apiUrl不应为空");
}
if (apiUrl.startsWith('http://')) {
this.handleError("apiUrl不需要http://开头");
}
const baseUrl = `http://acp3.${apiUrl}`;
this.seedPassword = seedPassword;
this.apUrl = `${baseUrl}/api/accesspoint`;
this.msgUrl = `${baseUrl}/api/message`;
// 预热加密模块
this.initializeCrypto();
}
/**
* 初始化并预热加密模块
*/
async initializeCrypto() {
try {
await preloadCrypto();
}
catch (error) {
console.warn('AgentCP 加密模块预热失败:', error);
}
}
/// 导入本地用户信息
async importAid(identity, seedPassword = "") {
this.seedPassword = seedPassword;
const { aid, privateKey, certPem } = identity;
try {
if (!aid || !privateKey || !certPem) {
this.handleError("参数缺失:aid、privateKey 或 certPem 不应为空");
}
const isValid = isPemValid(certPem);
if (!isValid) {
this.handleError("证书已过期");
}
await CertAndKeyStore.saveAid(aid);
await CertAndKeyStore.saveCertificate(aid, certPem);
await CertAndKeyStore.savePrivateKey(aid, privateKey);
this.activeAid = aid;
return true;
}
catch (err) {
this.handleError(`错误: ${err instanceof Error ? err.message : String(err)}`);
}
}
async loadAid(aid) {
const aids = await CertAndKeyStore.getAids();
if (aids && aids.length > 0) {
if (aids.includes(aid)) {
this.activeAid = aid;
return aid;
}
}
return null;
}
async createAid(aid) {
const loaded = await this.loadAid(aid);
if (loaded) {
this.activeAid = loaded;
return loaded;
}
const created = await createAid(aid, this.apUrl, this.seedPassword);
if (!created) {
this.handleError(`当前aid: ${aid}创建失败`);
}
this.activeAid = aid;
return aid;
}
async loadCurrentAid() {
const aids = await CertAndKeyStore.getAids();
if (aids && aids.length > 0) {
let currentAid = aids[0];
const firstNonGuestAid = aids.find((aid) => !aid.startsWith('guest'));
if (firstNonGuestAid) {
currentAid = firstNonGuestAid;
}
return this.loadAid(currentAid);
}
else {
return null;
}
}
async loadGuestAid() {
const loaded = await getGuestAid(this.apUrl, this.seedPassword);
if (!loaded) {
this.handleError('加载aid失败');
}
this.activeAid = loaded;
return loaded;
}
async loadAidList() {
const aids = await CertAndKeyStore.getAids();
if (aids) {
return aids;
}
else {
return null;
}
}
async online() {
var _a;
let messageSignature = '';
let messageServer = '';
let heartbeatServer = '';
const aid = this.activeAid;
const privateKey = await getDecryptKey(aid, this.seedPassword);
if (!privateKey) {
this.handleError(`私钥不存在或无效`);
}
const { publicKeyPem, certPem } = await getPublicKeyPem(aid);
if (!certPem) {
this.handleError(`证书不存在`);
}
const apData = await signIn(aid, this.apUrl, privateKey, publicKeyPem, certPem);
if (!apData) {
this.handleError(`${this.apUrl}接口signIn失败`);
}
const epData = await getEntryPointConfig(aid, this.apUrl);
if (!epData) {
this.handleError("接入点服务器get_accesspoint_config获取数据失败");
}
else {
if (epData) {
messageServer = epData.messageServer;
heartbeatServer = epData.heartbeatServer;
}
}
const msgData = await signIn(aid, this.msgUrl, privateKey, publicKeyPem, certPem);
if (!msgData) {
this.handleError(`${this.msgUrl}接口signIn失败`);
}
else {
messageSignature = (_a = msgData.signature) !== null && _a !== void 0 ? _a : '';
}
return {
messageSignature,
messageServer,
heartbeatServer
};
}
async getCertInfo(aid) {
const csr = await CertAndKeyStore.getCsr(aid);
const privateKey = await CertAndKeyStore.getPrivateKey(aid);
const { publicKeyPem, certPem } = await getPublicKeyPem(aid);
if (!certPem || !csr || !privateKey || !publicKeyPem) {
return null;
}
return {
privateKey,
publicKey: publicKeyPem,
csr,
cert: certPem
};
}
handleError(error, customMessage) {
const errorMessage = error instanceof Error ? error.message : String(error);
throw new Error(`${customMessage || '操作失败'}: ${errorMessage}`);
}
}
export { AgentCP };