@bolloon/bolloon-agent 0.1.13 → 0.1.14

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.
Files changed (52) hide show
  1. package/dist/agents/pi-sdk.js +185 -0
  2. package/dist/agents/shell-guard.js +354 -0
  3. package/dist/agents/shell-tool.js +83 -0
  4. package/dist/agents/skill-loader.js +174 -0
  5. package/dist/bollharness-integration/context-chain-router.js +3 -3
  6. package/dist/bollharness-integration/context-router.js +1 -1
  7. package/dist/heartbeat/Watchdog.js +7 -5
  8. package/dist/heartbeat/index.js +1 -0
  9. package/dist/heartbeat/self-improve-bus.js +85 -0
  10. package/dist/pi-ecosystem-judgment/index.js +1 -2
  11. package/dist/utils/auto-update.js +44 -12
  12. package/dist/web/client.js +839 -103
  13. package/dist/web/components/p2p/P2PModal.js +188 -0
  14. package/dist/web/components/p2p/index.js +264 -226
  15. package/dist/web/components/p2p/p2p-modal.js +657 -0
  16. package/dist/web/components/p2p/p2p-tools.js +248 -0
  17. package/dist/web/index.html +88 -8
  18. package/dist/web/server.js +2360 -0
  19. package/dist/web/style.css +506 -9
  20. package/package.json +2 -2
  21. package/scripts/build-cli.js +11 -1
  22. package/src/agents/pi-sdk.ts +196 -0
  23. package/src/agents/shell-guard.ts +417 -0
  24. package/src/agents/shell-tool.ts +103 -0
  25. package/src/agents/skill-loader.ts +202 -0
  26. package/src/bollharness-integration/context-chain-router.ts +3 -3
  27. package/src/bollharness-integration/context-router.ts +1 -1
  28. package/src/heartbeat/Watchdog.ts +7 -5
  29. package/src/heartbeat/index.ts +1 -0
  30. package/src/heartbeat/self-improve-bus.ts +110 -0
  31. package/src/types.d.ts +12 -0
  32. package/src/utils/auto-update.ts +45 -14
  33. package/src/web/client.js +839 -103
  34. package/src/web/index.html +88 -8
  35. package/src/web/server.ts +427 -101
  36. package/src/web/style.css +506 -9
  37. package/dist/bollharness-integration/bollharness-integration/context-router-judgment.d.ts +0 -48
  38. package/dist/bollharness-integration/bollharness-integration/context-router-judgment.js +0 -261
  39. package/dist/bollharness-integration/bollharness-integration/context-router.d.ts +0 -110
  40. package/dist/bollharness-integration/bollharness-integration/context-router.js +0 -542
  41. package/dist/bollharness-integration/bollharness-integration/gate-state-machine.d.ts +0 -87
  42. package/dist/bollharness-integration/bollharness-integration/gate-state-machine.js +0 -231
  43. package/dist/bollharness-integration/bollharness-integration/gate-transition-hooks.d.ts +0 -30
  44. package/dist/bollharness-integration/bollharness-integration/gate-transition-hooks.js +0 -91
  45. package/dist/bollharness-integration/bollharness-integration/guard-checker.d.ts +0 -105
  46. package/dist/bollharness-integration/bollharness-integration/guard-checker.js +0 -353
  47. package/dist/bollharness-integration/bollharness-integration/index.d.ts +0 -66
  48. package/dist/bollharness-integration/bollharness-integration/index.js +0 -32
  49. package/dist/bollharness-integration/bollharness-integration/integration.d.ts +0 -219
  50. package/dist/bollharness-integration/bollharness-integration/integration.js +0 -420
  51. package/dist/bollharness-integration/bollharness-integration/skill-adapter.d.ts +0 -151
  52. package/dist/bollharness-integration/bollharness-integration/skill-adapter.js +0 -518
@@ -0,0 +1,248 @@
1
+ /**
2
+ * P2P 工具调用模块
3
+ * 支持文件和本地信息的 P2P 传递
4
+ */
5
+ // 工具类型枚举
6
+ export var P2PToolType;
7
+ (function (P2PToolType) {
8
+ P2PToolType["FILE_TRANSFER"] = "file_transfer";
9
+ P2PToolType["LOCAL_INFO"] = "local_info";
10
+ P2PToolType["SYSTEM_INFO"] = "system_info";
11
+ P2PToolType["FILE_LIST"] = "file_list";
12
+ })(P2PToolType || (P2PToolType = {}));
13
+ // 文件传输
14
+ export async function transferFile(targetDid, fileInfo, messageId) {
15
+ try {
16
+ const payload = {
17
+ type: 'file',
18
+ tool: P2PToolType.FILE_TRANSFER,
19
+ data: {
20
+ name: fileInfo.name,
21
+ size: fileInfo.size,
22
+ mimeType: fileInfo.mimeType,
23
+ content: fileInfo.content
24
+ }
25
+ };
26
+ const res = await fetch('/api/message-p2p', {
27
+ method: 'POST',
28
+ headers: { 'Content-Type': 'application/json' },
29
+ body: JSON.stringify({
30
+ targetDid,
31
+ content: JSON.stringify(payload),
32
+ type: 'file'
33
+ })
34
+ });
35
+ if (res.ok) {
36
+ const data = await res.json();
37
+ return {
38
+ success: true,
39
+ messageId: data.messageId || messageId
40
+ };
41
+ }
42
+ else {
43
+ return { success: false, error: '文件传输失败' };
44
+ }
45
+ }
46
+ catch (e) {
47
+ return { success: false, error: e.message };
48
+ }
49
+ }
50
+ // 本地信息查询
51
+ export async function queryLocalInfo(targetDid, query) {
52
+ try {
53
+ const payload = {
54
+ type: 'info_query',
55
+ tool: P2PToolType.LOCAL_INFO,
56
+ query: query
57
+ };
58
+ const res = await fetch('/api/message-p2p', {
59
+ method: 'POST',
60
+ headers: { 'Content-Type': 'application/json' },
61
+ body: JSON.stringify({
62
+ targetDid,
63
+ content: JSON.stringify(payload),
64
+ type: 'ai-dialogue'
65
+ })
66
+ });
67
+ if (res.ok) {
68
+ const data = await res.json();
69
+ return {
70
+ success: true,
71
+ data: data.response,
72
+ messageId: data.messageId
73
+ };
74
+ }
75
+ else {
76
+ return { success: false, error: '信息查询失败' };
77
+ }
78
+ }
79
+ catch (e) {
80
+ return { success: false, error: e.message };
81
+ }
82
+ }
83
+ // 系统信息请求
84
+ export async function getSystemInfo(targetDid) {
85
+ try {
86
+ const payload = {
87
+ type: 'system_info_request',
88
+ tool: P2PToolType.SYSTEM_INFO
89
+ };
90
+ const res = await fetch('/api/message-p2p', {
91
+ method: 'POST',
92
+ headers: { 'Content-Type': 'application/json' },
93
+ body: JSON.stringify({
94
+ targetDid,
95
+ content: JSON.stringify(payload),
96
+ type: 'ai-dialogue'
97
+ })
98
+ });
99
+ if (res.ok) {
100
+ const data = await res.json();
101
+ return {
102
+ success: true,
103
+ data: data.response,
104
+ messageId: data.messageId
105
+ };
106
+ }
107
+ else {
108
+ return { success: false, error: '系统信息获取失败' };
109
+ }
110
+ }
111
+ catch (e) {
112
+ return { success: false, error: e.message };
113
+ }
114
+ }
115
+ // 文件列表请求
116
+ export async function listFiles(targetDid, path = '/') {
117
+ try {
118
+ const payload = {
119
+ type: 'file_list_request',
120
+ tool: P2PToolType.FILE_LIST,
121
+ path: path
122
+ };
123
+ const res = await fetch('/api/message-p2p', {
124
+ method: 'POST',
125
+ headers: { 'Content-Type': 'application/json' },
126
+ body: JSON.stringify({
127
+ targetDid,
128
+ content: JSON.stringify(payload),
129
+ type: 'ai-dialogue'
130
+ })
131
+ });
132
+ if (res.ok) {
133
+ const data = await res.json();
134
+ return {
135
+ success: true,
136
+ data: data.response,
137
+ messageId: data.messageId
138
+ };
139
+ }
140
+ else {
141
+ return { success: false, error: '文件列表获取失败' };
142
+ }
143
+ }
144
+ catch (e) {
145
+ return { success: false, error: e.message };
146
+ }
147
+ }
148
+ // 工具调用入口
149
+ export async function executeP2PTool(request) {
150
+ const { toolName, payload, targetDid } = request;
151
+ if (!targetDid) {
152
+ return { success: false, error: '未指定目标节点' };
153
+ }
154
+ switch (toolName) {
155
+ case P2PToolType.FILE_TRANSFER:
156
+ return transferFile(targetDid, payload.data);
157
+ case P2PToolType.LOCAL_INFO:
158
+ return queryLocalInfo(targetDid, payload.data);
159
+ case P2PToolType.SYSTEM_INFO:
160
+ return getSystemInfo(targetDid);
161
+ case P2PToolType.FILE_LIST:
162
+ return listFiles(targetDid, payload.data?.path || '/');
163
+ default:
164
+ return { success: false, error: `未知工具: ${toolName}` };
165
+ }
166
+ }
167
+ // 本地系统信息获取 (用于响应来自远程的请求)
168
+ export function getLocalSystemInfo() {
169
+ const memUsage = process.memoryUsage();
170
+ const cpuCores = require('os').cpus();
171
+ return {
172
+ platform: process.platform,
173
+ arch: process.arch,
174
+ nodeVersion: process.version,
175
+ memory: {
176
+ total: memUsage.heapTotal,
177
+ free: memUsage.heapTotal - memUsage.heapUsed,
178
+ used: memUsage.heapUsed
179
+ },
180
+ cpu: {
181
+ cores: cpuCores.length,
182
+ model: cpuCores[0]?.model || 'Unknown'
183
+ },
184
+ uptime: process.uptime()
185
+ };
186
+ }
187
+ // 本地文件列表 (用于响应来自远程的请求)
188
+ export function getLocalFileList(dirPath) {
189
+ try {
190
+ // Dynamic import for ESM compatibility
191
+ const pathModule = require('path');
192
+ const fs = require('fs');
193
+ const fullPath = pathModule.resolve(dirPath);
194
+ const files = fs.readdirSync(fullPath);
195
+ const fileList = files.map((name) => {
196
+ const fullFilePath = pathModule.join(fullPath, name);
197
+ let stat;
198
+ try {
199
+ stat = fs.statSync(fullFilePath);
200
+ }
201
+ catch {
202
+ return null;
203
+ }
204
+ return {
205
+ name: name,
206
+ size: stat.size,
207
+ isDirectory: stat.isDirectory(),
208
+ modified: stat.mtime.toISOString()
209
+ };
210
+ }).filter(Boolean);
211
+ return {
212
+ success: true,
213
+ path: fullPath,
214
+ files: fileList
215
+ };
216
+ }
217
+ catch (e) {
218
+ return {
219
+ success: false,
220
+ path: dirPath,
221
+ error: e.message
222
+ };
223
+ }
224
+ }
225
+ // 导出工具名称列表
226
+ export const P2P_TOOLS = [
227
+ {
228
+ name: P2PToolType.FILE_TRANSFER,
229
+ description: '传输文件到远程节点',
230
+ parameters: ['targetDid', 'fileInfo']
231
+ },
232
+ {
233
+ name: P2PToolType.LOCAL_INFO,
234
+ description: '查询远程节点本地信息',
235
+ parameters: ['targetDid', 'query']
236
+ },
237
+ {
238
+ name: P2PToolType.SYSTEM_INFO,
239
+ description: '获取远程节点系统信息',
240
+ parameters: ['targetDid']
241
+ },
242
+ {
243
+ name: P2PToolType.FILE_LIST,
244
+ description: '列出远程节点目录文件',
245
+ parameters: ['targetDid', 'path']
246
+ }
247
+ ];
248
+ console.log('[P2P Tools] 工具模块已加载');
@@ -46,14 +46,20 @@
46
46
 
47
47
  <div class="sidebar-section">
48
48
  <div class="section-header">
49
- <span class="section-title">频道</span>
49
+ <span class="section-title">智能体</span>
50
+ <button id="catalog-add-btn" class="section-header-action" title="添加智能体">
51
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
52
+ <line x1="12" y1="5" x2="12" y2="19"></line>
53
+ <line x1="5" y1="12" x2="19" y2="12"></line>
54
+ </svg>
55
+ </button>
50
56
  </div>
51
- <button id="new-channel-btn" class="section-action" title="新建频道">
57
+ <button id="new-channel-btn" class="section-action" title="新建智能体">
52
58
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
53
59
  <line x1="12" y1="5" x2="12" y2="19"></line>
54
60
  <line x1="5" y1="12" x2="19" y2="12"></line>
55
61
  </svg>
56
- <span>新建</span>
62
+ <span>新建智能体</span>
57
63
  </button>
58
64
  <ul class="channel-list" id="channel-list"></ul>
59
65
  </div>
@@ -73,11 +79,6 @@
73
79
  <h1 id="channel-name">Bolloon Agent</h1>
74
80
  </div>
75
81
  <div class="header-right">
76
- <button id="new-session-btn" class="header-action" title="新会话">
77
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
78
- <path d="M12 5v14M5 12h14"></path>
79
- </svg>
80
- </button>
81
82
  <button id="theme-toggle" class="theme-toggle" title="切换主题">
82
83
  <svg class="sun-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
83
84
  <circle cx="12" cy="12" r="5"></circle>
@@ -109,6 +110,14 @@
109
110
  <line x1="12" y1="8" x2="19" y2="16"></line>
110
111
  </svg>
111
112
  </button>
113
+ <button id="wallet-btn" class="header-action" title="钱包管理">
114
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
115
+ <path d="M21 12V7a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-3"></path>
116
+ <circle cx="17" cy="12" r="1.5" fill="currentColor"></circle>
117
+ <path d="M3 7l3-3h12l3 3"></path>
118
+ </svg>
119
+ <span id="wallet-badge" class="task-badge" style="display:none;">0</span>
120
+ </button>
112
121
  <button id="task-queue-btn" class="header-action" title="任务队列">
113
122
  <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
114
123
  <path d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2"></path>
@@ -181,6 +190,77 @@
181
190
  </div>
182
191
  </div>
183
192
 
193
+ <!-- Agent Add / Wallet / Auto-tool Modal -->
194
+ <div id="agent-add-modal" class="modal">
195
+ <div class="modal-content">
196
+ <div class="modal-header">
197
+ <h2 id="agent-add-title">添加智能体</h2>
198
+ <button id="agent-add-modal-close" class="modal-close">&times;</button>
199
+ </div>
200
+ <div class="modal-body">
201
+ <div class="form-group">
202
+ <label>智能体名称</label>
203
+ <input type="text" id="agent-add-name" placeholder="例如: 交易助手">
204
+ </div>
205
+ <div class="form-group">
206
+ <label>加密钱包地址 (EVM 0x... 或 Solana/Sui 等)</label>
207
+ <div style="display:flex;gap:8px;">
208
+ <input type="text" id="agent-add-wallet" placeholder="0x... (留空则不绑定)" style="flex:1;">
209
+ <button type="button" id="agent-generate-wallet-btn" class="btn-secondary btn-sm" title="本地生成新钱包">生成</button>
210
+ </div>
211
+ <small class="form-hint">本地生成的钱包仅在浏览器内存, 服务端只保存公链地址, 不会上传私钥。</small>
212
+ </div>
213
+ <div class="form-group">
214
+ <label class="checkbox-label">
215
+ <input type="checkbox" id="agent-add-auto-tools" checked>
216
+ <span>启用自动工具调用 (LLM 决定调用受信任工具时, agent 自动执行)</span>
217
+ </label>
218
+ </div>
219
+ <div id="agent-add-wallet-info" class="form-info" style="display:none;"></div>
220
+ <div class="btn-group">
221
+ <button id="agent-add-cancel-btn" class="btn-secondary">取消</button>
222
+ <button id="agent-add-confirm-btn" class="btn-primary">创建</button>
223
+ </div>
224
+ </div>
225
+ </div>
226
+ </div>
227
+
228
+ <!-- Wallet Manager Modal (header 钱包按钮入口) -->
229
+ <div id="wallet-modal" class="modal">
230
+ <div class="modal-content modal-wide">
231
+ <div class="modal-header">
232
+ <h2>钱包管理</h2>
233
+ <button id="wallet-modal-close" class="modal-close">&times;</button>
234
+ </div>
235
+ <div class="modal-body">
236
+ <div class="form-group">
237
+ <label>为当前智能体绑定加密钱包</label>
238
+ <div style="display:flex;gap:8px;">
239
+ <input type="text" id="wallet-bind-address" placeholder="0x... / Solana / Sui" style="flex:1;">
240
+ <button type="button" id="wallet-generate-btn" class="btn-secondary btn-sm" title="本地生成新钱包">生成</button>
241
+ </div>
242
+ <small class="form-hint">仅当前激活智能体会使用此钱包; 服务端只保存公链地址, 私钥仅在浏览器内存。</small>
243
+ </div>
244
+ <div class="form-group">
245
+ <label class="checkbox-label">
246
+ <input type="checkbox" id="wallet-auto-tools" checked>
247
+ <span>启用自动工具调用 (LLM 决定调用受信任工具时, agent 自动执行)</span>
248
+ </label>
249
+ </div>
250
+ <div id="wallet-new-info" class="form-info" style="display:none;"></div>
251
+ <div class="btn-group">
252
+ <button id="wallet-bind-btn" class="btn-primary">绑定到当前智能体</button>
253
+ <button id="wallet-unbind-btn" class="btn-secondary">解绑当前智能体</button>
254
+ </div>
255
+
256
+ <h3 style="margin-top:24px;font-size:14px;font-weight:600;">所有已绑定钱包</h3>
257
+ <div id="wallet-list" class="wallet-list">
258
+ <div class="wallet-empty">暂未绑定钱包</div>
259
+ </div>
260
+ </div>
261
+ </div>
262
+ </div>
263
+
184
264
  <div class="messages" id="messages">
185
265
  <div class="message message-ai">
186
266
  <div class="bubble bubble-ai">