@xdxer/dingtalk-agent 0.1.5-beta.3 → 0.1.5-beta.5

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 (59) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.en.md +92 -65
  3. package/README.md +92 -65
  4. package/dist/bin/dingtalk-agent.js +142 -16
  5. package/dist/bin/dingtalk-agent.js.map +1 -1
  6. package/dist/src/agent-platform.js +1 -0
  7. package/dist/src/agent-platform.js.map +1 -1
  8. package/dist/src/development-workspace.js +66 -3
  9. package/dist/src/development-workspace.js.map +1 -1
  10. package/dist/src/doctor.js +1 -1
  11. package/dist/src/doctor.js.map +1 -1
  12. package/dist/src/multica-deploy.js +101 -9
  13. package/dist/src/multica-deploy.js.map +1 -1
  14. package/dist/src/multica-provider.js +157 -2
  15. package/dist/src/multica-provider.js.map +1 -1
  16. package/dist/src/schedule-plan.js +105 -0
  17. package/dist/src/schedule-plan.js.map +1 -0
  18. package/dist/src/skill-manager.js +5 -0
  19. package/dist/src/skill-manager.js.map +1 -1
  20. package/docs/ARCHITECTURE.md +133 -18
  21. package/docs/PRIOR-ART.md +4 -0
  22. package/docs/SELF-TEST.md +1 -1
  23. package/docs/architecture/agent-platform-connection-layer.svg +120 -0
  24. package/docs/architecture/digital-employee-composition.svg +92 -0
  25. package/docs/architecture/dingtalk-agent-architecture.svg +125 -0
  26. package/docs/assets/digital-employee-at-work.svg +77 -0
  27. package/docs/schemas/multica-workspace-run.schema.json +150 -33
  28. package/docs/schemas/project.schema.json +22 -0
  29. package/docs/schemas/workspace-scaffold.schema.json +37 -0
  30. package/examples/agents/README.md +1 -1
  31. package/lab/project-workspace/fake-multica-provider.mjs +18 -2
  32. package/lab/project-workspace/opencode-provider-suite.json +1 -1
  33. package/lab/robot-eval/suite.json +1 -1
  34. package/package.json +3 -2
  35. package/skills/core/dingtalk-agent-compose/SKILL.md +22 -3
  36. package/skills/core/dingtalk-agent-compose/assets/AGENTS.template.md +1 -1
  37. package/skills/core/dingtalk-agent-compose/references/drive-and-schedules.md +124 -0
  38. package/skills/core/dingtalk-basic-behavior/SKILL.md +5 -4
  39. package/skills/core/dingtalk-basic-behavior/references/event-to-behavior.md +15 -1
  40. package/skills/core/dingtalk-basic-behavior/references/perception-and-gates.md +3 -0
  41. package/skills/core/dingtalk-basic-behavior/references/risk-authority-and-privacy.md +12 -0
  42. package/skills/core/dingtalk-people-group-memory/COMPLETENESS.md +36 -0
  43. package/skills/core/dingtalk-people-group-memory/SKILL.md +69 -0
  44. package/skills/core/dingtalk-people-group-memory/references/adapters.md +273 -0
  45. package/skills/core/dingtalk-people-group-memory/references/assembly-guidance.md +40 -0
  46. package/skills/core/dingtalk-people-group-memory/references/binding.md +110 -0
  47. package/skills/core/dingtalk-people-group-memory/references/cold-start.md +70 -0
  48. package/skills/core/dingtalk-people-group-memory/references/config-binding.md +89 -0
  49. package/skills/core/dingtalk-people-group-memory/references/consent-and-visibility.md +83 -0
  50. package/skills/core/dingtalk-people-group-memory/references/consolidation.md +162 -0
  51. package/skills/core/dingtalk-people-group-memory/references/event-ingest.md +103 -0
  52. package/skills/core/dingtalk-people-group-memory/references/guided-setup.md +70 -0
  53. package/skills/core/dingtalk-people-group-memory/references/model.md +148 -0
  54. package/skills/core/dingtalk-people-group-memory/references/storage-port.md +107 -0
  55. package/skills/platforms/deap/PLATFORM.md +30 -1
  56. package/skills/platforms/multica-dingtalk/PLATFORM.md +25 -0
  57. package/skills/platforms/multica-dingtalk/dingtalk-agent-deploy-multica/SKILL.md +3 -2
  58. package/skills/platforms/multica-dingtalk/multica-external/SKILL.md +15 -0
  59. package/docs/assets/agent-delivery-lifecycle.svg +0 -103
@@ -33,9 +33,10 @@ import { runStorageEvaluation } from '../src/storage-evals.js';
33
33
  import { runPersonalEventEvaluation } from '../src/personal-event-evals.js';
34
34
  import { doctor } from '../src/doctor.js';
35
35
  import { doctorDevelopmentWorkspace, inspectAgentProject, showDevelopmentWorkspace, } from '../src/development-workspace.js';
36
+ import { buildScheduleShow, buildSchedulePlan } from '../src/schedule-plan.js';
36
37
  import { applyOpenCodeWorkspace, evalOpenCodeWorkspace, planOpenCodeWorkspace, runOpenCodeWorkspace, useOpenCodeWorkspace, } from '../src/opencode-provider.js';
37
- import { inspectMulticaWorkspace, listMulticaWorkspaceResources, planMulticaWorkspace, statusMulticaWorkspace, } from '../src/multica-provider.js';
38
- import { applyMulticaDeployment, listMulticaDeployments, planMulticaDeployment, runMulticaWorkspaceIssue, statusMulticaDeployment, } from '../src/multica-deploy.js';
38
+ import { inspectMulticaWorkspace, listMulticaWorkspaceResources, planMulticaWorkspace, scaffoldMulticaWorkspace, statusMulticaWorkspace, } from '../src/multica-provider.js';
39
+ import { applyMulticaDeployment, listMulticaDeployments, planMulticaDeployment, runMulticaWorkspaceIssue, statusMulticaDeployment, statusMulticaWorkspaceRun, } from '../src/multica-deploy.js';
39
40
  import { applyObservation, applyPromotion, listPromotions, planObservation, planPromotion, statusPromotion, } from '../src/promotion.js';
40
41
  import { setup } from '../src/setup.js';
41
42
  import { upgradeAgent } from '../src/upgrade.js';
@@ -64,7 +65,7 @@ dta —— 给 Agent 安装钉钉员工的基础行为和工作环境
64
65
  dta setup 首次配置 CLI、DWS 和内置 Skill(基础行为 + Agent 装配 + 交付后评测)
65
66
  dta bootstrap --json 为当前 Agent 会话加载工作区
66
67
  dta agent enhance / audit 安全增强已有仓库,再审计定义、存储与 Skill 真加载
67
- dta info / dta workspace doctor <name> 查看 Project 并只读诊断 Workspace
68
+ dta info / workspace doctor / schedule show <name> 只读诊断 Project、Workspace 与声明的常驻节律
68
69
  dta agent-platform use <platform> → dta deploy / dta promote 声明平台归属并装平台技能包,再受控部署与晋级
69
70
 
70
71
  维护环境:
@@ -155,7 +156,7 @@ const DEPLOY_HELP = `
155
156
  dingtalk-agent Multica 受控部署
156
157
 
157
158
  deploy --workspace <name> --dry-run [--json]
158
- deploy --workspace <name> --plan-id <id> --yes [--no-wait] [--json]
159
+ deploy --workspace <name> --plan-id <id> --yes [--wait | --no-wait] [--json]
159
160
  deploy --workspace <name> --status [--operation-id <id>] [--json]
160
161
  deploy --workspace <name> --status --operation-id <id> --execute --yes [--json]
161
162
  deploy --workspace <name> --list [--json]
@@ -163,6 +164,9 @@ dingtalk-agent Multica 受控部署
163
164
  deploy --workspace <name> --retire --plan-id <id> --yes [--json]
164
165
 
165
166
  dry-run 不启动 Multica。apply/retire 必须携带当前 planId;scope 或源码漂移会在写入前拒绝。
167
+ apply 默认在同一条命令内等 load smoke 到 ~30 秒;云端 runtime 冷启常超 30 秒会返回 verifying,
168
+ 再用 --status --operation-id 独立 reconcile。加 --wait 把等待预算放宽到 4 分钟,一条命令直接到 ready;
169
+ --no-wait 立即返回 verifying(异步/CI)。--smoke-timeout <ms> 精确覆盖等待预算(上限 5 分钟)。
166
170
  status 默认只验本地脱敏 operation/Receipt;--execute --yes 才做远端独立回读。
167
171
  deploy 只管理 Agent、完整 Skill tree、assignment 和 load smoke,不创建机器人、Webhook、Autopilot 或定时 Trigger。
168
172
  `;
@@ -245,6 +249,7 @@ async function main() {
245
249
  workspace: { type: 'string' }, json: { type: 'boolean' },
246
250
  'dry-run': { type: 'boolean' }, yes: { type: 'boolean' },
247
251
  'plan-id': { type: 'string' }, 'no-wait': { type: 'boolean' },
252
+ wait: { type: 'boolean' },
248
253
  status: { type: 'boolean' }, list: { type: 'boolean' },
249
254
  execute: { type: 'boolean' }, 'operation-id': { type: 'string' },
250
255
  timeout: { type: 'string' }, 'smoke-timeout': { type: 'string' },
@@ -265,16 +270,18 @@ async function main() {
265
270
  const timeoutMs = parseOptionalTimeout(o.timeout, '--timeout');
266
271
  const smokeTimeoutMs = parseOptionalTimeout(o['smoke-timeout'], '--smoke-timeout');
267
272
  let out;
273
+ if (o.wait && o['no-wait'])
274
+ fail('deploy --wait 与 --no-wait 互斥');
268
275
  if (o.list) {
269
- if (o.execute || o['operation-id'] || o.retire || o['plan-id'] || o['no-wait'] ||
276
+ if (o.execute || o['operation-id'] || o.retire || o['plan-id'] || o['no-wait'] || o.wait ||
270
277
  o.timeout || o['smoke-timeout']) {
271
278
  fail('deploy --list 只接受 --workspace 和 --json');
272
279
  }
273
280
  out = listMulticaDeployments(PROJECT_START, o.workspace, PACKAGE_JSON.version);
274
281
  }
275
282
  else if (o.status) {
276
- if (o.retire || o['plan-id'] || o['no-wait'] || o['dry-run'] || o['smoke-timeout']) {
277
- fail('deploy --status 不接受 retire/plan-id/no-wait/dry-run/smoke-timeout');
283
+ if (o.retire || o['plan-id'] || o['no-wait'] || o.wait || o['dry-run'] || o['smoke-timeout']) {
284
+ fail('deploy --status 不接受 retire/plan-id/no-wait/wait/dry-run/smoke-timeout');
278
285
  }
279
286
  if (Boolean(o.execute) !== Boolean(o.yes)) {
280
287
  fail('deploy --status 远端 reconcile 必须同时传 --execute --yes');
@@ -285,9 +292,9 @@ async function main() {
285
292
  });
286
293
  }
287
294
  else if (o['dry-run']) {
288
- if (o.execute || o['operation-id'] || o['plan-id'] || o['no-wait'] ||
295
+ if (o.execute || o['operation-id'] || o['plan-id'] || o['no-wait'] || o.wait ||
289
296
  o.timeout || o['smoke-timeout']) {
290
- fail('deploy --dry-run 不接受 execute/operation-id/plan-id/no-wait/timeout/smoke-timeout');
297
+ fail('deploy --dry-run 不接受 execute/operation-id/plan-id/no-wait/wait/timeout/smoke-timeout');
291
298
  }
292
299
  out = planMulticaDeployment(PROJECT_START, o.workspace, {
293
300
  action: o.retire ? 'retire' : 'apply', cliVersion: PACKAGE_JSON.version,
@@ -297,12 +304,16 @@ async function main() {
297
304
  if (o.execute || o['operation-id'] || o.status || o.list || o['dry-run']) {
298
305
  fail('deploy apply 不接受 execute/operation-id/status/list/dry-run');
299
306
  }
300
- if (o.retire && (o['no-wait'] || o['smoke-timeout'])) {
301
- fail('deploy --retire 不接受 no-wait/smoke-timeout');
307
+ if (o.retire && (o['no-wait'] || o.wait || o['smoke-timeout'])) {
308
+ fail('deploy --retire 不接受 no-wait/wait/smoke-timeout');
302
309
  }
310
+ // --wait widens the in-band smoke-wait budget so one command reaches ready across a
311
+ // cold-start runtime; an explicit --smoke-timeout still wins. Default stays ~30s.
312
+ const effectiveSmokeTimeoutMs = smokeTimeoutMs !== undefined
313
+ ? smokeTimeoutMs : o.wait ? 240_000 : undefined;
303
314
  out = applyMulticaDeployment(PROJECT_START, o.workspace, {
304
315
  yes: o.yes, planId: o['plan-id'], noWait: o['no-wait'],
305
- timeoutMs, smokeTimeoutMs, cliVersion: PACKAGE_JSON.version,
316
+ timeoutMs, smokeTimeoutMs: effectiveSmokeTimeoutMs, cliVersion: PACKAGE_JSON.version,
306
317
  }, o.retire ? 'retire' : 'apply');
307
318
  }
308
319
  if (o.json)
@@ -413,6 +424,65 @@ async function main() {
413
424
  printProjectInfo(out);
414
425
  return;
415
426
  }
427
+ if (cmd === 'schedule') {
428
+ const sub = argv[1];
429
+ const { values: o, positionals } = parseArgs({
430
+ args: argv.slice(2), allowPositionals: true,
431
+ options: { json: { type: 'boolean' }, workspace: { type: 'string' } },
432
+ });
433
+ if (sub === 'show') {
434
+ const out = buildScheduleShow(PROJECT_START, PACKAGE_JSON.version);
435
+ if (o.json) {
436
+ console.log(JSON.stringify(out, null, 2));
437
+ return;
438
+ }
439
+ if (out.count === 0) {
440
+ console.log('本 Project 未声明任何常驻节律(schedules)。');
441
+ return;
442
+ }
443
+ console.log(`声明的常驻节律(internalized cron) · ${out.count} 条`);
444
+ for (const s of out.schedules) {
445
+ console.log(`\n ${s.name} ${s.cron} ${s.timezone} [${s.mode}]`);
446
+ if (s.wake)
447
+ console.log(` 唤醒 ${s.wake}`);
448
+ if (s.completion)
449
+ console.log(` ②判据 ${s.completion}`);
450
+ }
451
+ if (!out.minutesDistinct) {
452
+ console.log(`\n⚠️ 分钟位冲突: ${out.collidingMinutes.join(', ')} —— 外发类同分钟并发会重复送,请错开`);
453
+ process.exitCode = 2;
454
+ }
455
+ else {
456
+ console.log('\n✓ 各节律分钟位互不相同(外发防重复的静态前提满足)');
457
+ }
458
+ return;
459
+ }
460
+ if (sub === 'plan') {
461
+ const workspaceName = o.workspace || positionals[0];
462
+ if (!workspaceName)
463
+ fail('schedule plan 需要 --workspace <name>');
464
+ const info = inspectAgentProject(PROJECT_START, PACKAGE_JSON.version);
465
+ const plan = buildSchedulePlan(info, workspaceName);
466
+ if (o.json) {
467
+ console.log(JSON.stringify(plan, null, 2));
468
+ return;
469
+ }
470
+ console.log(`schedule 部署计划 · workspace=${plan.workspace} · provider=${plan.provider}`);
471
+ if (!plan.supported) {
472
+ console.log(`\n✗ 不支持: ${plan.reason}`);
473
+ console.log(` ${plan.reconcile}`);
474
+ process.exitCode = 2;
475
+ return;
476
+ }
477
+ console.log(` ${plan.count} 条声明 → provider ops:\n`);
478
+ for (const s of plan.schedules)
479
+ console.log(` # ${s.name}\n ${s.applyCommand}\n`);
480
+ console.log(`执行: ${plan.reconcile}`);
481
+ return;
482
+ }
483
+ fail(`可用: dta schedule show | plan --workspace <name>${suggest(sub || '', ['show', 'plan'], 'dta schedule')}`);
484
+ return;
485
+ }
416
486
  if (cmd === 'workspace') {
417
487
  const { values: o, positionals } = parseArgs({
418
488
  args: argv.slice(2), allowPositionals: true,
@@ -423,6 +493,8 @@ async function main() {
423
493
  cases: { type: 'string' }, lanes: { type: 'string' }, runs: { type: 'string' },
424
494
  out: { type: 'string' }, timeout: { type: 'string' },
425
495
  'previous-skill': { type: 'string' },
496
+ status: { type: 'boolean' }, 'run-id': { type: 'string' },
497
+ provider: { type: 'string' }, stage: { type: 'string' }, profile: { type: 'string' },
426
498
  },
427
499
  });
428
500
  if (sub === 'list') {
@@ -544,16 +616,46 @@ async function main() {
544
616
  return;
545
617
  }
546
618
  if (sub === 'create') {
547
- rejectWorkspaceOptions(o, ['json', 'yes', 'dry-run'], 'workspace create');
548
619
  if (positionals.length !== 1)
549
620
  fail('workspace create 需要且只接受一个 Workspace name');
550
621
  if (o.yes && o['dry-run'])
551
622
  fail('workspace create 的 --dry-run 与 --yes 不能同时使用');
623
+ const wsName = positionals[0];
624
+ // Resolve the provider kind to scaffold/build: explicit --provider wins, else an already
625
+ // declared Workspace keeps its kind, else the attributed platform's provider (registry-
626
+ // driven so deap inherits it), else opencode. multica has no local host — create authors
627
+ // its config entry; opencode keeps building the managed host.
628
+ if (o.provider && !['opencode', 'multica'].includes(String(o.provider))) {
629
+ fail('workspace create --provider 只支持 opencode 或 multica');
630
+ }
631
+ const declaredWs = inspectAgentProject(PROJECT_START, PACKAGE_JSON.version)
632
+ .workspaces.find((item) => item.name === wsName);
633
+ const platformProvider = resolveAgentPlatform(PROJECT_START).definition?.provider;
634
+ const kind = String(o.provider || declaredWs?.provider.kind || platformProvider || 'opencode');
635
+ if (declaredWs && o.provider && declaredWs.provider.kind !== kind) {
636
+ fail(`Workspace ${wsName} 已声明为 ${declaredWs.provider.kind},与 --provider ${kind} 冲突`);
637
+ }
638
+ if (kind === 'multica') {
639
+ rejectWorkspaceOptions(o, ['json', 'yes', 'dry-run', 'provider', 'stage', 'profile'], 'workspace create');
640
+ const out = scaffoldMulticaWorkspace(PROJECT_START, wsName, {
641
+ stage: o.stage, profile: o.profile, apply: o.yes, cliVersion: PACKAGE_JSON.version,
642
+ });
643
+ if (o.json)
644
+ console.log(JSON.stringify(out, null, 2));
645
+ else {
646
+ const tag = out.alreadyDeclared ? '已存在' : out.applied ? '已写入' : 'DRY-RUN';
647
+ console.log(`${tag} workspace ${out.workspace} · provider=multica · profile=${out.profile}`);
648
+ for (const step of out.nextSteps)
649
+ console.log(` ${step}`);
650
+ }
651
+ return;
652
+ }
653
+ rejectWorkspaceOptions(o, ['json', 'yes', 'dry-run', 'provider'], 'workspace create');
552
654
  const out = o.yes
553
- ? applyOpenCodeWorkspace(PROJECT_START, positionals[0], {
655
+ ? applyOpenCodeWorkspace(PROJECT_START, wsName, {
554
656
  yes: true, cliVersion: PACKAGE_JSON.version,
555
657
  })
556
- : planOpenCodeWorkspace(PROJECT_START, positionals[0], PACKAGE_JSON.version);
658
+ : planOpenCodeWorkspace(PROJECT_START, wsName, PACKAGE_JSON.version);
557
659
  if (o.json)
558
660
  console.log(JSON.stringify(out, null, 2));
559
661
  else
@@ -572,11 +674,35 @@ async function main() {
572
674
  return;
573
675
  }
574
676
  if (sub === 'run') {
677
+ const timeoutMs = o.timeout === undefined ? undefined : Number(o.timeout);
678
+ if (o.status) {
679
+ // Resume a timed-out multica run by re-reading the SAME Issue; no new Issue is created.
680
+ rejectWorkspaceOptions(o, ['json', 'yes', 'execute', 'out', 'timeout', 'status', 'run-id'], 'workspace run --status');
681
+ if (positionals.length !== 1)
682
+ fail('workspace run --status 需要一个 Workspace name');
683
+ if (o['prompt-file'])
684
+ fail('workspace run --status 不接受 --prompt-file;用 --run-id 续读');
685
+ if (!o['run-id'])
686
+ fail('workspace run --status 需要 --run-id <上次 run 的 runId>');
687
+ const out = statusMulticaWorkspaceRun(PROJECT_START, positionals[0], {
688
+ runId: o['run-id'], execute: o.execute, yes: o.yes, timeoutMs, out: o.out,
689
+ cliVersion: PACKAGE_JSON.version,
690
+ });
691
+ if (o.json)
692
+ console.log(JSON.stringify(out, null, 2));
693
+ else {
694
+ console.log(`${out.passed ? '✅' : '❌'} workspace run ${out.runId} (resumed)`);
695
+ if (out.answer)
696
+ console.log(out.answer);
697
+ }
698
+ if (!out.passed)
699
+ process.exitCode = 2;
700
+ return;
701
+ }
575
702
  rejectWorkspaceOptions(o, ['json', 'yes', 'execute', 'prompt-file', 'out', 'timeout'], 'workspace run');
576
703
  if (positionals.length !== 1 || !o['prompt-file']) {
577
704
  fail('workspace run 需要一个 Workspace name 和 --prompt-file <file>');
578
705
  }
579
- const timeoutMs = o.timeout === undefined ? undefined : Number(o.timeout);
580
706
  const prompt = readProjectText(PROJECT_START, o['prompt-file'], 'workspace run prompt');
581
707
  const workspace = showDevelopmentWorkspace(PROJECT_START, positionals[0], PACKAGE_JSON.version);
582
708
  const out = workspace.provider.kind === 'multica'