@bolloon/bolloon-agent 0.2.1 → 0.2.3
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/bin/ipfs +0 -0
- package/dist/agents/judgment-protocol.js +479 -0
- package/dist/agents/parse-tool-call.js +304 -0
- package/dist/agents/pi-sdk.js +190 -267
- package/dist/agents/react-loop.js +86 -0
- package/dist/agents/session-store.js +157 -0
- package/dist/agents/tool-registry.js +136 -0
- package/dist/agents/workflow-pivot-loop.js +40 -0
- package/dist/bollharness/src/index.js +5 -0
- package/dist/bollharness/src/scripts/checks/check_adr_plan_numbering.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_api_types.js +45 -0
- package/dist/bollharness/src/scripts/checks/check_artifact_link.js +146 -0
- package/dist/bollharness/src/scripts/checks/check_bridge_deps.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_bugfix_binding.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_bugfix_binding_ci.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_doc_file_references.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_doc_freshness.js +135 -0
- package/dist/bollharness/src/scripts/checks/check_doc_links.js +31 -0
- package/dist/bollharness/src/scripts/checks/check_file_existence_claims.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_fragment_integrity.js +34 -0
- package/dist/bollharness/src/scripts/checks/check_hook_installed.js +63 -0
- package/dist/bollharness/src/scripts/checks/check_issue_closure.js +41 -0
- package/dist/bollharness/src/scripts/checks/check_mcp_parity.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_security.js +48 -0
- package/dist/bollharness/src/scripts/checks/check_skill_parity.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_versions.js +6 -0
- package/dist/bollharness/src/scripts/checks/finding.js +13 -0
- package/dist/bollharness/src/scripts/checks/next_decision_number.js +20 -0
- package/dist/bollharness/src/scripts/checks/regenerate_magic_docs.js +6 -0
- package/dist/bollharness/src/scripts/ci/detect_rebaseline_triggers.js +8 -0
- package/dist/bollharness/src/scripts/ci/scan_subprocess_cfg.js +8 -0
- package/dist/bollharness/src/scripts/ci/scan_verify_artifacts.js +8 -0
- package/dist/bollharness/src/scripts/ci/scan_yaml_schema.js +8 -0
- package/dist/bollharness/src/scripts/context_router.js +67 -0
- package/dist/bollharness/src/scripts/deploy-guard.js +157 -0
- package/dist/bollharness/src/scripts/guard-feedback.js +192 -0
- package/dist/bollharness/src/scripts/guard_router.js +158 -0
- package/dist/bollharness/src/scripts/hooks/_hook_output.js +6 -0
- package/dist/bollharness/src/scripts/hooks/auto-python3.js +6 -0
- package/dist/bollharness/src/scripts/hooks/deploy-progress-on-session-end.js +6 -0
- package/dist/bollharness/src/scripts/hooks/failure-analyzer.js +6 -0
- package/dist/bollharness/src/scripts/hooks/gate-judgment-inject.js +92 -0
- package/dist/bollharness/src/scripts/hooks/gate-transition-judgment.js +63 -0
- package/dist/bollharness/src/scripts/hooks/inbox-ack.js +6 -0
- package/dist/bollharness/src/scripts/hooks/inbox-inject-on-start.js +6 -0
- package/dist/bollharness/src/scripts/hooks/inbox-validate.js +6 -0
- package/dist/bollharness/src/scripts/hooks/inbox-write-ledger.js +6 -0
- package/dist/bollharness/src/scripts/hooks/initializer-agent.js +6 -0
- package/dist/bollharness/src/scripts/hooks/loop-detection.js +73 -0
- package/dist/bollharness/src/scripts/hooks/owner-guard.js +6 -0
- package/dist/bollharness/src/scripts/hooks/precompact.js +6 -0
- package/dist/bollharness/src/scripts/hooks/review-agent-gatekeeper.js +6 -0
- package/dist/bollharness/src/scripts/hooks/risk-tracker.js +108 -0
- package/dist/bollharness/src/scripts/hooks/sanitize-on-read.js +6 -0
- package/dist/bollharness/src/scripts/hooks/session-reflection.js +7 -0
- package/dist/bollharness/src/scripts/hooks/session-start-magic-docs.js +7 -0
- package/dist/bollharness/src/scripts/hooks/session-start-reset-risk.js +7 -0
- package/dist/bollharness/src/scripts/hooks/session-start-toolkit-reminder.js +7 -0
- package/dist/bollharness/src/scripts/hooks/stop-evaluator.js +157 -0
- package/dist/bollharness/src/scripts/hooks/tool-call-counter.js +6 -0
- package/dist/bollharness/src/scripts/hooks/trace-analyzer.js +10 -0
- package/dist/bollharness/src/scripts/install/install-trust-token.js +7 -0
- package/dist/bollharness/src/scripts/install/multi_project_registry.js +9 -0
- package/dist/bollharness/src/scripts/install/phase2_auto.js +21 -0
- package/dist/bollharness/src/scripts/install/pre_commit_installer.js +6 -0
- package/dist/bollharness/src/scripts/install/tier_selector.js +7 -0
- package/dist/bollharness/src/scripts/install/transcript_miner.js +7 -0
- package/dist/bollharness/src/scripts/lib/claim_patterns.js +10 -0
- package/dist/bollharness/src/scripts/lib/sanitize_patterns.js +12 -0
- package/dist/bollharness/src/scripts/sanitize.js +6 -0
- package/dist/constraint-runtime/src/tools/PolymarketSDK/cancelOrder.js +6 -0
- package/dist/constraint-runtime/src/tools/PolymarketSDK/createOrder.js +6 -0
- package/dist/constraint-runtime/src/tools/PolymarketSDK/getMarket.js +5 -0
- package/dist/constraint-runtime/src/tools/PolymarketSDK/getOrders.js +6 -0
- package/dist/constraint-runtime/src/tools/PolymarketSDK/listMarkets.js +4 -0
- package/dist/constraint-runtime/src/tools/SafeSDK/deploySafe.js +6 -0
- package/dist/constraint-runtime/src/tools/WalletTools/autoPay.js +29 -0
- package/dist/constraint-runtime/src/tools/WalletTools/createWallet.js +10 -0
- package/dist/constraint-runtime/src/tools/WalletTools/getBalance.js +13 -0
- package/dist/constraint-runtime/src/tools/WalletTools/importWallet.js +22 -0
- package/dist/constraint-runtime/src/tools/WalletTools/sendTransaction.js +25 -0
- package/dist/constraint-runtime/src/tools/WalletTools/signMessage.js +10 -0
- package/dist/constraint-runtime/src/tools/WalletTools/transferToken.js +25 -0
- package/dist/electron/config.js.map +1 -0
- package/dist/electron/dialogs.js.map +1 -0
- package/dist/electron/first-run.js.map +1 -0
- package/dist/electron/ipc.js.map +1 -0
- package/dist/electron/logger.js.map +1 -0
- package/dist/electron/main.js.map +1 -0
- package/dist/electron/menu.js.map +1 -0
- package/dist/electron/paths.js.map +1 -0
- package/dist/electron/server.js +2 -1
- package/dist/electron/server.js.map +1 -0
- package/dist/electron/tray.js.map +1 -0
- package/dist/electron/window.js.map +1 -0
- package/dist/electron-preload.js +29 -0
- package/dist/electron-preload.js.map +1 -0
- package/dist/electron.js +5 -0
- package/dist/electron.js.map +1 -0
- package/dist/llm/config-store.js +24 -8
- package/dist/llm/pi-ai.js +33 -19
- package/dist/workflows/collaboration.js +374 -0
- package/dist/workflows/index.js +54 -0
- package/package.json +18 -4
- package/.comm/README.md +0 -21
- package/.comm/default/2026-06-17T08-23-00-017Z-8a735de8.md +0 -7
- package/CLAUDE.md +0 -3
- package/build/icon.icns +0 -0
- package/build/icon.ico +0 -0
- package/build/icon.png +0 -0
- package/build/tray.png +0 -0
- package/build/trayTemplate.png +0 -0
- package/scripts/auto-evolve-oneshot.sh +0 -155
- package/scripts/auto-evolve-snapshot.sh +0 -136
- package/scripts/build-cli.js +0 -216
- package/scripts/detect-schema-changes.sh +0 -48
- package/scripts/lefthook-helper.sh +0 -69
- package/scripts/postinstall.js +0 -153
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-Agent Collaboration Workflow
|
|
3
|
+
*
|
|
4
|
+
* 工作流设计:
|
|
5
|
+
* 1. 命令解析 - 理解用户意图
|
|
6
|
+
* 2. DID查询 - 从IPNS/IPFS查找已注册智能体
|
|
7
|
+
* 3. 协作判断 - 分析是否需要多智能体协作
|
|
8
|
+
* 4. 任务分发 - 发送文档给其他智能体
|
|
9
|
+
* 5. 结果汇总 - 收集并整合协作结果
|
|
10
|
+
*/
|
|
11
|
+
import { AgentProtocol } from '../agents/protocol.js';
|
|
12
|
+
import { p2pNetwork } from '../network/p2p.js';
|
|
13
|
+
import { documentReader } from '../documents/reader.js';
|
|
14
|
+
import { getMinimax } from '../constraints/index.js';
|
|
15
|
+
import { IpfsClient } from '@diap/sdk';
|
|
16
|
+
/**
|
|
17
|
+
* 命令解析器 - 将用户输入解析为结构化意图
|
|
18
|
+
*/
|
|
19
|
+
export class CommandParser {
|
|
20
|
+
collaborationKeywords = ['协作', '合作', '其他', '帮忙', '请教', '团队', '分享', '交给'];
|
|
21
|
+
improvementKeywords = ['改进', '优化', '修改', '完善', '润色', '修正'];
|
|
22
|
+
queryKeywords = ['查看', '列表', '查询', '有哪些', '谁在线'];
|
|
23
|
+
parse(input, context) {
|
|
24
|
+
const lowerInput = input.toLowerCase();
|
|
25
|
+
// 检测是否需要协作
|
|
26
|
+
const needCollaboration = this.collaborationKeywords.some(k => lowerInput.includes(k));
|
|
27
|
+
// 解析动作
|
|
28
|
+
let action = 'query';
|
|
29
|
+
if (lowerInput.includes('改进') || lowerInput.includes('优化') || lowerInput.includes('修改')) {
|
|
30
|
+
action = 'improve';
|
|
31
|
+
}
|
|
32
|
+
else if (lowerInput.includes('总结') || lowerInput.includes('摘要')) {
|
|
33
|
+
action = 'summarize';
|
|
34
|
+
}
|
|
35
|
+
else if (lowerInput.includes('读取') || lowerInput.includes('阅读')) {
|
|
36
|
+
action = 'read';
|
|
37
|
+
}
|
|
38
|
+
else if (lowerInput.includes('汇报') || lowerInput.includes('报告')) {
|
|
39
|
+
action = 'report';
|
|
40
|
+
}
|
|
41
|
+
else if (this.queryKeywords.some(k => lowerInput.includes(k))) {
|
|
42
|
+
action = 'query';
|
|
43
|
+
}
|
|
44
|
+
// 提取目标文件/主题
|
|
45
|
+
const targetMatch = input.match(/[\w\.\/]+\.(md|txt|pdf|docx)/i);
|
|
46
|
+
const target = targetMatch ? targetMatch[0] : undefined;
|
|
47
|
+
// 提取需求描述
|
|
48
|
+
const requirements = this.extractRequirements(input);
|
|
49
|
+
// 识别建议的智能体(如果有)
|
|
50
|
+
const suggestedAgents = this.extractAgentNames(input);
|
|
51
|
+
return {
|
|
52
|
+
action,
|
|
53
|
+
target,
|
|
54
|
+
requirements,
|
|
55
|
+
context: context || input,
|
|
56
|
+
needCollaboration,
|
|
57
|
+
suggestedAgents
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
extractRequirements(input) {
|
|
61
|
+
// 查找引号内的内容或特定模式
|
|
62
|
+
const quotes = input.match(/["'""]([^""']+)[""'"]/);
|
|
63
|
+
if (quotes)
|
|
64
|
+
return quotes[1];
|
|
65
|
+
const afterKeywords = input.match(/(?:改进|优化|修改|要求|需要)[::]\s*(.+)/i);
|
|
66
|
+
if (afterKeywords)
|
|
67
|
+
return afterKeywords[1];
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
extractAgentNames(input) {
|
|
71
|
+
const names = input.match(/[@@]\w+/g);
|
|
72
|
+
return names ? names.map(n => n.substring(1)) : undefined;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* DID注册表 - 管理已知智能体的DID信息
|
|
77
|
+
*/
|
|
78
|
+
export class DIDRegistry {
|
|
79
|
+
agents = new Map();
|
|
80
|
+
ipfsClient;
|
|
81
|
+
constructor(ipfsApiUrl = 'http://127.0.0.1:5001') {
|
|
82
|
+
this.ipfsClient = new IpfsClient(ipfsApiUrl, null);
|
|
83
|
+
}
|
|
84
|
+
async registerAgent(agent) {
|
|
85
|
+
this.agents.set(agent.did, {
|
|
86
|
+
...agent,
|
|
87
|
+
lastSeen: Date.now()
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
async unregisterAgent(did) {
|
|
91
|
+
this.agents.delete(did);
|
|
92
|
+
}
|
|
93
|
+
getAgent(did) {
|
|
94
|
+
return this.agents.get(did);
|
|
95
|
+
}
|
|
96
|
+
getAllAgents() {
|
|
97
|
+
return Array.from(this.agents.values());
|
|
98
|
+
}
|
|
99
|
+
getOnlineAgents() {
|
|
100
|
+
const now = Date.now();
|
|
101
|
+
const timeout = 5 * 60 * 1000; // 5分钟超时
|
|
102
|
+
return this.getAllAgents().filter(a => a.lastSeen && (now - a.lastSeen) < timeout);
|
|
103
|
+
}
|
|
104
|
+
async resolveDIDFromIPNS(ipnsName) {
|
|
105
|
+
try {
|
|
106
|
+
const cid = await this.ipfsClient.resolveIpns(ipnsName);
|
|
107
|
+
const content = await this.ipfsClient.get(cid);
|
|
108
|
+
const doc = JSON.parse(content);
|
|
109
|
+
return {
|
|
110
|
+
did: doc.id,
|
|
111
|
+
name: doc.name || doc.id,
|
|
112
|
+
ipnsName
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
console.error(`Failed to resolve DID from IPNS ${ipnsName}:`, error);
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
async discoverAgents() {
|
|
121
|
+
const discovered = [];
|
|
122
|
+
const peers = p2pNetwork.getPeers();
|
|
123
|
+
for (const peerId of peers) {
|
|
124
|
+
// 尝试从已知IPNS名称列表中解析
|
|
125
|
+
// 实际实现中应该通过某种服务发现机制
|
|
126
|
+
const agent = this.getAgentByPeerId(peerId);
|
|
127
|
+
if (agent) {
|
|
128
|
+
discovered.push(agent);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return discovered;
|
|
132
|
+
}
|
|
133
|
+
getAgentByPeerId(peerId) {
|
|
134
|
+
for (const agent of this.agents.values()) {
|
|
135
|
+
if (agent.peerId === peerId) {
|
|
136
|
+
return agent;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* 协作决策器 - 判断是否需要多智能体协作
|
|
144
|
+
*/
|
|
145
|
+
export class CollaborationDecider {
|
|
146
|
+
threshold = 0.7;
|
|
147
|
+
async shouldCollaborate(intent, qualityScore) {
|
|
148
|
+
// 明确要求协作
|
|
149
|
+
if (intent.needCollaboration)
|
|
150
|
+
return true;
|
|
151
|
+
// 质量问题,建议协作改进
|
|
152
|
+
if (qualityScore && qualityScore < this.threshold)
|
|
153
|
+
return true;
|
|
154
|
+
// 复杂任务建议协作
|
|
155
|
+
if (intent.action === 'improve' && intent.requirements) {
|
|
156
|
+
if (intent.requirements.length > 200)
|
|
157
|
+
return true; // 复杂需求
|
|
158
|
+
}
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
selectAgentsForTask(intent, availableAgents) {
|
|
162
|
+
if (!availableAgents.length)
|
|
163
|
+
return [];
|
|
164
|
+
// 如果用户指定了智能体
|
|
165
|
+
if (intent.suggestedAgents?.length) {
|
|
166
|
+
return availableAgents.filter(a => intent.suggestedAgents.some(name => a.name.includes(name) || a.did.includes(name)));
|
|
167
|
+
}
|
|
168
|
+
// 根据任务类型选择
|
|
169
|
+
switch (intent.action) {
|
|
170
|
+
case 'improve':
|
|
171
|
+
// 改进任务可以选多个智能体并行处理
|
|
172
|
+
return availableAgents.slice(0, 3);
|
|
173
|
+
case 'summarize':
|
|
174
|
+
// 摘要任务选一个即可
|
|
175
|
+
return [availableAgents[0]];
|
|
176
|
+
default:
|
|
177
|
+
return availableAgents.slice(0, 2);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* 任务分发器 - 管理多智能体任务分发和结果收集
|
|
183
|
+
*/
|
|
184
|
+
export class TaskDispatcher {
|
|
185
|
+
protocol;
|
|
186
|
+
pendingTasks = new Map();
|
|
187
|
+
constructor(protocol) {
|
|
188
|
+
this.protocol = protocol;
|
|
189
|
+
}
|
|
190
|
+
async dispatchSummarize(intent, target, agents) {
|
|
191
|
+
const taskId = `summarize-${Date.now()}`;
|
|
192
|
+
this.pendingTasks.set(taskId, { intent, agents });
|
|
193
|
+
// 广播任务给选定的智能体
|
|
194
|
+
for (const agent of agents) {
|
|
195
|
+
const task = {
|
|
196
|
+
taskId,
|
|
197
|
+
action: 'summarize',
|
|
198
|
+
target,
|
|
199
|
+
context: intent.context
|
|
200
|
+
};
|
|
201
|
+
await this.protocol.sendTask(task, agent.peerId || agent.did);
|
|
202
|
+
}
|
|
203
|
+
return taskId;
|
|
204
|
+
}
|
|
205
|
+
async dispatchImprove(intent, target, agents) {
|
|
206
|
+
const taskId = `improve-${Date.now()}`;
|
|
207
|
+
this.pendingTasks.set(taskId, { intent, agents });
|
|
208
|
+
// 向每个智能体发送改进请求
|
|
209
|
+
for (const agent of agents) {
|
|
210
|
+
await this.protocol.requestImprove(target, intent.requirements || '', agent.peerId);
|
|
211
|
+
}
|
|
212
|
+
return taskId;
|
|
213
|
+
}
|
|
214
|
+
cancelTask(taskId) {
|
|
215
|
+
this.pendingTasks.delete(taskId);
|
|
216
|
+
}
|
|
217
|
+
getPendingTasks() {
|
|
218
|
+
return Array.from(this.pendingTasks.keys());
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* 多智能体协作工作流 - 主协调器
|
|
223
|
+
*/
|
|
224
|
+
export class MultiAgentWorkflow {
|
|
225
|
+
parser;
|
|
226
|
+
registry;
|
|
227
|
+
decider;
|
|
228
|
+
dispatcher;
|
|
229
|
+
protocol;
|
|
230
|
+
constructor() {
|
|
231
|
+
this.parser = new CommandParser();
|
|
232
|
+
this.registry = new DIDRegistry();
|
|
233
|
+
this.decider = new CollaborationDecider();
|
|
234
|
+
this.protocol = new AgentProtocol('local', 'coordinator');
|
|
235
|
+
this.dispatcher = new TaskDispatcher(this.protocol);
|
|
236
|
+
this.setupResultHandlers();
|
|
237
|
+
}
|
|
238
|
+
setupResultHandlers() {
|
|
239
|
+
// 处理返回结果
|
|
240
|
+
p2pNetwork.onMessage('result', async (data, from) => {
|
|
241
|
+
const msg = JSON.parse(new TextDecoder().decode(data));
|
|
242
|
+
const result = JSON.parse(msg.payload);
|
|
243
|
+
console.log(`\n📥 收到来自 ${from} 的结果:`);
|
|
244
|
+
console.log(` 质量: ${(result.qualityScore * 10).toFixed(1)}/10`);
|
|
245
|
+
console.log(` 摘要: ${result.result?.substring(0, 100)}...`);
|
|
246
|
+
});
|
|
247
|
+
// 处理改进结果
|
|
248
|
+
p2pNetwork.onMessage('improved', async (data, from) => {
|
|
249
|
+
const msg = JSON.parse(new TextDecoder().decode(data));
|
|
250
|
+
const result = JSON.parse(msg.payload);
|
|
251
|
+
console.log(`\n✨ 收到来自 ${from} 的改进结果:`);
|
|
252
|
+
console.log(` 质量: ${(result.qualityScore * 10).toFixed(1)}/10`);
|
|
253
|
+
console.log(` 自动发送: ${result.shouldAutoSend ? '是' : '否'}`);
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* 处理用户输入的完整流程
|
|
258
|
+
*/
|
|
259
|
+
async process(input, context) {
|
|
260
|
+
// 1. 命令解析
|
|
261
|
+
const intent = this.parser.parse(input, context);
|
|
262
|
+
console.log(`\n🔍 解析命令:`, intent);
|
|
263
|
+
// 2. 发现可用的智能体
|
|
264
|
+
const agents = await this.registry.discoverAgents();
|
|
265
|
+
console.log(`\n👥 发现 ${agents.length} 个在线智能体`);
|
|
266
|
+
// 3. 协作决策
|
|
267
|
+
const shouldCollaborate = await this.decider.shouldCollaborate(intent);
|
|
268
|
+
console.log(`\n🤔 协作决策: ${shouldCollaborate ? '需要协作' : '独立完成'}`);
|
|
269
|
+
if (!shouldCollaborate) {
|
|
270
|
+
// 独立执行
|
|
271
|
+
return this.executeIndependently(intent);
|
|
272
|
+
}
|
|
273
|
+
// 4. 选择执行智能体
|
|
274
|
+
const selectedAgents = this.decider.selectAgentsForTask(intent, agents);
|
|
275
|
+
console.log(`\n🎯 选中 ${selectedAgents.length} 个智能体执行`);
|
|
276
|
+
if (selectedAgents.length === 0) {
|
|
277
|
+
// 没有可用智能体,降级为独立执行
|
|
278
|
+
console.log(`\n⚠️ 没有可用智能体,降级为独立执行`);
|
|
279
|
+
return this.executeIndependently(intent);
|
|
280
|
+
}
|
|
281
|
+
// 5. 分发任务
|
|
282
|
+
return this.dispatchToAgents(intent, selectedAgents);
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* 独立执行(无需协作)
|
|
286
|
+
*/
|
|
287
|
+
async executeIndependently(intent) {
|
|
288
|
+
try {
|
|
289
|
+
let result;
|
|
290
|
+
let qualityScore = 0.5;
|
|
291
|
+
if (intent.action === 'read' || intent.action === 'summarize') {
|
|
292
|
+
if (!intent.target) {
|
|
293
|
+
return { success: false, collaborated: false, agents: [], error: '缺少目标文件' };
|
|
294
|
+
}
|
|
295
|
+
const content = await documentReader.read(intent.target);
|
|
296
|
+
const llm = getMinimax();
|
|
297
|
+
const summarizeResult = await llm.summarize(content.text, intent.context);
|
|
298
|
+
result = summarizeResult.summary;
|
|
299
|
+
qualityScore = summarizeResult.qualityScore;
|
|
300
|
+
}
|
|
301
|
+
else if (intent.action === 'improve' && intent.target) {
|
|
302
|
+
const content = await documentReader.read(intent.target);
|
|
303
|
+
const llm = getMinimax();
|
|
304
|
+
result = await llm.improveContent(content.text, intent.requirements || '', intent.context);
|
|
305
|
+
qualityScore = llm.estimateQuality(content.text, result);
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
return { success: false, collaborated: false, agents: [], error: '未知动作' };
|
|
309
|
+
}
|
|
310
|
+
return {
|
|
311
|
+
success: true,
|
|
312
|
+
collaborated: false,
|
|
313
|
+
agents: [],
|
|
314
|
+
result,
|
|
315
|
+
qualityScore
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
catch (error) {
|
|
319
|
+
return {
|
|
320
|
+
success: false,
|
|
321
|
+
collaborated: false,
|
|
322
|
+
agents: [],
|
|
323
|
+
error: String(error)
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* 分发给多个智能体协作执行
|
|
329
|
+
*/
|
|
330
|
+
async dispatchToAgents(intent, agents) {
|
|
331
|
+
try {
|
|
332
|
+
if (!intent.target) {
|
|
333
|
+
return { success: false, collaborated: true, agents, error: '缺少目标文件' };
|
|
334
|
+
}
|
|
335
|
+
let taskId;
|
|
336
|
+
if (intent.action === 'summarize' || intent.action === 'read') {
|
|
337
|
+
taskId = await this.dispatcher.dispatchSummarize(intent, intent.target, agents);
|
|
338
|
+
}
|
|
339
|
+
else if (intent.action === 'improve') {
|
|
340
|
+
taskId = await this.dispatcher.dispatchImprove(intent, intent.target, agents);
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
return { success: false, collaborated: true, agents, error: '不支持的协作动作' };
|
|
344
|
+
}
|
|
345
|
+
return {
|
|
346
|
+
success: true,
|
|
347
|
+
collaborated: true,
|
|
348
|
+
agents,
|
|
349
|
+
taskId,
|
|
350
|
+
result: `任务已分发,等待结果...`
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
catch (error) {
|
|
354
|
+
return {
|
|
355
|
+
success: false,
|
|
356
|
+
collaborated: true,
|
|
357
|
+
agents,
|
|
358
|
+
error: String(error)
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* 查询当前在线的智能体
|
|
364
|
+
*/
|
|
365
|
+
async listAgents() {
|
|
366
|
+
return this.registry.discoverAgents();
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* 注册一个新智能体
|
|
370
|
+
*/
|
|
371
|
+
async registerAgent(agent) {
|
|
372
|
+
await this.registry.registerAgent(agent);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-Agent Collaboration Workflows
|
|
3
|
+
*
|
|
4
|
+
* 工作流设计文档:
|
|
5
|
+
*
|
|
6
|
+
* ┌─────────────────────────────────────────────────────────────┐
|
|
7
|
+
* │ 用户输入 │
|
|
8
|
+
* └─────────────────────────────────────────────────────────────┘
|
|
9
|
+
* │
|
|
10
|
+
* ▼
|
|
11
|
+
* ┌─────────────────────────────────────────────────────────────┐
|
|
12
|
+
* │ 命令解析器 (CommandParser) │
|
|
13
|
+
* │ - 识别动作: read/summarize/improve/query/collaborate │
|
|
14
|
+
* │ - 提取目标文件、需求描述 │
|
|
15
|
+
* │ - 检测协作关键词 │
|
|
16
|
+
* └─────────────────────────────────────────────────────────────┘
|
|
17
|
+
* │
|
|
18
|
+
* ▼
|
|
19
|
+
* ┌─────────────────────────────────────────────────────────────┐
|
|
20
|
+
* │ DID注册表 (DIDRegistry) │
|
|
21
|
+
* │ - 管理已知智能体的DID信息 │
|
|
22
|
+
* │ - 从IPNS解析其他智能体DID文档 │
|
|
23
|
+
* │ - 追踪在线状态 │
|
|
24
|
+
* └─────────────────────────────────────────────────────────────┘
|
|
25
|
+
* │
|
|
26
|
+
* ▼
|
|
27
|
+
* ┌─────────────────────────────────────────────────────────────┐
|
|
28
|
+
* │ 协作决策器 (CollaborationDecider) │
|
|
29
|
+
* │ - 基于任务复杂度、关键词、质量评分决策 │
|
|
30
|
+
* │ - 选择合适的执行智能体 │
|
|
31
|
+
* └─────────────────────────────────────────────────────────────┘
|
|
32
|
+
* │
|
|
33
|
+
* ┌─────────────┴─────────────┐
|
|
34
|
+
* │ │
|
|
35
|
+
* ▼ ▼
|
|
36
|
+
* ┌─────────────────┐ ┌─────────────────┐
|
|
37
|
+
* │ 独立执行 │ │ 多智能体协作 │
|
|
38
|
+
* │ - 直接处理 │ │ │
|
|
39
|
+
* │ - 返回结果 │ │ - 分发任务 │
|
|
40
|
+
* └─────────────────┘ │ - 收集结果 │
|
|
41
|
+
* │ - 汇总汇报 │
|
|
42
|
+
* └─────────────────┘
|
|
43
|
+
* │
|
|
44
|
+
* ▼
|
|
45
|
+
* ┌─────────────────┐
|
|
46
|
+
* │ 任务分发器 │
|
|
47
|
+
* │ (TaskDispatcher) │
|
|
48
|
+
* │ │
|
|
49
|
+
* │ - Protocol发送 │
|
|
50
|
+
* │ - 任务追踪 │
|
|
51
|
+
* │ - 结果收集 │
|
|
52
|
+
* └─────────────────┘
|
|
53
|
+
*/
|
|
54
|
+
export { CommandParser, DIDRegistry, CollaborationDecider, TaskDispatcher, MultiAgentWorkflow } from './collaboration.js';
|
package/package.json
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bolloon/bolloon-agent",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "P2P AI Document Agent - 全局安装后执行 `bolloon` 启动产品",
|
|
6
|
-
"main": "dist/cli.js",
|
|
7
|
-
"author": "Bolloon
|
|
6
|
+
"main": "dist/cli-entry.js",
|
|
7
|
+
"author": "Bolloon Leo",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/logos-42/bolloon.git"
|
|
11
|
+
},
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"files": [
|
|
14
|
+
"dist",
|
|
15
|
+
"bin"
|
|
16
|
+
],
|
|
8
17
|
"bin": {
|
|
9
18
|
"bolloon": "./bin/bolloon-cli.cjs"
|
|
10
19
|
},
|
|
@@ -23,6 +32,8 @@
|
|
|
23
32
|
"electron:dev": "concurrently \"npm run dev:web\" \"npm run electron:start\"",
|
|
24
33
|
"electron:build": "npm run build:electron && electron-builder",
|
|
25
34
|
"electron:pack": "electron-builder --dir",
|
|
35
|
+
"app:bundle": "node scripts/build-app-bundle.cjs",
|
|
36
|
+
"app:bundle:open": "node scripts/build-app-bundle.cjs && open \"release/mac-arm64/Bolloon Agent.app\"",
|
|
26
37
|
"test": "vitest run",
|
|
27
38
|
"test:watch": "vitest",
|
|
28
39
|
"test:pi-sdk": "tsx src/test/pi-sdk.test.ts",
|
|
@@ -34,6 +45,8 @@
|
|
|
34
45
|
"dependencies": {
|
|
35
46
|
"@bolloon/bolloon-agent": "^0.1.36",
|
|
36
47
|
"@bolloon/constraint-runtime": "0.1.0",
|
|
48
|
+
"@capacitor/core": "^8.4.1",
|
|
49
|
+
"@capacitor/ios": "^8.4.1",
|
|
37
50
|
"@chainsafe/libp2p-noise": "^17.0.0",
|
|
38
51
|
"@chainsafe/libp2p-yamux": "^8.0.1",
|
|
39
52
|
"@diap/sdk": "^0.1.10",
|
|
@@ -60,6 +73,7 @@
|
|
|
60
73
|
"viem": "^2.52.0"
|
|
61
74
|
},
|
|
62
75
|
"devDependencies": {
|
|
76
|
+
"@capacitor/cli": "^8.4.1",
|
|
63
77
|
"@playwright/test": "^1.60.0",
|
|
64
78
|
"@types/express": "^5.0.6",
|
|
65
79
|
"@types/node": "^25.9.1",
|
|
@@ -68,7 +82,7 @@
|
|
|
68
82
|
"@types/react-dom": "^18.3.0",
|
|
69
83
|
"concurrently": "^9.2.1",
|
|
70
84
|
"electron": "^42.3.0",
|
|
71
|
-
"electron-builder": "^26.
|
|
85
|
+
"electron-builder": "^26.15.5",
|
|
72
86
|
"lefthook": "^2.1.9",
|
|
73
87
|
"playwright": "^1.60.0",
|
|
74
88
|
"tsx": "^4.0.0",
|
package/.comm/README.md
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# .comm/ — 跨机聊天收件箱
|
|
2
|
-
|
|
3
|
-
Bolloon chat transport: commits-as-messages.
|
|
4
|
-
每条消息 = 一个 markdown 文件 + 一次 git commit + push.
|
|
5
|
-
|
|
6
|
-
## 目录约定
|
|
7
|
-
|
|
8
|
-
- `<role>/` — 每个 role 一个子目录, 里面是该角色发的所有消息
|
|
9
|
-
- `_state/` — 本地运行态 (cursor, seen, lock), 不 commit
|
|
10
|
-
- `_inbox/` — 看门狗把对方消息反写到本地, 不 commit
|
|
11
|
-
|
|
12
|
-
## 子命令
|
|
13
|
-
|
|
14
|
-
```
|
|
15
|
-
bolloon --chat-init
|
|
16
|
-
bolloon --chat-send "..."
|
|
17
|
-
bolloon --chat-pull
|
|
18
|
-
bolloon --chat-list
|
|
19
|
-
bolloon --chat-watch
|
|
20
|
-
bolloon --chat-status
|
|
21
|
-
```
|
package/CLAUDE.md
DELETED
package/build/icon.icns
DELETED
|
Binary file
|
package/build/icon.ico
DELETED
|
Binary file
|
package/build/icon.png
DELETED
|
Binary file
|
package/build/tray.png
DELETED
|
Binary file
|
package/build/trayTemplate.png
DELETED
|
Binary file
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# auto-evolve-oneshot.sh — 阶段 D 单次修复 (shell 版)
|
|
3
|
-
#
|
|
4
|
-
# 流程 (全本地, 用 MINIMAX_API_KEY 调 LLM):
|
|
5
|
-
# 1. 跑 vitest, 抓 fail
|
|
6
|
-
# 2. 让 LLM 修
|
|
7
|
-
# 3. 解析 LLM 输出的 diff, 写到 staging
|
|
8
|
-
# 4. 跑 reviewer (护栏 4)
|
|
9
|
-
# 5. PASS → git apply + commit (护栏 1 拦)
|
|
10
|
-
|
|
11
|
-
set -uo pipefail # 不加 -e: vitest 失败要继续
|
|
12
|
-
|
|
13
|
-
REPO="$(cd "$(dirname "$0")/.." && pwd)"
|
|
14
|
-
cd "$REPO"
|
|
15
|
-
|
|
16
|
-
echo "[oneshot] REPO=$REPO"
|
|
17
|
-
|
|
18
|
-
# 1. 跑 vitest
|
|
19
|
-
npx vitest run --reporter=json --no-color 2>/dev/null > /tmp/vt-out.json
|
|
20
|
-
TOTAL_FAIL=$(python3 -c "
|
|
21
|
-
import json
|
|
22
|
-
d = json.load(open('/tmp/vt-out.json'))
|
|
23
|
-
print(sum(1 for f in d.get('testResults',[]) for a in f.get('assertionResults',[]) if a.get('status')=='failed'))
|
|
24
|
-
")
|
|
25
|
-
echo "[oneshot] vitest failed=$TOTAL_FAIL"
|
|
26
|
-
|
|
27
|
-
if [ "$TOTAL_FAIL" = "0" ]; then
|
|
28
|
-
echo "[oneshot] ✅ 全部通过, 不需要修"
|
|
29
|
-
exit 0
|
|
30
|
-
fi
|
|
31
|
-
|
|
32
|
-
# 2. 抽 fail 信息
|
|
33
|
-
FAIL_SUMMARY=$(python3 -c "
|
|
34
|
-
import json
|
|
35
|
-
d = json.load(open('/tmp/vt-out.json'))
|
|
36
|
-
for f in d.get('testResults', []):
|
|
37
|
-
for a in f.get('assertionResults', []):
|
|
38
|
-
if a.get('status') == 'failed':
|
|
39
|
-
print('FILE:', f.get('name'))
|
|
40
|
-
print('TEST:', a.get('fullName') or a.get('title'))
|
|
41
|
-
print('ERROR:')
|
|
42
|
-
for m in a.get('failureMessages', [])[:2]:
|
|
43
|
-
print(m[:600])
|
|
44
|
-
print('---')
|
|
45
|
-
" | head -60)
|
|
46
|
-
echo "[oneshot] 2. 调 LLM 修..."
|
|
47
|
-
|
|
48
|
-
# 3. 用 LLM 生成修复
|
|
49
|
-
# prompt: 要 LLM 输出 ```diff ... ``` 块
|
|
50
|
-
# 3. 写 prompt 到文件 (避免 shell 反引号冲突)
|
|
51
|
-
PROMPT_FILE="/tmp/oneshot-prompt.txt"
|
|
52
|
-
cat > "$PROMPT_FILE" <<PROMPT_EOF
|
|
53
|
-
你是一个谨慎的代码修复助手. 你的工作是修复失败的测试.
|
|
54
|
-
|
|
55
|
-
约束: 改动最小, 不改测试, 不引入 any/unknown/@ts-ignore.
|
|
56
|
-
|
|
57
|
-
输出格式: 严格只输出一个 \`\`\`diff ... \`\`\` 块, 第一个字符 \`\`\`diff, 最后一个字符 \`\`\`. 中间是 unified diff (--- a/path +++ b/path 风格). 不要在 diff 块外输出任何文字.
|
|
58
|
-
|
|
59
|
-
FAIL 信息:
|
|
60
|
-
$(cat /tmp/vt-out.json | python3 -c "
|
|
61
|
-
import json
|
|
62
|
-
d = json.load(open('/tmp/vt-out.json'))
|
|
63
|
-
for f in d.get('testResults', []):
|
|
64
|
-
for a in f.get('assertionResults', []):
|
|
65
|
-
if a.get('status') == 'failed':
|
|
66
|
-
print('FILE:', f.get('name'))
|
|
67
|
-
print('TEST:', a.get('fullName') or a.get('title'))
|
|
68
|
-
print('ERROR:')
|
|
69
|
-
for m in a.get('failureMessages', [])[:2]:
|
|
70
|
-
print(m[:600])
|
|
71
|
-
print('---')
|
|
72
|
-
" | head -60)
|
|
73
|
-
|
|
74
|
-
请**只**输出 diff 块:
|
|
75
|
-
PROMPT_EOF
|
|
76
|
-
|
|
77
|
-
LLM_OUTPUT=$(npx tsx -r dotenv/config -e "
|
|
78
|
-
import { initMinimax } from './src/llm/pi-ai.js';
|
|
79
|
-
import * as fs from 'fs';
|
|
80
|
-
const prompt = fs.readFileSync('$PROMPT_FILE', 'utf-8');
|
|
81
|
-
const client = initMinimax();
|
|
82
|
-
const text = await client.generateText({ messages: [{ role: 'user', content: prompt }], maxTokens: 4096, temperature: 0.2 });
|
|
83
|
-
process.stdout.write(text || '');
|
|
84
|
-
" 2>/tmp/llm-err.log)
|
|
85
|
-
|
|
86
|
-
if [ -z "$LLM_OUTPUT" ]; then
|
|
87
|
-
echo "[oneshot] ❌ LLM 没返回"
|
|
88
|
-
exit 2
|
|
89
|
-
fi
|
|
90
|
-
|
|
91
|
-
# 4. 解析 diff
|
|
92
|
-
DIFF=$(echo "$LLM_OUTPUT" | python3 -c "
|
|
93
|
-
import sys, re
|
|
94
|
-
text = sys.stdin.read()
|
|
95
|
-
m = re.search(r'\`\`\`diff\s*([\s\S]*?)\`\`\`', text)
|
|
96
|
-
if m:
|
|
97
|
-
diff = m.group(1).strip()
|
|
98
|
-
if not diff.endswith('\n'):
|
|
99
|
-
diff += '\n'
|
|
100
|
-
print(diff)
|
|
101
|
-
else:
|
|
102
|
-
sys.exit(1)
|
|
103
|
-
" 2>/dev/null) || {
|
|
104
|
-
echo "[oneshot] ❌ LLM 输出没 diff 块"
|
|
105
|
-
echo "--- LLM 原始输出 (前 800) ---"
|
|
106
|
-
echo "$LLM_OUTPUT" | head -c 800
|
|
107
|
-
echo ""
|
|
108
|
-
exit 3
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
echo "[oneshot] 拿到 diff: $(echo "$DIFF" | wc -l) lines"
|
|
112
|
-
|
|
113
|
-
# 5. 写 staging
|
|
114
|
-
ID="oneshot-$(date +%s)"
|
|
115
|
-
mkdir -p "staging/auto-evolve/$ID"
|
|
116
|
-
echo "$DIFF" > "staging/auto-evolve/$ID/$ID.patch"
|
|
117
|
-
echo "$ID" > "staging/auto-evolve/$ID/.patch-id"
|
|
118
|
-
echo "[oneshot] patch 写到 staging/auto-evolve/$ID/"
|
|
119
|
-
|
|
120
|
-
# 6. 跑 reviewer
|
|
121
|
-
echo "[oneshot] 3. 跑 reviewer..."
|
|
122
|
-
npx tsx -r dotenv/config scripts/diff-reviewer.ts "$ID" > /tmp/reviewer.log 2>&1 || true
|
|
123
|
-
VERDICT=$(python3 -c "
|
|
124
|
-
import json
|
|
125
|
-
try:
|
|
126
|
-
print(json.load(open('staging/auto-evolve/$ID/.review-verdict')).get('verdict','UNKNOWN'))
|
|
127
|
-
except:
|
|
128
|
-
print('UNKNOWN')
|
|
129
|
-
")
|
|
130
|
-
echo "[oneshot] reviewer verdict: $VERDICT"
|
|
131
|
-
|
|
132
|
-
# 7. apply + commit
|
|
133
|
-
if [ "$VERDICT" = "PASS" ]; then
|
|
134
|
-
echo "[oneshot] 4. apply + commit"
|
|
135
|
-
if git apply --recount --whitespace=fix "staging/auto-evolve/$ID/$ID.patch" 2>/tmp/apply.err; then
|
|
136
|
-
git add -A
|
|
137
|
-
git commit -m "auto-evolve: $ID (LLM 修复)"
|
|
138
|
-
echo "[oneshot] ✅ 提交成功"
|
|
139
|
-
# 验证
|
|
140
|
-
npx vitest run --reporter=json --no-color 2>/dev/null > /tmp/vt-after.json
|
|
141
|
-
AFTER_FAIL=$(python3 -c "
|
|
142
|
-
import json
|
|
143
|
-
print(sum(1 for f in json.load(open('/tmp/vt-after.json')).get('testResults',[]) for a in f.get('assertionResults',[]) if a.get('status')=='failed'))
|
|
144
|
-
")
|
|
145
|
-
echo "[oneshot] 修复后 fail: $AFTER_FAIL (之前 $TOTAL_FAIL)"
|
|
146
|
-
else
|
|
147
|
-
echo "[oneshot] ❌ git apply 失败:"
|
|
148
|
-
cat /tmp/apply.err
|
|
149
|
-
exit 4
|
|
150
|
-
fi
|
|
151
|
-
else
|
|
152
|
-
echo "[oneshot] ❌ reviewer verdict=$VERDICT, 不 apply"
|
|
153
|
-
cat /tmp/reviewer.log | head -10
|
|
154
|
-
exit 5
|
|
155
|
-
fi
|