@xdxer/dingtalk-agent 0.1.1 → 0.1.4-beta.0
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/LICENSE +21 -0
- package/README.md +247 -76
- package/dist/bin/dingtalk-agent.js +763 -0
- package/dist/bin/dingtalk-agent.js.map +1 -0
- package/dist/src/actions.js +562 -0
- package/dist/src/actions.js.map +1 -0
- package/dist/src/boot.js +70 -0
- package/dist/src/boot.js.map +1 -0
- package/dist/src/bootstrap.js +144 -0
- package/dist/src/bootstrap.js.map +1 -0
- package/dist/src/config.js +86 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/doctor.js +166 -0
- package/dist/src/doctor.js.map +1 -0
- package/dist/src/driver.js +45 -0
- package/dist/src/driver.js.map +1 -0
- package/{src → dist/src}/duty.js +42 -44
- package/dist/src/duty.js.map +1 -0
- package/dist/src/dws.js +270 -0
- package/dist/src/dws.js.map +1 -0
- package/dist/src/events.js +233 -0
- package/dist/src/events.js.map +1 -0
- package/dist/src/fields.js +132 -0
- package/dist/src/fields.js.map +1 -0
- package/dist/src/init.js +41 -0
- package/dist/src/init.js.map +1 -0
- package/dist/src/kb.js +240 -0
- package/dist/src/kb.js.map +1 -0
- package/dist/src/package-root.js +17 -0
- package/dist/src/package-root.js.map +1 -0
- package/dist/src/runs.js +79 -0
- package/dist/src/runs.js.map +1 -0
- package/dist/src/sessions.js +668 -0
- package/dist/src/sessions.js.map +1 -0
- package/dist/src/setup.js +101 -0
- package/dist/src/setup.js.map +1 -0
- package/dist/src/skill-manager.js +288 -0
- package/dist/src/skill-manager.js.map +1 -0
- package/dist/src/skills.js +200 -0
- package/dist/src/skills.js.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/waits.js +945 -0
- package/dist/src/waits.js.map +1 -0
- package/dist/src/workspace.js +173 -0
- package/dist/src/workspace.js.map +1 -0
- package/docs/ARCHITECTURE.md +217 -0
- package/docs/INSTALLATION.md +135 -0
- package/docs/MINIMAL-WORKSPACE-V1.md +172 -0
- package/docs/OPEN-SOURCE-REFERENCES.md +107 -0
- package/docs/SELF-TEST.md +252 -0
- package/docs/architecture/dingtalk-agent-blueprint.png +0 -0
- package/docs/architecture/dingtalk-agent-blueprint.svg +144 -0
- package/docs/architecture/durable-async-agent-runtime.png +0 -0
- package/docs/architecture/durable-async-agent-runtime.svg +234 -0
- package/docs//345/206/205/347/275/221/345/256/236/347/233/270.md +77 -0
- package/evals/baselines/2026-07-14/behavior-summary.json +28 -0
- package/evals/baselines/2026-07-14/contract-summary.json +18 -0
- package/evals/baselines/2026-07-14/live-canary-summary.json +25 -0
- package/evals/baselines/2026-07-15/dingtalk-basic-behavior-0.3.0/SKILL.md +72 -0
- package/evals/baselines/2026-07-15/dingtalk-basic-behavior-0.3.0/references/action-contract.md +31 -0
- package/evals/baselines/2026-07-15/dingtalk-basic-behavior-0.3.0/references/event-to-behavior.md +22 -0
- package/evals/baselines/2026-07-15/dingtalk-basic-behavior-0.3.0/references/memory-and-evolution.md +25 -0
- package/evals/baselines/2026-07-15/dingtalk-basic-behavior-0.3.0/references/runtime-modes.md +34 -0
- package/evals/baselines/2026-07-15/task-lifecycle-summary.json +50 -0
- package/evals/evals.json +316 -0
- package/evals/fixtures/dm-ambiguous-send.json +4 -0
- package/evals/fixtures/dm-blocked.json +4 -0
- package/evals/fixtures/dm-clear.json +4 -0
- package/evals/fixtures/dm-discussion.json +4 -0
- package/evals/fixtures/dm-doc-write-no-tool.json +4 -0
- package/evals/fixtures/dm-long-task-ack.json +4 -0
- package/evals/fixtures/dm-nonblocking-gap.json +4 -0
- package/evals/fixtures/dm-structured-task.json +4 -0
- package/evals/fixtures/group.json +10 -0
- package/evals/fixtures/mentioned.json +3 -0
- package/evals/run-contract-evals.mjs +1106 -0
- package/evals/run-shadow-evals.mjs +267 -0
- package/evals/runners/README.md +66 -0
- package/evals/runners/claude-shadow.mjs +533 -0
- package/evals/schemas/action-request.schema.json +77 -0
- package/evals/shadow-evals.json +133 -0
- package/package.json +28 -6
- package/skills/AGENTS.md +21 -3
- package/skills/dingtalk-basic-behavior/SKILL.md +86 -0
- package/skills/dingtalk-basic-behavior/assets/task-checkpoint.md +37 -0
- package/skills/dingtalk-basic-behavior/references/action-contract.md +31 -0
- package/skills/dingtalk-basic-behavior/references/event-to-behavior.md +24 -0
- package/skills/dingtalk-basic-behavior/references/memory-and-evolution.md +27 -0
- package/skills/dingtalk-basic-behavior/references/runtime-modes.md +34 -0
- package/skills/dingtalk-basic-behavior/references/task-lifecycle.md +108 -0
- package/skills//345/237/272/347/241/200/350/241/214/344/270/272.md +44 -0
- package/skills//345/277/203/350/267/263.md +11 -0
- package/skills//346/266/210/346/201/257.md +14 -14
- package/skills//350/257/204/346/265/213.md +14 -1
- package/skills//351/222/211/351/222/211.md +3 -2
- package/templates/behaviors/basic.json +68 -0
- package/templates/fields/default/field.json +25 -0
- package/bin/dingtalk-agent.js +0 -289
- package/src/boot.js +0 -65
- package/src/config.js +0 -42
- package/src/dws.js +0 -192
- package/src/init.js +0 -84
- package/src/kb.js +0 -221
- package/src/runs.js +0 -77
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waits.js","sourceRoot":"","sources":["../../src/waits.ts"],"names":[],"mappings":"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","sourcesContent":["// 单链 Durable Wait(TypeScript source)。\n//\n// v1 只解决一件事:ask 之后,下一条来自同一 Field/tenant/conversation/actor\n// 的 DM 或直接 @,恢复原 Session 并创建新 Run。这里不实现通用 workflow/stack。\n\nimport {\n existsSync, linkSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync,\n writeFileSync,\n} from 'node:fs'\nimport { dirname, resolve, join } from 'node:path'\nimport { hostname } from 'node:os'\nimport { randomUUID } from 'node:crypto'\nimport { digest, stableStringify } from './events.js'\n\nconst OPEN_CHAIN = new Set([\n 'arming', 'active', 'uncertain', 'claimed', 'cancel-pending',\n])\nconst RESUMABLE = new Set(['active', 'uncertain'])\nconst DEFAULT_TTL_MS = 7 * 24 * 60 * 60 * 1000\n\nexport function armWait(root, cfg, input) {\n const scope = scopeFromTarget(input.fieldId, input.event, input.target)\n if (!scope) {\n throw new Error('ask 无法建立 Wait:必须有 tenant、conversation、actor,且事件是 DM 或直接 @')\n }\n const rootPath = waitRoot(root, cfg)\n const scopeHash = digest(stableStringify(scope))\n const path = join(rootPath, `${scopeHash}.json`)\n const waitId = `wait_${digest(`${input.sessionId}\\0${input.actionId}`).slice(0, 20)}`\n const history = join(rootPath, 'history', `${waitId}.json`)\n mkdirSync(rootPath, { recursive: true })\n // 旧 ask 的 Receipt 可能在同一 scope 已进入下一轮 Wait 后重放;历史记录存在时\n // 只返回原 Wait,不能用旧 Receipt 覆盖当前正在等待的新问题。\n if (existsSync(history)) {\n const recorded = readJson(history)\n assertScope(recorded, scope, scopeHash)\n if (recorded.id === waitId && recorded.actionId === input.actionId &&\n recorded.sessionId === input.sessionId) return recorded\n }\n return withLock(path, () => {\n let existing = existsSync(path) ? readJson(path) : null\n if (existing) {\n assertScope(existing, scope, scopeHash)\n existing = repairFromReceipt(root, cfg, path, existing)\n }\n if (existing?.id === waitId && existing.actionId === input.actionId) return existing\n const ownedClaim = existing?.status === 'claimed' &&\n existing.sessionId === input.sessionId &&\n existing.claim?.runId === input.sourceRunId\n if (existing && OPEN_CHAIN.has(existing.status) && !expired(existing) &&\n !ownedClaim) {\n throw new Error(\n `同一人员/会话已有未完成 Wait ${existing.id}(Session ${existing.sessionId});` +\n '单链 v1 拒绝并行追问')\n }\n if (ownedClaim) {\n persistHistory(path, {\n ...existing, status: 'continued', continuedAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n })\n }\n const now = new Date().toISOString()\n const ttl = positiveNumber(cfg.runtime?.waitTtlMs, DEFAULT_TTL_MS)\n const record = {\n $schema: 'dingtalk-agent/wait@1',\n id: waitId,\n scopeHash,\n scope,\n fieldId: input.fieldId,\n sessionId: input.sessionId,\n sessionPath: resolve(input.sessionPath),\n sourceRunId: input.sourceRunId,\n actionId: input.actionId,\n questionText: String(input.questionText || ''),\n status: 'arming',\n version: Number(existing?.version || 0) + 1,\n createdAt: now,\n updatedAt: now,\n expiresAt: new Date(Date.now() + ttl).toISOString(),\n delivery: null,\n claim: null,\n }\n persistWait(path, record)\n return record\n })\n}\n\n/** Receipt 是真值;重放 Receipt 也能幂等补齐 active/uncertain Wait。 */\nexport function reconcileWaitFromReceipt(root, cfg, wait, receipt) {\n if (!wait) return null\n if (wait.actionId !== receipt.actionId) {\n throw new Error(`Wait/Receipt actionId 不一致: ${wait.actionId}/${receipt.actionId}`)\n }\n if (wait.lastAppliedReceiptActionId === receipt.actionId) return wait\n const path = join(waitRoot(root, cfg), `${wait.scopeHash}.json`)\n return withLock(path, () => {\n if (!existsSync(path)) throw new Error(`Wait 索引丢失: ${wait.id}`)\n const current = readJson(path)\n if (current.id === wait.id && current.actionId === receipt.actionId) {\n if (current.lastAppliedReceiptActionId === receipt.actionId) return current\n const next = applyReceipt(current, receipt)\n persistWait(path, next)\n return next\n }\n // 该链可能已经进入下一轮 Wait;旧 Receipt 只补自己的历史,不得覆盖 scope head。\n const history = join(waitRoot(root, cfg), 'history', `${wait.id}.json`)\n if (!existsSync(history)) {\n throw new Error(`Wait/Receipt 身份冲突: wait=${current.id}, action=${receipt.actionId}`)\n }\n const recorded = readJson(history)\n if (recorded.id !== wait.id || recorded.actionId !== receipt.actionId) {\n throw new Error(`Wait 历史与 Receipt 身份冲突: wait=${wait.id}, action=${receipt.actionId}`)\n }\n if (recorded.lastAppliedReceiptActionId === receipt.actionId) return recorded\n const next = applyReceipt(recorded, receipt)\n persistHistory(path, next)\n return next\n })\n}\n\n/** DWS 已返回可查询结果后立即开放 Wait;平台回读可以随后完成。 */\nexport function markWaitTransportAccepted(root, cfg, wait, result) {\n if (!wait) return null\n const path = join(waitRoot(root, cfg), `${wait.scopeHash}.json`)\n return withLock(path, () => {\n if (!existsSync(path)) throw new Error(`Wait 索引丢失: ${wait.id}`)\n const current = readJson(path)\n if (current.id === wait.id) {\n const next = applyTransportResult(current, result)\n persistWait(path, next)\n return next\n }\n const history = join(waitRoot(root, cfg), 'history', `${wait.id}.json`)\n if (!existsSync(history)) throw new Error(`Wait 已被其他链替换: ${wait.id}`)\n const recorded = readJson(history)\n if (recorded.id !== wait.id || recorded.actionId !== wait.actionId) {\n throw new Error(`Wait 历史与 transport-result 身份冲突: ${wait.id}`)\n }\n const next = applyTransportResult(recorded, result)\n persistHistory(path, next)\n return next\n })\n}\n\n/** resumed Run 给出最终 reply/silence 后,释放单链 scope。 */\nexport function completeWaitFromReceipt(root, cfg, resume, receipt) {\n if (resume?.mode !== 'resume' || !resume.waitId) return null\n const rootPath = waitRoot(root, cfg)\n const historyPath = join(rootPath, 'history', `${resume.waitId}.json`)\n let recorded = existsSync(historyPath) ? readJson(historyPath) : null\n let scopeHash = recorded?.scopeHash || resume.waitScopeHash || ''\n if (!scopeHash && existsSync(rootPath)) {\n const matches = readdirSync(rootPath)\n .filter((name) => name.endsWith('.json'))\n .map((name) => readJson(join(rootPath, name)))\n .filter((candidate) => candidate.id === resume.waitId)\n if (matches.length === 1) {\n recorded = matches[0]\n scopeHash = recorded.scopeHash\n }\n }\n if (!scopeHash) throw new Error(`Wait 历史丢失且无法从 scope head 修复: ${resume.waitId}`)\n const path = join(rootPath, `${scopeHash}.json`)\n return withLock(path, () => {\n if (!recorded) {\n const current = existsSync(path) ? readJson(path) : null\n if (!current || current.id !== resume.waitId) {\n throw new Error(`Wait 历史丢失且 scope head 不匹配: ${resume.waitId}`)\n }\n recorded = current\n persistHistory(path, recorded)\n }\n const now = new Date().toISOString()\n const current = existsSync(path) ? readJson(path) : null\n if (current?.id === recorded.id) {\n if (current.status === 'cancelled') {\n persistHistory(path, current)\n return current\n }\n const next = {\n ...current,\n status: current.status === 'cancel-pending' ? 'cancel-pending' : 'completed',\n updatedAt: now, completedAt: now,\n completedByReceiptActionId: receipt.actionId,\n }\n persistWait(path, next)\n return next\n }\n const next = {\n ...recorded, status: recorded.status === 'cancelled' ? 'cancelled' : 'completed',\n updatedAt: now, completedAt: now, completedByReceiptActionId: receipt.actionId,\n }\n persistHistory(path, next)\n return next\n })\n}\n\n/**\n * 显式 /stop、/cancel 是宿主控制面:不依赖当前 Field/Behavior/Skill。\n * 先写 cancel-pending,再在线性化锁内提升 Session generation,最后写 cancelled。\n */\nexport function cancelWaitForEvent(root, cfg, event) {\n if (!isCancelCommand(event.message?.text)) return null\n const eventScope = scopeWithoutField(event)\n if (!eventScope) return null\n const rootPath = waitRoot(root, cfg)\n const replay = readEventBinding(rootPath, event.id)\n if (replay) {\n assertEventBinding(replay, event, 'cancel', eventScope)\n if (replay.outcome === 'no-match') return null\n if (replay.outcome === 'ambiguous') {\n throw new Error(`取消命中多个 Wait,已固化为 ambiguous: ${(replay.candidates || []).join(', ')}`)\n }\n return cancelBoundWait(root, cfg, event, replay)\n }\n if (!existsSync(rootPath)) {\n createNoMatchBinding(rootPath, event, 'cancel', eventScope)\n return null\n }\n const candidates: Array<{ path: string; record: Record<string, any> }> = []\n for (const name of readdirSync(rootPath)) {\n if (!name.endsWith('.json')) continue\n const path = join(rootPath, name)\n const record = readJson(path)\n const sameCancel = record.claim?.eventId === event.id &&\n record.claim?.cancelRequested === true\n if (sameEventScope(record.scope, eventScope) &&\n (OPEN_CHAIN.has(record.status) || sameCancel ||\n (record.status === 'cancelled' && record.claim?.eventId === event.id))) {\n candidates.push({ path, record })\n }\n }\n if (candidates.length > 1) {\n createNoMatchBinding(rootPath, event, 'cancel', eventScope, {\n outcome: 'ambiguous', candidates: candidates.map((x) => x.record.id).sort(),\n })\n throw new Error(`取消命中多个 Wait,拒绝猜测: ${candidates.map((x) => x.record.id).join(', ')}`)\n }\n if (!candidates.length) {\n createNoMatchBinding(rootPath, event, 'cancel', eventScope)\n return null\n }\n const { path } = candidates[0]\n const bound = withLock(path, () => {\n let current = readJson(path)\n if (!sameEventScope(current.scope, eventScope)) {\n throw new Error(`取消 Wait 作用域漂移: ${current.id}`)\n }\n current = repairFromReceipt(root, cfg, path, current)\n if (current.status === 'cancelled' && current.claim?.eventId === event.id) {\n return createEventBinding(rootPath, event, 'cancel', current)\n }\n if (!OPEN_CHAIN.has(current.status)) {\n createNoMatchBinding(rootPath, event, 'cancel', eventScope)\n return null\n }\n // 先把 head 置为 pending,再写 ledger。两者之间即使 SIGKILL,重放也会从\n // pending 的 eventId 恢复;Action 无法趁 binding→effect-lock 窗口建立 W2。\n const now = new Date().toISOString()\n const sameCancel = current.claim?.eventId === event.id &&\n current.claim?.cancelRequested === true\n ensureClaimBinding(rootPath, current)\n const pending = {\n ...current,\n status: 'cancel-pending',\n updatedAt: now,\n previousClaim: sameCancel ? current.previousClaim || null : current.claim || null,\n claim: {\n eventId: event.id, eventKind: event.kind, claimedAt: now,\n runId: '', cancelRequested: true,\n },\n }\n persistWait(path, pending)\n const binding = createEventBinding(rootPath, event, 'cancel', pending)\n return binding\n })\n return bound ? cancelBoundWait(root, cfg, event, bound) : null\n}\n\n/** Action 与 cancel 共用这一把锁;先拿到锁的一方定义副作用先后。 */\nexport function acquireSessionEffectLock(root, sessionPath) {\n const dir = resolve(root, '.dingtalk-agent/session-effect-locks')\n mkdirSync(dir, { recursive: true })\n return acquireLock(\n join(dir, `${digest(resolve(sessionPath))}.lock`), 30 * 60_000, 3 * 60_000)\n}\n\n/**\n * incoming Event 在创建新 Session 前调用。显式 sessionKey/correlation 由调用方优先处理。\n * claimed/cancelled + 同 eventId 可重入,覆盖 materialize 过程中崩溃后的恢复窗口。\n */\nexport function claimWait(root, cfg, fieldId, event) {\n const scope = scopeFromEvent(fieldId, event)\n if (!scope) return null\n const rootPath = waitRoot(root, cfg)\n const scopeHash = digest(stableStringify(scope))\n const path = join(rootPath, `${scopeHash}.json`)\n const replay = readEventBinding(rootPath, event.id)\n if (replay) {\n assertEventBinding(replay, event, 'claim', scope)\n if (replay.outcome === 'no-match') return null\n return claimBoundWait(root, cfg, event, replay)\n }\n return withLock(path, () => {\n if (!existsSync(path)) {\n createNoMatchBinding(rootPath, event, 'claim', scope)\n return null\n }\n let current = readJson(path)\n assertScope(current, scope, scopeHash)\n current = repairFromReceipt(root, cfg, path, current)\n if (current.status === 'claimed' && current.claim?.eventId === event.id &&\n current.claim?.cancelRequested !== true) {\n createEventBinding(rootPath, event, 'claim', current)\n return current\n }\n if (expired(current)) {\n ensureClaimBinding(rootPath, current)\n if (OPEN_CHAIN.has(current.status)) {\n const next = { ...current, status: 'expired', updatedAt: new Date().toISOString() }\n persistWait(path, next)\n }\n createNoMatchBinding(rootPath, event, 'claim', scope)\n return null\n }\n if (!RESUMABLE.has(current.status)) {\n createNoMatchBinding(rootPath, event, 'claim', scope)\n return null\n }\n const now = new Date().toISOString()\n const next = {\n ...current,\n status: 'claimed',\n updatedAt: now,\n claim: {\n eventId: event.id,\n eventKind: event.kind,\n claimedAt: now,\n runId: '',\n cancelRequested: false,\n },\n }\n persistWait(path, next)\n createEventBinding(rootPath, event, 'claim', next)\n return next\n })\n}\n\nexport function attachClaimedRun(root, cfg, wait, eventId, runId) {\n if (!wait) return null\n const path = join(waitRoot(root, cfg), `${wait.scopeHash}.json`)\n return withLock(path, () => {\n const loaded = readBoundWait(path, wait.id)\n if (!loaded || loaded.record.claim?.eventId !== eventId) {\n throw new Error(`Wait claim 身份冲突: wait=${wait.id}, event=${eventId}`)\n }\n const current = loaded.record\n if (current.claim.runId && current.claim.runId !== runId) {\n throw new Error(`Wait ${wait.id} 已绑定其他 Run: ${current.claim.runId}`)\n }\n if (current.claim.runId === runId) {\n // head 已写而 history 未写时,幂等重试必须顺手补齐历史真值。\n persistBoundWait(path, current, loaded.isHead)\n return current\n }\n const next = {\n ...current,\n updatedAt: new Date().toISOString(),\n claim: { ...current.claim, runId },\n }\n persistBoundWait(path, next, loaded.isHead)\n return next\n })\n}\n\nexport function waitRoot(root, cfg) {\n return resolve(root, cfg.runtime?.waitRoot || '.dingtalk-agent/waits')\n}\n\nexport function readWaitForEvent(root, cfg, fieldId, event) {\n const scope = scopeFromEvent(fieldId, event)\n if (!scope) return null\n const path = join(waitRoot(root, cfg), `${digest(stableStringify(scope))}.json`)\n return existsSync(path) ? readJson(path) : null\n}\n\nexport function isCancelCommand(text) {\n return /^\\/(?:stop|cancel|停止|取消)$/i.test(String(text || '').trim())\n}\n\n/** eventId 一旦绑定 Wait,重放永远解析原 Wait,不能重新扫描当前 scope head。 */\nfunction createEventBinding(rootPath, event, operation, wait) {\n const path = eventBindingPath(rootPath, event.id)\n const binding = {\n $schema: 'dingtalk-agent/wait-event-binding@1',\n eventId: event.id,\n eventKind: event.kind,\n operation,\n outcome: 'matched',\n waitId: wait.id,\n scopeHash: wait.scopeHash,\n scope: wait.scope,\n fieldId: wait.fieldId,\n sessionId: wait.sessionId,\n sessionPath: wait.sessionPath,\n sourceRunId: wait.sourceRunId,\n actionId: wait.actionId,\n boundAt: new Date().toISOString(),\n }\n if (!writeJsonCreateAtomic(path, binding)) {\n const existing = readJson(path)\n if (stableStringify(bindingIdentity(existing)) !== stableStringify(bindingIdentity(binding))) {\n throw new Error(`Event ${event.id} 已绑定其他 Wait,拒绝 ABA 重解释`)\n }\n return existing\n }\n return binding\n}\n\nfunction createNoMatchBinding(\n rootPath,\n event,\n operation,\n scope,\n options: Record<string, any> = {},\n) {\n const path = eventBindingPath(rootPath, event.id)\n const binding = {\n $schema: 'dingtalk-agent/wait-event-binding@1',\n eventId: event.id,\n eventKind: event.kind,\n operation,\n outcome: options.outcome || 'no-match',\n candidates: options.candidates || [],\n waitId: '',\n scopeHash: digest(stableStringify(scope)),\n scope,\n fieldId: '',\n sessionId: '',\n sessionPath: '',\n sourceRunId: '',\n actionId: '',\n boundAt: new Date().toISOString(),\n }\n if (!writeJsonCreateAtomic(path, binding)) {\n const existing = readJson(path)\n if (stableStringify(bindingIdentity(existing)) !== stableStringify(bindingIdentity(binding))) {\n throw new Error(`Event ${event.id} 的 Wait 路由决策已固化,拒绝重新解释`)\n }\n return existing\n }\n return binding\n}\n\nfunction readEventBinding(rootPath, eventId) {\n const path = eventBindingPath(rootPath, eventId)\n return existsSync(path) ? readJson(path) : null\n}\n\nfunction eventBindingPath(rootPath, eventId) {\n return join(rootPath, 'events', `${digest(eventId)}.json`)\n}\n\nfunction bindingIdentity(value) {\n return {\n eventId: value.eventId,\n eventKind: value.eventKind,\n operation: value.operation,\n outcome: value.outcome,\n candidates: value.candidates || [],\n waitId: value.waitId,\n scopeHash: value.scopeHash,\n scope: value.scope,\n fieldId: value.fieldId,\n sessionId: value.sessionId,\n sessionPath: value.sessionPath,\n sourceRunId: value.sourceRunId,\n actionId: value.actionId,\n }\n}\n\nfunction assertEventBinding(binding, event, operation, expectedScope) {\n if (binding.eventId !== event.id || binding.eventKind !== event.kind ||\n binding.operation !== operation) {\n throw new Error(`Event ${event.id} 的 Wait binding 类型冲突`)\n }\n const scopeMatches = operation === 'cancel'\n ? sameEventScope(binding.scope, expectedScope)\n : stableStringify(binding.scope) === stableStringify(expectedScope)\n if (!scopeMatches || binding.scopeHash !== digest(stableStringify(binding.scope))) {\n throw new Error(`Event ${event.id} 的 Wait binding 作用域漂移`)\n }\n}\n\nfunction assertWaitBinding(record, binding) {\n const actual = {\n waitId: record.id,\n scopeHash: record.scopeHash,\n fieldId: record.fieldId,\n sessionId: record.sessionId,\n sessionPath: record.sessionPath,\n sourceRunId: record.sourceRunId,\n actionId: record.actionId,\n }\n const expected = {\n waitId: binding.waitId,\n scopeHash: binding.scopeHash,\n fieldId: binding.fieldId,\n sessionId: binding.sessionId,\n sessionPath: binding.sessionPath,\n sourceRunId: binding.sourceRunId,\n actionId: binding.actionId,\n }\n if (stableStringify(actual) !== stableStringify(expected)) {\n throw new Error(`Wait event binding 身份漂移: ${binding.waitId}`)\n }\n}\n\nfunction cancelBoundWait(root, cfg, event, binding) {\n const path = join(waitRoot(root, cfg), `${binding.scopeHash}.json`)\n let pending = withLock(path, () => {\n const loaded = readBoundWait(path, binding.waitId)\n if (!loaded) throw new Error(`取消绑定的 Wait 不存在: ${binding.waitId}`)\n let current = loaded.record\n assertWaitBinding(current, binding)\n if (loaded.isHead) current = repairFromReceipt(root, cfg, path, current)\n if (current.status === 'cancelled' && current.claim?.eventId === event.id) return current\n if (['cancel-pending', 'cancelled'].includes(current.status) &&\n current.claim?.cancelRequested === true && current.claim?.eventId !== event.id) {\n // 两个 stop 同时到达时只让先行者提升 generation;后来者成为同 Session 的安全 no-op。\n return suppressedClaim(current, event.id)\n }\n const sameCancel = current.claim?.eventId === event.id &&\n current.claim?.cancelRequested === true\n if (!OPEN_CHAIN.has(current.status) && !sameCancel) {\n throw new Error(`取消绑定的 Wait 已进入 ${current.status}: ${binding.waitId}`)\n }\n const now = new Date().toISOString()\n ensureClaimBinding(waitRoot(root, cfg), current)\n const next = {\n ...current,\n status: 'cancel-pending',\n updatedAt: now,\n previousClaim: sameCancel ? current.previousClaim || null : current.claim || null,\n claim: {\n eventId: event.id, eventKind: event.kind, claimedAt: now,\n runId: '', cancelRequested: true,\n },\n }\n persistBoundWait(path, next, loaded.isHead)\n return next\n })\n\n if (pending.suppressed) return pending\n applyCancelFence(root, pending, event.id)\n pending = withLock(path, () => {\n const loaded = readBoundWait(path, binding.waitId)\n if (!loaded) throw new Error(`取消完成时 Wait 丢失: ${binding.waitId}`)\n const current = loaded.record\n assertWaitBinding(current, binding)\n if (current.claim?.eventId !== event.id) {\n throw new Error(`取消 Wait 身份漂移: ${binding.waitId}`)\n }\n if (current.status === 'cancelled') {\n persistBoundWait(path, current, loaded.isHead)\n return current\n }\n const next = { ...current, status: 'cancelled', updatedAt: new Date().toISOString() }\n persistBoundWait(path, next, loaded.isHead)\n return next\n })\n return pending\n}\n\nfunction claimBoundWait(root, cfg, event, binding) {\n const path = join(waitRoot(root, cfg), `${binding.scopeHash}.json`)\n return withLock(path, () => {\n const loaded = readBoundWait(path, binding.waitId)\n if (!loaded) throw new Error(`回复绑定的 Wait 不存在: ${binding.waitId}`)\n let current = loaded.record\n assertWaitBinding(current, binding)\n if (loaded.isHead) current = repairFromReceipt(root, cfg, path, current)\n if (current.status === 'claimed' && current.claim?.eventId === event.id) {\n if (!loaded.isHead) throw new Error(`已 claim 的 Wait 不再是 scope head: ${binding.waitId}`)\n return current\n }\n if (['cancel-pending', 'cancelled'].includes(current.status) &&\n current.claim?.cancelRequested === true) {\n return suppressedClaim(current, event.id)\n }\n if (!loaded.isHead || !RESUMABLE.has(current.status) || expired(current)) {\n throw new Error(`回复事件已绑定 Wait ${binding.waitId},但当前状态为 ${current.status};拒绝回退成新事项`)\n }\n const now = new Date().toISOString()\n const next = {\n ...current,\n status: 'claimed',\n updatedAt: now,\n claim: {\n eventId: event.id, eventKind: event.kind, claimedAt: now,\n runId: '', cancelRequested: false,\n },\n }\n persistWait(path, next)\n return next\n })\n}\n\nfunction suppressedClaim(record, eventId) {\n const cancelEventId = record.claim?.eventId || ''\n return {\n ...record,\n suppressed: true,\n cancelEventId,\n claim: {\n eventId,\n claimedAt: new Date().toISOString(),\n runId: '',\n cancelRequested: true,\n supersededByEventId: cancelEventId,\n },\n }\n}\n\nfunction ensureClaimBinding(rootPath, record) {\n const claim = record.claim?.cancelRequested !== true\n ? record.claim\n : record.previousClaim?.cancelRequested !== true ? record.previousClaim : null\n if (!claim?.eventId) return null\n if (!claim.eventKind) {\n throw new Error(`Wait ${record.id} 的 claim 缺少 eventKind,无法安全修复 event ledger`)\n }\n return createEventBinding(rootPath, {\n id: claim.eventId,\n kind: claim.eventKind,\n }, 'claim', record)\n}\n\nfunction readBoundWait(scopePath, waitId) {\n if (existsSync(scopePath)) {\n const current = readJson(scopePath)\n if (current.id === waitId) return { record: current, isHead: true }\n }\n const history = join(dirname(scopePath), 'history', `${waitId}.json`)\n return existsSync(history) ? { record: readJson(history), isHead: false } : null\n}\n\nfunction persistBoundWait(scopePath, record, isHead) {\n if (isHead) persistWait(scopePath, record)\n else persistHistory(scopePath, record)\n}\n\nfunction scopeFromTarget(fieldId, event, target) {\n if (!['im.message.dm', 'im.message.mentioned'].includes(event.kind)) return null\n return completeScope({\n fieldId,\n tenantId: target?.tenantId || event.tenant?.id,\n conversationId: target?.conversationId || event.conversation?.id,\n actorId: target?.senderOpenDingTalkId || event.actor?.openDingTalkId,\n })\n}\n\nfunction scopeFromEvent(fieldId, event) {\n if (!['im.message.dm', 'im.message.mentioned'].includes(event.kind)) return null\n return completeScope({\n fieldId,\n tenantId: event.tenant?.id,\n conversationId: event.conversation?.id,\n actorId: event.actor?.openDingTalkId,\n })\n}\n\nfunction scopeWithoutField(event) {\n if (!['im.message.dm', 'im.message.mentioned'].includes(event.kind)) return null\n return completeScope({\n tenantId: event.tenant?.id,\n conversationId: event.conversation?.id,\n actorId: event.actor?.openDingTalkId,\n })\n}\n\nfunction sameEventScope(scope, expected) {\n return scope?.tenantId === expected.tenantId &&\n scope?.conversationId === expected.conversationId &&\n scope?.actorId === expected.actorId\n}\n\nfunction completeScope(value) {\n const scope = Object.fromEntries(Object.entries(value).map(([k, v]) => [k, String(v || '').trim()]))\n return Object.values(scope).every(Boolean) ? scope : null\n}\n\nfunction assertScope(record, scope, scopeHash) {\n if (record.scopeHash !== scopeHash || stableStringify(record.scope) !== stableStringify(scope)) {\n throw new Error(`Wait scope hash 碰撞或内容漂移: ${scopeHash}`)\n }\n}\n\nfunction expired(record) {\n const deadline = Date.parse(record.expiresAt || '')\n return Number.isFinite(deadline) && deadline <= Date.now()\n}\n\nfunction positiveNumber(value, fallback) {\n const n = Number(value)\n return Number.isFinite(n) && n > 0 ? n : fallback\n}\n\nfunction applyReceipt(record, receipt) {\n const keepLifecycle = new Set([\n 'claimed', 'cancel-pending', 'cancelled', 'completed', 'continued', 'expired',\n ]).has(record.status)\n const transportAccepted = Boolean(record.delivery?.transportAccepted)\n return {\n ...record,\n status: keepLifecycle\n ? record.status\n : (receipt.outcome === 'uncertain' && !transportAccepted ? 'uncertain' : 'active'),\n updatedAt: new Date().toISOString(),\n lastAppliedReceiptActionId: receipt.actionId,\n delivery: {\n ...(record.delivery || {}),\n outcome: receipt.outcome,\n verified: Boolean(receipt.verified),\n verification: receipt.verification || '',\n questionMessageId: findValue(\n receipt, ['openMessageId', 'openMsgId', 'open_message_id']) ||\n record.delivery?.questionMessageId || '',\n },\n }\n}\n\nfunction applyTransportResult(record, result) {\n return {\n ...record,\n status: record.status === 'arming' || record.status === 'uncertain'\n ? 'active' : record.status,\n updatedAt: new Date().toISOString(),\n delivery: {\n ...(record.delivery || {}),\n transportAccepted: true,\n questionMessageId: findValue(result,\n ['openMessageId', 'openMsgId', 'open_message_id']) ||\n record.delivery?.questionMessageId || '',\n },\n }\n}\n\n/** 在 incoming Event 路由时修复 Receipt/transport-result 已落盘但 Wait 仍 arming 的窗口。 */\nfunction repairFromReceipt(root, cfg, path, record) {\n if (record.status !== 'arming') return record\n const actionPath = join(\n resolve(root, cfg.runtime?.eventIndexRoot || '.dingtalk-agent/event-index'),\n 'actions', record.sourceRunId, record.actionId)\n const receiptPath = join(actionPath, 'receipt.json')\n const resultPath = join(actionPath, 'transport-result.json')\n if (!existsSync(receiptPath) && !existsSync(resultPath)) return record\n\n const receipt = existsSync(receiptPath) ? readJson(receiptPath) : null\n const result = existsSync(resultPath) ? readJson(resultPath) : null\n const next = {\n ...record,\n status: (result || receipt?.outcome !== 'uncertain') ? 'active' : 'uncertain',\n updatedAt: new Date().toISOString(),\n lastAppliedReceiptActionId: receipt?.actionId || record.lastAppliedReceiptActionId,\n delivery: {\n ...(record.delivery || {}),\n transportAccepted: Boolean(result),\n outcome: receipt?.outcome || 'transport-accepted',\n verified: Boolean(receipt?.verified),\n verification: receipt?.verification || '',\n questionMessageId: findValue(receipt,\n ['openMessageId', 'openMsgId', 'open_message_id']) ||\n findValue(result, ['openMessageId', 'openMsgId', 'open_message_id']) ||\n record.delivery?.questionMessageId || '',\n },\n }\n persistWait(path, next)\n return next\n}\n\nfunction applyCancelFence(root, wait, eventId) {\n const releaseEffect = acquireSessionEffectLock(root, wait.sessionPath)\n try {\n const lockRoot = resolve(root, '.dingtalk-agent/session-locks')\n mkdirSync(lockRoot, { recursive: true })\n const releaseState = acquireLock(\n join(lockRoot, `${digest(resolve(wait.sessionPath))}.lock`), 2 * 60_000)\n try {\n const sessionPath = join(resolve(wait.sessionPath), 'session.json')\n if (!existsSync(sessionPath)) throw new Error(`取消目标 Session 不存在: ${wait.sessionId}`)\n const session = readJson(sessionPath)\n if (session.id !== wait.sessionId || session.fieldId !== wait.fieldId) {\n throw new Error(`取消目标 Session 身份不一致: ${wait.sessionId}`)\n }\n if (session.lastCancelEventId === eventId) return\n const generation = validGeneration(session.generation)\n persist(sessionPath, {\n ...session,\n generation: generation + 1,\n lastCancelEventId: eventId,\n cancelledAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n })\n } finally {\n releaseState()\n }\n } finally {\n releaseEffect()\n }\n}\n\nfunction validGeneration(value) {\n const n = Number(value ?? 1)\n if (!Number.isInteger(n) || n < 1) throw new Error('Session generation 非法,拒绝取消')\n return n\n}\n\nfunction persist(path, value) {\n mkdirSync(dirname(path), { recursive: true })\n const temp = `${path}.${process.pid}.${Date.now()}.${randomUUID()}.tmp`\n writeFileSync(temp, JSON.stringify(value, null, 2) + '\\n', { flag: 'wx' })\n renameSync(temp, path)\n}\n\nfunction writeJsonCreateAtomic(path, value) {\n mkdirSync(dirname(path), { recursive: true })\n const temp = `${path}.${process.pid}.${Date.now()}.${randomUUID()}.tmp`\n writeFileSync(temp, JSON.stringify(value, null, 2) + '\\n', { flag: 'wx' })\n try {\n linkSync(temp, path)\n return true\n } catch (e) {\n if (e.code === 'EEXIST') return false\n throw e\n } finally {\n rmSync(temp, { force: true })\n }\n}\n\nfunction persistWait(scopePath, record) {\n persist(scopePath, record)\n persistHistory(scopePath, record)\n}\n\nfunction persistHistory(scopePath, record) {\n persist(join(dirname(scopePath), 'history', `${record.id}.json`), record)\n mirror(record)\n}\n\nfunction mirror(record) {\n try {\n const dir = join(record.sessionPath, 'waits')\n mkdirSync(dir, { recursive: true })\n persist(join(dir, `${record.id}.json`), record)\n } catch (e) {\n console.error(` ⚠️ Wait 审计镜像写入失败(waitRoot 权威真值已保留): ${e.message}`)\n }\n}\n\nfunction readJson(path) {\n return JSON.parse(readFileSync(path, 'utf8'))\n}\n\nconst LOCK_HOST = hostname()\nconst sleep = (ms) => Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms)\n\nfunction withLock(path, fn) {\n const lockPath = `${path}.lock`\n mkdirSync(dirname(path), { recursive: true })\n const release = acquireLock(lockPath)\n try { return fn() } finally { release() }\n}\n\nfunction acquireLock(path, staleAfterMs = 60_000, waitMs = 5_000) {\n const token = randomUUID()\n const deadline = Date.now() + waitMs\n while (true) {\n try {\n mkdirSync(path)\n try {\n persist(join(path, 'owner.json'), {\n token, pid: process.pid, host: LOCK_HOST, acquiredAt: new Date().toISOString(),\n })\n } catch (e) {\n rmSync(path, { recursive: true, force: true })\n throw e\n }\n return () => {\n try {\n const owner = readJson(join(path, 'owner.json'))\n if (owner.token === token) rmSync(path, { recursive: true, force: true })\n } catch {}\n }\n } catch (e) {\n if (e.code !== 'EEXIST') throw e\n if (staleLock(path, staleAfterMs)) {\n const tomb = `${path}.stale.${process.pid}.${randomUUID()}`\n try {\n renameSync(path, tomb)\n rmSync(tomb, { recursive: true, force: true })\n continue\n } catch (moveError) {\n if (moveError.code === 'ENOENT' || moveError.code === 'EEXIST') continue\n throw moveError\n }\n }\n if (Date.now() >= deadline) throw new Error(`Wait 正在被其他事件更新: ${path}`)\n sleep(50)\n }\n }\n}\n\nfunction staleLock(path, staleAfterMs) {\n let age\n try { age = Date.now() - statSync(path).mtimeMs } catch { return true }\n let owner\n try { owner = readJson(join(path, 'owner.json')) } catch {}\n if (!owner) return age >= 2_000\n if (owner.host === LOCK_HOST && Number.isInteger(Number(owner.pid))) {\n try { process.kill(Number(owner.pid), 0); return false }\n catch (e) { if (e.code === 'ESRCH') return true }\n }\n return age >= staleAfterMs\n}\n\nfunction findValue(value, keys) {\n if (!value || typeof value !== 'object') return ''\n for (const key of keys) if (value[key]) return String(value[key])\n for (const child of Object.values(value)) {\n const found = findValue(child, keys)\n if (found) return found\n }\n return ''\n}\n"]}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
// Agent Workspace:一个物理目录对应一个稳定 Context/Field。
|
|
2
|
+
// 人和模型读取 Markdown;机器控制状态仍留在宿主私有 JSON 中。
|
|
3
|
+
import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync, } from 'node:fs';
|
|
4
|
+
import { basename, dirname, join, relative, resolve } from 'node:path';
|
|
5
|
+
import { digest } from './events.js';
|
|
6
|
+
import * as dws from './dws.js';
|
|
7
|
+
export const WORKSPACE_FILE = '.dingtalk-agent/workspace.json';
|
|
8
|
+
export function workspacePath(root) {
|
|
9
|
+
return join(root, WORKSPACE_FILE);
|
|
10
|
+
}
|
|
11
|
+
export function ensureWorkspace(root, options = {}) {
|
|
12
|
+
const path = workspacePath(root);
|
|
13
|
+
if (existsSync(path)) {
|
|
14
|
+
const current = loadWorkspace(root);
|
|
15
|
+
if (options.contextId && options.contextId !== current.contextId) {
|
|
16
|
+
throw new Error(`当前目录已绑定 contextId=${current.contextId};一个物理 Workspace 不能重新绑定为 ${options.contextId}`);
|
|
17
|
+
}
|
|
18
|
+
return current;
|
|
19
|
+
}
|
|
20
|
+
const contextId = clean(options.contextId || basename(resolve(root)) || 'default');
|
|
21
|
+
const id = clean(options.id || contextId);
|
|
22
|
+
const spec = {
|
|
23
|
+
$schema: 'dingtalk-agent/workspace@1',
|
|
24
|
+
id,
|
|
25
|
+
contextId,
|
|
26
|
+
fieldId: 'default',
|
|
27
|
+
dws: { profile: '', expectedUserId: '' },
|
|
28
|
+
// 用 Skill name 声明,不把 Workspace 绑死到某个物理安装目录。
|
|
29
|
+
// Resolver 依次查 Workspace override、全局安装和 npm 内置版本。
|
|
30
|
+
skills: ['dingtalk-basic-behavior'],
|
|
31
|
+
mounts: {
|
|
32
|
+
profile: 'local-md:WORKSPACE.md',
|
|
33
|
+
memory: options.memory || 'local-md:MEMORY.md',
|
|
34
|
+
knowledge: options.knowledge || 'local-md:knowledge/INDEX.md',
|
|
35
|
+
skills: 'local-dir:skills',
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
39
|
+
writeFileSync(path, JSON.stringify(spec, null, 2) + '\n', { flag: 'wx' });
|
|
40
|
+
writeDefaultMarkdown(root, spec);
|
|
41
|
+
for (const dir of ['.dingtalk-agent/cache', '.dingtalk-agent/pending']) {
|
|
42
|
+
mkdirSync(join(root, dir), { recursive: true });
|
|
43
|
+
}
|
|
44
|
+
return spec;
|
|
45
|
+
}
|
|
46
|
+
export function loadWorkspace(root) {
|
|
47
|
+
const path = workspacePath(root);
|
|
48
|
+
if (!existsSync(path)) {
|
|
49
|
+
throw new Error('缺少 .dingtalk-agent/workspace.json;只有 Prepared Run runtime 才需要 `dingtalk-agent init`。' +
|
|
50
|
+
'普通 Agent Session 请使用全局 Skill,按需运行 `dingtalk-agent bootstrap`。');
|
|
51
|
+
}
|
|
52
|
+
let value;
|
|
53
|
+
try {
|
|
54
|
+
value = JSON.parse(readFileSync(path, 'utf8'));
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
throw new Error(`Workspace manifest 不是合法 JSON: ${error.message}`);
|
|
58
|
+
}
|
|
59
|
+
return validateWorkspace(value);
|
|
60
|
+
}
|
|
61
|
+
export function resolveContextId(spec, supplied = '') {
|
|
62
|
+
const contextId = clean(supplied || spec.contextId);
|
|
63
|
+
if (contextId !== spec.contextId) {
|
|
64
|
+
throw new Error(`contextId=${contextId} 不属于当前 Workspace(期望 ${spec.contextId});请由上游选择正确工作目录`);
|
|
65
|
+
}
|
|
66
|
+
return contextId;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Provider 只负责把语义内容冻结成本地 Markdown;锁、Wait、去重和 Receipt 不走这里。
|
|
70
|
+
* dingtalk-doc 只读显式 node,不搜索、不创建、不覆盖。
|
|
71
|
+
*/
|
|
72
|
+
export function snapshotWorkspaceMounts(root, runPath, spec) {
|
|
73
|
+
const destination = join(runPath, 'context', 'mounts');
|
|
74
|
+
mkdirSync(destination, { recursive: true });
|
|
75
|
+
const snapshots = [];
|
|
76
|
+
for (const [slot, uri] of Object.entries(spec.mounts)) {
|
|
77
|
+
const mount = parseMount(uri);
|
|
78
|
+
if (mount.provider === 'local-dir') {
|
|
79
|
+
// skills 是逻辑槽:实际内容由 Skill resolver 从 Workspace override、
|
|
80
|
+
// 全局目录或 npm 内置版本解析并在 Session 创建时冻结。
|
|
81
|
+
if (slot !== 'skills')
|
|
82
|
+
safeLocalPath(root, mount.ref);
|
|
83
|
+
snapshots.push({
|
|
84
|
+
slot, provider: mount.provider, source: uri,
|
|
85
|
+
// P0 的目录型 mount 只有 skills;真实内容由 Session 绑定并冻结到这里。
|
|
86
|
+
snapshotPath: slot === 'skills' ? 'context/skills' : '', hash: '',
|
|
87
|
+
});
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const markdown = mount.provider === 'local-md'
|
|
91
|
+
? readFileSync(safeLocalPath(root, mount.ref), 'utf8')
|
|
92
|
+
: String(dws.readDoc(mount.ref, spec.dws.profile));
|
|
93
|
+
const path = join(destination, `${safeName(slot)}.md`);
|
|
94
|
+
writeFileSync(path, markdown.endsWith('\n') ? markdown : markdown + '\n');
|
|
95
|
+
snapshots.push({
|
|
96
|
+
slot,
|
|
97
|
+
provider: mount.provider,
|
|
98
|
+
source: uri,
|
|
99
|
+
snapshotPath: relative(runPath, path).split('\\').join('/'),
|
|
100
|
+
hash: digest(markdown),
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
writeFileSync(join(destination, 'manifest.json'), JSON.stringify({ $schema: 'dingtalk-agent/mount-snapshot@1', entries: snapshots }, null, 2) + '\n');
|
|
104
|
+
return snapshots;
|
|
105
|
+
}
|
|
106
|
+
function validateWorkspace(value) {
|
|
107
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
108
|
+
throw new Error('Workspace manifest 必须是 JSON object');
|
|
109
|
+
}
|
|
110
|
+
const input = value;
|
|
111
|
+
if (input.$schema !== 'dingtalk-agent/workspace@1') {
|
|
112
|
+
throw new Error('Workspace manifest 缺少 dingtalk-agent/workspace@1 schema');
|
|
113
|
+
}
|
|
114
|
+
for (const key of ['id', 'contextId', 'fieldId']) {
|
|
115
|
+
if (!clean(input[key]))
|
|
116
|
+
throw new Error(`Workspace manifest 缺少 ${key}`);
|
|
117
|
+
}
|
|
118
|
+
if (!Array.isArray(input.skills) || input.skills.some((item) => typeof item !== 'string')) {
|
|
119
|
+
throw new Error('Workspace skills 必须是 string[]');
|
|
120
|
+
}
|
|
121
|
+
if (!input.dws || typeof input.dws.profile !== 'string' ||
|
|
122
|
+
typeof input.dws.expectedUserId !== 'string') {
|
|
123
|
+
throw new Error('Workspace dws 必须包含 string profile / expectedUserId');
|
|
124
|
+
}
|
|
125
|
+
const requiredSlots = ['profile', 'memory', 'knowledge', 'skills'];
|
|
126
|
+
if (!input.mounts || requiredSlots.some((slot) => typeof input.mounts[slot] !== 'string')) {
|
|
127
|
+
throw new Error(`Workspace mounts 必须包含 ${requiredSlots.join(' / ')}`);
|
|
128
|
+
}
|
|
129
|
+
for (const uri of Object.values(input.mounts))
|
|
130
|
+
parseMount(String(uri));
|
|
131
|
+
return input;
|
|
132
|
+
}
|
|
133
|
+
function parseMount(uri) {
|
|
134
|
+
const separator = uri.indexOf(':');
|
|
135
|
+
const provider = uri.slice(0, separator);
|
|
136
|
+
const ref = separator >= 0 ? uri.slice(separator + 1).trim() : '';
|
|
137
|
+
if (!['local-md', 'local-dir', 'dingtalk-doc'].includes(provider) || !ref) {
|
|
138
|
+
throw new Error(`不支持的 Workspace mount: ${uri}`);
|
|
139
|
+
}
|
|
140
|
+
return { provider: provider, ref };
|
|
141
|
+
}
|
|
142
|
+
function safeLocalPath(root, ref) {
|
|
143
|
+
const rootReal = realpathSync(resolve(root));
|
|
144
|
+
const candidate = resolve(rootReal, ref);
|
|
145
|
+
if (!existsSync(candidate))
|
|
146
|
+
throw new Error(`Workspace mount 不存在: ${ref}`);
|
|
147
|
+
const actual = realpathSync(candidate);
|
|
148
|
+
const rel = relative(rootReal, actual);
|
|
149
|
+
if (rel === '..' || rel.startsWith(`..${process.platform === 'win32' ? '\\' : '/'}`)) {
|
|
150
|
+
throw new Error(`Workspace local mount 必须位于当前目录内: ${ref}`);
|
|
151
|
+
}
|
|
152
|
+
return actual;
|
|
153
|
+
}
|
|
154
|
+
function writeDefaultMarkdown(root, spec) {
|
|
155
|
+
const files = [
|
|
156
|
+
['WORKSPACE.md', `# Agent Workspace\n\n- Context ID: ${spec.contextId}\n- Workspace: ${spec.id}\n- Field: ${spec.fieldId}\n\n这里定义稳定的身份、职责、协作边界和内容挂载。\n`],
|
|
157
|
+
['MEMORY.md', '# Long-term Memory\n\n只保存经过筛选、带来源的长期记忆。当前事项放在 Session memory。\n'],
|
|
158
|
+
['knowledge/INDEX.md', '# Knowledge Index\n\n按需列出本 Workspace 可用的知识入口。\n'],
|
|
159
|
+
];
|
|
160
|
+
for (const [rel, content] of files) {
|
|
161
|
+
const path = join(root, rel);
|
|
162
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
163
|
+
if (!existsSync(path))
|
|
164
|
+
writeFileSync(path, content);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function safeName(value) {
|
|
168
|
+
return value.replace(/[^a-zA-Z0-9._-]+/g, '-');
|
|
169
|
+
}
|
|
170
|
+
function clean(value) {
|
|
171
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/workspace.ts"],"names":[],"mappings":"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","sourcesContent":["// Agent Workspace:一个物理目录对应一个稳定 Context/Field。\n// 人和模型读取 Markdown;机器控制状态仍留在宿主私有 JSON 中。\n\nimport {\n existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync,\n} from 'node:fs'\nimport { basename, dirname, join, relative, resolve } from 'node:path'\nimport { digest } from './events.js'\nimport * as dws from './dws.js'\n\nexport const WORKSPACE_FILE = '.dingtalk-agent/workspace.json'\n\nexport interface WorkspaceSpec {\n $schema: 'dingtalk-agent/workspace@1'\n id: string\n contextId: string\n fieldId: string\n dws: { profile: string; expectedUserId: string }\n skills: string[]\n mounts: Record<'profile' | 'memory' | 'knowledge' | 'skills', string>\n}\n\nexport interface WorkspaceInitOptions {\n contextId?: string\n id?: string\n memory?: string\n knowledge?: string\n}\n\nexport interface MountSnapshot {\n slot: string\n provider: 'local-md' | 'local-dir' | 'dingtalk-doc'\n source: string\n snapshotPath: string\n hash: string\n}\n\nexport function workspacePath(root: string): string {\n return join(root, WORKSPACE_FILE)\n}\n\nexport function ensureWorkspace(\n root: string,\n options: WorkspaceInitOptions = {},\n): WorkspaceSpec {\n const path = workspacePath(root)\n if (existsSync(path)) {\n const current = loadWorkspace(root)\n if (options.contextId && options.contextId !== current.contextId) {\n throw new Error(\n `当前目录已绑定 contextId=${current.contextId};一个物理 Workspace 不能重新绑定为 ${options.contextId}`,\n )\n }\n return current\n }\n\n const contextId = clean(options.contextId || basename(resolve(root)) || 'default')\n const id = clean(options.id || contextId)\n const spec: WorkspaceSpec = {\n $schema: 'dingtalk-agent/workspace@1',\n id,\n contextId,\n fieldId: 'default',\n dws: { profile: '', expectedUserId: '' },\n // 用 Skill name 声明,不把 Workspace 绑死到某个物理安装目录。\n // Resolver 依次查 Workspace override、全局安装和 npm 内置版本。\n skills: ['dingtalk-basic-behavior'],\n mounts: {\n profile: 'local-md:WORKSPACE.md',\n memory: options.memory || 'local-md:MEMORY.md',\n knowledge: options.knowledge || 'local-md:knowledge/INDEX.md',\n skills: 'local-dir:skills',\n },\n }\n\n mkdirSync(dirname(path), { recursive: true })\n writeFileSync(path, JSON.stringify(spec, null, 2) + '\\n', { flag: 'wx' })\n writeDefaultMarkdown(root, spec)\n for (const dir of ['.dingtalk-agent/cache', '.dingtalk-agent/pending']) {\n mkdirSync(join(root, dir), { recursive: true })\n }\n return spec\n}\n\nexport function loadWorkspace(root: string): WorkspaceSpec {\n const path = workspacePath(root)\n if (!existsSync(path)) {\n throw new Error(\n '缺少 .dingtalk-agent/workspace.json;只有 Prepared Run runtime 才需要 `dingtalk-agent init`。' +\n '普通 Agent Session 请使用全局 Skill,按需运行 `dingtalk-agent bootstrap`。',\n )\n }\n let value: unknown\n try { value = JSON.parse(readFileSync(path, 'utf8')) }\n catch (error) { throw new Error(`Workspace manifest 不是合法 JSON: ${error.message}`) }\n return validateWorkspace(value)\n}\n\nexport function resolveContextId(spec: WorkspaceSpec, supplied = ''): string {\n const contextId = clean(supplied || spec.contextId)\n if (contextId !== spec.contextId) {\n throw new Error(\n `contextId=${contextId} 不属于当前 Workspace(期望 ${spec.contextId});请由上游选择正确工作目录`,\n )\n }\n return contextId\n}\n\n/**\n * Provider 只负责把语义内容冻结成本地 Markdown;锁、Wait、去重和 Receipt 不走这里。\n * dingtalk-doc 只读显式 node,不搜索、不创建、不覆盖。\n */\nexport function snapshotWorkspaceMounts(\n root: string,\n runPath: string,\n spec: WorkspaceSpec,\n): MountSnapshot[] {\n const destination = join(runPath, 'context', 'mounts')\n mkdirSync(destination, { recursive: true })\n const snapshots: MountSnapshot[] = []\n\n for (const [slot, uri] of Object.entries(spec.mounts)) {\n const mount = parseMount(uri)\n if (mount.provider === 'local-dir') {\n // skills 是逻辑槽:实际内容由 Skill resolver 从 Workspace override、\n // 全局目录或 npm 内置版本解析并在 Session 创建时冻结。\n if (slot !== 'skills') safeLocalPath(root, mount.ref)\n snapshots.push({\n slot, provider: mount.provider, source: uri,\n // P0 的目录型 mount 只有 skills;真实内容由 Session 绑定并冻结到这里。\n snapshotPath: slot === 'skills' ? 'context/skills' : '', hash: '',\n })\n continue\n }\n\n const markdown = mount.provider === 'local-md'\n ? readFileSync(safeLocalPath(root, mount.ref), 'utf8')\n : String(dws.readDoc(mount.ref, spec.dws.profile))\n const path = join(destination, `${safeName(slot)}.md`)\n writeFileSync(path, markdown.endsWith('\\n') ? markdown : markdown + '\\n')\n snapshots.push({\n slot,\n provider: mount.provider,\n source: uri,\n snapshotPath: relative(runPath, path).split('\\\\').join('/'),\n hash: digest(markdown),\n })\n }\n\n writeFileSync(\n join(destination, 'manifest.json'),\n JSON.stringify({ $schema: 'dingtalk-agent/mount-snapshot@1', entries: snapshots }, null, 2) + '\\n',\n )\n return snapshots\n}\n\nfunction validateWorkspace(value: unknown): WorkspaceSpec {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error('Workspace manifest 必须是 JSON object')\n }\n const input = value as Record<string, any>\n if (input.$schema !== 'dingtalk-agent/workspace@1') {\n throw new Error('Workspace manifest 缺少 dingtalk-agent/workspace@1 schema')\n }\n for (const key of ['id', 'contextId', 'fieldId']) {\n if (!clean(input[key])) throw new Error(`Workspace manifest 缺少 ${key}`)\n }\n if (!Array.isArray(input.skills) || input.skills.some((item: unknown) => typeof item !== 'string')) {\n throw new Error('Workspace skills 必须是 string[]')\n }\n if (!input.dws || typeof input.dws.profile !== 'string' ||\n typeof input.dws.expectedUserId !== 'string') {\n throw new Error('Workspace dws 必须包含 string profile / expectedUserId')\n }\n const requiredSlots = ['profile', 'memory', 'knowledge', 'skills']\n if (!input.mounts || requiredSlots.some((slot) => typeof input.mounts[slot] !== 'string')) {\n throw new Error(`Workspace mounts 必须包含 ${requiredSlots.join(' / ')}`)\n }\n for (const uri of Object.values(input.mounts)) parseMount(String(uri))\n return input as WorkspaceSpec\n}\n\nfunction parseMount(uri: string): {\n provider: 'local-md' | 'local-dir' | 'dingtalk-doc'\n ref: string\n} {\n const separator = uri.indexOf(':')\n const provider = uri.slice(0, separator)\n const ref = separator >= 0 ? uri.slice(separator + 1).trim() : ''\n if (!['local-md', 'local-dir', 'dingtalk-doc'].includes(provider) || !ref) {\n throw new Error(`不支持的 Workspace mount: ${uri}`)\n }\n return { provider: provider as 'local-md' | 'local-dir' | 'dingtalk-doc', ref }\n}\n\nfunction safeLocalPath(root: string, ref: string): string {\n const rootReal = realpathSync(resolve(root))\n const candidate = resolve(rootReal, ref)\n if (!existsSync(candidate)) throw new Error(`Workspace mount 不存在: ${ref}`)\n const actual = realpathSync(candidate)\n const rel = relative(rootReal, actual)\n if (rel === '..' || rel.startsWith(`..${process.platform === 'win32' ? '\\\\' : '/'}`)) {\n throw new Error(`Workspace local mount 必须位于当前目录内: ${ref}`)\n }\n return actual\n}\n\nfunction writeDefaultMarkdown(root: string, spec: WorkspaceSpec): void {\n const files: Array<[string, string]> = [\n ['WORKSPACE.md', `# Agent Workspace\\n\\n- Context ID: ${spec.contextId}\\n- Workspace: ${spec.id}\\n- Field: ${spec.fieldId}\\n\\n这里定义稳定的身份、职责、协作边界和内容挂载。\\n`],\n ['MEMORY.md', '# Long-term Memory\\n\\n只保存经过筛选、带来源的长期记忆。当前事项放在 Session memory。\\n'],\n ['knowledge/INDEX.md', '# Knowledge Index\\n\\n按需列出本 Workspace 可用的知识入口。\\n'],\n ]\n for (const [rel, content] of files) {\n const path = join(root, rel)\n mkdirSync(dirname(path), { recursive: true })\n if (!existsSync(path)) writeFileSync(path, content)\n }\n}\n\nfunction safeName(value: string): string {\n return value.replace(/[^a-zA-Z0-9._-]+/g, '-')\n}\n\nfunction clean(value: unknown): string {\n return typeof value === 'string' ? value.trim() : ''\n}\n"]}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# dingtalk-agent:Skill-first 代码与运行架构
|
|
2
|
+
|
|
3
|
+
## 一句话结论
|
|
4
|
+
|
|
5
|
+
主入口是“外部 Agent 会话 + 全局 Basic Behavior Skill”;Workspace/Storage 是按需上下文,Prepared Run 是需要强可靠性时才启用的宿主模式,`listen` 只是其中一个可替换 Driver。
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
```mermaid
|
|
10
|
+
flowchart TB
|
|
11
|
+
USER["钉钉协作事项 / 用户请求"] --> HOST["Claude Code / Codex / Agent Host"]
|
|
12
|
+
SKILL["全局 Basic Behavior\n何时说、问、静默"] --> HOST
|
|
13
|
+
HOST --> BOOT["bootstrap\n按需发现上下文"]
|
|
14
|
+
BOOT --> LOCAL["local-dir\n挂载 Markdown"]
|
|
15
|
+
BOOT --> REMOTE["dingtalk-doc\nDWS 拉取只读快照"]
|
|
16
|
+
HOST --> ROLE["岗位 / Workflow Skill\nFDE、周报、事故处理"]
|
|
17
|
+
HOST --> MODE{"有可信 Event?"}
|
|
18
|
+
MODE -- "否" --> DIRECT["Direct / Mounted Session\n按需使用 DWS"]
|
|
19
|
+
MODE -- "是" --> RUNTIME["Prepared Run Runtime\nSession / Run / Wait / Gate"]
|
|
20
|
+
RUNTIME --> ACTION["ack / reply / ask / silence"]
|
|
21
|
+
ACTION --> DWS["DWS 产品能力"]
|
|
22
|
+
DIRECT --> DWS
|
|
23
|
+
DRIVER["可选 Driver\n云端 / DWS listen / fixture"] -. "标准 Event" .-> RUNTIME
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Why:一个普通 Claude Code Session 已经有模型、工具和生命周期。再要求它先启动一个以 `listen` 为中心的运行时,会让基础行为依赖部署形态。真正可迁移的是 Skill;CLI 只在需要硬边界的地方介入。
|
|
27
|
+
|
|
28
|
+
## 四层职责
|
|
29
|
+
|
|
30
|
+
| 层 | 回答的问题 | 不负责什么 |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| Agent Definition / Storage | 我是谁、服务谁、长期内容放哪 | 不决定单次消息是否可外发 |
|
|
33
|
+
| Basic Behavior Skill | 何时响应、如何追问、何时沉默、记什么 | 不猜 API 参数和收件人 ID |
|
|
34
|
+
| Role / Workflow Skill | FDE 评价、周报、事故处理等业务方法 | 不扩大基础权限 |
|
|
35
|
+
| CLI + DWS | CLI 固定事务边界;DWS 调具体产品能力 | CLI 不复制整个 DWS 命令面 |
|
|
36
|
+
|
|
37
|
+
动作是否进入 `dingtalk-agent` 的判断标准:是否需要冻结作用域、身份、权限、幂等键、回读、状态迁移或跨产品组合。若都不需要,继续直接使用 DWS。
|
|
38
|
+
|
|
39
|
+
## 三种运行模式
|
|
40
|
+
|
|
41
|
+
### 1. Direct Session
|
|
42
|
+
|
|
43
|
+
没有 `CONTEXT.md`,也没有 Workspace manifest。全局 Skill 仍然生效;Agent 使用当前用户请求与宿主显式提供的上下文,不自动 init、不假造钉钉目标。
|
|
44
|
+
|
|
45
|
+
### 2. Mounted Session
|
|
46
|
+
|
|
47
|
+
通过 `bootstrap` 发现或拉取身份、记忆和知识:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
dingtalk-agent bootstrap --json
|
|
51
|
+
dingtalk-agent bootstrap --storage local-dir:/workspace --json
|
|
52
|
+
dingtalk-agent bootstrap --storage 'dingtalk-doc:<node-or-url>' --json
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
本地目录不复制;远端文档先用 `doc info` probe,只有 `ALIDOC/adoc` 才用 `doc read` 拉为隐藏只读快照。
|
|
56
|
+
|
|
57
|
+
### 3. Prepared Run
|
|
58
|
+
|
|
59
|
+
上游提供可信事件 envelope 后,运行时冻结目标、身份、Field、Skill 和动作预算。此时 Agent 只能通过 typed Broker 或四个 `act` 动作产生消息副作用。
|
|
60
|
+
|
|
61
|
+
```text
|
|
62
|
+
Driver → normalizeEvent → Session → Run → Agent → Action Gate → DWS → Receipt
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
它适合真实数字员工的自动运行,不是每个交互式 Agent Session 的强制前置。
|
|
66
|
+
|
|
67
|
+
## 新任务如何承接
|
|
68
|
+
|
|
69
|
+
这里借鉴 Claude Tag 的公开行为,但不复制任何逆向 Prompt。关键不是“每次先向人提问”,而是先在内部形成任务合同,再把真正阻塞的未知量交还给人:
|
|
70
|
+
|
|
71
|
+
```text
|
|
72
|
+
感知消息
|
|
73
|
+
→ 区分讨论 / 派活
|
|
74
|
+
→ UNDERSTAND(目标、交付物、范围、完成条件、权限)
|
|
75
|
+
→ CLARIFY(先查上下文;阻塞才问一个问题)
|
|
76
|
+
→ PLAN(复杂任务才建 checklist)
|
|
77
|
+
→ EXECUTE(在里程碑、方向改变、等待时更新)
|
|
78
|
+
→ VERIFY(工具结果 + 必要回读)
|
|
79
|
+
→ COMPLETE(结果、证据、遗留项、下一责任人)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Why:如果把“先澄清”实现成固定追问,信息完整的任务也会被打断;如果完全不澄清,Agent 又会在对象、权限或完成条件不明时擅自执行。真正的分界是缺口是否阻塞安全执行。
|
|
83
|
+
|
|
84
|
+
Claude Tag 官方的线程模型与本项目高度一致:一个 thread 是一项工作的 session;长任务使用 checklist;结果回到原 thread;空闲后沙箱释放,新回复到来时重建沙箱继续。因此持久化的是显式 checkpoint 和外部成果,不是 JavaScript/LLM 隐藏栈。
|
|
85
|
+
|
|
86
|
+
## 机器 Setup 与 Workspace Init 为什么分开
|
|
87
|
+
|
|
88
|
+
机器首次使用从不会依赖全局 PATH 的入口开始:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npx --yes @xdxer/dingtalk-agent@beta setup
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`setup` 只处理用户级 CLI、PATH、DWS 健康/认证和全局 Skill;它不初始化当前代码仓库。普通 Session 随后直接 `bootstrap`,只有需要长期 Workspace 或 Prepared Run 时才 `init`。三者分开,避免把“机器缺命令”“Agent 缺行为”和“当前目录需要持久状态”混成一个不可恢复的大初始化。
|
|
95
|
+
|
|
96
|
+
## Workspace 初始化为什么是可选的
|
|
97
|
+
|
|
98
|
+
全局安装一次:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
dingtalk-agent skill install
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
物理结构:
|
|
105
|
+
|
|
106
|
+
```text
|
|
107
|
+
~/.agents/skills/dingtalk-basic-behavior/ canonical copy
|
|
108
|
+
~/.claude/skills/dingtalk-basic-behavior relative symlink
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
canonical 不链接 npm/node_modules,避免包升级、卸载或 npx cache 清理造成断链。安装有 ownership marker、内容 hash 和原子 staging;陌生同名目录不覆盖,本地修改不静默丢弃。
|
|
112
|
+
|
|
113
|
+
`dingtalk-agent init` 只在需要持久 Workspace/Prepared Run 时执行一次。它会创建最小 manifest、默认 Markdown 和机器策略,不再写项目的 `AGENTS.md`、`CLAUDE.md`、`.gitignore`、Ontology,也不复制 Skill。contextId 可省略,由目录名稳定派生。
|
|
114
|
+
|
|
115
|
+
## Storage 与 Context
|
|
116
|
+
|
|
117
|
+
公开 Provider:
|
|
118
|
+
|
|
119
|
+
```text
|
|
120
|
+
local-dir:<path> 直接挂载已有目录
|
|
121
|
+
local-md:<path> Workspace manifest 的单文件挂载
|
|
122
|
+
dingtalk-doc:<node-or-url> DWS 拉取在线文档快照
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
`contextId` 只保留为 Prepared Run 的兼容字段,不是普通 Session 必须理解或传入的参数。`bootstrap` 用 Storage canonical identity 派生内部 `scopeId`。
|
|
126
|
+
|
|
127
|
+
语义内容与控制状态必须隔离:
|
|
128
|
+
|
|
129
|
+
| 可放 Markdown / 钉钉文档 | 必须留在宿主 state store |
|
|
130
|
+
|---|---|
|
|
131
|
+
| 身份、长期记忆、知识、Skill 候选、业务 task checkpoint | EventIndex、Wait、锁、generation、幂等键、Action intent/receipt |
|
|
132
|
+
|
|
133
|
+
Why:Markdown 没有可靠 CAS;请求超时也不能证明写失败,不能承担并发控制。
|
|
134
|
+
|
|
135
|
+
Task checkpoint 只在跨 Run、等待依赖、已经产生副作用、需要接手或用户要求跟踪时创建。Prepared Run 使用 `$DTA_SESSION/memory/task.md`;Mounted Session 只写显式配置的本地 state root;远端可映射到一项任务一篇钉钉文档,但当前 `dingtalk-doc` bootstrap 仍只读,写入必须经过授权的 DWS/typed provider 并回读。
|
|
136
|
+
|
|
137
|
+
## Prepared Run 的四个公开对象
|
|
138
|
+
|
|
139
|
+
| 对象 | 生命周期 | 物理形态 | 作用 |
|
|
140
|
+
|---|---|---|---|
|
|
141
|
+
| Workspace | 长期、可选 | 一个目录或远端语义挂载 | 身份、内容、Field 和 Skill 清单 |
|
|
142
|
+
| Session | 一件事 | `.dingtalk-agent/sessions/.../<sessionId>` | 工作记忆、Skill 绑定、跨消息延续 |
|
|
143
|
+
| Run | 一次信号 | `Session/runs/<runId>` | 冻结输入;每次可启动新沙箱 |
|
|
144
|
+
| Action | 一次效果 | intent + attempt + receipt | `ack/reply/ask/silence` |
|
|
145
|
+
|
|
146
|
+
可选的 Task checkpoint 是 Session 的业务投影,不是第五个运行时控制对象。P0 直接令 `taskId = sessionId`;只有真实失败证明 Markdown checkpoint 不够可靠时,才考虑增加 provider-neutral 的 `task show/checkpoint` 两个命令。
|
|
147
|
+
|
|
148
|
+
Wait、Event Journal、dispatch outbox 和 reply target 是宿主内部实现,不要求 Agent 学习。
|
|
149
|
+
|
|
150
|
+
## 与异步进程模型的对应
|
|
151
|
+
|
|
152
|
+
| 进程隐喻 | 实体 |
|
|
153
|
+
|---|---|
|
|
154
|
+
| Heap | Field/Workspace 的身份、知识、Skill |
|
|
155
|
+
| Stack | Session working memory 与事项状态 |
|
|
156
|
+
| 一次函数调用 | Run |
|
|
157
|
+
| syscall | Action |
|
|
158
|
+
| await continuation | 宿主内部 Wait |
|
|
159
|
+
| interrupt | 新事件、心跳、显式取消 |
|
|
160
|
+
|
|
161
|
+
`ask` 后当前 Run 结束,沙箱释放;匹配事件产生新 Run,并回到原 Session。系统恢复业务 checkpoint,不序列化 JavaScript native stack。
|
|
162
|
+
|
|
163
|
+
## TypeScript 模块边界
|
|
164
|
+
|
|
165
|
+
```mermaid
|
|
166
|
+
flowchart TB
|
|
167
|
+
CLI["bin/dingtalk-agent.ts\ncomposition root"] --> SM["skill-manager.ts\n全局安装与漂移保护"]
|
|
168
|
+
CLI --> BS["bootstrap.ts\nStorage 水合"]
|
|
169
|
+
CLI --> DRIVER["driver.ts\n可选事件入口"]
|
|
170
|
+
DRIVER --> EVENTS["events.ts\nnormalize"]
|
|
171
|
+
EVENTS --> SESSIONS["sessions.ts\nSession / Run / dispatch"]
|
|
172
|
+
SESSIONS --> WORKSPACE["workspace.ts\nmanifest / mounts"]
|
|
173
|
+
SESSIONS --> SKILLS["skills.ts\nlocal → global → bundled resolver"]
|
|
174
|
+
SESSIONS --> WAITS["waits.ts\ncontinuation"]
|
|
175
|
+
CLI --> ACTIONS["actions.ts\nAction Gate"]
|
|
176
|
+
ACTIONS --> DWS["dws.ts\ntyped platform adapter"]
|
|
177
|
+
BS --> DWS
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Skill resolver 的优先级:
|
|
181
|
+
|
|
182
|
+
```text
|
|
183
|
+
Workspace override → ~/.agents/skills → Claude/legacy exposure → npm bundled
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
创建 Session 后立即冻结 Skill manifest;同一事项不会因全局 Skill 升级而中途变规则,新 Session 才使用新版本。
|
|
187
|
+
|
|
188
|
+
## FDE 教练实例
|
|
189
|
+
|
|
190
|
+
| 基础框架 | FDE 教练 |
|
|
191
|
+
|---|---|
|
|
192
|
+
| 全局 Basic Behavior | 先判断被 @/DM/普通群聊的响应资格 |
|
|
193
|
+
| Workspace/Storage | 菲迪身份、评价原则、学员资料 |
|
|
194
|
+
| Role Skill | 生成评价、等待确认、调整、发布的方法 |
|
|
195
|
+
| Session | “给张三本轮评价并等确认”这一件事 |
|
|
196
|
+
| Run | 每条新信号唤醒的一次沙箱 |
|
|
197
|
+
| Action | 收到、回复、追问、沉默 |
|
|
198
|
+
|
|
199
|
+
FDE 的评价模板和发布流程不进入全局 Basic Behavior;否则任何钉钉员工都会被污染成教练。
|
|
200
|
+
|
|
201
|
+
## 当前明确不做
|
|
202
|
+
|
|
203
|
+
- 不把 `listen` 作为 Agent 主进程;
|
|
204
|
+
- 不自动 init 任意代码仓库;
|
|
205
|
+
- 不复制整个 DWS 成另一套 CLI;
|
|
206
|
+
- 不把钉钉文档当锁或事务数据库;
|
|
207
|
+
- 不序列化语言运行时栈;
|
|
208
|
+
- 不允许在线 Run 自动扩大身份、权限或启用 Skill。
|
|
209
|
+
|
|
210
|
+
## 验收
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
npm run typecheck
|
|
214
|
+
npm run eval:contract
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
28 个确定性场景覆盖三条主链:setup/PATH/DWS/多客户端发现、Skill-first 安装/水合,以及 Prepared Run 的 Session、Wait、幂等、目标与回执。
|