@bolloon/bolloon-agent 0.4.27 → 0.4.28

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.
@@ -35,7 +35,18 @@ const CAPABILITY_WORDS = ['schema_valid', 'source_declared', 'content_hash_bound
35
35
  */
36
36
  export function parseResourceContract(frontmatter, opts = {}) {
37
37
  const fm = frontmatter || {};
38
- const raw = fm.resource && typeof fm.resource === 'object' ? fm.resource : fm;
38
+ // 手写 SKILL.md `resource: {…}` 常被最小 YAML 解析器当成**字符串**留下 这里两种都吃。
39
+ // (真跑抓到过: 夹具技能因此被判"没有资源契约字段", 顾问直接看不到任何可执行资源。)
40
+ let resObj = fm.resource;
41
+ if (typeof resObj === 'string') {
42
+ try {
43
+ resObj = JSON.parse(resObj);
44
+ }
45
+ catch {
46
+ resObj = undefined;
47
+ }
48
+ }
49
+ const raw = resObj && typeof resObj === 'object' ? resObj : fm;
39
50
  const issues = [];
40
51
  const name = String(raw?.name || opts.skillName || fm.name || '').trim();
41
52
  const version = String(raw?.version || opts.skillVersion || fm.version || '').trim();
package/dist/cli-entry.js CHANGED
@@ -161,6 +161,9 @@ function parseArgs() {
161
161
  return { mode: 'trace', args: args.slice(1) };
162
162
  case 'p2p':
163
163
  return { mode: 'p2p', args: args.slice(1) };
164
+ // 2026-09-18: M1 唯一入口 —— 一个任务 → 一个 Skill → 一个报告卡
165
+ case 'task':
166
+ return { mode: 'task', args: args.slice(1) };
164
167
  // 2026-09-13: 初始化向导 (用户身份 + 模型供应商 + API key)
165
168
  case 'setup':
166
169
  case 'init':
@@ -332,6 +335,93 @@ async function handleUpdateCommand(updateArgs) {
332
335
  * 无参 → 列出最近几次运行 + 每步摘要; 带 runId → 输出完整轨迹 (文本或 JSON)。
333
336
  * 文本格式与小工具/别的智能体对齐, 可直接复制粘贴交换。
334
337
  */
338
+ /**
339
+ * `bolloon task "<任务>" --budget 0.05 [--input '<json>'] [--json]`
340
+ * `bolloon task --resume <goalId>`
341
+ *
342
+ * M1 唯一入口 (leo 2026-09-18 冻结规则 ①): 用户只给任务和预算,
343
+ * 不点名 Skill、不看内部状态。进度只报 4 个用户态, 结论在报告卡里。
344
+ */
345
+ async function handleTaskCommand(taskArgs) {
346
+ const { runTask, resumeTask } = await import('./agents/task/task-runner.js');
347
+ const wantJson = taskArgs.includes('--json');
348
+ const flag = (name) => {
349
+ const i = taskArgs.indexOf(name);
350
+ return i >= 0 ? taskArgs[i + 1] : undefined;
351
+ };
352
+ const resumeId = flag('--resume');
353
+ const budget = flag('--budget');
354
+ const perPurchase = flag('--per-purchase');
355
+ const daily = flag('--daily');
356
+ const inputRaw = flag('--input');
357
+ let input;
358
+ if (inputRaw !== undefined) {
359
+ try {
360
+ input = JSON.parse(inputRaw);
361
+ }
362
+ catch (e) {
363
+ console.error(`${MAGENTA}--input 不是合法 JSON: ${String(e?.message || e)}${RESET}`);
364
+ process.exit(1);
365
+ }
366
+ }
367
+ const STAGE_LABEL = { prepare: '准备中', acquire: '正在获取能力', execute: '正在执行', report: '报告' };
368
+ const onStage = (stage, note) => {
369
+ if (wantJson)
370
+ return;
371
+ console.error(` ${CYAN}${STAGE_LABEL[stage] || stage}${RESET} ${note}`);
372
+ };
373
+ if (resumeId) {
374
+ const r = await resumeTask({ goalId: resumeId, input, allowLocalDev: true });
375
+ if (wantJson)
376
+ console.log(JSON.stringify({ resumed: r.resumed, action: r.action, reason: r.reason, mustNotRepay: r.mustNotRepay, card: r.card }, null, 2));
377
+ else {
378
+ console.log('');
379
+ console.log(r.text);
380
+ console.log('');
381
+ }
382
+ process.exit(r.ok ? 0 : 1);
383
+ }
384
+ const words = taskArgs.filter((a, i) => {
385
+ if (a.startsWith('--'))
386
+ return false;
387
+ const prev = taskArgs[i - 1];
388
+ return !['--budget', '--per-purchase', '--daily', '--input'].includes(prev || '');
389
+ });
390
+ const task = words.join(' ').trim();
391
+ if (!task) {
392
+ console.log(`
393
+ ${BOLD}bolloon task${RESET} — 给一个任务, 让智能体买到能力并做完它
394
+
395
+ ${CYAN}bolloon task "判断这款厨房用品是否适合进入日本市场" --budget 0.05${RESET}
396
+ ${CYAN}bolloon task --resume <goalId>${RESET}
397
+
398
+ 选项:
399
+ --budget <USDC> 这笔任务最多花多少 (M1 硬上限 0.05; 不能中途扩大)
400
+ --per-purchase <USDC> 单次购买上限 (M1 硬上限 0.02)
401
+ --daily <USDC> 当日预算 (M1 硬上限 0.10)
402
+ --input '<json>' 显式给技能输入 (跳过自动推导)
403
+ --json 机器可读输出
404
+ `);
405
+ return;
406
+ }
407
+ const r = await runTask({ task, budget, perPurchase, daily, input, allowLocalDev: true, onStage });
408
+ if (wantJson) {
409
+ console.log(JSON.stringify({
410
+ ok: r.ok, status: r.card.status, conclusion: r.card.conclusion, card: r.card,
411
+ goalId: r.goalId, runId: r.runId, transactionId: r.transactionId,
412
+ advisor: r.advisor, payment: r.payment, outputIssues: r.outputIssues,
413
+ budget: { taskBudget: r.budget.taskBudget, perPurchase: r.budget.perPurchase, daily: r.budget.daily, clamped: r.budget.clamped },
414
+ stages: r.stages,
415
+ }, null, 2));
416
+ }
417
+ else {
418
+ console.log('');
419
+ console.log(r.text);
420
+ console.log('');
421
+ }
422
+ // 一次性命令: 显式收尾 (DIAP/HTTP 句柄不该吊住进程)
423
+ process.exit(r.ok ? 0 : 1);
424
+ }
335
425
  async function handleTraceCommand(traceArgs) {
336
426
  const { listRuns, readRun } = await import('./agents/run-store.js');
337
427
  const { runToTraceText, runToTraceJson, summarizeTrace } = await import('./agents/trace-export.js');
@@ -677,6 +767,10 @@ async function main() {
677
767
  case 'p2p':
678
768
  await handleP2pCommand(args);
679
769
  break;
770
+ // 2026-09-18: M1 任务闭环 (bolloon task "<任务>" --budget 0.05 / --resume <goalId>)
771
+ case 'task':
772
+ await handleTaskCommand(args);
773
+ break;
680
774
  // 2026-09-13: bolloon setup — 首次运行初始化向导
681
775
  case 'setup':
682
776
  await handleSetupCommand(args);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bolloon/bolloon-agent",
3
- "version": "0.4.27",
3
+ "version": "0.4.28",
4
4
  "type": "module",
5
5
  "description": "P2P AI Document Agent - 全局安装后执行 `bolloon` 启动产品",
6
6
  "main": "dist/cli-entry.js",