@xdxer/dingtalk-agent 0.1.4 → 0.1.5-beta.10

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 (186) hide show
  1. package/CHANGELOG.md +232 -0
  2. package/README.en.md +115 -89
  3. package/README.md +111 -86
  4. package/dist/bin/dingtalk-agent.js +742 -152
  5. package/dist/bin/dingtalk-agent.js.map +1 -1
  6. package/dist/src/actions.js +3 -2
  7. package/dist/src/actions.js.map +1 -1
  8. package/dist/src/agent-audit.js +202 -85
  9. package/dist/src/agent-audit.js.map +1 -1
  10. package/dist/src/agent-definition.js +7 -3
  11. package/dist/src/agent-definition.js.map +1 -1
  12. package/dist/src/agent-enhance.js +51 -32
  13. package/dist/src/agent-enhance.js.map +1 -1
  14. package/dist/src/agent-platform.js +4 -4
  15. package/dist/src/agent-platform.js.map +1 -1
  16. package/dist/src/bootstrap.js +6 -2
  17. package/dist/src/bootstrap.js.map +1 -1
  18. package/dist/src/development-workspace.js +210 -34
  19. package/dist/src/development-workspace.js.map +1 -1
  20. package/dist/src/doctor.js +65 -9
  21. package/dist/src/doctor.js.map +1 -1
  22. package/dist/src/dws.js +67 -3
  23. package/dist/src/dws.js.map +1 -1
  24. package/dist/src/init.js +2 -1
  25. package/dist/src/init.js.map +1 -1
  26. package/dist/src/memory/noop-receipt.js +306 -0
  27. package/dist/src/memory/noop-receipt.js.map +1 -0
  28. package/dist/src/memory/operational.js +27 -3
  29. package/dist/src/memory/operational.js.map +1 -1
  30. package/dist/src/memory/remote-state.js +2 -1
  31. package/dist/src/memory/remote-state.js.map +1 -1
  32. package/dist/src/multica-deploy.js +692 -125
  33. package/dist/src/multica-deploy.js.map +1 -1
  34. package/dist/src/multica-provider.js +303 -25
  35. package/dist/src/multica-provider.js.map +1 -1
  36. package/dist/src/multica-runtime-vocabulary.js +110 -0
  37. package/dist/src/multica-runtime-vocabulary.js.map +1 -0
  38. package/dist/src/opencode-evals.js +6 -6
  39. package/dist/src/opencode-evals.js.map +1 -1
  40. package/dist/src/opencode-provider.js +21 -7
  41. package/dist/src/opencode-provider.js.map +1 -1
  42. package/dist/src/opencode-workspace.js +3 -3
  43. package/dist/src/opencode-workspace.js.map +1 -1
  44. package/dist/src/personal-event-evals.js +4 -2
  45. package/dist/src/personal-event-evals.js.map +1 -1
  46. package/dist/src/promotion.js +2 -1
  47. package/dist/src/promotion.js.map +1 -1
  48. package/dist/src/remote-semantic-state-live-evals.js +14 -8
  49. package/dist/src/remote-semantic-state-live-evals.js.map +1 -1
  50. package/dist/src/remote-state-evals.js +2 -2
  51. package/dist/src/remote-state-evals.js.map +1 -1
  52. package/dist/src/robot-evals.js +3 -3
  53. package/dist/src/robot-evals.js.map +1 -1
  54. package/dist/src/schedule-plan.js +380 -0
  55. package/dist/src/schedule-plan.js.map +1 -0
  56. package/dist/src/sessions.js +1 -1
  57. package/dist/src/sessions.js.map +1 -1
  58. package/dist/src/skill-manager.js +145 -13
  59. package/dist/src/skill-manager.js.map +1 -1
  60. package/dist/src/skills.js +2 -0
  61. package/dist/src/skills.js.map +1 -1
  62. package/dist/src/tui.js +369 -0
  63. package/dist/src/tui.js.map +1 -0
  64. package/dist/src/upgrade.js +113 -33
  65. package/dist/src/upgrade.js.map +1 -1
  66. package/dist/src/waits.js +2 -1
  67. package/dist/src/waits.js.map +1 -1
  68. package/dist/src/workspace.js +12 -7
  69. package/dist/src/workspace.js.map +1 -1
  70. package/docs/AGENT-IN-PRODUCTION.md +255 -0
  71. package/docs/ARCHITECTURE.md +366 -0
  72. package/docs/INSTALLATION.md +8 -8
  73. package/docs/PLATFORM-GUARDRAILS.md +188 -0
  74. package/docs/PRIOR-ART.md +126 -0
  75. package/docs/SELF-TEST.md +182 -0
  76. package/docs/architecture/agent-platform-connection-layer.svg +120 -0
  77. package/docs/architecture/digital-employee-composition.svg +92 -0
  78. package/docs/architecture/dingtalk-agent-architecture.svg +125 -0
  79. package/docs/assets/digital-employee-at-work.svg +77 -0
  80. package/docs/schemas/multica-deployment-plan.schema.json +3 -1
  81. package/docs/schemas/multica-deployment-receipt.schema.json +17 -3
  82. package/docs/schemas/multica-deployment-status.schema.json +6 -2
  83. package/docs/schemas/multica-workspace-inspection.schema.json +16 -0
  84. package/docs/schemas/multica-workspace-run-plan.schema.json +31 -0
  85. package/docs/schemas/multica-workspace-run.schema.json +161 -0
  86. package/docs/schemas/multica-workspace-status.schema.json +2 -0
  87. package/docs/schemas/project.schema.json +54 -3
  88. package/docs/schemas/workspace-scaffold.schema.json +38 -0
  89. package/examples/agents/README.md +45 -0
  90. package/examples/agents/fde-coach/AGENTS.md +2 -25
  91. package/examples/agents/fde-coach/agent/AGENTS.md +35 -0
  92. package/examples/agents/fde-coach/agent.bindings.json +10 -0
  93. package/examples/agents/release-manager/AGENTS.md +2 -25
  94. package/examples/agents/release-manager/agent/AGENTS.md +35 -0
  95. package/examples/agents/release-manager/agent.bindings.json +10 -0
  96. package/lab/agent-eval/catalog.json +5 -5
  97. package/lab/agent-eval/classic-failures.json +4 -4
  98. package/lab/agent-eval/completion-gate-regression.json +9 -9
  99. package/lab/agent-eval/personal-event-live.example.json +3 -3
  100. package/lab/agent-eval/remote-semantic-state-live.example.json +1 -1
  101. package/lab/agent-eval/workspace/opencode.json +2 -2
  102. package/lab/project-workspace/fake-multica-provider.mjs +171 -17
  103. package/lab/project-workspace/multica-deploy.fixture.json +2 -2
  104. package/lab/project-workspace/multica-readonly.fixture.json +4 -16
  105. package/lab/project-workspace/opencode-provider-suite.json +3 -3
  106. package/lab/project-workspace/project.fixture.json +2 -6
  107. package/lab/robot-eval/suite.json +1 -1
  108. package/lab/robot-eval/workspace/AGENTS.md +1 -1
  109. package/lab/robot-eval/workspace/opencode.json +2 -2
  110. package/lab/schemas/personal-event-eval.schema.json +1 -1
  111. package/package.json +18 -11
  112. package/skills/README.md +10 -8
  113. package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/SKILL.md +49 -24
  114. package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/AGENTS.template.md +1 -1
  115. package/skills/core/dta-agent-compose/assets/REPOSITORY.template.md +10 -0
  116. package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/agent.bindings.dingtalk-doc.template.json +2 -2
  117. package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/agent.bindings.local.template.json +2 -2
  118. package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/hosts/opencode/opencode.template.json +3 -2
  119. package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/evals/evals.json +4 -4
  120. package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/agent-definition-contract.md +7 -7
  121. package/skills/core/dta-agent-compose/references/drive-and-schedules.md +166 -0
  122. package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/host-loading-contract.md +11 -13
  123. package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/hosts/claude-code.md +13 -12
  124. package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/hosts/opencode.md +14 -13
  125. package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/SKILL.md +28 -3
  126. package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/assets/eval-catalog.template.json +1 -1
  127. package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/evals/evals.json +1 -1
  128. package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/eval-topology.md +3 -3
  129. package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/interactive-debug-channels.md +10 -4
  130. package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/SKILL.md +21 -5
  131. package/skills/core/dta-basic-behavior/references/event-to-behavior.md +38 -0
  132. package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/memory-and-evolution.md +3 -1
  133. package/skills/core/dta-basic-behavior/references/perception-and-gates.md +87 -0
  134. package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/risk-authority-and-privacy.md +12 -0
  135. package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/truth-and-recovery.md +4 -2
  136. package/skills/core/dta-people-group-memory/COMPLETENESS.md +36 -0
  137. package/skills/core/dta-people-group-memory/SKILL.md +69 -0
  138. package/skills/core/dta-people-group-memory/references/adapters.md +273 -0
  139. package/skills/core/dta-people-group-memory/references/assembly-guidance.md +40 -0
  140. package/skills/core/dta-people-group-memory/references/binding.md +110 -0
  141. package/skills/core/dta-people-group-memory/references/cold-start.md +70 -0
  142. package/skills/core/dta-people-group-memory/references/config-binding.md +89 -0
  143. package/skills/core/dta-people-group-memory/references/consent-and-visibility.md +83 -0
  144. package/skills/core/dta-people-group-memory/references/consolidation.md +162 -0
  145. package/skills/core/dta-people-group-memory/references/event-ingest.md +103 -0
  146. package/skills/core/dta-people-group-memory/references/guided-setup.md +70 -0
  147. package/skills/core/dta-people-group-memory/references/model.md +148 -0
  148. package/skills/core/dta-people-group-memory/references/storage-port.md +107 -0
  149. package/skills/platforms/deap/PLATFORM.md +30 -1
  150. package/skills/platforms/multica-dingtalk/PLATFORM.md +35 -9
  151. package/skills/platforms/multica-dingtalk/{dingtalk-agent-deploy-multica → dta-deploy-multica}/SKILL.md +10 -8
  152. package/skills/platforms/multica-dingtalk/dta-deploy-multica/references/multica-deployment-contract.md +67 -0
  153. package/skills/platforms/multica-dingtalk/{multica-external → dta-ops-multica}/SKILL.md +81 -11
  154. package/skills/platforms/multica-dingtalk/{multica-external → dta-ops-multica}/scripts/bootstrap.sh +2 -2
  155. package/skills/platforms/multica-dingtalk/{multica-external → dta-ops-multica}/scripts/multica_ext.py +264 -16
  156. package/dist/src/map.js +0 -157
  157. package/dist/src/map.js.map +0 -1
  158. package/docs/SECOND-AGENT-ACCEPTANCE.md +0 -62
  159. package/docs/architecture/agent-memory-topology.png +0 -0
  160. package/docs/architecture/agent-memory-topology.svg +0 -132
  161. package/docs/architecture/dingtalk-agent-blueprint.png +0 -0
  162. package/docs/architecture/durable-async-agent-runtime.png +0 -0
  163. package/docs/architecture/general-agent-kernel-topology.png +0 -0
  164. package/docs/architecture/provider-bound-development-workspace.png +0 -0
  165. package/docs/architecture/task-completion-gate.png +0 -0
  166. package/docs/assets/agent-delivery-lifecycle.svg +0 -103
  167. package/skills/core/dingtalk-basic-behavior/references/event-to-behavior.md +0 -24
  168. package/skills/core/dingtalk-basic-behavior/references/perception-and-gates.md +0 -28
  169. package/skills/platforms/deap/README.md +0 -3
  170. package/skills/platforms/multica-dingtalk/dingtalk-agent-boot-multica/SKILL.md +0 -40
  171. package/skills/platforms/multica-dingtalk/dingtalk-agent-deploy-multica/references/multica-deployment-contract.md +0 -49
  172. /package/examples/agents/fde-coach/{skills → agent/skills}/fde-coach/SKILL.md +0 -0
  173. /package/examples/agents/release-manager/{skills → agent/skills}/release-manager/SKILL.md +0 -0
  174. /package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/role-skill.template.md +0 -0
  175. /package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/storage-routing.md +0 -0
  176. /package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/evidence-contract.md +0 -0
  177. /package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/failure-to-case.md +0 -0
  178. /package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/local-connector-smoke.md +0 -0
  179. /package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/scenario-taxonomy.md +0 -0
  180. /package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/storage-modes.md +0 -0
  181. /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/assets/memory-candidate-proposal.json +0 -0
  182. /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/assets/task-checkpoint.json +0 -0
  183. /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/action-contract.md +0 -0
  184. /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/runtime-modes.md +0 -0
  185. /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/task-lifecycle.md +0 -0
  186. /package/skills/platforms/multica-dingtalk/{dingtalk-agent-deploy-multica → dta-deploy-multica}/references/promotion-observation-contract.md +0 -0
@@ -30,6 +30,7 @@ const commandKey = (() => {
30
30
  if (core[0] === 'agent' && core[1] === 'skills') return `agent skills ${core[2]}`
31
31
  if (core[0] === 'skill' && core[1] === 'files') return `skill files ${core[2]}`
32
32
  if (core[0] === 'issue' && core[1] === 'run-messages') return 'issue run-messages'
33
+ if (core[0] === 'issue' && core[1] === 'comment') return `issue comment ${core[2]}`
33
34
  return core.slice(0, 2).join(' ')
34
35
  })()
35
36
  appendFileSync(callsPath, `${JSON.stringify({ command: commandKey, args: raw })}\n`)
@@ -41,7 +42,7 @@ if (['autopilot', 'webhook', 'robot', 'schedule', 'trigger'].includes(core[0]))
41
42
  const mutating = new Set([
42
43
  'skill create', 'skill update', 'skill delete', 'skill files upsert', 'skill files delete',
43
44
  'agent create', 'agent update', 'agent archive', 'agent restore', 'agent skills set',
44
- 'issue create', 'issue status',
45
+ 'issue create', 'issue comment add', 'issue status',
45
46
  ])
46
47
  if (mutating.has(commandKey) && mutationMarker) appendFileSync(mutationMarker, `${commandKey}\n`)
47
48
  const confirmedFailure = process.env.DTA_FAKE_FAIL_ON || ''
@@ -56,7 +57,7 @@ const finish = (value, mutation = false) => {
56
57
  if (timeoutFailure === commandKey && !state.fired.includes(`timeout:${commandKey}`)) {
57
58
  state.fired.push(`timeout:${commandKey}`)
58
59
  save()
59
- Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 5000)
60
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 8000)
60
61
  }
61
62
  if (value !== undefined) json(value)
62
63
  process.exit(0)
@@ -81,7 +82,9 @@ if (commandKey === 'config show') {
81
82
  process.exit(0)
82
83
  }
83
84
  if (commandKey === 'auth status') {
84
- if (!state.authenticated) {
85
+ // 复刻 multica Go CLI 的保留语义:环境里存在 MULTICA_AGENT_ID 即切 Agent 身份鉴权,
86
+ // 用户 token 判无效(B11)。dta 剔除该变量后本分支不应再命中。
87
+ if (!state.authenticated || process.env.MULTICA_AGENT_ID) {
85
88
  console.error("Not authenticated. Run 'multica login' to authenticate.")
86
89
  process.exit(0)
87
90
  }
@@ -92,7 +95,11 @@ if (commandKey === 'auth status') {
92
95
  }
93
96
  if (commandKey === 'workspace list') finish([state.workspace])
94
97
  if (commandKey === 'workspace get') finish(state.workspace)
95
- if (commandKey === 'runtime list') { requireScope(); finish([state.runtime]) }
98
+ if (commandKey === 'runtime list') {
99
+ requireScope()
100
+ const provider = process.env.DTA_FAKE_MULTICA_RUNTIME_PROVIDER || state.runtime.provider
101
+ finish([{ ...state.runtime, provider }, ...(state.extraRuntimes || [])])
102
+ }
96
103
  if (commandKey === 'agent list') { requireScope(); finish(state.agents) }
97
104
  if (commandKey === 'skill list') { requireScope(); finish(state.skills) }
98
105
 
@@ -211,20 +218,93 @@ if (commandKey === 'agent archive' || commandKey === 'agent restore') {
211
218
  finish(agent, true)
212
219
  }
213
220
 
214
- if (commandKey === 'issue create') {
215
- requireScope()
216
- const agentId = flag('--assignee-id')
221
+ const makeIssueRun = (issueId, agentId, description) => {
217
222
  const agent = state.agents.find((item) => item.id === agentId)
218
223
  if (!agent) process.exit(94)
219
- const description = flag('--description')
220
224
  const marker = description.match(/^marker=(.+)$/m)?.[1] || ''
221
- const issueId = id('issue')
225
+ // 递增的确定性 created_at:readSmoke 取最新 run 判定,重试产生的新 run 必须排在旧
226
+ // 失败 run 之后(真实平台的时间戳天然递增)。
227
+ const sequence = state.sequence.task
222
228
  const taskId = id('task')
229
+ const createdAt = new Date(sequence * 60_000).toISOString()
223
230
  const loaded = (agent.skill_ids || []).map((skillId) => state.skills.find((item) => item.id === skillId)?.name)
224
231
  .filter(Boolean).sort()
232
+ // 冷沙箱竞态模拟:前 N 个 smoke run 看不到刚推送的 Skill(B7)。
233
+ const notFoundBudget = Number(process.env.DTA_FAKE_MULTICA_SKILL_NOT_FOUND_RUNS || 0)
234
+ const notFoundUsed = state.fired.filter((item) => item === 'skill-not-found').length
235
+ if (marker && notFoundBudget > notFoundUsed) {
236
+ state.fired.push('skill-not-found')
237
+ const missing = loaded[0] || 'dta-basic-behavior'
238
+ const messages = [
239
+ { type: 'tool_use', tool: 'read_file', input: { text: `Loading skill '${missing}' (SKILL.md)` } },
240
+ { type: 'tool_result', tool: 'read_file', content: `Skill view failed: Skill '${missing}' not found` },
241
+ { type: 'text', content: 'Only the dws skill is available in this sandbox; cannot execute the verification.' },
242
+ ].map((item, index) => ({ task_id: taskId, issue_id: issueId, seq: index + 1, ...item }))
243
+ return {
244
+ id: taskId, issue_id: issueId, agent_id: agentId, status: 'failed',
245
+ created_at: createdAt, messages,
246
+ }
247
+ }
225
248
  const reply = JSON.stringify({ schema: 'dta-multica-load-smoke@1', marker, loaded })
226
- const replyPath = `/tmp/${taskId}/reply.md`
227
- const messages = [
249
+ if (marker && process.env.DTA_FAKE_MULTICA_SMOKE_NO_COMMENT !== '1') {
250
+ state.comments ||= {}
251
+ ;(state.comments[issueId] ||= []).push({ id: id('file'), issue_id: issueId, content: reply })
252
+ }
253
+ const resultMode = process.env.DTA_FAKE_MULTICA_SMOKE_RESULT_FILE || ''
254
+ const resultName = resultMode === 'json-force' ? 'result.json' : 'result.md'
255
+ const resultPath = `/home/user/multica_workspaces/ws-contract-deploy/${taskId}/workdir/${resultName}`
256
+ // `md-bare` 复刻线上实测写法:write 用绝对路径,随后的 comment add / rm 用**裸文件名**
257
+ // 引用同一个 workdir 文件(2026-07-22 fde-prod smoke task e3490d24 实测轨迹)。
258
+ const responseTools = resultMode === 'md-bare'
259
+ ? [
260
+ { type: 'tool_use', tool: 'write', input: { filePath: resultPath, content: reply } },
261
+ { type: 'tool_use', tool: 'bash', input: {
262
+ command: `multica issue comment add ${issueId} --content-file ${resultName}`,
263
+ } },
264
+ { type: 'tool_use', tool: 'bash', input: {
265
+ command: `multica issue status ${issueId} in_review && rm ${resultName}`,
266
+ } },
267
+ ]
268
+ : resultMode
269
+ ? [
270
+ { type: 'tool_use', tool: 'write', input: { filePath: resultPath, content: reply } },
271
+ { type: 'tool_use', tool: 'bash', input: {
272
+ command: `multica issue comment add ${issueId} --content-file ${resultMode === 'json-force' ? `./${resultName}` : resultPath}`,
273
+ } },
274
+ { type: 'tool_use', tool: 'bash', input: {
275
+ command: resultMode === 'json-force'
276
+ ? `multica issue status ${issueId} in_review && rm -f ./${resultName}`
277
+ : `rm ${resultPath} && multica issue status ${issueId} in_review`,
278
+ } },
279
+ ]
280
+ : [
281
+ { type: 'tool_use', tool: 'bash', input: { command: [
282
+ "cat > ./reply.md << 'REPLY_EOF'",
283
+ reply,
284
+ 'REPLY_EOF',
285
+ `multica issue comment add ${issueId} --content-file ./reply.md && rm ./reply.md`,
286
+ ].join('\n') } },
287
+ { type: 'tool_use', tool: 'bash', input: { command: `multica issue status ${issueId} in_review` } },
288
+ ]
289
+ // 云 runtime 词汇(B8 实测轨迹):skill 装载走 read_file + tool_result 的
290
+ // **Skill loaded**,命令走 terminal 的 `$ ` 前缀文本;穿插无害噪声命令。
291
+ const cloudSmokeMessages = [
292
+ { type: 'tool_use', tool: 'terminal', input: { text: `$ multica issue get ${issueId} --output json` } },
293
+ ...loaded.flatMap((name) => [
294
+ { type: 'tool_use', tool: 'read_file', input: { text: `Loading skill '${name}' (SKILL.md)` } },
295
+ { type: 'tool_result', tool: 'read_file', content: `**Skill loaded** - Name: ${name}` },
296
+ ]),
297
+ { type: 'tool_use', tool: 'terminal', input: { text: '$ ls -la' } },
298
+ ...(process.env.DTA_FAKE_MULTICA_SMOKE_UNSAFE === '1'
299
+ ? [{ type: 'tool_use', tool: 'dws', input: { command: 'contact current-user' } }] : []),
300
+ { type: 'text', content: 'Required skills loaded; posting the structured result.' },
301
+ { type: 'tool_use', tool: 'write', input: { filePath: resultPath, content: reply } },
302
+ { type: 'tool_use', tool: 'terminal', input: { text: `$ multica issue comment add ${issueId} --content-file result.json` } },
303
+ { type: 'tool_result', tool: 'terminal', content: `Comment added to issue ${issueId}.` },
304
+ { type: 'tool_use', tool: 'terminal', input: { text: `$ multica issue status ${issueId} in_review` } },
305
+ { type: 'text', content: 'Load smoke result posted to the current issue.' },
306
+ ]
307
+ const hostSmokeMessages = [
228
308
  { type: 'tool_use', tool: 'bash', input: { command: `multica issue get ${issueId} --output json` } },
229
309
  { type: 'tool_use', tool: 'bash', input: { command: `multica issue metadata list ${issueId} --output json` } },
230
310
  { type: 'tool_use', tool: 'bash', input: { command: `multica issue comment list ${issueId} --recent 10 --output json` } },
@@ -232,26 +312,100 @@ if (commandKey === 'issue create') {
232
312
  ...loaded.map((name) => ({ type: 'tool_use', tool: 'skill', input: { name } })),
233
313
  ...(process.env.DTA_FAKE_MULTICA_SMOKE_UNSAFE === '1'
234
314
  ? [{ type: 'tool_use', tool: 'dws', input: { command: 'contact current-user' } }] : []),
235
- { type: 'tool_use', tool: 'write', input: { filePath: replyPath, content: reply } },
236
315
  { type: 'text', content: 'Required skills loaded; posting the structured result.' },
237
- { type: 'tool_use', tool: 'bash', input: { command: `multica issue comment add ${issueId} --content-file ${replyPath}` } },
238
- { type: 'tool_use', tool: 'bash', input: { command: `rm ${replyPath} && multica issue status ${issueId} in_review` } },
316
+ ...responseTools,
239
317
  { type: 'text', content: 'Load smoke result posted to the current issue.' },
240
- ].map((item, index) => ({
318
+ ]
319
+ // 伪造轨迹:banner 只出现在 terminal echo 的 tool_result 里(模型可指定的内容),
320
+ // 没有任何 read_file 装载结果——判定必须拒绝把它当装载证据。
321
+ const cloudSpoofMessages = [
322
+ ...loaded.flatMap((name) => [
323
+ { type: 'tool_use', tool: 'terminal', input: { text: `$ echo "**Skill loaded** - Name: ${name}"` } },
324
+ { type: 'tool_result', tool: 'terminal', content: `**Skill loaded** - Name: ${name}` },
325
+ ]),
326
+ { type: 'text', content: 'Required skills loaded; posting the structured result.' },
327
+ { type: 'tool_use', tool: 'write', input: { filePath: resultPath, content: reply } },
328
+ { type: 'tool_use', tool: 'terminal', input: { text: `$ multica issue comment add ${issueId} --content-file result.json` } },
329
+ ]
330
+ const vocabMode = process.env.DTA_FAKE_MULTICA_TRACE_VOCAB || ''
331
+ const smokeMessages = vocabMode === 'cloud' ? cloudSmokeMessages
332
+ : vocabMode === 'cloud-spoof' ? cloudSpoofMessages : hostSmokeMessages
333
+ const conversationMessages = [
334
+ { type: 'tool_use', tool: 'skill', input: { name: 'release-manager' } },
335
+ { type: 'text', content: 'Multica contract answer from the assigned Agent.' },
336
+ ]
337
+ const messages = (marker ? smokeMessages : conversationMessages).map((item, index) => ({
241
338
  task_id: taskId, issue_id: issueId, seq: index + 1, ...item,
242
339
  }))
340
+ return {
341
+ id: taskId, issue_id: issueId, agent_id: agentId, status: 'completed',
342
+ created_at: createdAt, messages,
343
+ }
344
+ }
345
+
346
+ if (commandKey === 'issue create') {
347
+ requireScope()
348
+ const agentId = flag('--assignee-id')
349
+ const agent = state.agents.find((item) => item.id === agentId)
350
+ if (!agent) process.exit(94)
351
+ const description = flag('--description')
352
+ const issueId = id('issue')
353
+ const runs = process.env.DTA_FAKE_MULTICA_SMOKE_NO_TASK_ON_CREATE === '1'
354
+ ? [] : [makeIssueRun(issueId, agentId, description)]
243
355
  const issue = {
244
356
  id: issueId, title: flag('--title'), description, assignee_id: agentId, status: 'done',
245
- runs: [{ id: taskId, issue_id: issueId, agent_id: agentId, status: 'completed', created_at: new Date(0).toISOString(), messages }],
357
+ runs,
246
358
  }
247
359
  state.issues.push(issue)
248
360
  finish(issue, true)
249
361
  }
362
+ if (commandKey === 'issue comment add') {
363
+ requireScope()
364
+ const issue = state.issues.find((item) => item.id === core[3])
365
+ if (!issue) process.exit(94)
366
+ const content = flag('--content')
367
+ if (!content.includes(`mention://agent/${issue.assignee_id}`)) process.exit(95)
368
+ const newRun = makeIssueRun(issue.id, issue.assignee_id, issue.description || '')
369
+ // 复刻真实平台:mention 触发的 run 是异步创建的,前 N 次 issue runs 读还看不到它。
370
+ const delayReads = Number(process.env.DTA_FAKE_MULTICA_RUN_DELAY_READS || 0)
371
+ if (delayReads > 0) {
372
+ state.delayedRuns ||= {}
373
+ state.delayedRuns[issue.id] = { remaining: delayReads, run: newRun }
374
+ } else {
375
+ issue.runs.push(newRun)
376
+ }
377
+ issue.status = 'done'
378
+ state.comments ||= {}
379
+ const comment = { id: id('file'), issue_id: issue.id, content }
380
+ ;(state.comments[issue.id] ||= []).push(comment)
381
+ finish(comment, true)
382
+ }
383
+ if (commandKey === 'issue comment list') {
384
+ requireScope()
385
+ const issue = state.issues.find((item) => item.id === core[3])
386
+ if (!issue) process.exit(94)
387
+ finish((state.comments || {})[issue.id] || [])
388
+ }
250
389
  if (commandKey === 'issue runs') {
251
390
  requireScope()
252
391
  const issue = state.issues.find((item) => item.id === core[2])
253
392
  if (!issue) process.exit(94)
254
- finish(issue.runs.map(({ messages, ...run }) => run))
393
+ // 延迟中的 run 每被读一次倒计数一次,归零才可见(模拟异步 run 创建)。
394
+ const delayed = (state.delayedRuns || {})[issue.id]
395
+ let materialized = false
396
+ if (delayed) {
397
+ delayed.remaining -= 1
398
+ if (delayed.remaining <= 0) {
399
+ issue.runs.push(delayed.run)
400
+ delete state.delayedRuns[issue.id]
401
+ }
402
+ materialized = true
403
+ }
404
+ // Simulate an overrunning run: report the task as still running so the poll loop times out.
405
+ // The persisted run stays terminal, so a later `--status --run-id` resume sees it completed.
406
+ const forceRunning = process.env.DTA_FAKE_MULTICA_RUN_FORCE_RUNNING === '1'
407
+ finish(issue.runs.map(({ messages, ...run }) =>
408
+ forceRunning ? { ...run, status: 'running' } : run), materialized)
255
409
  }
256
410
  if (commandKey === 'issue run-messages') {
257
411
  requireScope()
@@ -9,8 +9,8 @@
9
9
  "runtime": {
10
10
  "id": "runtime-contract-deploy",
11
11
  "workspace_id": "ws-contract-deploy",
12
- "name": "Contract Codex Runtime",
13
- "provider": "codex",
12
+ "name": "Contract OpenCode Runtime",
13
+ "provider": "opencode",
14
14
  "status": "online"
15
15
  },
16
16
  "authenticated": true,
@@ -9,8 +9,8 @@
9
9
  "runtime": {
10
10
  "id": "runtime-contract-codex",
11
11
  "workspace_id": "ws-contract-release",
12
- "name": "Contract Codex Runtime",
13
- "provider": "codex",
12
+ "name": "Contract OpenCode Runtime",
13
+ "provider": "opencode",
14
14
  "status": "online"
15
15
  },
16
16
  "agent": {
@@ -30,7 +30,7 @@
30
30
  {
31
31
  "id": "skill-contract-basic",
32
32
  "workspace_id": "ws-contract-release",
33
- "name": "dingtalk-basic-behavior",
33
+ "name": "dta-basic-behavior",
34
34
  "description": "shared behavior"
35
35
  },
36
36
  {
@@ -38,19 +38,13 @@
38
38
  "workspace_id": "ws-contract-release",
39
39
  "name": "release-manager",
40
40
  "description": "release role"
41
- },
42
- {
43
- "id": "skill-contract-boot",
44
- "workspace_id": "ws-contract-release",
45
- "name": "dingtalk-agent-boot-multica",
46
- "description": "Multica boot"
47
41
  }
48
42
  ],
49
43
  "assignedSkills": [
50
44
  {
51
45
  "id": "skill-contract-basic",
52
46
  "workspace_id": "ws-contract-release",
53
- "name": "dingtalk-basic-behavior",
47
+ "name": "dta-basic-behavior",
54
48
  "enabled": true
55
49
  },
56
50
  {
@@ -58,12 +52,6 @@
58
52
  "workspace_id": "ws-contract-release",
59
53
  "name": "release-manager",
60
54
  "enabled": true
61
- },
62
- {
63
- "id": "skill-contract-boot",
64
- "workspace_id": "ws-contract-release",
65
- "name": "dingtalk-agent-boot-multica",
66
- "enabled": true
67
55
  }
68
56
  ]
69
57
  }
@@ -29,7 +29,7 @@
29
29
  "surface": "workspace",
30
30
  "type": "agentDefinition",
31
31
  "status": "ready",
32
- "requiredSkills": ["dingtalk-basic-behavior", "release-manager"]
32
+ "requiredSkills": ["dta-basic-behavior", "release-manager"]
33
33
  },
34
34
  {
35
35
  "id": "artifact-exists",
@@ -54,8 +54,8 @@
54
54
  }
55
55
  ],
56
56
  "sourceRefs": [
57
- "docs/plans/2026-07-16/provider-bound-development-workspace.md#12-分阶段实现与验收",
58
- "skills/core/dingtalk-agent-eval/references/evidence-contract.md"
57
+ "docs/ARCHITECTURE.md#8-开发生命周期从定义到观测",
58
+ "skills/core/dta-agent-eval/references/evidence-contract.md"
59
59
  ],
60
60
  "manualChecks": [
61
61
  "工具轨迹对同一 Artifact completed write 后 completed read"
@@ -5,7 +5,7 @@
5
5
  "agent": {
6
6
  "definition": "AGENTS.md",
7
7
  "skills": [
8
- "dingtalk-basic-behavior",
8
+ "dta-basic-behavior",
9
9
  "release-manager"
10
10
  ]
11
11
  },
@@ -29,11 +29,7 @@
29
29
  "profile": "dev",
30
30
  "workspaceIdFrom": "env:MULTICA_WORKSPACE_ID",
31
31
  "runtimeIdFrom": "env:MULTICA_RUNTIME_ID",
32
- "agentIdFrom": "env:MULTICA_AGENT_ID"
33
- },
34
- "storage": {
35
- "memory": "dingtalk-doc:replace-with-memory-node",
36
- "knowledge": "dingtalk-doc:replace-with-knowledge-node"
32
+ "agentIdFrom": "env:DTA_MULTICA_DEV_AGENT_ID"
37
33
  },
38
34
  "authority": {
39
35
  "dwsProfileFrom": "env:DTA_DWS_PROFILE",
@@ -12,7 +12,7 @@
12
12
  "capability": "basic-skill",
13
13
  "prompt": "这是基础行为加载探针。只依据已经进入当前上下文的正文,严格输出 skill=<name>@<metadata.version>;如果正文不可见,只输出 skill=not-loaded。禁止猜测,不要补充解释。",
14
14
  "expectations": [
15
- { "id": "exact-basic-version", "type": "equals", "value": "skill=dingtalk-basic-behavior@0.11.0" }
15
+ { "id": "exact-basic-version", "type": "equals", "value": "skill=dta-basic-behavior@0.14.1" }
16
16
  ],
17
17
  "manualChecks": []
18
18
  },
@@ -4,7 +4,7 @@
4
4
 
5
5
  你是一个通过钉钉与同事协作的数字员工。即使没有额外事件类型、Workspace 提示或自动化触发器,也要像正在和对方对话的可靠同事一样正常理解和完成工作。
6
6
 
7
- OpenCode Host 由原生 project rule 加载项目根的本文,不把它重复写入 custom instructions;在本体与 Basic 这两个受管加载面中,`opencode.json#instructions` 只显式注入 `.agents/skills/dingtalk-basic-behavior/SKILL.md`。本文只定义验证员工的身份和测试边界,不复制 Basic Skill 的行为答案。
7
+ OpenCode Host 由原生 project rule 加载项目根的本文,不把它重复写入 custom instructions;在本体与 Basic 这两个受管加载面中,`opencode.json#instructions` 只显式注入 `.agents/skills/dta-basic-behavior/SKILL.md`。本文只定义验证员工的身份和测试边界,不复制 Basic Skill 的行为答案。
8
8
 
9
9
  ## 职责
10
10
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://opencode.ai/config.json",
3
3
  "instructions": [
4
- ".agents/skills/dingtalk-basic-behavior/SKILL.md"
4
+ ".agents/skills/dta-basic-behavior/SKILL.md"
5
5
  ],
6
6
  "default_agent": "dta-eval",
7
7
  "agent": {
@@ -16,7 +16,7 @@
16
16
  "permission": {
17
17
  "skill": {
18
18
  "*": "deny",
19
- "dingtalk-basic-behavior": "allow"
19
+ "dta-basic-behavior": "allow"
20
20
  }
21
21
  }
22
22
  }
@@ -18,7 +18,7 @@
18
18
  "type": "array",
19
19
  "minItems": 1,
20
20
  "uniqueItems": true,
21
- "contains": { "const": "dingtalk-basic-behavior" },
21
+ "contains": { "const": "dta-basic-behavior" },
22
22
  "items": { "type": "string", "minLength": 1 }
23
23
  },
24
24
  "maxOutwardActions": { "type": "integer", "minimum": 1, "maximum": 20 },
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xdxer/dingtalk-agent",
3
- "version": "0.1.4",
4
- "description": "钉钉数字员工的 Skill-first 行为范式:全局 Skill 决策,CLI 固定事务边界,Workspace 按需。",
3
+ "version": "0.1.5-beta.10",
4
+ "description": " Agent 装配成钉钉数字员工:Skill 决策,CLI 固定事务边界,Agent 本体运行在哪个 Managed Agent Platform 上是可替换的。",
5
5
  "keywords": [
6
6
  "dingtalk",
7
7
  "agent",
@@ -17,12 +17,12 @@
17
17
  "files": [
18
18
  "dist/bin",
19
19
  "dist/src",
20
- "skills/core/dingtalk-basic-behavior",
21
- "skills/platforms/multica-dingtalk/dingtalk-agent-boot-multica",
22
- "skills/core/dingtalk-agent-compose",
23
- "skills/platforms/multica-dingtalk/dingtalk-agent-deploy-multica",
24
- "skills/core/dingtalk-agent-eval",
25
- "skills/platforms/multica-dingtalk/multica-external",
20
+ "skills/core/dta-basic-behavior",
21
+ "skills/core/dta-agent-compose",
22
+ "skills/core/dta-people-group-memory",
23
+ "skills/platforms/multica-dingtalk/dta-deploy-multica",
24
+ "skills/core/dta-agent-eval",
25
+ "skills/platforms/multica-dingtalk/dta-ops-multica",
26
26
  "skills/platforms/multica-dingtalk/PLATFORM.md",
27
27
  "skills/platforms/deap/PLATFORM.md",
28
28
  "skills/README.md",
@@ -39,8 +39,12 @@
39
39
  "evals/baselines/2026-07-17/personal-event-live-readiness-summary.json",
40
40
  "evals/baselines/2026-07-17/agent-enhance-opencode-dogfood-summary.json",
41
41
  "lab",
42
+ "docs/AGENT-IN-PRODUCTION.md",
43
+ "docs/PLATFORM-GUARDRAILS.md",
44
+ "docs/ARCHITECTURE.md",
42
45
  "docs/INSTALLATION.md",
43
- "docs/SECOND-AGENT-ACCEPTANCE.md",
46
+ "docs/PRIOR-ART.md",
47
+ "docs/SELF-TEST.md",
44
48
  "README.md",
45
49
  "README.en.md",
46
50
  "CHANGELOG.md"
@@ -57,8 +61,11 @@
57
61
  "eval:behavior": "npm run build && node evals/run-shadow-evals.mjs",
58
62
  "eval:opencode": "npm run build && node dist/bin/dingtalk-agent.js lab eval --engine opencode --workspace lab/robot-eval/workspace --suite lab/robot-eval/suite.json --lanes stateless --execute --yes --json",
59
63
  "prepack": "npm run build",
60
- "release:check": "node scripts/check-skill-versions.mjs && node scripts/release-readiness.mjs --json",
61
- "check:skill-versions": "node scripts/check-skill-versions.mjs"
64
+ "release:check": "npm run build && node scripts/check-skill-versions.mjs && node scripts/check-docs.mjs && node scripts/check-schedule.mjs && node evals/run-contract-evals.mjs --full && node scripts/release-readiness.mjs --json",
65
+ "check:skill-versions": "node scripts/check-skill-versions.mjs",
66
+ "check:docs": "node scripts/check-docs.mjs",
67
+ "check:schedule": "node scripts/check-schedule.mjs",
68
+ "eval:contract:full": "npm run build && node evals/run-contract-evals.mjs --full"
62
69
  },
63
70
  "devDependencies": {
64
71
  "@types/node": "^18.19.0",
package/skills/README.md CHANGED
@@ -4,20 +4,22 @@
4
4
 
5
5
  ```text
6
6
  skills/
7
- ├── core/ 所有钉钉数字员工通用,默认套装随 setup / skill install 安装
8
- │ ├── dingtalk-basic-behavior/ 基础行为协议(响应资格、追问、确认、沉默、完成标准)
9
- │ ├── dingtalk-agent-compose/ 创建/装配 Agent 的方法(含平台选择与发布链细则)
10
- └── dingtalk-agent-eval/ 评测方法:场景分类、多证据断言、晋级门禁
11
- └── platforms/ 按 Managed Agent Platform 分组,只在 `dta agent-platform use <name>` 时装填
7
+ ├── core/ 所有钉钉数字员工通用,默认套装随 setup / skill install 安装
8
+ │ ├── dta-basic-behavior/ 基础行为协议(响应资格、追问、确认、沉默、完成标准)
9
+ │ ├── dta-agent-compose/ 创建/装配 Agent 的方法(含平台选择与发布链细则)
10
+ ├── dta-agent-eval/ 评测方法:场景分类、多证据断言、晋级门禁
11
+ └── dta-people-group-memory/ 人/会话双实体记忆;绑定存储前完全惰性
12
+ └── platforms/ 按 Managed Agent Platform 分组,只在 `dta agent-platform use <name>` 时装填
12
13
  ├── multica-dingtalk/ 钉钉 Multica 托管平台
13
- │ ├── dingtalk-agent-deploy-multica/ 经 dta 稳定 CLI 的受控部署、晋级与观测
14
- ├── dingtalk-agent-boot-multica/ 部署产物在 Multica Host 内的启动协议
15
- │ └── multica-external/ 平台运维执行体(纯 HTTPS,供给/绑定/观测/调度)
14
+ │ ├── dta-deploy-multica/ 经 dta 稳定 CLI 的受控部署、晋级与观测
15
+ └── dta-ops-multica/ 平台运维执行体(纯 HTTPS,供给/绑定/观测/调度)
16
16
  └── deap/ 敬请期待
17
17
  ```
18
18
 
19
19
  规则:
20
20
 
21
+ - **命名文法:核心 `dta-<domain>`,平台 `dta-<role>-<platform>`。** 一方 Skill 一律以 `dta-` 开头——`~/.agents/skills/<name>/` 是三个 Host 共享的扁平命名空间,不归本仓库所有,前缀是唯一能声明归属、避免与第三方包撞名的东西。平台 Skill 的 `<role>` 必须等于 `src/agent-platform.ts` 注册表里该条目的 role(`deploy` / `ops`),让文件系统和注册表不会各说各话。
21
22
  - Skill 名字全局唯一,目录 basename 必须等于 frontmatter `name`;代码中一律通过 `src/skill-manager.ts` 的 `bundledSkillPath()` 解析路径,不要硬编码目录层级。
23
+ - 改名是**破坏性变更**:旧名字不会从用户机器上消失。任何重命名都必须同时在 `src/skill-manager.ts` 的 `LEGACY_SKILL_RENAMES` 登记一条,让 `dta doctor` 能报残留、`dta skill uninstall <旧名> --legacy` 能清理。
22
24
  - 新平台 = `skills/platforms/<platform>/` 一个目录 + `src/agent-platform.ts` 注册表一条记录(status、skills、commands)。平台相关方法学只放平台包,不进 core、不进 CLI。
23
25
  - core 变更走 `npm run eval:contract` 的确定性合同;平台包变更至少更新对应平台的 readiness/发布链细则并保持与注册表一致。