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

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/dist/src/map.js DELETED
@@ -1,157 +0,0 @@
1
- // Managed Agents Platform(MAP)注册表与工作区归属解析。
2
- //
3
- // 一个 Agent 工作区归属于至多一个托管平台;归属解析顺序固定:
4
- // DTA_MAP 环境变量 > dingtalk-agent.json#map > .dingtalk-agent/map.json > 按 Provider 声明推断。
5
- // 平台相关的方法学不写进 CLI——它们随对应平台的 Skill 包分发,只在用户选择该平台时安装。
6
- // 平台命令(如 deploy/promote/observe)必须先通过归属门禁;coming-soon 平台一律 fail-closed。
7
- import { existsSync, lstatSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
8
- import { dirname, join, parse, resolve } from 'node:path';
9
- import { findAgentProjectRoot } from './development-workspace.js';
10
- import { installGlobalSkill } from './skill-manager.js';
11
- export const MANAGED_AGENT_PLATFORMS = [
12
- {
13
- name: 'multica-dingtalk',
14
- label: 'Multica (DingTalk)',
15
- status: 'supported',
16
- description: '钉钉 Multica 托管平台:受控部署、晋级与观测回流。',
17
- skills: ['dingtalk-agent-deploy', 'dingtalk-agent-boot-multica'],
18
- commands: ['deploy', 'promote', 'observe'],
19
- },
20
- {
21
- name: 'deap',
22
- label: 'DEAP',
23
- status: 'coming-soon',
24
- description: '敬请期待。',
25
- skills: [],
26
- commands: [],
27
- },
28
- ];
29
- export const MAP_FILE = '.dingtalk-agent/map.json';
30
- const PROJECT_FILE = 'dingtalk-agent.json';
31
- export function mapDefinition(name) {
32
- return MANAGED_AGENT_PLATFORMS.find((item) => item.name === name) || null;
33
- }
34
- export function resolveMap(start = process.cwd(), env = process.env) {
35
- const fromEnv = String(env.DTA_MAP || '').trim();
36
- if (fromEnv)
37
- return resolution(fromEnv, 'env', '');
38
- const projectRoot = findAgentProjectRoot(start);
39
- if (projectRoot) {
40
- const manifestPath = join(projectRoot, PROJECT_FILE);
41
- if (existsSync(manifestPath) && !lstatSync(manifestPath).isSymbolicLink()) {
42
- const manifest = readJsonOrNull(manifestPath);
43
- const declared = typeof manifest?.map === 'string' ? manifest.map.trim() : '';
44
- if (declared)
45
- return resolution(declared, 'project-manifest', manifestPath);
46
- }
47
- }
48
- const mapPath = findUp(start, MAP_FILE);
49
- if (mapPath) {
50
- const stored = readJsonOrNull(mapPath);
51
- const declared = typeof stored?.map === 'string' ? stored.map.trim() : '';
52
- if (declared)
53
- return resolution(declared, 'map-file', mapPath);
54
- }
55
- if (projectRoot) {
56
- const manifest = readJsonOrNull(join(projectRoot, PROJECT_FILE));
57
- const providers = Object.values(manifest?.workspaces || {})
58
- .map((workspace) => workspace?.provider?.kind);
59
- if (providers.includes('multica')) {
60
- return resolution('multica-dingtalk', 'inferred', join(projectRoot, PROJECT_FILE));
61
- }
62
- }
63
- return resolution(null, 'none', '');
64
- }
65
- export function useMap(start, name, options) {
66
- const definition = mapDefinition(name);
67
- if (!definition) {
68
- throw new Error(`未知 managed agents platform: ${name}\n` +
69
- `可用: ${MANAGED_AGENT_PLATFORMS.map((item) => `${item.name}(${statusLabel(item.status)})`).join('、')}`);
70
- }
71
- if (definition.status !== 'supported') {
72
- throw new Error(`${definition.label} 敬请期待——当前版本尚未开放该平台。`);
73
- }
74
- const projectRoot = findAgentProjectRoot(start);
75
- let written;
76
- if (projectRoot && existsSync(join(projectRoot, PROJECT_FILE))) {
77
- const manifestPath = join(projectRoot, PROJECT_FILE);
78
- if (lstatSync(manifestPath).isSymbolicLink()) {
79
- throw new Error(`${PROJECT_FILE} 不能是符号链接`);
80
- }
81
- const manifest = readJsonOrNull(manifestPath);
82
- if (!manifest || typeof manifest !== 'object') {
83
- throw new Error(`${PROJECT_FILE} 不是合法 JSON,无法写入 map 归属`);
84
- }
85
- manifest.map = definition.name;
86
- writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
87
- written = manifestPath;
88
- }
89
- else {
90
- const target = join(resolve(start), MAP_FILE);
91
- mkdirSync(dirname(target), { recursive: true });
92
- writeFileSync(target, JSON.stringify({ $schema: 'dingtalk-agent/map@1', map: definition.name }, null, 2) + '\n');
93
- written = target;
94
- }
95
- const skillInstalls = [];
96
- if (options.installSkills !== false) {
97
- for (const skill of definition.skills) {
98
- skillInstalls.push(installGlobalSkill(options.packageRoot, {
99
- name: skill, home: options.home, env: options.env,
100
- }));
101
- }
102
- }
103
- return { ...resolveMap(start, options.env || process.env), written, skillInstalls };
104
- }
105
- /** deploy/promote/observe 等平台命令的归属门禁:未归属、未知或 coming-soon 一律 fail-closed。 */
106
- export function requireSupportedMap(command, start = process.cwd(), env = process.env) {
107
- const resolved = resolveMap(start, env);
108
- if (!resolved.map) {
109
- throw new Error(`当前工作区未声明 managed agents platform,无法执行 \`${command}\`。\n` +
110
- '先运行 `dta map use multica-dingtalk`,或设置 DTA_MAP 环境变量。');
111
- }
112
- if (!resolved.definition) {
113
- throw new Error(`工作区声明了未知 platform: ${resolved.map}(来源 ${resolved.source})。\n` +
114
- `可用: ${MANAGED_AGENT_PLATFORMS.map((item) => item.name).join('、')}`);
115
- }
116
- if (resolved.definition.status !== 'supported') {
117
- throw new Error(`${resolved.definition.label} 敬请期待——\`${command}\` 尚未在该平台开放。`);
118
- }
119
- if (!resolved.definition.commands.includes(command)) {
120
- throw new Error(`${resolved.definition.label} 不承接命令 \`${command}\`。`);
121
- }
122
- return resolved;
123
- }
124
- export function statusLabel(status) {
125
- return status === 'supported' ? '已支持' : '敬请期待';
126
- }
127
- function resolution(name, source, file) {
128
- return {
129
- $schema: 'dingtalk-agent/map-resolution@1',
130
- map: name,
131
- source,
132
- file,
133
- definition: name ? mapDefinition(name) : null,
134
- platforms: MANAGED_AGENT_PLATFORMS,
135
- };
136
- }
137
- function readJsonOrNull(path) {
138
- try {
139
- return JSON.parse(readFileSync(path, 'utf8'));
140
- }
141
- catch {
142
- return null;
143
- }
144
- }
145
- function findUp(start, relativePath) {
146
- let dir = resolve(start);
147
- while (true) {
148
- const candidate = join(dir, relativePath);
149
- if (existsSync(candidate) && !lstatSync(candidate).isSymbolicLink())
150
- return candidate;
151
- const parent = dirname(dir);
152
- if (parent === dir || dir === parse(dir).root)
153
- return null;
154
- dir = parent;
155
- }
156
- }
157
- //# sourceMappingURL=map.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"map.js","sourceRoot":"","sources":["../../src/map.ts"],"names":[],"mappings":"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","sourcesContent":["// Managed Agents Platform(MAP)注册表与工作区归属解析。\n//\n// 一个 Agent 工作区归属于至多一个托管平台;归属解析顺序固定:\n// DTA_MAP 环境变量 > dingtalk-agent.json#map > .dingtalk-agent/map.json > 按 Provider 声明推断。\n// 平台相关的方法学不写进 CLI——它们随对应平台的 Skill 包分发,只在用户选择该平台时安装。\n// 平台命令(如 deploy/promote/observe)必须先通过归属门禁;coming-soon 平台一律 fail-closed。\n\nimport { existsSync, lstatSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { dirname, join, parse, resolve } from 'node:path'\n\nimport { findAgentProjectRoot } from './development-workspace.js'\nimport { installGlobalSkill, type GlobalSkillStatus } from './skill-manager.js'\n\nexport type MapStatus = 'supported' | 'coming-soon'\n\nexport interface MapDefinition {\n name: string\n label: string\n status: MapStatus\n description: string\n skills: string[]\n commands: string[]\n}\n\nexport const MANAGED_AGENT_PLATFORMS: MapDefinition[] = [\n {\n name: 'multica-dingtalk',\n label: 'Multica (DingTalk)',\n status: 'supported',\n description: '钉钉 Multica 托管平台:受控部署、晋级与观测回流。',\n skills: ['dingtalk-agent-deploy', 'dingtalk-agent-boot-multica'],\n commands: ['deploy', 'promote', 'observe'],\n },\n {\n name: 'deap',\n label: 'DEAP',\n status: 'coming-soon',\n description: '敬请期待。',\n skills: [],\n commands: [],\n },\n]\n\nexport const MAP_FILE = '.dingtalk-agent/map.json'\nconst PROJECT_FILE = 'dingtalk-agent.json'\n\nexport type MapSource = 'env' | 'project-manifest' | 'map-file' | 'inferred' | 'none'\n\nexport interface MapResolution {\n $schema: 'dingtalk-agent/map-resolution@1'\n map: string | null\n source: MapSource\n file: string\n definition: MapDefinition | null\n platforms: MapDefinition[]\n}\n\nexport interface MapUseResult extends MapResolution {\n written: string\n skillInstalls: GlobalSkillStatus[]\n}\n\nexport function mapDefinition(name: string): MapDefinition | null {\n return MANAGED_AGENT_PLATFORMS.find((item) => item.name === name) || null\n}\n\nexport function resolveMap(start = process.cwd(), env: NodeJS.ProcessEnv = process.env): MapResolution {\n const fromEnv = String(env.DTA_MAP || '').trim()\n if (fromEnv) return resolution(fromEnv, 'env', '')\n\n const projectRoot = findAgentProjectRoot(start)\n if (projectRoot) {\n const manifestPath = join(projectRoot, PROJECT_FILE)\n if (existsSync(manifestPath) && !lstatSync(manifestPath).isSymbolicLink()) {\n const manifest = readJsonOrNull(manifestPath)\n const declared = typeof manifest?.map === 'string' ? manifest.map.trim() : ''\n if (declared) return resolution(declared, 'project-manifest', manifestPath)\n }\n }\n\n const mapPath = findUp(start, MAP_FILE)\n if (mapPath) {\n const stored = readJsonOrNull(mapPath)\n const declared = typeof stored?.map === 'string' ? stored.map.trim() : ''\n if (declared) return resolution(declared, 'map-file', mapPath)\n }\n\n if (projectRoot) {\n const manifest = readJsonOrNull(join(projectRoot, PROJECT_FILE))\n const providers = Object.values(manifest?.workspaces || {})\n .map((workspace: any) => workspace?.provider?.kind)\n if (providers.includes('multica')) {\n return resolution('multica-dingtalk', 'inferred', join(projectRoot, PROJECT_FILE))\n }\n }\n\n return resolution(null, 'none', '')\n}\n\nexport interface MapUseOptions {\n packageRoot: string\n home?: string\n env?: NodeJS.ProcessEnv\n installSkills?: boolean\n}\n\nexport function useMap(start: string, name: string, options: MapUseOptions): MapUseResult {\n const definition = mapDefinition(name)\n if (!definition) {\n throw new Error(\n `未知 managed agents platform: ${name}\\n` +\n `可用: ${MANAGED_AGENT_PLATFORMS.map((item) => `${item.name}(${statusLabel(item.status)})`).join('、')}`,\n )\n }\n if (definition.status !== 'supported') {\n throw new Error(`${definition.label} 敬请期待——当前版本尚未开放该平台。`)\n }\n\n const projectRoot = findAgentProjectRoot(start)\n let written: string\n if (projectRoot && existsSync(join(projectRoot, PROJECT_FILE))) {\n const manifestPath = join(projectRoot, PROJECT_FILE)\n if (lstatSync(manifestPath).isSymbolicLink()) {\n throw new Error(`${PROJECT_FILE} 不能是符号链接`)\n }\n const manifest = readJsonOrNull(manifestPath)\n if (!manifest || typeof manifest !== 'object') {\n throw new Error(`${PROJECT_FILE} 不是合法 JSON,无法写入 map 归属`)\n }\n manifest.map = definition.name\n writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\\n')\n written = manifestPath\n } else {\n const target = join(resolve(start), MAP_FILE)\n mkdirSync(dirname(target), { recursive: true })\n writeFileSync(target, JSON.stringify(\n { $schema: 'dingtalk-agent/map@1', map: definition.name }, null, 2,\n ) + '\\n')\n written = target\n }\n\n const skillInstalls: GlobalSkillStatus[] = []\n if (options.installSkills !== false) {\n for (const skill of definition.skills) {\n skillInstalls.push(installGlobalSkill(options.packageRoot, {\n name: skill, home: options.home, env: options.env,\n }))\n }\n }\n\n return { ...resolveMap(start, options.env || process.env), written, skillInstalls }\n}\n\n/** deploy/promote/observe 等平台命令的归属门禁:未归属、未知或 coming-soon 一律 fail-closed。 */\nexport function requireSupportedMap(\n command: string, start = process.cwd(), env: NodeJS.ProcessEnv = process.env,\n): MapResolution {\n const resolved = resolveMap(start, env)\n if (!resolved.map) {\n throw new Error(\n `当前工作区未声明 managed agents platform,无法执行 \\`${command}\\`。\\n` +\n '先运行 `dta map use multica-dingtalk`,或设置 DTA_MAP 环境变量。',\n )\n }\n if (!resolved.definition) {\n throw new Error(\n `工作区声明了未知 platform: ${resolved.map}(来源 ${resolved.source})。\\n` +\n `可用: ${MANAGED_AGENT_PLATFORMS.map((item) => item.name).join('、')}`,\n )\n }\n if (resolved.definition.status !== 'supported') {\n throw new Error(`${resolved.definition.label} 敬请期待——\\`${command}\\` 尚未在该平台开放。`)\n }\n if (!resolved.definition.commands.includes(command)) {\n throw new Error(`${resolved.definition.label} 不承接命令 \\`${command}\\`。`)\n }\n return resolved\n}\n\nexport function statusLabel(status: MapStatus): string {\n return status === 'supported' ? '已支持' : '敬请期待'\n}\n\nfunction resolution(name: string | null, source: MapSource, file: string): MapResolution {\n return {\n $schema: 'dingtalk-agent/map-resolution@1',\n map: name,\n source,\n file,\n definition: name ? mapDefinition(name) : null,\n platforms: MANAGED_AGENT_PLATFORMS,\n }\n}\n\nfunction readJsonOrNull(path: string): any {\n try { return JSON.parse(readFileSync(path, 'utf8')) } catch { return null }\n}\n\nfunction findUp(start: string, relativePath: string): string | null {\n let dir = resolve(start)\n while (true) {\n const candidate = join(dir, relativePath)\n if (existsSync(candidate) && !lstatSync(candidate).isSymbolicLink()) return candidate\n const parent = dirname(dir)\n if (parent === dir || dir === parse(dir).root) return null\n dir = parent\n }\n}\n"]}
@@ -1,62 +0,0 @@
1
- # 一小时复制第二个岗位 Agent
2
-
3
- ## 结论
4
-
5
- 第二个 Agent 不复制运行时,只复制一份 Agent kit 并替换四类绑定:`AGENTS.md`、Role Skills、Field/存储、DWS authority。事件监听不在本流程内;没有事件时 Agent 仍以 Direct/Mounted Session 正常工作,有可信事件时再进入同一个 Prepared Runtime。
6
-
7
- 仓库提供两份已通过同一合同的实例:
8
-
9
- - `examples/agents/fde-coach`:FDE 教练;
10
- - `examples/agents/release-manager`:发布经理。
11
-
12
- 两者共享 Basic Behavior、Invocation、Session/Run/Wait、双半闸门与 Receipt;Definition、Role Skill、Field、Session state、记忆和权限完全隔离。
13
-
14
- ## 60 分钟执行表
15
-
16
- | 时间 | 开发者动作 | 验收标准 |
17
- |---|---|---|
18
- | 0–10 分钟 | 复制任一 example,改目录名 | 原 example 不被覆盖,新目录不含 `.dingtalk-agent` |
19
- | 10–20 分钟 | 改 `AGENTS.md` 的身份、服务对象、职责、交付与拒绝边界 | 另一个 Agent 能回答“我是谁、负责什么、不做什么” |
20
- | 20–30 分钟 | 新建/改名 `skills/<role>/SKILL.md` | 目录名等于 frontmatter `name`;只含岗位方法,不重复基础行为 |
21
- | 30–40 分钟 | 配置 Field、存储路由和 DWS authority | 使用可信 ID;不同 Agent 不共用 state root、业务 scope 或生产权限 |
22
- | 40–50 分钟 | 先 `dta bootstrap --json`,需要 Prepared Run 时再显式 `dta init` | Direct 默认 ready/partial 可解释;init 采用 `AGENTS.md` 并发现 Role Skill |
23
- | 50–60 分钟 | 跑合同/mock Lab,检查冻结快照和隔离 | 无可信 target 不外发;两个 Agent 的 Definition/Session/记忆/权限不串 |
24
-
25
- ## 最小操作
26
-
27
- ```bash
28
- cp -R examples/agents/release-manager /path/to/my-agent
29
- cd /path/to/my-agent
30
-
31
- # 先验证本体;这一步不要求 Workspace,也不产生钉钉副作用
32
- dta bootstrap --json
33
-
34
- # 只有需要可信事件和 Prepared Run 时才初始化一次
35
- dta init
36
- dta bootstrap --json
37
- ```
38
-
39
- 首次 `init` 会优先采用已有 `AGENTS.md`,发现 `skills/*/SKILL.md`,并保留已有 `fields/default/field.json`。初始化后新增 Skill 不会自动热启用:离线评审后把 Skill name 加入 `.dingtalk-agent/workspace.json#skills`,由新 Session 重新冻结。
40
-
41
- ## 自动化验收
42
-
43
- ```bash
44
- npm run typecheck
45
- npm run eval:contract
46
- ```
47
-
48
- 合同 42 会从两份 example 分别创建临时 Workspace,并检查:
49
-
50
- 1. 初始化前 Direct bootstrap 可工作且没有可信 target;
51
- 2. 初始化后 `AGENTS.md`、Role Skill 与显式 Field 被正确采用;
52
- 3. 两个 Definition、DWS profile、Session ID 不同,共享 Basic Behavior hash;
53
- 4. FDE 的 Task Checkpoint 与 Memory Candidate 在发布经理 state root 中不可见;
54
- 5. 两者都通过同一 fake-DWS Lab 的 Action/Receipt/平台回读合同。
55
-
56
- 2026-07-16 本地基线为 42/42,通过;双 Agent 合同自动执行约 2–3 秒。这个数字证明模板化装配和隔离可自动验证,不代表真实账号、专用群、AI 表格和钉钉文档已接通。真实 L4 仍需为每个 Agent 提供专用测试对象、allowlist 和明确 `--live --yes` 授权。
57
-
58
- ## 验收边界
59
-
60
- - 通过:开发者只改本体、岗位 Skill、存储/Field/authority,即可得到第二个结构完整、状态隔离的 Agent;
61
- - 不包含:Webhook、定时器、personal-event listener 等触发端;
62
- - 不冒充:mock 平台可见不等于真实钉钉送达,真实写入必须另走 Lab L3/L4 晋级门禁。
@@ -1,132 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 900" width="1440" height="900" role="img" aria-labelledby="title desc">
2
- <title id="title">dingtalk-agent 三层语义记忆与控制状态拓扑</title>
3
- <desc id="desc">Agent Run 按需读写三层语义记忆:Session 工作记忆、钉钉原生业务记忆、长期知识;Wait、锁、generation、幂等和 Receipt 位于独立控制状态;Git 用于定义与 Skill 的版本发布,不作为运行时锁或 PCB。</desc>
4
- <style>
5
- text { font-family:'Helvetica Neue',Helvetica,Arial,'PingFang SC','Microsoft YaHei',sans-serif; }
6
- .title { fill:#111827;font-size:28px;font-weight:700; }
7
- .subtitle { fill:#6b7280;font-size:14px; }
8
- .lane { fill:#475569;font-size:12px;font-weight:700;letter-spacing:.08em; }
9
- .node-title { fill:#111827;font-size:16px;font-weight:700; }
10
- .node-sub { fill:#4b5563;font-size:12px; }
11
- .small { fill:#64748b;font-size:11px; }
12
- .label { fill:#475569;font-size:11px;font-weight:600; }
13
- </style>
14
- <defs>
15
- <marker id="blue" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto"><polygon points="0 0,10 3.5,0 7" fill="#2563eb"/></marker>
16
- <marker id="green" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto"><polygon points="0 0,10 3.5,0 7" fill="#059669"/></marker>
17
- <marker id="purple" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto"><polygon points="0 0,10 3.5,0 7" fill="#7c3aed"/></marker>
18
- <marker id="rose" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto"><polygon points="0 0,10 3.5,0 7" fill="#dc2626"/></marker>
19
- <filter id="shadow" x="-20%" y="-20%" width="140%" height="140%"><feDropShadow dx="0" dy="2" stdDeviation="3" flood-color="#0f172a" flood-opacity=".10"/></filter>
20
- </defs>
21
-
22
- <rect width="1440" height="900" fill="#ffffff"/>
23
- <text x="40" y="48" class="title">三层语义记忆,各归各的介质</text>
24
- <text x="40" y="75" class="subtitle">语义记忆服务“想起什么”;控制状态保证“只执行一次、从正确位置继续”。两者必须分开。</text>
25
-
26
- <rect x="30" y="105" width="300" height="620" rx="14" fill="#eff6ff" stroke="#60a5fa" stroke-width="1.6"/>
27
- <text x="50" y="132" class="lane">AGENT RUNTIME</text>
28
-
29
- <rect x="70" y="180" width="220" height="122" rx="12" fill="#ffffff" stroke="#60a5fa" stroke-width="2.2" filter="url(#shadow)"/>
30
- <rect x="74" y="184" width="212" height="114" rx="9" fill="none" stroke="#60a5fa" stroke-width=".8" opacity=".5"/>
31
- <text x="180" y="218" text-anchor="middle" class="node-title">Agent Run</text>
32
- <text x="180" y="243" text-anchor="middle" class="node-sub">一次事件唤醒</text>
33
- <text x="180" y="265" text-anchor="middle" class="node-sub">推理 · 工具 · ActionRequest</text>
34
- <text x="180" y="286" text-anchor="middle" class="small">沙箱可丢弃</text>
35
-
36
- <rect x="70" y="355" width="220" height="132" rx="10" fill="#faf5ff" stroke="#c084fc" stroke-width="1.7"/>
37
- <text x="180" y="388" text-anchor="middle" class="node-title">Session</text>
38
- <text x="180" y="412" text-anchor="middle" class="node-sub">一件事的稳定语义边界</text>
39
- <text x="180" y="435" text-anchor="middle" class="node-sub">goal · checkpoint · next</text>
40
- <text x="180" y="457" text-anchor="middle" class="node-sub">waitFor · evidence</text>
41
- <text x="180" y="478" text-anchor="middle" class="small">跨 Run,不跨事项</text>
42
-
43
- <rect x="70" y="540" width="220" height="128" rx="10" fill="#fef2f2" stroke="#f87171" stroke-width="1.8" stroke-dasharray="6 4"/>
44
- <text x="180" y="572" text-anchor="middle" class="node-title">Control State Client</text>
45
- <text x="180" y="596" text-anchor="middle" class="node-sub">claim · resume · commit</text>
46
- <text x="180" y="619" text-anchor="middle" class="node-sub">不暴露平台凭据</text>
47
- <text x="180" y="643" text-anchor="middle" class="small">通过宿主原子接口读写</text>
48
-
49
- <path d="M180 302 L180 355" fill="none" stroke="#2563eb" stroke-width="2" marker-end="url(#blue)"/>
50
- <path d="M180 487 L180 540" fill="none" stroke="#dc2626" stroke-width="1.8" marker-end="url(#rose)"/>
51
-
52
- <rect x="365" y="105" width="645" height="620" rx="14" fill="#f8fafc" stroke="#cbd5e1" stroke-width="1.2" stroke-dasharray="7 5"/>
53
- <text x="385" y="132" class="lane">THREE SEMANTIC MEMORY TIERS</text>
54
-
55
- <rect x="405" y="165" width="565" height="138" rx="12" fill="#eff6ff" stroke="#93c5fd" stroke-width="1.8" filter="url(#shadow)"/>
56
- <rect x="425" y="184" width="78" height="34" rx="17" fill="#2563eb"/><text x="464" y="207" text-anchor="middle" fill="#ffffff" font-size="13" font-weight="700">L1 短期</text>
57
- <text x="525" y="205" class="node-title">Session 工作记忆</text>
58
- <text x="425" y="242" class="node-sub">介质:宿主 state root / 原子本地存储;可生成 Markdown checkpoint 供人审阅</text>
59
- <text x="425" y="267" class="node-sub">内容:当前目标、做到哪、下一步、在等什么、已有哪些证据</text>
60
- <text x="425" y="289" class="small">高频更新 · 事项结束后归档/压缩 · 不承担锁和幂等</text>
61
-
62
- <rect x="405" y="348" width="565" height="138" rx="12" fill="#f0fdfa" stroke="#5eead4" stroke-width="1.8" filter="url(#shadow)"/>
63
- <rect x="425" y="367" width="78" height="34" rx="17" fill="#0f766e"/><text x="464" y="390" text-anchor="middle" fill="#ffffff" font-size="13" font-weight="700">L2 工作</text>
64
- <text x="525" y="388" class="node-title">钉钉原生业务记忆</text>
65
- <text x="425" y="425" class="node-sub">介质:AI 表格宽表 / Todo / Calendar / 业务系统的唯一事实源</text>
66
- <text x="425" y="450" class="node-sub">内容:日报摘要、待办快照、互动记录、可聚合的业务热数据</text>
67
- <text x="425" y="472" class="small">结构化查询 · 跨 Agent 可读 · ID 与 schema 必须显式绑定</text>
68
-
69
- <rect x="405" y="531" width="565" height="138" rx="12" fill="#f0fdf4" stroke="#86efac" stroke-width="1.8" filter="url(#shadow)"/>
70
- <rect x="425" y="550" width="78" height="34" rx="17" fill="#15803d"/><text x="464" y="573" text-anchor="middle" fill="#ffffff" font-size="13" font-weight="700">L3 长期</text>
71
- <text x="525" y="571" class="node-title">知识与能力资产</text>
72
- <text x="425" y="608" class="node-sub">介质:钉钉文档树 / 知识库 / Wiki;按来源、范围与版本治理</text>
73
- <text x="425" y="633" class="node-sub">内容:身份、职责、Skill、SOP、人物模式、错误库、稳定知识</text>
74
- <text x="425" y="655" class="small">低频写入 · 需证据与准入 · 新 Run 才加载已发布版本</text>
75
-
76
- <path d="M405 220 L330 220" fill="none" stroke="#059669" stroke-width="1.8" marker-end="url(#green)"/>
77
- <path d="M330 258 L405 258" fill="none" stroke="#059669" stroke-width="1.6" stroke-dasharray="5 3" marker-end="url(#green)"/>
78
- <rect x="342" y="194" width="52" height="20" rx="5" fill="#ffffff" opacity=".96"/><text x="368" y="209" text-anchor="middle" class="label">read</text>
79
- <rect x="342" y="266" width="52" height="20" rx="5" fill="#ffffff" opacity=".96"/><text x="368" y="281" text-anchor="middle" class="label">write</text>
80
-
81
- <path d="M405 400 L330 400" fill="none" stroke="#059669" stroke-width="1.8" marker-end="url(#green)"/>
82
- <path d="M330 444 L405 444" fill="none" stroke="#059669" stroke-width="1.6" stroke-dasharray="5 3" marker-end="url(#green)"/>
83
- <rect x="337" y="374" width="62" height="20" rx="5" fill="#ffffff" opacity=".96"/><text x="368" y="389" text-anchor="middle" class="label">query</text>
84
- <rect x="342" y="452" width="52" height="20" rx="5" fill="#ffffff" opacity=".96"/><text x="368" y="467" text-anchor="middle" class="label">write</text>
85
-
86
- <path d="M405 583 L330 583" fill="none" stroke="#059669" stroke-width="1.8" marker-end="url(#green)"/>
87
- <path d="M330 627 L405 627" fill="none" stroke="#059669" stroke-width="1.6" stroke-dasharray="5 3" marker-end="url(#green)"/>
88
- <rect x="342" y="557" width="52" height="20" rx="5" fill="#ffffff" opacity=".96"/><text x="368" y="572" text-anchor="middle" class="label">load</text>
89
- <rect x="335" y="635" width="66" height="20" rx="5" fill="#ffffff" opacity=".96"/><text x="368" y="650" text-anchor="middle" class="label">propose</text>
90
-
91
- <path d="M687 303 L687 348" fill="none" stroke="#7c3aed" stroke-width="1.7" marker-end="url(#purple)"/>
92
- <path d="M687 486 L687 531" fill="none" stroke="#7c3aed" stroke-width="1.7" marker-end="url(#purple)"/>
93
- <rect x="700" y="316" width="78" height="20" rx="5" fill="#ffffff" opacity=".96"/><text x="739" y="331" text-anchor="middle" class="label">结构化</text>
94
- <rect x="700" y="499" width="78" height="20" rx="5" fill="#ffffff" opacity=".96"/><text x="739" y="514" text-anchor="middle" class="label">验证沉淀</text>
95
-
96
- <rect x="1045" y="105" width="365" height="320" rx="14" fill="#fef2f2" stroke="#f87171" stroke-width="1.6" stroke-dasharray="7 5"/>
97
- <text x="1065" y="132" fill="#b91c1c" font-size="12" font-weight="700" letter-spacing=".08em">CONTROL PLANE · 不是记忆</text>
98
- <text x="1227" y="173" text-anchor="middle" class="node-title">宿主控制状态</text>
99
-
100
- <rect x="1080" y="200" width="295" height="176" rx="10" fill="#ffffff" stroke="#fca5a5" stroke-width="1.5"/>
101
- <text x="1105" y="230" class="node-sub">• EventIndex / delivery claim</text>
102
- <text x="1105" y="258" class="node-sub">• Wait / correlation / timer</text>
103
- <text x="1105" y="286" class="node-sub">• lock / generation / cancellation</text>
104
- <text x="1105" y="314" class="node-sub">• idempotency key / action budget</text>
105
- <text x="1105" y="342" class="node-sub">• Action intent / attempt / receipt</text>
106
- <text x="1227" y="366" text-anchor="middle" class="small">需要 CAS / 原子写 / 可恢复语义</text>
107
-
108
- <path d="M1045 270 L1018 270 L1018 708 L320 708 L320 604 L290 604" fill="none" stroke="#dc2626" stroke-width="1.8" marker-end="url(#rose)"/>
109
- <rect x="925" y="681" width="88" height="20" rx="5" fill="#ffffff" opacity=".96"/><text x="969" y="696" text-anchor="middle" class="label">atomic state</text>
110
-
111
- <rect x="1045" y="465" width="365" height="260" rx="14" fill="#faf5ff" stroke="#c084fc" stroke-width="1.6"/>
112
- <text x="1065" y="492" fill="#7e22ce" font-size="12" font-weight="700" letter-spacing=".08em">GIT RELEASE PLANE</text>
113
- <text x="1227" y="535" text-anchor="middle" class="node-title">定义与 Skill 的版本面</text>
114
- <text x="1080" y="574" class="node-sub">• Agent Definition / Skill 源码与快照</text>
115
- <text x="1080" y="603" class="node-sub">• 候选改进、评审、发布、回滚</text>
116
- <text x="1080" y="632" class="node-sub">• 人可干预的语义 checkpoint 导出</text>
117
- <rect x="1080" y="656" width="295" height="42" rx="8" fill="#ffffff" stroke="#d8b4fe" stroke-width="1.2"/>
118
- <text x="1227" y="675" text-anchor="middle" fill="#7e22ce" font-size="12" font-weight="700">Git ≠ runtime lock / Wait / PCB authority</text>
119
- <text x="1227" y="692" text-anchor="middle" class="small">发布是双向的,运行控制仍归宿主</text>
120
-
121
- <path d="M1045 585 L1000 585 L1000 600 L970 600" fill="none" stroke="#7c3aed" stroke-width="1.7" stroke-dasharray="5 3" marker-end="url(#purple)"/>
122
- <rect x="980" y="556" width="63" height="20" rx="5" fill="#ffffff" opacity=".96"/><text x="1011" y="571" text-anchor="middle" class="label">publish</text>
123
-
124
- <rect x="30" y="765" width="1380" height="78" rx="10" fill="#f8fafc" stroke="#cbd5e1" stroke-width="1"/>
125
- <text x="50" y="792" fill="#111827" font-size="13" font-weight="700">介质选择原则</text>
126
- <text x="50" y="821" fill="#334155" font-size="14">当前事项 → Session | 可统计业务事实 → 原生表/任务/日历 | 稳定可复用知识 → 文档/Wiki | 并发与副作用 → Control State | 发布与回滚 → Git</text>
127
-
128
- <line x1="40" y1="873" x2="76" y2="873" stroke="#059669" stroke-width="1.8" marker-end="url(#green)"/><text x="84" y="877" class="small">读取</text>
129
- <line x1="150" y1="873" x2="186" y2="873" stroke="#059669" stroke-width="1.6" stroke-dasharray="5 3" marker-end="url(#green)"/><text x="194" y="877" class="small">写入</text>
130
- <line x1="265" y1="873" x2="301" y2="873" stroke="#7c3aed" stroke-width="1.7" marker-end="url(#purple)"/><text x="309" y="877" class="small">压缩 / 发布</text>
131
- <line x1="440" y1="873" x2="476" y2="873" stroke="#dc2626" stroke-width="1.8" marker-end="url(#rose)"/><text x="484" y="877" class="small">原子控制</text>
132
- </svg>
@@ -1,3 +0,0 @@
1
- # DEAP · 敬请期待
2
-
3
- DEAP 平台的技能包预留位。注册表状态为 `coming-soon`:`dta agent-platform use deap` 与平台命令一律 fail-closed,开放时在 `src/agent-platform.ts` 中把状态改为 `supported` 并在此目录放入平台技能包。