@bolloon/bolloon-agent 0.1.38 → 0.1.39
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/dist/agents/constraint-layer.js +1 -2
- package/dist/web/client.js +2861 -3746
- package/dist/web/components/p2p/index.js +226 -264
- package/dist/web/ui/message-renderer.js +323 -434
- package/dist/web/ui/step-timeline.js +255 -351
- package/package.json +1 -1
- package/dist/bollharness-integration/llm/pi-ai.js +0 -397
- package/dist/bollharness-integration/pi-ecosystem-colony/index.js +0 -365
- package/dist/bollharness-integration/pi-ecosystem-goals/index.js +0 -458
- package/dist/bollharness-integration/pi-ecosystem-judgment/decision.js +0 -300
- package/dist/bollharness-integration/pi-ecosystem-judgment/distillation.js +0 -291
- package/dist/bollharness-integration/pi-ecosystem-judgment/index.js +0 -445
- package/dist/bollharness-integration/pi-ecosystem-mcp/index.js +0 -331
- package/dist/bollharness-integration/pi-ecosystem-subagents/index.js +0 -303
- package/dist/constraints/commands.js +0 -100
- package/dist/constraints/permissions.js +0 -37
- package/dist/constraints/runtime.js +0 -135
- package/dist/constraints/session.js +0 -48
- package/dist/constraints/system-init.js +0 -51
- package/dist/constraints/tools.js +0 -104
- package/dist/llm/minimax-provider.js +0 -46
- package/dist/llm/minimax.js +0 -45
- package/dist/pi-ecosystem-colony/index.js +0 -365
- package/dist/runtime/context/minimax-prompt.js +0 -178
- package/dist/runtime/context/sys-prompt.js +0 -1
- package/dist/social/ant-colony/AdaptiveHeartbeat.js +0 -101
- package/dist/social/ant-colony/PheromoneEngine.js +0 -227
- package/dist/social/ant-colony/index.js +0 -6
- package/dist/social/ant-colony/types.js +0 -24
- package/dist/utils/double.js +0 -6
- package/dist/web/components/p2p/P2PModal.js +0 -188
- package/dist/web/components/p2p/p2p-modal.js +0 -657
- package/dist/web/components/p2p/p2p-tools.js +0 -248
|
@@ -1,397 +0,0 @@
|
|
|
1
|
-
export class PiAIModel {
|
|
2
|
-
config;
|
|
3
|
-
provider;
|
|
4
|
-
constructor(config) {
|
|
5
|
-
this.config = config;
|
|
6
|
-
this.provider = config.provider;
|
|
7
|
-
}
|
|
8
|
-
async chat(message, context) {
|
|
9
|
-
const systemPrompt = this.buildSystemPrompt(context);
|
|
10
|
-
const messages = [
|
|
11
|
-
{ role: 'system', content: systemPrompt },
|
|
12
|
-
{ role: 'user', content: message }
|
|
13
|
-
];
|
|
14
|
-
try {
|
|
15
|
-
const response = await this.generateText({
|
|
16
|
-
messages,
|
|
17
|
-
temperature: 0.8
|
|
18
|
-
});
|
|
19
|
-
return { reply: response };
|
|
20
|
-
}
|
|
21
|
-
catch (error) {
|
|
22
|
-
console.error('PiAI chat error:', error);
|
|
23
|
-
return { reply: '抱歉,AI服务暂时不可用。' };
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
async summarize(text, context) {
|
|
27
|
-
const prompt = this.buildSummarizePrompt(text, context);
|
|
28
|
-
try {
|
|
29
|
-
const response = await this.generateText({
|
|
30
|
-
messages: [
|
|
31
|
-
{ role: 'system', content: 'You are a professional document summarizer.' },
|
|
32
|
-
{ role: 'user', content: prompt }
|
|
33
|
-
],
|
|
34
|
-
temperature: 0.7
|
|
35
|
-
});
|
|
36
|
-
const qualityScore = this.estimateQuality(text, response);
|
|
37
|
-
return { summary: response, qualityScore };
|
|
38
|
-
}
|
|
39
|
-
catch (error) {
|
|
40
|
-
console.error('PiAI summarize error:', error);
|
|
41
|
-
return {
|
|
42
|
-
summary: text.substring(0, 500) + '...',
|
|
43
|
-
qualityScore: 0.5
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
async improveContent(content, requirements, context) {
|
|
48
|
-
const prompt = this.buildImprovePrompt(content, requirements, context);
|
|
49
|
-
try {
|
|
50
|
-
const response = await this.generateText({
|
|
51
|
-
messages: [
|
|
52
|
-
{ role: 'system', content: 'You are a professional document editor and improver.' },
|
|
53
|
-
{ role: 'user', content: prompt }
|
|
54
|
-
],
|
|
55
|
-
temperature: 0.8
|
|
56
|
-
});
|
|
57
|
-
return response;
|
|
58
|
-
}
|
|
59
|
-
catch (error) {
|
|
60
|
-
console.error('PiAI improve error:', error);
|
|
61
|
-
return content;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
async generateText(options) {
|
|
65
|
-
const { messages, temperature = 0.7, maxTokens = 4096 } = options;
|
|
66
|
-
switch (this.provider) {
|
|
67
|
-
case 'openai':
|
|
68
|
-
case 'minimax':
|
|
69
|
-
return this.callOpenAI(messages, temperature, maxTokens);
|
|
70
|
-
case 'anthropic':
|
|
71
|
-
return this.callAnthropic(messages, temperature, maxTokens);
|
|
72
|
-
case 'ollama':
|
|
73
|
-
return this.callOllama(messages, temperature);
|
|
74
|
-
case 'openrouter':
|
|
75
|
-
return this.callOpenRouter(messages, temperature, maxTokens);
|
|
76
|
-
case 'gemini':
|
|
77
|
-
return this.callGemini(messages, temperature, maxTokens);
|
|
78
|
-
case 'local':
|
|
79
|
-
return this.callLocal(messages, temperature);
|
|
80
|
-
default:
|
|
81
|
-
throw new Error(`Unsupported provider: ${this.provider}`);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
getApiKey() {
|
|
85
|
-
return this.config.apiKey || this.getEnvApiKey();
|
|
86
|
-
}
|
|
87
|
-
getEnvApiKey() {
|
|
88
|
-
const envVars = {
|
|
89
|
-
openai: process.env.OPENAI_API_KEY || '',
|
|
90
|
-
anthropic: process.env.ANTHROPIC_API_KEY || '',
|
|
91
|
-
ollama: '',
|
|
92
|
-
openrouter: process.env.OPENROUTER_API_KEY || '',
|
|
93
|
-
gemini: process.env.GEMINI_API_KEY || '',
|
|
94
|
-
minimax: process.env.MINIMAX_API_KEY || '',
|
|
95
|
-
local: ''
|
|
96
|
-
};
|
|
97
|
-
return envVars[this.provider] || '';
|
|
98
|
-
}
|
|
99
|
-
getBaseUrl() {
|
|
100
|
-
if (this.config.baseUrl) {
|
|
101
|
-
return this.config.baseUrl;
|
|
102
|
-
}
|
|
103
|
-
const baseUrls = {
|
|
104
|
-
openai: 'https://api.openai.com/v1',
|
|
105
|
-
anthropic: 'https://api.anthropic.com/v1',
|
|
106
|
-
ollama: process.env.OLLAMA_BASE_URL || 'http://localhost:11434',
|
|
107
|
-
openrouter: 'https://openrouter.ai/api/v1',
|
|
108
|
-
gemini: 'https://generativelanguage.googleapis.com/v1beta',
|
|
109
|
-
minimax: 'https://api.minimaxi.com/v1',
|
|
110
|
-
local: 'http://localhost:11434'
|
|
111
|
-
};
|
|
112
|
-
return baseUrls[this.provider];
|
|
113
|
-
}
|
|
114
|
-
mapModel() {
|
|
115
|
-
const modelMap = {
|
|
116
|
-
openai: this.config.model || 'gpt-4',
|
|
117
|
-
anthropic: this.config.model || 'claude-3-5-sonnet-20241022',
|
|
118
|
-
ollama: this.config.model || 'llama3.2',
|
|
119
|
-
openrouter: this.config.model || 'anthropic/claude-3.5-sonnet',
|
|
120
|
-
gemini: this.config.model || 'gemini-2.0-flash',
|
|
121
|
-
minimax: this.config.model || 'MiniMax-M2.7',
|
|
122
|
-
local: this.config.model || 'llama3.2'
|
|
123
|
-
};
|
|
124
|
-
return modelMap[this.provider];
|
|
125
|
-
}
|
|
126
|
-
async callOpenAI(messages, temperature, maxTokens) {
|
|
127
|
-
const apiKey = this.getApiKey();
|
|
128
|
-
if (!apiKey) {
|
|
129
|
-
throw new Error('OPENAI_API_KEY not set');
|
|
130
|
-
}
|
|
131
|
-
const response = await fetch(`${this.getBaseUrl()}/chat/completions`, {
|
|
132
|
-
method: 'POST',
|
|
133
|
-
headers: {
|
|
134
|
-
'Content-Type': 'application/json',
|
|
135
|
-
'Authorization': `Bearer ${apiKey}`
|
|
136
|
-
},
|
|
137
|
-
body: JSON.stringify({
|
|
138
|
-
model: this.mapModel(),
|
|
139
|
-
messages,
|
|
140
|
-
temperature,
|
|
141
|
-
max_tokens: maxTokens
|
|
142
|
-
})
|
|
143
|
-
});
|
|
144
|
-
if (!response.ok) {
|
|
145
|
-
throw new Error(`OpenAI API error: ${response.status}`);
|
|
146
|
-
}
|
|
147
|
-
const data = await response.json();
|
|
148
|
-
return data.choices?.[0]?.message?.content || '';
|
|
149
|
-
}
|
|
150
|
-
async callAnthropic(messages, temperature, maxTokens) {
|
|
151
|
-
const apiKey = this.getApiKey();
|
|
152
|
-
if (!apiKey) {
|
|
153
|
-
throw new Error('ANTHROPIC_API_KEY not set');
|
|
154
|
-
}
|
|
155
|
-
const systemMessage = messages.find(m => m.role === 'system')?.content || '';
|
|
156
|
-
const userMessages = messages.filter(m => m.role !== 'system');
|
|
157
|
-
const response = await fetch(`${this.getBaseUrl()}/messages`, {
|
|
158
|
-
method: 'POST',
|
|
159
|
-
headers: {
|
|
160
|
-
'Content-Type': 'application/json',
|
|
161
|
-
'x-api-key': apiKey,
|
|
162
|
-
'anthropic-version': '2023-06-01',
|
|
163
|
-
'anthropic-dangerous-direct-browser-access': 'true'
|
|
164
|
-
},
|
|
165
|
-
body: JSON.stringify({
|
|
166
|
-
model: this.mapModel(),
|
|
167
|
-
messages: userMessages,
|
|
168
|
-
system: systemMessage,
|
|
169
|
-
temperature,
|
|
170
|
-
max_tokens: maxTokens
|
|
171
|
-
})
|
|
172
|
-
});
|
|
173
|
-
if (!response.ok) {
|
|
174
|
-
throw new Error(`Anthropic API error: ${response.status}`);
|
|
175
|
-
}
|
|
176
|
-
const data = await response.json();
|
|
177
|
-
return data.content?.[0]?.text || '';
|
|
178
|
-
}
|
|
179
|
-
async callOllama(messages, temperature) {
|
|
180
|
-
const response = await fetch(`${this.getBaseUrl()}/api/chat`, {
|
|
181
|
-
method: 'POST',
|
|
182
|
-
headers: {
|
|
183
|
-
'Content-Type': 'application/json'
|
|
184
|
-
},
|
|
185
|
-
body: JSON.stringify({
|
|
186
|
-
model: this.mapModel(),
|
|
187
|
-
messages,
|
|
188
|
-
temperature,
|
|
189
|
-
stream: false
|
|
190
|
-
})
|
|
191
|
-
});
|
|
192
|
-
if (!response.ok) {
|
|
193
|
-
throw new Error(`Ollama API error: ${response.status}`);
|
|
194
|
-
}
|
|
195
|
-
const data = await response.json();
|
|
196
|
-
return data.message?.content || '';
|
|
197
|
-
}
|
|
198
|
-
async callOpenRouter(messages, temperature, maxTokens) {
|
|
199
|
-
const apiKey = this.getApiKey();
|
|
200
|
-
if (!apiKey) {
|
|
201
|
-
throw new Error('OPENROUTER_API_KEY not set');
|
|
202
|
-
}
|
|
203
|
-
const response = await fetch(`${this.getBaseUrl()}/chat/completions`, {
|
|
204
|
-
method: 'POST',
|
|
205
|
-
headers: {
|
|
206
|
-
'Content-Type': 'application/json',
|
|
207
|
-
'Authorization': `Bearer ${apiKey}`,
|
|
208
|
-
'HTTP-Referer': 'https://openclaw.ai',
|
|
209
|
-
'X-Title': 'OpenClaw'
|
|
210
|
-
},
|
|
211
|
-
body: JSON.stringify({
|
|
212
|
-
model: this.mapModel(),
|
|
213
|
-
messages,
|
|
214
|
-
temperature,
|
|
215
|
-
max_tokens: maxTokens
|
|
216
|
-
})
|
|
217
|
-
});
|
|
218
|
-
if (!response.ok) {
|
|
219
|
-
throw new Error(`OpenRouter API error: ${response.status}`);
|
|
220
|
-
}
|
|
221
|
-
const data = await response.json();
|
|
222
|
-
return data.choices?.[0]?.message?.content || '';
|
|
223
|
-
}
|
|
224
|
-
async callGemini(messages, temperature, maxTokens) {
|
|
225
|
-
const apiKey = this.getApiKey();
|
|
226
|
-
if (!apiKey) {
|
|
227
|
-
throw new Error('GEMINI_API_KEY not set');
|
|
228
|
-
}
|
|
229
|
-
const contents = messages
|
|
230
|
-
.filter(m => m.role !== 'system')
|
|
231
|
-
.map(m => ({
|
|
232
|
-
role: m.role === 'assistant' ? 'model' : 'user',
|
|
233
|
-
parts: [{ text: m.content }]
|
|
234
|
-
}));
|
|
235
|
-
const systemInstruction = messages.find(m => m.role === 'system')?.content;
|
|
236
|
-
const response = await fetch(`${this.getBaseUrl()}/models/${this.mapModel()}:generateContent?key=${apiKey}`, {
|
|
237
|
-
method: 'POST',
|
|
238
|
-
headers: {
|
|
239
|
-
'Content-Type': 'application/json'
|
|
240
|
-
},
|
|
241
|
-
body: JSON.stringify({
|
|
242
|
-
contents,
|
|
243
|
-
systemInstruction: systemInstruction ? { parts: [{ text: systemInstruction }] } : undefined,
|
|
244
|
-
generationConfig: {
|
|
245
|
-
temperature,
|
|
246
|
-
maxOutputTokens: maxTokens
|
|
247
|
-
}
|
|
248
|
-
})
|
|
249
|
-
});
|
|
250
|
-
if (!response.ok) {
|
|
251
|
-
throw new Error(`Gemini API error: ${response.status}`);
|
|
252
|
-
}
|
|
253
|
-
const data = await response.json();
|
|
254
|
-
return data.candidates?.[0]?.content?.parts?.[0]?.text || '';
|
|
255
|
-
}
|
|
256
|
-
async callLocal(messages, temperature) {
|
|
257
|
-
return this.callOllama(messages, temperature);
|
|
258
|
-
}
|
|
259
|
-
buildSystemPrompt(context) {
|
|
260
|
-
const envDetails = this.getEnvironmentDetails();
|
|
261
|
-
return `You are a friendly AI assistant in a P2P document collaboration network.
|
|
262
|
-
|
|
263
|
-
## User Working Directory
|
|
264
|
-
${context || process.cwd()}
|
|
265
|
-
|
|
266
|
-
## Environment
|
|
267
|
-
${envDetails}`;
|
|
268
|
-
}
|
|
269
|
-
getEnvironmentDetails() {
|
|
270
|
-
return `
|
|
271
|
-
## Available Workflows
|
|
272
|
-
- read - Read documents
|
|
273
|
-
- summarize - Summarize documents
|
|
274
|
-
- improve - Improve documents
|
|
275
|
-
- collaborate - Multi-agent collaboration
|
|
276
|
-
- query - Query status
|
|
277
|
-
- report - Generate reports
|
|
278
|
-
|
|
279
|
-
## System Capabilities
|
|
280
|
-
- Document processing (Markdown, Text, PDF, DOCX)
|
|
281
|
-
- Multi-agent collaboration (P2P network)
|
|
282
|
-
- Workflow engine (constraint layer)
|
|
283
|
-
- Quality assessment and auto-send
|
|
284
|
-
|
|
285
|
-
## Current Time
|
|
286
|
-
${new Date().toISOString()}`;
|
|
287
|
-
}
|
|
288
|
-
buildSummarizePrompt(text, context) {
|
|
289
|
-
const maxLength = 8000;
|
|
290
|
-
const truncatedText = text.length > maxLength ? text.substring(0, maxLength) + '...' : text;
|
|
291
|
-
let prompt = `Please generate a concise and accurate summary for the following document:
|
|
292
|
-
|
|
293
|
-
${truncatedText}
|
|
294
|
-
|
|
295
|
-
Please output in the following format:
|
|
296
|
-
## Summary
|
|
297
|
-
[Write summary here]
|
|
298
|
-
|
|
299
|
-
## Quality Self-Assessment
|
|
300
|
-
[Score 1-10, with reasoning]`;
|
|
301
|
-
if (context) {
|
|
302
|
-
prompt = `Context: ${context}
|
|
303
|
-
|
|
304
|
-
${prompt}`;
|
|
305
|
-
}
|
|
306
|
-
return prompt;
|
|
307
|
-
}
|
|
308
|
-
buildImprovePrompt(content, requirements, context) {
|
|
309
|
-
const maxLength = 8000;
|
|
310
|
-
const truncatedContent = content.length > maxLength ? content.substring(0, maxLength) + '...' : content;
|
|
311
|
-
let prompt = `Please improve the document according to the following requirements:
|
|
312
|
-
|
|
313
|
-
Requirements: ${requirements}
|
|
314
|
-
|
|
315
|
-
Original Document:
|
|
316
|
-
${truncatedContent}
|
|
317
|
-
|
|
318
|
-
Please output only the improved document without additional explanation.`;
|
|
319
|
-
if (context) {
|
|
320
|
-
prompt = `Context: ${context}
|
|
321
|
-
|
|
322
|
-
${prompt}`;
|
|
323
|
-
}
|
|
324
|
-
return prompt;
|
|
325
|
-
}
|
|
326
|
-
estimateQuality(original, summary) {
|
|
327
|
-
const coverageRatio = summary.length / Math.max(original.length, 1);
|
|
328
|
-
const hasKeyPoints = /\d+\s*[.。]/.test(summary);
|
|
329
|
-
const decentLength = summary.length > 100 && summary.length < original.length * 0.5;
|
|
330
|
-
let score = 0.5;
|
|
331
|
-
if (coverageRatio > 0.1 && coverageRatio < 0.5)
|
|
332
|
-
score += 0.2;
|
|
333
|
-
if (hasKeyPoints)
|
|
334
|
-
score += 0.15;
|
|
335
|
-
if (decentLength)
|
|
336
|
-
score += 0.15;
|
|
337
|
-
return Math.min(1, score);
|
|
338
|
-
}
|
|
339
|
-
async shouldAutoSend(qualityScore, threshold = 0.7) {
|
|
340
|
-
return qualityScore >= threshold;
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
let modelInstance = null;
|
|
344
|
-
function detectProvider() {
|
|
345
|
-
if (process.env.OPENAI_API_KEY)
|
|
346
|
-
return 'openai';
|
|
347
|
-
if (process.env.ANTHROPIC_API_KEY)
|
|
348
|
-
return 'anthropic';
|
|
349
|
-
if (process.env.OPENROUTER_API_KEY)
|
|
350
|
-
return 'openrouter';
|
|
351
|
-
if (process.env.GEMINI_API_KEY)
|
|
352
|
-
return 'gemini';
|
|
353
|
-
if (process.env.OLLAMA_BASE_URL)
|
|
354
|
-
return 'ollama';
|
|
355
|
-
if (process.env.MINIMAX_API_KEY)
|
|
356
|
-
return 'minimax';
|
|
357
|
-
return 'openai';
|
|
358
|
-
}
|
|
359
|
-
function detectModel(provider) {
|
|
360
|
-
const defaults = {
|
|
361
|
-
openai: 'gpt-4',
|
|
362
|
-
anthropic: 'claude-3-5-sonnet-20241022',
|
|
363
|
-
ollama: 'llama3.2',
|
|
364
|
-
openrouter: 'anthropic/claude-3.5-sonnet',
|
|
365
|
-
gemini: 'gemini-2.0-flash',
|
|
366
|
-
minimax: 'MiniMax-M2.7',
|
|
367
|
-
local: 'llama3.2'
|
|
368
|
-
};
|
|
369
|
-
return defaults[provider];
|
|
370
|
-
}
|
|
371
|
-
export function initPiAI(config = {}) {
|
|
372
|
-
const provider = config.provider || detectProvider();
|
|
373
|
-
const model = config.model || detectModel(provider);
|
|
374
|
-
modelInstance = new PiAIModel({
|
|
375
|
-
provider,
|
|
376
|
-
apiKey: config.apiKey,
|
|
377
|
-
baseUrl: config.baseUrl,
|
|
378
|
-
model
|
|
379
|
-
});
|
|
380
|
-
return modelInstance;
|
|
381
|
-
}
|
|
382
|
-
export function getModel() {
|
|
383
|
-
if (!modelInstance) {
|
|
384
|
-
throw new Error('PiAI not initialized. Call initPiAI first.');
|
|
385
|
-
}
|
|
386
|
-
return modelInstance;
|
|
387
|
-
}
|
|
388
|
-
export function isModelAvailable() {
|
|
389
|
-
return modelInstance !== null;
|
|
390
|
-
}
|
|
391
|
-
export function getMinimax() {
|
|
392
|
-
return getModel();
|
|
393
|
-
}
|
|
394
|
-
export function initMinimax(config = {}) {
|
|
395
|
-
return initPiAI(config);
|
|
396
|
-
}
|
|
397
|
-
export { PiAIModel as MinimaxLLM };
|