@bolloon/bolloon-agent 0.1.37 → 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/package.json +1 -1
- package/scripts/auto-evolve-oneshot.sh +155 -0
- package/scripts/auto-evolve-snapshot.sh +136 -0
- package/scripts/build-cli.js +216 -0
- package/scripts/detect-schema-changes.sh +48 -0
- package/scripts/postinstall.js +153 -0
- 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
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Postinstall 脚本
|
|
3
|
+
* npm 安装后自动执行
|
|
4
|
+
*
|
|
5
|
+
* 主要任务:
|
|
6
|
+
* 1. 确保 bin 目录存在且可执行
|
|
7
|
+
* 2. 初始化本地配置
|
|
8
|
+
* 3. 检查依赖完整性
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import * as fs from 'fs';
|
|
12
|
+
import * as path from 'path';
|
|
13
|
+
import { fileURLToPath } from 'url';
|
|
14
|
+
|
|
15
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
16
|
+
const __dirname = path.dirname(__filename);
|
|
17
|
+
const rootDir = path.join(__dirname, '..');
|
|
18
|
+
|
|
19
|
+
const RESET = '\x1b[0m';
|
|
20
|
+
const GREEN = '\x1b[32m';
|
|
21
|
+
const YELLOW = '\x1b[33m';
|
|
22
|
+
const CYAN = '\x1b[36m';
|
|
23
|
+
|
|
24
|
+
function log(msg, color = RESET) {
|
|
25
|
+
console.log(color + msg + RESET);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function initUserDirs() {
|
|
29
|
+
// 创建用户数据目录
|
|
30
|
+
const home = process.env.HOME || process.env.USERPROFILE || '/tmp';
|
|
31
|
+
const bolloonDir = path.join(home, '.bolloon');
|
|
32
|
+
|
|
33
|
+
const dirs = [
|
|
34
|
+
bolloonDir,
|
|
35
|
+
path.join(bolloonDir, 'sessions'),
|
|
36
|
+
path.join(bolloonDir, 'peer-store'),
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
for (const dir of dirs) {
|
|
40
|
+
if (!fs.existsSync(dir)) {
|
|
41
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
42
|
+
log(` ✓ 创建目录: ${dir}`, GREEN);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 初始化配置文件
|
|
47
|
+
const configPath = path.join(bolloonDir, 'config.json');
|
|
48
|
+
if (!fs.existsSync(configPath)) {
|
|
49
|
+
const defaultConfig = {
|
|
50
|
+
version: '0.1.12',
|
|
51
|
+
initializedAt: new Date().toISOString(),
|
|
52
|
+
defaults: {
|
|
53
|
+
port: 54188,
|
|
54
|
+
theme: 'dark',
|
|
55
|
+
autoConnect: true,
|
|
56
|
+
},
|
|
57
|
+
providers: {
|
|
58
|
+
minimax: { enabled: false },
|
|
59
|
+
openai: { enabled: false },
|
|
60
|
+
anthropic: { enabled: false },
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
fs.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2));
|
|
64
|
+
log(` ✓ 创建配置: ${configPath}`, GREEN);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return bolloonDir;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function checkNativeDeps() {
|
|
71
|
+
// 检查必要的原生依赖
|
|
72
|
+
const nativeDeps = [
|
|
73
|
+
'libp2p',
|
|
74
|
+
'@diap/sdk',
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
let allOk = true;
|
|
78
|
+
|
|
79
|
+
for (const dep of nativeDeps) {
|
|
80
|
+
const depPath = path.join(rootDir, 'node_modules', dep);
|
|
81
|
+
if (!fs.existsSync(depPath)) {
|
|
82
|
+
log(` ⚠ 缺少依赖: ${dep}`, YELLOW);
|
|
83
|
+
allOk = false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return allOk;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function setupPlatform() {
|
|
91
|
+
const platform = process.platform;
|
|
92
|
+
|
|
93
|
+
log(`\n 平台: ${platform}`, CYAN);
|
|
94
|
+
|
|
95
|
+
if (platform === 'win32') {
|
|
96
|
+
// Windows: 确保 .cmd 文件存在
|
|
97
|
+
const binDir = path.join(rootDir, 'bin');
|
|
98
|
+
const cmdPath = path.join(binDir, 'bolloon.cmd');
|
|
99
|
+
|
|
100
|
+
if (fs.existsSync(binDir) && !fs.existsSync(cmdPath)) {
|
|
101
|
+
const cmdContent = `@echo off
|
|
102
|
+
node "%~dp0..\\dist\\cli.js" %*
|
|
103
|
+
`;
|
|
104
|
+
fs.writeFileSync(cmdPath, cmdContent);
|
|
105
|
+
log(' ✓ Windows 入口已创建', GREEN);
|
|
106
|
+
}
|
|
107
|
+
} else {
|
|
108
|
+
// Unix/Linux/Mac: 确保 bin 文件可执行
|
|
109
|
+
const binDir = path.join(rootDir, 'bin');
|
|
110
|
+
const binPath = path.join(binDir, 'bolloon.js');
|
|
111
|
+
|
|
112
|
+
if (fs.existsSync(binPath)) {
|
|
113
|
+
try {
|
|
114
|
+
fs.chmodSync(binPath, 0o755);
|
|
115
|
+
log(' ✓ bin/bolloon.js 已设为可执行', GREEN);
|
|
116
|
+
} catch (err) {
|
|
117
|
+
log(` ⚠ 无法设置执行权限: ${err.message}`, YELLOW);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function main() {
|
|
124
|
+
console.log('\n📦 Bolloon 安装后处理...\n');
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
// 1. 初始化用户目录
|
|
128
|
+
const bolloonDir = initUserDirs();
|
|
129
|
+
log(` ✓ 用户数据目录: ${bolloonDir}`, GREEN);
|
|
130
|
+
|
|
131
|
+
// 2. 检查依赖
|
|
132
|
+
const depsOk = checkNativeDeps();
|
|
133
|
+
if (!depsOk) {
|
|
134
|
+
log('\n ⚠ 部分依赖缺失,建议运行: npm install', YELLOW);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// 3. 平台特定设置
|
|
138
|
+
setupPlatform();
|
|
139
|
+
|
|
140
|
+
console.log('\n✅ 安装完成!\n');
|
|
141
|
+
console.log(' 使用方式:');
|
|
142
|
+
console.log(' bolloon # 启动 GUI');
|
|
143
|
+
console.log(' bolloon --web # 启动 Web UI');
|
|
144
|
+
console.log(' bolloon --cli # 命令行模式');
|
|
145
|
+
console.log(' bolloon --help # 显示帮助\n');
|
|
146
|
+
console.log(` 配置文件: ${path.join(bolloonDir, 'config.json')}\n`);
|
|
147
|
+
} catch (err) {
|
|
148
|
+
console.error('\n❌ 安装后处理失败:', err.message);
|
|
149
|
+
console.error(' 这通常不影响基本功能,继续安装...\n');
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
main();
|
|
@@ -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 };
|