@bolloon/bolloon-agent 0.1.12 → 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.
- package/dist/agents/p2p-chat-tools.js +321 -0
- package/dist/agents/p2p-document-tools.js +121 -1
- package/dist/agents/pi-sdk.js +185 -0
- package/dist/agents/shell-guard.js +354 -0
- package/dist/agents/shell-tool.js +83 -0
- package/dist/agents/skill-loader.js +174 -0
- package/dist/agents/workflow-pivot-loop.js +4 -4
- package/dist/bollharness-integration/context-chain-router.js +3 -3
- package/dist/bollharness-integration/context-router.js +1 -1
- package/dist/cli-entry.js +1 -1
- package/dist/documents/reader.js +5 -0
- package/dist/documents/store.js +1 -1
- package/dist/heartbeat/Watchdog.js +7 -5
- package/dist/heartbeat/index.js +1 -0
- package/dist/heartbeat/self-improve-bus.js +85 -0
- package/dist/llm/pi-ai.js +6 -5
- package/dist/network/iroh-discovery.js +2 -1
- package/dist/network/iroh-transport.js +15 -2
- package/dist/network/p2p.js +9 -8
- package/dist/network/storage/adapters/json-adapter.js +16 -1
- package/dist/network/storage/index.js +2 -1
- package/dist/pi-ecosystem-judgment/index.js +42 -115
- package/dist/social/channels/channel-heartbeat-agent.js +1 -1
- package/dist/utils/auto-update.js +44 -12
- package/dist/web/client.js +839 -103
- package/dist/web/index.html +100 -8
- package/dist/web/server.js +568 -98
- package/dist/web/style.css +506 -9
- package/package.json +2 -2
- package/scripts/build-cli.js +11 -1
- package/scripts/build-web.ts +1 -1
- package/src/agents/p2p-chat-tools.ts +383 -0
- package/src/agents/p2p-document-tools.ts +151 -1
- package/src/agents/pi-sdk.ts +196 -0
- package/src/agents/shell-guard.ts +417 -0
- package/src/agents/shell-tool.ts +103 -0
- package/src/agents/skill-loader.ts +202 -0
- package/src/agents/workflow-pivot-loop.ts +13 -12
- package/src/bollharness-integration/channel-judgment-engine.ts +1 -1
- package/src/bollharness-integration/context-chain-router.ts +3 -3
- package/src/bollharness-integration/context-router.ts +1 -1
- package/src/documents/reader.ts +5 -0
- package/src/documents/store.ts +1 -1
- package/src/heartbeat/Watchdog.ts +7 -5
- package/src/heartbeat/index.ts +1 -0
- package/src/heartbeat/self-improve-bus.ts +110 -0
- package/src/llm/pi-ai.ts +6 -5
- package/src/network/iroh-discovery.ts +2 -1
- package/src/network/iroh-transport.ts +15 -2
- package/src/network/p2p.ts +9 -8
- package/src/network/storage/adapters/json-adapter.ts +17 -2
- package/src/network/storage/index.ts +19 -3
- package/src/social/channels/channel-heartbeat-agent.ts +1 -1
- package/src/types.d.ts +12 -0
- package/src/utils/auto-update.ts +45 -14
- package/src/web/client.js +839 -103
- package/src/web/index.html +88 -8
- package/src/web/server.ts +577 -102
- package/src/web/style.css +506 -9
- package/tsconfig.electron.json +1 -1
- package/tsconfig.json +1 -1
- package/dist/bollharness-integration/bollharness-integration/context-router-judgment.d.ts +0 -48
- package/dist/bollharness-integration/bollharness-integration/context-router-judgment.js +0 -261
- package/dist/bollharness-integration/bollharness-integration/context-router.d.ts +0 -110
- package/dist/bollharness-integration/bollharness-integration/context-router.js +0 -542
- package/dist/bollharness-integration/bollharness-integration/gate-state-machine.d.ts +0 -87
- package/dist/bollharness-integration/bollharness-integration/gate-state-machine.js +0 -231
- package/dist/bollharness-integration/bollharness-integration/gate-transition-hooks.d.ts +0 -30
- package/dist/bollharness-integration/bollharness-integration/gate-transition-hooks.js +0 -91
- package/dist/bollharness-integration/bollharness-integration/guard-checker.d.ts +0 -105
- package/dist/bollharness-integration/bollharness-integration/guard-checker.js +0 -353
- package/dist/bollharness-integration/bollharness-integration/index.d.ts +0 -66
- package/dist/bollharness-integration/bollharness-integration/index.js +0 -32
- package/dist/bollharness-integration/bollharness-integration/integration.d.ts +0 -219
- package/dist/bollharness-integration/bollharness-integration/integration.js +0 -420
- package/dist/bollharness-integration/bollharness-integration/skill-adapter.d.ts +0 -151
- package/dist/bollharness-integration/bollharness-integration/skill-adapter.js +0 -518
|
@@ -16,12 +16,13 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import * as fs from 'fs/promises';
|
|
18
18
|
import * as path from 'path';
|
|
19
|
+
import yaml from 'js-yaml';
|
|
19
20
|
const JUDGMENTS_DIR = path.join(process.env.HOME || '/tmp', '.bolloon', 'judgments');
|
|
20
21
|
const JUDGMENT_FILES = {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
rule: path.join(JUDGMENTS_DIR, 'rules.yaml'),
|
|
23
|
+
preference: path.join(JUDGMENTS_DIR, 'preferences.yaml'),
|
|
24
|
+
trajectory: path.join(JUDGMENTS_DIR, 'trajectories.yaml'),
|
|
25
|
+
reward: path.join(JUDGMENTS_DIR, 'rewards.yaml'),
|
|
25
26
|
};
|
|
26
27
|
let judgmentCache = new Map();
|
|
27
28
|
let valueFunctionCache = null;
|
|
@@ -99,8 +100,9 @@ async function saveJudgments(type, judgments) {
|
|
|
99
100
|
const filePath = JUDGMENT_FILES[type];
|
|
100
101
|
if (!filePath)
|
|
101
102
|
return;
|
|
102
|
-
const
|
|
103
|
-
|
|
103
|
+
const body = yaml.dump({ judgments });
|
|
104
|
+
const header = '# Auto-generated by Pi Judgment System\n# Do not edit manually\n\n';
|
|
105
|
+
await fs.writeFile(filePath, header + body, 'utf-8');
|
|
104
106
|
cacheDirty = true;
|
|
105
107
|
}
|
|
106
108
|
/**
|
|
@@ -323,122 +325,37 @@ function parseYaml(content) {
|
|
|
323
325
|
try {
|
|
324
326
|
if (!content.trim())
|
|
325
327
|
return [];
|
|
326
|
-
|
|
327
|
-
const lines = content.split('\n');
|
|
328
|
-
const arrayItems = [];
|
|
329
|
-
let inArray = false;
|
|
330
|
-
let currentItem = null;
|
|
331
|
-
let currentItemIndent = 0;
|
|
332
|
-
for (const line of lines) {
|
|
333
|
-
const trimmed = line.trim();
|
|
334
|
-
const indent = line.search(/\S/);
|
|
335
|
-
const isArrayItem = trimmed.startsWith('-');
|
|
336
|
-
const isComment = trimmed.startsWith('#');
|
|
337
|
-
if (isComment)
|
|
338
|
-
continue;
|
|
339
|
-
if (trimmed.startsWith('judgments:')) {
|
|
340
|
-
inArray = true;
|
|
341
|
-
continue;
|
|
342
|
-
}
|
|
343
|
-
if (!inArray)
|
|
344
|
-
continue;
|
|
345
|
-
if (isArrayItem) {
|
|
346
|
-
if (currentItem) {
|
|
347
|
-
arrayItems.push(currentItem);
|
|
348
|
-
}
|
|
349
|
-
currentItem = {};
|
|
350
|
-
currentItemIndent = indent + 1;
|
|
351
|
-
const itemContent = trimmed.substring(1).trim();
|
|
352
|
-
const kvMatch = itemContent.match(/^(\w+):\s*(.*)/);
|
|
353
|
-
if (kvMatch) {
|
|
354
|
-
currentItem[kvMatch[1]] = parseValue(kvMatch[2]);
|
|
355
|
-
}
|
|
356
|
-
continue;
|
|
357
|
-
}
|
|
358
|
-
if (currentItem && indent > currentItemIndent) {
|
|
359
|
-
const kvMatch = trimmed.match(/^(\w+):\s*(.*)/);
|
|
360
|
-
if (kvMatch) {
|
|
361
|
-
currentItem[kvMatch[1]] = parseValue(kvMatch[2]);
|
|
362
|
-
}
|
|
363
|
-
continue;
|
|
364
|
-
}
|
|
365
|
-
if (trimmed.includes(':')) {
|
|
366
|
-
const kvMatch = trimmed.match(/^(\w+):\s*(.*)/);
|
|
367
|
-
if (kvMatch && !isArrayItem) {
|
|
368
|
-
data[kvMatch[1]] = parseValue(kvMatch[2]);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
if (currentItem) {
|
|
373
|
-
arrayItems.push(currentItem);
|
|
374
|
-
}
|
|
375
|
-
if (arrayItems.length > 0) {
|
|
376
|
-
data['judgments'] = arrayItems;
|
|
377
|
-
}
|
|
378
|
-
return data;
|
|
328
|
+
return yaml.load(content) ?? [];
|
|
379
329
|
}
|
|
380
330
|
catch {
|
|
381
331
|
return [];
|
|
382
332
|
}
|
|
383
333
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
334
|
+
/**
|
|
335
|
+
* (YAML serialization now delegated to js-yaml)
|
|
336
|
+
*/
|
|
337
|
+
/**
|
|
338
|
+
* Best-effort coercion for a scalar frontmatter value.
|
|
339
|
+
* Returns booleans, numbers, or the raw string.
|
|
340
|
+
*/
|
|
341
|
+
function parseFrontmatterValue(raw) {
|
|
342
|
+
const value = raw.trim();
|
|
343
|
+
if (value === '')
|
|
344
|
+
return '';
|
|
345
|
+
if (value === 'true')
|
|
387
346
|
return true;
|
|
388
|
-
if (
|
|
347
|
+
if (value === 'false')
|
|
389
348
|
return false;
|
|
390
|
-
if (
|
|
349
|
+
if (value === 'null' || value === '~')
|
|
391
350
|
return null;
|
|
392
|
-
if (
|
|
393
|
-
return Number(
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
*/
|
|
399
|
-
function serializeYaml(data) {
|
|
400
|
-
const lines = ['# Auto-generated by Pi Judgment System', '# Do not edit manually', ''];
|
|
401
|
-
if (typeof data === 'object' && data !== null) {
|
|
402
|
-
lines.push('judgments:');
|
|
403
|
-
const d = data;
|
|
404
|
-
const arr = d.judgments;
|
|
405
|
-
if (Array.isArray(arr)) {
|
|
406
|
-
for (const item of arr) {
|
|
407
|
-
lines.push(' - ' + serializeObject(item, 4));
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
return lines.join('\n');
|
|
412
|
-
}
|
|
413
|
-
function serializeObject(obj, indent) {
|
|
414
|
-
if (typeof obj !== 'object' || obj === null) {
|
|
415
|
-
return String(obj);
|
|
416
|
-
}
|
|
417
|
-
const spaces = ' '.repeat(indent);
|
|
418
|
-
const innerSpace = ' '.repeat(indent + 2);
|
|
419
|
-
const parts = [];
|
|
420
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
421
|
-
if (value === undefined || value === null)
|
|
422
|
-
continue;
|
|
423
|
-
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
424
|
-
parts.push(`${key}:`);
|
|
425
|
-
parts.push(serializeObject(value, indent + 2));
|
|
426
|
-
}
|
|
427
|
-
else if (Array.isArray(value)) {
|
|
428
|
-
parts.push(`${key}:`);
|
|
429
|
-
for (const item of value) {
|
|
430
|
-
parts.push(`${innerSpace}- ${serializeObject(item, indent + 4)}`);
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
else {
|
|
434
|
-
const strValue = typeof value === 'string' ? `"${value}"` : String(value);
|
|
435
|
-
parts.push(`${key}: ${strValue}`);
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
if (parts.length === 1 && !parts[0].includes(':')) {
|
|
439
|
-
return parts[0];
|
|
351
|
+
if (/^-?\d+(\.\d+)?$/.test(value))
|
|
352
|
+
return Number(value);
|
|
353
|
+
// Strip surrounding quotes if present
|
|
354
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
355
|
+
(value.startsWith("'") && value.endsWith("'"))) {
|
|
356
|
+
return value.slice(1, -1);
|
|
440
357
|
}
|
|
441
|
-
return
|
|
358
|
+
return value;
|
|
442
359
|
}
|
|
443
360
|
/**
|
|
444
361
|
* Extract YAML frontmatter from markdown
|
|
@@ -447,6 +364,16 @@ function extractFrontmatter(content) {
|
|
|
447
364
|
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
448
365
|
if (!match)
|
|
449
366
|
return {};
|
|
367
|
+
// Try js-yaml first; fall back to simple line parser if it fails or types missing.
|
|
368
|
+
try {
|
|
369
|
+
const parsed = yaml.load(match[1]);
|
|
370
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
371
|
+
return parsed;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
catch {
|
|
375
|
+
// fall through to manual parsing
|
|
376
|
+
}
|
|
450
377
|
const frontmatter = {};
|
|
451
378
|
const lines = match[1].split('\n');
|
|
452
379
|
let currentKey = '';
|
|
@@ -465,10 +392,10 @@ function extractFrontmatter(content) {
|
|
|
465
392
|
const [key, ...valueParts] = trimmed.split(':');
|
|
466
393
|
const value = valueParts.join(':').trim();
|
|
467
394
|
if (currentKey === 'judgment' && indent > 0) {
|
|
468
|
-
frontmatter[currentKey][key] =
|
|
395
|
+
frontmatter[currentKey][key] = parseFrontmatterValue(value);
|
|
469
396
|
}
|
|
470
397
|
else {
|
|
471
|
-
frontmatter[key.trim()] =
|
|
398
|
+
frontmatter[key.trim()] = parseFrontmatterValue(value);
|
|
472
399
|
currentKey = key.trim();
|
|
473
400
|
}
|
|
474
401
|
}
|
|
@@ -306,7 +306,7 @@ export class ChannelHeartbeatAgent {
|
|
|
306
306
|
currentMessage: message,
|
|
307
307
|
senderName: peer.name
|
|
308
308
|
};
|
|
309
|
-
const decision = this.judgmentEngine.decide(context);
|
|
309
|
+
const decision = await this.judgmentEngine.decide(context);
|
|
310
310
|
if (decision.shouldCall) {
|
|
311
311
|
console.log(`[HeartbeatAgent] Auto-triggering Harness: Gate ${decision.gate} for ${peer.name}`);
|
|
312
312
|
// 这里可以发送消息触发对方响应
|
|
@@ -241,24 +241,25 @@ function checkNpmOutdated() {
|
|
|
241
241
|
* 自动更新 npm 包
|
|
242
242
|
*/
|
|
243
243
|
async function updatePackages(packages) {
|
|
244
|
+
// 记录更新前的版本,用于事后判断"是否真的升级了"
|
|
245
|
+
// 与 getInstalledVersion 的"优先读全局"保持一致 —— install 也用 -g,
|
|
246
|
+
// 否则判断和执行落在不同的目录,永远改不到那个被读取的版本号。
|
|
247
|
+
const targets = packages && packages.length > 0 ? packages : ['@bolloon/bolloon-agent'];
|
|
248
|
+
const before = new Map();
|
|
249
|
+
for (const p of targets)
|
|
250
|
+
before.set(p, getInstalledVersion(p));
|
|
251
|
+
const isGlobal = !packages || packages.length === 0;
|
|
252
|
+
const args = isGlobal
|
|
253
|
+
? ['npm', 'install', '-g', ...targets]
|
|
254
|
+
: ['npm', 'install', ...targets, '--save'];
|
|
255
|
+
log(`\n${CYAN}📦 正在更新包...${RESET}\n`, RESET);
|
|
244
256
|
try {
|
|
245
|
-
|
|
246
|
-
? ['npm', 'install', ...packages, '--save']
|
|
247
|
-
: ['npm', 'install', '-g', '@bolloon/bolloon-agent'];
|
|
248
|
-
log(`\n${CYAN}📦 正在更新包...${RESET}\n`, RESET);
|
|
249
|
-
// 执行 npm install
|
|
250
|
-
const result = execSync(args.join(' '), {
|
|
257
|
+
execSync(args.join(' '), {
|
|
251
258
|
encoding: 'utf-8',
|
|
252
259
|
timeout: 300000, // 5分钟超时
|
|
253
260
|
stdio: 'inherit',
|
|
254
261
|
cwd: process.cwd()
|
|
255
262
|
});
|
|
256
|
-
return {
|
|
257
|
-
success: true,
|
|
258
|
-
updated: true,
|
|
259
|
-
message: '更新成功',
|
|
260
|
-
updatedPackages: packages
|
|
261
|
-
};
|
|
262
263
|
}
|
|
263
264
|
catch (e) {
|
|
264
265
|
return {
|
|
@@ -268,6 +269,37 @@ async function updatePackages(packages) {
|
|
|
268
269
|
error: e.message
|
|
269
270
|
};
|
|
270
271
|
}
|
|
272
|
+
// install 退出码 0 并不等于"真的升上去了"("up to date" 也是 0)。
|
|
273
|
+
// 重新读取磁盘版本,只有真的达到目标 latest 之一才算 updated。
|
|
274
|
+
const upgraded = [];
|
|
275
|
+
const failed = [];
|
|
276
|
+
for (const p of targets) {
|
|
277
|
+
const after = getInstalledVersion(p);
|
|
278
|
+
const was = before.get(p);
|
|
279
|
+
if (after && was && compareVersions(was, after) < 0) {
|
|
280
|
+
upgraded.push(p);
|
|
281
|
+
}
|
|
282
|
+
else if (after && was && compareVersions(was, after) === 0) {
|
|
283
|
+
// 版本没变 —— install 跑过但没改动;不当作"刚升级"
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
failed.push(p);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
if (upgraded.length > 0) {
|
|
290
|
+
return {
|
|
291
|
+
success: true,
|
|
292
|
+
updated: true,
|
|
293
|
+
message: `已更新: ${upgraded.join(', ')}`,
|
|
294
|
+
updatedPackages: upgraded
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
return {
|
|
298
|
+
success: true,
|
|
299
|
+
updated: false,
|
|
300
|
+
message: '已是最新版本,无需重启',
|
|
301
|
+
updatedPackages: []
|
|
302
|
+
};
|
|
271
303
|
}
|
|
272
304
|
/**
|
|
273
305
|
* 检查并自动更新(启动时调用)
|