@bolloon/bolloon-agent 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bolloon/bolloon-agent",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "description": "P2P AI Document Agent - 全局安装后执行 `bolloon` 启动产品",
6
6
  "main": "dist/cli.js",
package/src/web/server.ts CHANGED
@@ -71,6 +71,7 @@ interface SessionMessage {
71
71
 
72
72
  interface Session {
73
73
  channelId: string;
74
+ sessionId: string;
74
75
  messages: SessionMessage[];
75
76
  lastUpdated: string;
76
77
  }
@@ -103,8 +104,10 @@ async function saveChannels(channels: Channel[]): Promise<void> {
103
104
  });
104
105
  }
105
106
 
106
- async function loadSession(channelId: string): Promise<Session | null> {
107
- const sessionPath = path.join(SESSION_CACHE_PATH, `${channelId}.json`);
107
+ async function loadSession(channelId: string, sessionId?: string): Promise<Session | null> {
108
+ // sessionId is optional for backward compatibility; if provided, load specific session
109
+ const key = sessionId ? `${channelId}:${sessionId}` : channelId;
110
+ const sessionPath = path.join(SESSION_CACHE_PATH, `${key}.json`);
108
111
  try {
109
112
  const data = await fs.readFile(sessionPath, 'utf-8');
110
113
  return JSON.parse(data);
@@ -114,7 +117,8 @@ async function loadSession(channelId: string): Promise<Session | null> {
114
117
  }
115
118
 
116
119
  async function saveSession(session: Session): Promise<void> {
117
- const sessionPath = path.join(SESSION_CACHE_PATH, `${session.channelId}.json`);
120
+ const key = session.sessionId ? `${session.channelId}:${session.sessionId}` : session.channelId;
121
+ const sessionPath = path.join(SESSION_CACHE_PATH, `${key}.json`);
118
122
  await fs.writeFile(sessionPath, JSON.stringify(session, null, 2));
119
123
  }
120
124
 
@@ -541,6 +545,7 @@ export async function createWebServer(port: number = 3000) {
541
545
  // 获取频道信息,包括真实 DID 和完整 DID 文档
542
546
  const channels = await loadChannels();
543
547
  const channel = channels.find(c => c.id === channelId);
548
+ const currentSessionId = channel?.currentSessionId || 'default';
544
549
  const realChannelDid = channelDid || channel?.did || '';
545
550
  const realChannelName = channel?.name || '';
546
551
  const realChannelDidDoc = channel?.didDocument;
@@ -568,7 +573,7 @@ export async function createWebServer(port: number = 3000) {
568
573
  }
569
574
  };
570
575
 
571
- console.log(`[消息处理] 开始处理用户消息, channelId: ${channelId}`);
576
+ console.log(`[消息处理] 开始处理用户消息, channelId: ${channelId}, sessionId: ${currentSessionId}`);
572
577
 
573
578
  // 将真实 DID 作为上下文前缀,让 AI 使用真实的 DID 而不是自己编造的
574
579
  const contextHint = realChannelDid ? `[系统上下文] 当前频道名称: ${realChannelName}, 你的真实 DID: ${realChannelDid}\n\n` : '';
@@ -576,8 +581,9 @@ export async function createWebServer(port: number = 3000) {
576
581
 
577
582
  broadcast({ type: 'ai', content: fullResponse }, channelId);
578
583
 
579
- const existingSession = await loadSession(channelId);
580
- const session: Session = existingSession || { channelId, messages: [], lastUpdated: new Date().toISOString() };
584
+ const existingSession = await loadSession(channelId, currentSessionId);
585
+ const session: Session = existingSession || { channelId, sessionId: currentSessionId, messages: [], lastUpdated: new Date().toISOString() };
586
+ session.sessionId = currentSessionId;
581
587
  session.messages.push({ id: crypto.randomUUID(), type: 'user' as const, content: text, timestamp: new Date().toISOString() });
582
588
  session.messages.push({ id: crypto.randomUUID(), type: 'ai' as const, content: fullResponse, timestamp: new Date().toISOString() });
583
589
  session.lastUpdated = new Date().toISOString();
@@ -707,7 +713,7 @@ app.get('/channels', async (_req, res) => {
707
713
  console.log(`[创建频道] 先保存频道 ID: ${id}`);
708
714
  channels.push(channel);
709
715
  await saveChannels(channels);
710
- await saveSession({ channelId: id, messages: [], lastUpdated: new Date().toISOString() });
716
+ await saveSession({ channelId: id, sessionId: 'default', messages: [], lastUpdated: new Date().toISOString() });
711
717
  res.json(channel);
712
718
 
713
719
  // 后台生成 DID
@@ -907,6 +913,7 @@ app.get('/channels', async (_req, res) => {
907
913
  try {
908
914
  const channels = await loadChannels();
909
915
  const channel = channels.find(c => c.id === channelId);
916
+ const currentSessionId = channel?.currentSessionId || 'default';
910
917
  const realChannelDid = channel?.did || '';
911
918
  const realChannelName = channel?.name || '';
912
919
  const realChannelDidDoc = channel?.didDocument;
@@ -933,7 +940,7 @@ app.get('/channels', async (_req, res) => {
933
940
  broadcast({ type: 'ai', content: fullResponse }, channelId);
934
941
 
935
942
  // 更新 session
936
- const existingSession = await loadSession(channelId);
943
+ const existingSession = await loadSession(channelId, currentSessionId);
937
944
  if (existingSession && existingSession.messages.length > 0) {
938
945
  // 移除最后一个 AI 消息,替换为新的
939
946
  const lastAiIndex = existingSession.messages.map((m: any) => m.type).lastIndexOf('ai');
@@ -1699,26 +1706,18 @@ app.get('/channels', async (_req, res) => {
1699
1706
  return;
1700
1707
  }
1701
1708
 
1702
- // 通过 P2P 发送消息
1703
- if (p2pCommunicator) {
1704
- const payload = JSON.stringify({
1705
- from: 'bolloon-web',
1706
- content: message,
1707
- timestamp: Date.now()
1708
- });
1709
-
1710
- // 找到连接并发送
1711
- const connections = p2pCommunicator.getConnections();
1712
- for (const conn of connections) {
1713
- if (conn.publicKey.includes(targetPeerId) || targetPeerId.includes(conn.publicKey.substring(0, 16))) {
1714
- conn.send(payload);
1715
- res.json({ ok: true, sent: true });
1716
- return;
1717
- }
1709
+ // 通过 P2P 发送消息(如果可用)
1710
+ try {
1711
+ const comm = p2pCommunicator as any;
1712
+ if (comm && typeof comm.send === 'function') {
1713
+ await comm.send(message, targetPeerId);
1714
+ res.json({ ok: true, sent: true });
1715
+ return;
1718
1716
  }
1719
- }
1717
+ } catch {}
1720
1718
 
1721
- res.json({ ok: true, sent: false, message: '对方不在线,消息已加入队列' });
1719
+ // 如果 P2P 不可用,消息已在上面加入队列
1720
+ res.json({ ok: true, queued: true, message: '消息已加入队列,等待对方上线' });
1722
1721
  } catch (err: any) {
1723
1722
  res.status(500).json({ error: err.message });
1724
1723
  }