@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.
Files changed (77) hide show
  1. package/dist/agents/p2p-chat-tools.js +321 -0
  2. package/dist/agents/p2p-document-tools.js +121 -1
  3. package/dist/agents/pi-sdk.js +185 -0
  4. package/dist/agents/shell-guard.js +354 -0
  5. package/dist/agents/shell-tool.js +83 -0
  6. package/dist/agents/skill-loader.js +174 -0
  7. package/dist/agents/workflow-pivot-loop.js +4 -4
  8. package/dist/bollharness-integration/context-chain-router.js +3 -3
  9. package/dist/bollharness-integration/context-router.js +1 -1
  10. package/dist/cli-entry.js +1 -1
  11. package/dist/documents/reader.js +5 -0
  12. package/dist/documents/store.js +1 -1
  13. package/dist/heartbeat/Watchdog.js +7 -5
  14. package/dist/heartbeat/index.js +1 -0
  15. package/dist/heartbeat/self-improve-bus.js +85 -0
  16. package/dist/llm/pi-ai.js +6 -5
  17. package/dist/network/iroh-discovery.js +2 -1
  18. package/dist/network/iroh-transport.js +15 -2
  19. package/dist/network/p2p.js +9 -8
  20. package/dist/network/storage/adapters/json-adapter.js +16 -1
  21. package/dist/network/storage/index.js +2 -1
  22. package/dist/pi-ecosystem-judgment/index.js +42 -115
  23. package/dist/social/channels/channel-heartbeat-agent.js +1 -1
  24. package/dist/utils/auto-update.js +44 -12
  25. package/dist/web/client.js +839 -103
  26. package/dist/web/index.html +100 -8
  27. package/dist/web/server.js +568 -98
  28. package/dist/web/style.css +506 -9
  29. package/package.json +2 -2
  30. package/scripts/build-cli.js +11 -1
  31. package/scripts/build-web.ts +1 -1
  32. package/src/agents/p2p-chat-tools.ts +383 -0
  33. package/src/agents/p2p-document-tools.ts +151 -1
  34. package/src/agents/pi-sdk.ts +196 -0
  35. package/src/agents/shell-guard.ts +417 -0
  36. package/src/agents/shell-tool.ts +103 -0
  37. package/src/agents/skill-loader.ts +202 -0
  38. package/src/agents/workflow-pivot-loop.ts +13 -12
  39. package/src/bollharness-integration/channel-judgment-engine.ts +1 -1
  40. package/src/bollharness-integration/context-chain-router.ts +3 -3
  41. package/src/bollharness-integration/context-router.ts +1 -1
  42. package/src/documents/reader.ts +5 -0
  43. package/src/documents/store.ts +1 -1
  44. package/src/heartbeat/Watchdog.ts +7 -5
  45. package/src/heartbeat/index.ts +1 -0
  46. package/src/heartbeat/self-improve-bus.ts +110 -0
  47. package/src/llm/pi-ai.ts +6 -5
  48. package/src/network/iroh-discovery.ts +2 -1
  49. package/src/network/iroh-transport.ts +15 -2
  50. package/src/network/p2p.ts +9 -8
  51. package/src/network/storage/adapters/json-adapter.ts +17 -2
  52. package/src/network/storage/index.ts +19 -3
  53. package/src/social/channels/channel-heartbeat-agent.ts +1 -1
  54. package/src/types.d.ts +12 -0
  55. package/src/utils/auto-update.ts +45 -14
  56. package/src/web/client.js +839 -103
  57. package/src/web/index.html +88 -8
  58. package/src/web/server.ts +577 -102
  59. package/src/web/style.css +506 -9
  60. package/tsconfig.electron.json +1 -1
  61. package/tsconfig.json +1 -1
  62. package/dist/bollharness-integration/bollharness-integration/context-router-judgment.d.ts +0 -48
  63. package/dist/bollharness-integration/bollharness-integration/context-router-judgment.js +0 -261
  64. package/dist/bollharness-integration/bollharness-integration/context-router.d.ts +0 -110
  65. package/dist/bollharness-integration/bollharness-integration/context-router.js +0 -542
  66. package/dist/bollharness-integration/bollharness-integration/gate-state-machine.d.ts +0 -87
  67. package/dist/bollharness-integration/bollharness-integration/gate-state-machine.js +0 -231
  68. package/dist/bollharness-integration/bollharness-integration/gate-transition-hooks.d.ts +0 -30
  69. package/dist/bollharness-integration/bollharness-integration/gate-transition-hooks.js +0 -91
  70. package/dist/bollharness-integration/bollharness-integration/guard-checker.d.ts +0 -105
  71. package/dist/bollharness-integration/bollharness-integration/guard-checker.js +0 -353
  72. package/dist/bollharness-integration/bollharness-integration/index.d.ts +0 -66
  73. package/dist/bollharness-integration/bollharness-integration/index.js +0 -32
  74. package/dist/bollharness-integration/bollharness-integration/integration.d.ts +0 -219
  75. package/dist/bollharness-integration/bollharness-integration/integration.js +0 -420
  76. package/dist/bollharness-integration/bollharness-integration/skill-adapter.d.ts +0 -151
  77. 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
- rules: path.join(JUDGMENTS_DIR, 'rules.yaml'),
22
- preferences: path.join(JUDGMENTS_DIR, 'preferences.yaml'),
23
- trajectories: path.join(JUDGMENTS_DIR, 'trajectories.yaml'),
24
- rewards: path.join(JUDGMENTS_DIR, 'rewards.yaml'),
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 yaml = serializeYaml({ judgments });
103
- await fs.writeFile(filePath, yaml, 'utf-8');
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
- const data = {};
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
- function parseValue(value) {
385
- const trimmed = value.trim();
386
- if (trimmed === 'true')
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 (trimmed === 'false')
347
+ if (value === 'false')
389
348
  return false;
390
- if (trimmed === 'null' || trimmed === 'undefined')
349
+ if (value === 'null' || value === '~')
391
350
  return null;
392
- if (!isNaN(Number(trimmed)) && trimmed !== '')
393
- return Number(trimmed);
394
- return trimmed;
395
- }
396
- /**
397
- * Simple YAML serializer
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 parts.join(`\n${spaces}`);
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] = parseValue(value);
395
+ frontmatter[currentKey][key] = parseFrontmatterValue(value);
469
396
  }
470
397
  else {
471
- frontmatter[key.trim()] = parseValue(value);
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
- const args = packages && packages.length > 0
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
  * 检查并自动更新(启动时调用)