@xdxer/dingtalk-agent 0.1.4-beta.1 → 0.1.4-beta.11
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/CHANGELOG.md +70 -0
- package/README.en.md +397 -0
- package/README.md +500 -47
- package/dist/bin/dingtalk-agent.js +1263 -351
- package/dist/bin/dingtalk-agent.js.map +1 -1
- package/dist/src/actions.js +98 -14
- package/dist/src/actions.js.map +1 -1
- package/dist/src/agent-audit.js +460 -0
- package/dist/src/agent-audit.js.map +1 -0
- package/dist/src/agent-bindings.js +132 -0
- package/dist/src/agent-bindings.js.map +1 -0
- package/dist/src/agent-definition.js +182 -0
- package/dist/src/agent-definition.js.map +1 -0
- package/dist/src/agent-enhance.js +678 -0
- package/dist/src/agent-enhance.js.map +1 -0
- package/dist/src/agent-platform.js +158 -0
- package/dist/src/agent-platform.js.map +1 -0
- package/dist/src/bootstrap.js +125 -17
- package/dist/src/bootstrap.js.map +1 -1
- package/dist/src/config.js +1 -7
- package/dist/src/config.js.map +1 -1
- package/dist/src/development-workspace.js +736 -0
- package/dist/src/development-workspace.js.map +1 -0
- package/dist/src/doctor.js +49 -22
- package/dist/src/doctor.js.map +1 -1
- package/dist/src/dws.js +145 -0
- package/dist/src/dws.js.map +1 -1
- package/dist/src/eval-evidence.js +193 -0
- package/dist/src/eval-evidence.js.map +1 -0
- package/dist/src/init.js +1 -1
- package/dist/src/init.js.map +1 -1
- package/dist/src/invocation.js +36 -0
- package/dist/src/invocation.js.map +1 -0
- package/dist/src/lab.js +679 -0
- package/dist/src/lab.js.map +1 -0
- package/dist/src/lease.js +100 -0
- package/dist/src/lease.js.map +1 -0
- package/dist/src/map.js +157 -0
- package/dist/src/map.js.map +1 -0
- package/dist/src/memory/candidates.js +451 -0
- package/dist/src/memory/candidates.js.map +1 -0
- package/dist/src/memory/completion-evidence.js +536 -0
- package/dist/src/memory/completion-evidence.js.map +1 -0
- package/dist/src/memory/operational.js +263 -0
- package/dist/src/memory/operational.js.map +1 -0
- package/dist/src/memory/remote-state.js +478 -0
- package/dist/src/memory/remote-state.js.map +1 -0
- package/dist/src/memory/task-checkpoints.js +204 -0
- package/dist/src/memory/task-checkpoints.js.map +1 -0
- package/dist/src/multica-deploy.js +1480 -0
- package/dist/src/multica-deploy.js.map +1 -0
- package/dist/src/multica-provider.js +685 -0
- package/dist/src/multica-provider.js.map +1 -0
- package/dist/src/opencode-evals.js +1062 -0
- package/dist/src/opencode-evals.js.map +1 -0
- package/dist/src/opencode-provider.js +531 -0
- package/dist/src/opencode-provider.js.map +1 -0
- package/dist/src/opencode-workspace.js +197 -0
- package/dist/src/opencode-workspace.js.map +1 -0
- package/dist/src/perception.js +225 -0
- package/dist/src/perception.js.map +1 -0
- package/dist/src/personal-event-evals.js +595 -0
- package/dist/src/personal-event-evals.js.map +1 -0
- package/dist/src/promotion.js +786 -0
- package/dist/src/promotion.js.map +1 -0
- package/dist/src/remote-semantic-state-live-evals.js +888 -0
- package/dist/src/remote-semantic-state-live-evals.js.map +1 -0
- package/dist/src/remote-semantic-state-worker.js +38 -0
- package/dist/src/remote-semantic-state-worker.js.map +1 -0
- package/dist/src/remote-state-evals.js +501 -0
- package/dist/src/remote-state-evals.js.map +1 -0
- package/dist/src/response-gate.js +51 -0
- package/dist/src/response-gate.js.map +1 -0
- package/dist/src/robot-evals.js +770 -0
- package/dist/src/robot-evals.js.map +1 -0
- package/dist/src/sessions.js +66 -105
- package/dist/src/sessions.js.map +1 -1
- package/dist/src/setup.js +14 -12
- package/dist/src/setup.js.map +1 -1
- package/dist/src/skill-manager.js +128 -203
- package/dist/src/skill-manager.js.map +1 -1
- package/dist/src/skills.js.map +1 -1
- package/dist/src/storage-evals.js +26 -0
- package/dist/src/storage-evals.js.map +1 -0
- package/dist/src/types.js.map +1 -1
- package/dist/src/upgrade.js +137 -0
- package/dist/src/upgrade.js.map +1 -0
- package/dist/src/waits.js +5 -1
- package/dist/src/waits.js.map +1 -1
- package/dist/src/workspace.js +28 -3
- package/dist/src/workspace.js.map +1 -1
- package/docs/INSTALLATION.md +119 -14
- package/docs/SECOND-AGENT-ACCEPTANCE.md +62 -0
- package/docs/architecture/agent-memory-topology.png +0 -0
- package/docs/architecture/agent-memory-topology.svg +132 -0
- package/docs/architecture/general-agent-kernel-topology.png +0 -0
- package/docs/architecture/general-agent-kernel-topology.svg +149 -0
- package/docs/architecture/provider-bound-development-workspace.png +0 -0
- package/docs/architecture/provider-bound-development-workspace.svg +141 -0
- package/docs/architecture/task-completion-gate.png +0 -0
- package/docs/architecture/task-completion-gate.svg +191 -0
- package/docs/schemas/agent-audit-load-evidence.schema.json +14 -0
- package/docs/schemas/agent-audit.schema.json +92 -0
- package/docs/schemas/agent-bindings.schema.json +54 -0
- package/docs/schemas/agent-definition.schema.json +78 -0
- package/docs/schemas/agent-enhancement-plan.schema.json +88 -0
- package/docs/schemas/agent-enhancement-receipt.schema.json +37 -0
- package/docs/schemas/agent-platform.schema.json +13 -0
- package/docs/schemas/enriched-invocation.schema.json +46 -0
- package/docs/schemas/eval-candidate-plan.schema.json +28 -0
- package/docs/schemas/eval-candidate-result.schema.json +20 -0
- package/docs/schemas/eval-candidate.schema.json +30 -0
- package/docs/schemas/invocation.schema.json +19 -0
- package/docs/schemas/memory-candidate-proposal.schema.json +18 -0
- package/docs/schemas/memory-candidate.schema.json +76 -0
- package/docs/schemas/memory-publish-target.schema.json +25 -0
- package/docs/schemas/multica-deployment-list.schema.json +29 -0
- package/docs/schemas/multica-deployment-operation.schema.json +51 -0
- package/docs/schemas/multica-deployment-plan.schema.json +70 -0
- package/docs/schemas/multica-deployment-receipt.schema.json +87 -0
- package/docs/schemas/multica-deployment-status.schema.json +23 -0
- package/docs/schemas/multica-workspace-inspection.schema.json +77 -0
- package/docs/schemas/multica-workspace-plan.schema.json +68 -0
- package/docs/schemas/multica-workspace-resource-list.schema.json +27 -0
- package/docs/schemas/multica-workspace-status.schema.json +34 -0
- package/docs/schemas/observation.schema.json +21 -0
- package/docs/schemas/operational-memory-provider.schema.json +36 -0
- package/docs/schemas/operational-memory-record.schema.json +24 -0
- package/docs/schemas/perception-input.schema.json +56 -0
- package/docs/schemas/project.schema.json +113 -0
- package/docs/schemas/promotion-list.schema.json +36 -0
- package/docs/schemas/promotion-plan.schema.json +60 -0
- package/docs/schemas/promotion-policy.schema.json +29 -0
- package/docs/schemas/promotion-receipt.schema.json +43 -0
- package/docs/schemas/promotion-status.schema.json +23 -0
- package/docs/schemas/release-readiness.schema.json +66 -0
- package/docs/schemas/remote-semantic-state-live-eval.schema.json +60 -0
- package/docs/schemas/remote-semantic-state-manifest.schema.json +79 -0
- package/docs/schemas/remote-semantic-state-provider.schema.json +98 -0
- package/docs/schemas/response-gate.schema.json +20 -0
- package/docs/schemas/task-checkpoint.schema.json +71 -0
- package/docs/schemas/task-completion-evidence.schema.json +154 -0
- package/docs/schemas/workspace-doctor.schema.json +56 -0
- package/docs/schemas/workspace-state.schema.json +39 -0
- package/evals/baselines/2026-07-16/opencode-basic-010-completion-summary.json +123 -0
- package/evals/baselines/2026-07-16/opencode-basic-skill-required-summary.json +69 -0
- package/evals/baselines/2026-07-16/opencode-multi-surface-summary.json +63 -0
- package/evals/baselines/2026-07-16/remote-state-live-summary.json +70 -0
- package/evals/baselines/2026-07-17/agent-enhance-opencode-dogfood-summary.json +98 -0
- package/evals/baselines/2026-07-17/personal-event-live-readiness-summary.json +68 -0
- package/examples/agents/fde-coach/AGENTS.md +26 -0
- package/examples/agents/fde-coach/MEMORY.md +3 -0
- package/examples/agents/fde-coach/fields/default/field.json +24 -0
- package/examples/agents/fde-coach/knowledge/INDEX.md +4 -0
- package/examples/agents/fde-coach/skills/fde-coach/SKILL.md +13 -0
- package/examples/agents/release-manager/AGENTS.md +26 -0
- package/examples/agents/release-manager/MEMORY.md +3 -0
- package/examples/agents/release-manager/fields/default/field.json +24 -0
- package/examples/agents/release-manager/knowledge/INDEX.md +4 -0
- package/examples/agents/release-manager/skills/release-manager/SKILL.md +13 -0
- package/lab/README.md +109 -0
- package/lab/agent-eval/catalog.json +91 -0
- package/lab/agent-eval/classic-failures.json +177 -0
- package/lab/agent-eval/completion-gate-regression.json +99 -0
- package/lab/agent-eval/personal-event-live.example.json +94 -0
- package/lab/agent-eval/remote-semantic-state-live.example.json +70 -0
- package/lab/agent-eval/remote-semantic-state-provider.fixture.json +47 -0
- package/lab/agent-eval/remote-state-workspace/AGENTS.md +8 -0
- package/lab/agent-eval/remote-state-workspace/opencode.json +7 -0
- package/lab/agent-eval/remote-state-workspace/skills/remote-state-operator/SKILL.md +13 -0
- package/lab/agent-eval/remote-state.example.json +31 -0
- package/lab/agent-eval/workspace/AGENTS.md +7 -0
- package/lab/agent-eval/workspace/MEMORY.md +4 -0
- package/lab/agent-eval/workspace/artifacts/pending-review.md +3 -0
- package/lab/agent-eval/workspace/knowledge/INDEX.md +4 -0
- package/lab/agent-eval/workspace/opencode.json +20 -0
- package/lab/manifest.example.json +27 -0
- package/lab/manifest.personal-event.example.json +27 -0
- package/lab/project-workspace/README.md +11 -0
- package/lab/project-workspace/fake-multica-provider.mjs +266 -0
- package/lab/project-workspace/multica-deploy.fixture.json +29 -0
- package/lab/project-workspace/multica-readonly.fixture.json +69 -0
- package/lab/project-workspace/observation.fixture.json +14 -0
- package/lab/project-workspace/opencode-provider-suite.json +65 -0
- package/lab/project-workspace/project.fixture.json +44 -0
- package/lab/project-workspace/promotion-policy.fixture.json +15 -0
- package/lab/robot-eval/pool.example.json +30 -0
- package/lab/robot-eval/suite.json +123 -0
- package/lab/robot-eval/workspace/AGENTS.md +21 -0
- package/lab/robot-eval/workspace/MEMORY.md +3 -0
- package/lab/robot-eval/workspace/knowledge/INDEX.md +5 -0
- package/lab/robot-eval/workspace/opencode.json +22 -0
- package/lab/schemas/agent-eval-catalog.schema.json +47 -0
- package/lab/schemas/lab-manifest.schema.json +70 -0
- package/lab/schemas/personal-event-eval.schema.json +91 -0
- package/lab/schemas/remote-state-eval.schema.json +66 -0
- package/lab/schemas/robot-eval-suite.schema.json +184 -0
- package/lab/schemas/robot-pool.schema.json +56 -0
- package/package.json +26 -14
- package/skills/dingtalk-agent-boot-multica/SKILL.md +40 -0
- package/skills/dingtalk-agent-compose/SKILL.md +110 -0
- package/skills/dingtalk-agent-compose/assets/AGENTS.template.md +26 -0
- package/skills/dingtalk-agent-compose/assets/agent.bindings.dingtalk-doc.template.json +13 -0
- package/skills/dingtalk-agent-compose/assets/agent.bindings.local.template.json +13 -0
- package/skills/dingtalk-agent-compose/assets/opencode.template.json +12 -0
- package/skills/dingtalk-agent-compose/assets/role-skill.template.md +24 -0
- package/skills/dingtalk-agent-compose/evals/evals.json +94 -0
- package/skills/dingtalk-agent-compose/references/agent-definition-contract.md +55 -0
- package/skills/dingtalk-agent-compose/references/opencode-host-contract.md +65 -0
- package/skills/dingtalk-agent-compose/references/storage-routing.md +20 -0
- package/skills/dingtalk-agent-deploy/SKILL.md +60 -0
- package/skills/dingtalk-agent-deploy/references/multica-deployment-contract.md +49 -0
- package/skills/dingtalk-agent-deploy/references/promotion-observation-contract.md +49 -0
- package/skills/dingtalk-agent-eval/SKILL.md +116 -0
- package/skills/dingtalk-agent-eval/assets/eval-catalog.template.json +18 -0
- package/skills/dingtalk-agent-eval/evals/evals.json +61 -0
- package/skills/dingtalk-agent-eval/references/eval-topology.md +34 -0
- package/skills/dingtalk-agent-eval/references/evidence-contract.md +31 -0
- package/skills/dingtalk-agent-eval/references/scenario-taxonomy.md +25 -0
- package/skills/dingtalk-agent-eval/references/storage-modes.md +75 -0
- package/skills/dingtalk-basic-behavior/SKILL.md +63 -3
- package/skills/dingtalk-basic-behavior/assets/memory-candidate-proposal.json +10 -0
- package/skills/dingtalk-basic-behavior/assets/{task-checkpoint.md → task-checkpoint.json} +2 -21
- package/skills/dingtalk-basic-behavior/references/action-contract.md +2 -0
- package/skills/dingtalk-basic-behavior/references/memory-and-evolution.md +15 -1
- package/skills/dingtalk-basic-behavior/references/perception-and-gates.md +28 -0
- package/skills/dingtalk-basic-behavior/references/task-lifecycle.md +32 -7
- package/dist/src/boot.js +0 -70
- package/dist/src/boot.js.map +0 -1
- package/dist/src/duty.js +0 -74
- package/dist/src/duty.js.map +0 -1
- package/dist/src/kb.js +0 -240
- package/dist/src/kb.js.map +0 -1
- package/dist/src/runs.js +0 -79
- package/dist/src/runs.js.map +0 -1
- package/docs/ARCHITECTURE.md +0 -217
- package/docs/MINIMAL-WORKSPACE-V1.md +0 -172
- package/docs/OPEN-SOURCE-REFERENCES.md +0 -107
- package/docs/SELF-TEST.md +0 -252
- package/docs//345/206/205/347/275/221/345/256/236/347/233/270.md +0 -77
- package/evals/baselines/2026-07-14/behavior-summary.json +0 -28
- package/evals/baselines/2026-07-14/contract-summary.json +0 -18
- package/evals/baselines/2026-07-14/live-canary-summary.json +0 -25
- package/evals/baselines/2026-07-15/dingtalk-basic-behavior-0.3.0/SKILL.md +0 -72
- package/evals/baselines/2026-07-15/dingtalk-basic-behavior-0.3.0/references/action-contract.md +0 -31
- package/evals/baselines/2026-07-15/dingtalk-basic-behavior-0.3.0/references/event-to-behavior.md +0 -22
- package/evals/baselines/2026-07-15/dingtalk-basic-behavior-0.3.0/references/memory-and-evolution.md +0 -25
- package/evals/baselines/2026-07-15/dingtalk-basic-behavior-0.3.0/references/runtime-modes.md +0 -34
- package/evals/baselines/2026-07-15/task-lifecycle-summary.json +0 -50
- package/evals/evals.json +0 -316
- package/evals/fixtures/dm-ambiguous-send.json +0 -4
- package/evals/fixtures/dm-blocked.json +0 -4
- package/evals/fixtures/dm-clear.json +0 -4
- package/evals/fixtures/dm-discussion.json +0 -4
- package/evals/fixtures/dm-doc-write-no-tool.json +0 -4
- package/evals/fixtures/dm-long-task-ack.json +0 -4
- package/evals/fixtures/dm-nonblocking-gap.json +0 -4
- package/evals/fixtures/dm-structured-task.json +0 -4
- package/evals/fixtures/group.json +0 -10
- package/evals/fixtures/mentioned.json +0 -3
- package/evals/run-contract-evals.mjs +0 -1106
- package/evals/run-shadow-evals.mjs +0 -267
- package/evals/runners/README.md +0 -66
- package/evals/runners/claude-shadow.mjs +0 -533
- package/evals/schemas/action-request.schema.json +0 -77
- package/evals/shadow-evals.json +0 -133
- package/skills/AGENTS.md +0 -104
- package/skills//344/273/273/345/212/241.md +0 -48
- package/skills//345/237/272/347/241/200/350/241/214/344/270/272.md +0 -44
- package/skills//345/277/203/350/267/263.md +0 -79
- package/skills//346/266/210/346/201/257.md +0 -50
- package/skills//347/237/245/350/257/206.md +0 -55
- package/skills//350/257/204/346/265/213.md +0 -62
- package/skills//351/222/211/351/222/211.md +0 -64
- package/templates/ontology/index.md +0 -24
- package/templates/ontology/self/access.md +0 -38
- package/templates/ontology/self/role-spec.md +0 -34
- package/templates/ontology/self/workspace.md +0 -41
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
import { existsSync, lstatSync, mkdirSync, readFileSync, realpathSync, renameSync, writeFileSync, } from 'node:fs';
|
|
2
|
+
import { dirname, isAbsolute, join, relative, resolve } from 'node:path';
|
|
3
|
+
import * as dws from '../dws.js';
|
|
4
|
+
import { digest, stableStringify } from '../events.js';
|
|
5
|
+
export const REMOTE_MARKDOWN_FORBIDDEN_FIELDS = [
|
|
6
|
+
'waitId', 'generation', 'idempotencyKey', 'lease', 'Action Receipt', 'credentials',
|
|
7
|
+
];
|
|
8
|
+
const FORBIDDEN_MARKDOWN_PATTERNS = [
|
|
9
|
+
['waitId', /\bwait[-_ ]?id\b/i],
|
|
10
|
+
['generation', /\bgeneration\b/i],
|
|
11
|
+
['idempotencyKey', /\bidempotency[-_ ]?key\b/i],
|
|
12
|
+
['lease', /\blease\b/i],
|
|
13
|
+
['Action Receipt', /\baction[-_ ]?receipt\b/i],
|
|
14
|
+
['credentials', /\b(?:credential|client[-_ ]?secret|access[-_ ]?token|refresh[-_ ]?token|password)s?\b/i],
|
|
15
|
+
];
|
|
16
|
+
export function planRemoteSemanticState(value) {
|
|
17
|
+
const provider = validateProvider(value);
|
|
18
|
+
return {
|
|
19
|
+
$schema: 'dingtalk-agent/remote-semantic-state-plan@1',
|
|
20
|
+
providerId: provider.id,
|
|
21
|
+
providerHash: digest(stableStringify(provider)),
|
|
22
|
+
scopeId: provider.scopeId,
|
|
23
|
+
sideEffect: false,
|
|
24
|
+
remoteRead: false,
|
|
25
|
+
layers: {
|
|
26
|
+
l1: { provider: provider.layers.l1.provider, mode: provider.layers.l1.mode },
|
|
27
|
+
l2: { provider: provider.layers.l2.provider, mode: provider.layers.l2.mode },
|
|
28
|
+
l3: { provider: provider.layers.l3.provider, mode: provider.layers.l3.mode },
|
|
29
|
+
},
|
|
30
|
+
controlState: provider.controlState,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export function rehydrateRemoteSemanticState(root, bootstrap, value) {
|
|
34
|
+
const provider = validateProvider(value);
|
|
35
|
+
validateDefinitionBinding(bootstrap, provider);
|
|
36
|
+
const stateDir = validateStateDir(root, bootstrap.stateDir);
|
|
37
|
+
const providerHash = digest(stableStringify(provider));
|
|
38
|
+
const memory = validateBootstrapMount(root, stateDir, bootstrap, provider, 'memory', provider.layers.l1.uri);
|
|
39
|
+
const knowledge = validateBootstrapMount(root, stateDir, bootstrap, provider, 'knowledge', provider.layers.l3.uri);
|
|
40
|
+
const identity = dws.getSelf(provider.authority.profile);
|
|
41
|
+
const actualUserId = String(findValue(identity, ['userId', 'user_id', 'userid']) || '');
|
|
42
|
+
if (!actualUserId || actualUserId !== provider.authority.expectedUserId) {
|
|
43
|
+
throw new Error(`Remote Semantic State DWS 身份不符:expected=${provider.authority.expectedUserId}, ` +
|
|
44
|
+
`actual=${actualUserId || '-'}`);
|
|
45
|
+
}
|
|
46
|
+
assertRemoteMarkdownSafe('l1', memory.content);
|
|
47
|
+
assertRemoteMarkdownSafe('l3', knowledge.content);
|
|
48
|
+
const memoryReadback = readRemoteDocument(provider.layers.l1.uri, provider.authority.profile, 'l1');
|
|
49
|
+
const knowledgeReadback = readRemoteDocument(provider.layers.l3.uri, provider.authority.profile, 'l3');
|
|
50
|
+
if (digest(memoryReadback) !== memory.mount.hash) {
|
|
51
|
+
throw new Error('Remote Semantic State l1 远端状态在 bootstrap 后发生漂移');
|
|
52
|
+
}
|
|
53
|
+
if (digest(knowledgeReadback) !== knowledge.mount.hash) {
|
|
54
|
+
throw new Error('Remote Semantic State l3 远端状态在 bootstrap 后发生漂移');
|
|
55
|
+
}
|
|
56
|
+
const structured = readStructuredHotState(provider);
|
|
57
|
+
const structuredReadback = readStructuredHotState(provider);
|
|
58
|
+
const structuredBody = stableStringify(structured);
|
|
59
|
+
if (structuredBody !== stableStringify(structuredReadback)) {
|
|
60
|
+
throw new Error('Remote Semantic State l2 AI 表格在独立回读时发生漂移');
|
|
61
|
+
}
|
|
62
|
+
const aggregateRoot = join(stateDir, 'cache', 'remote-semantic-state', provider.id);
|
|
63
|
+
const structuredPath = join(aggregateRoot, 'l2', 'record.json');
|
|
64
|
+
writeAtomic(structuredPath, structuredBody);
|
|
65
|
+
const layers = {
|
|
66
|
+
l1: manifestLayer('l1', provider.layers.l1, memory.mount.source, 'ALIDOC/adoc', relativeCachePath(stateDir, memory.mount.path), memory.mount.hash),
|
|
67
|
+
l2: manifestLayer('l2', provider.layers.l2, `dingtalk-aitable:${provider.layers.l2.baseId}/${provider.layers.l2.tableId}/${provider.layers.l2.recordId}`, 'application/json', relativeCachePath(stateDir, structuredPath), digest(structuredBody)),
|
|
68
|
+
l3: manifestLayer('l3', provider.layers.l3, knowledge.mount.source, 'ALIDOC/adoc', relativeCachePath(stateDir, knowledge.mount.path), knowledge.mount.hash),
|
|
69
|
+
};
|
|
70
|
+
const stateHash = semanticStateHash(providerHash, bootstrap.definition.hash, provider.scopeId, layers, structured.nextAction);
|
|
71
|
+
const unsigned = {
|
|
72
|
+
$schema: 'dingtalk-agent/remote-semantic-state-manifest@1',
|
|
73
|
+
providerId: provider.id,
|
|
74
|
+
providerHash,
|
|
75
|
+
scopeId: provider.scopeId,
|
|
76
|
+
definitionHash: bootstrap.definition.hash,
|
|
77
|
+
authority: {
|
|
78
|
+
profile: provider.authority.profile,
|
|
79
|
+
expectedUserId: provider.authority.expectedUserId,
|
|
80
|
+
actualUserId,
|
|
81
|
+
},
|
|
82
|
+
layers,
|
|
83
|
+
nextAction: structured.nextAction,
|
|
84
|
+
stateHash,
|
|
85
|
+
controlState: {
|
|
86
|
+
provider: 'host-atomic-store',
|
|
87
|
+
remoteProjection: false,
|
|
88
|
+
excludedFromRemoteMarkdown: [...REMOTE_MARKDOWN_FORBIDDEN_FIELDS],
|
|
89
|
+
},
|
|
90
|
+
pulledAt: new Date().toISOString(),
|
|
91
|
+
};
|
|
92
|
+
const manifest = {
|
|
93
|
+
...unsigned,
|
|
94
|
+
hash: digest(stableStringify(unsigned)),
|
|
95
|
+
};
|
|
96
|
+
writeAtomic(join(aggregateRoot, 'manifest.json'), JSON.stringify(manifest, null, 2) + '\n');
|
|
97
|
+
return verifyRemoteSemanticStateCache(root, bootstrap, provider);
|
|
98
|
+
}
|
|
99
|
+
export function verifyRemoteSemanticStateCache(root, bootstrap, value) {
|
|
100
|
+
const provider = validateProvider(value);
|
|
101
|
+
validateDefinitionBinding(bootstrap, provider);
|
|
102
|
+
const stateDir = validateStateDir(root, bootstrap.stateDir);
|
|
103
|
+
const providerHash = digest(stableStringify(provider));
|
|
104
|
+
const memory = validateBootstrapMount(root, stateDir, bootstrap, provider, 'memory', provider.layers.l1.uri);
|
|
105
|
+
const knowledge = validateBootstrapMount(root, stateDir, bootstrap, provider, 'knowledge', provider.layers.l3.uri);
|
|
106
|
+
const manifestPath = join(stateDir, 'cache', 'remote-semantic-state', provider.id, 'manifest.json');
|
|
107
|
+
if (!existsSync(manifestPath))
|
|
108
|
+
throw new Error('Remote Semantic State 缺少聚合 manifest');
|
|
109
|
+
const manifest = readJson(manifestPath);
|
|
110
|
+
if (manifest.$schema !== 'dingtalk-agent/remote-semantic-state-manifest@1') {
|
|
111
|
+
throw new Error('Remote Semantic State manifest schema 非法');
|
|
112
|
+
}
|
|
113
|
+
if (manifest.providerId !== provider.id || manifest.providerHash !== providerHash ||
|
|
114
|
+
manifest.scopeId !== provider.scopeId ||
|
|
115
|
+
manifest.definitionHash !== bootstrap.definition.hash) {
|
|
116
|
+
throw new Error('Remote Semantic State manifest Provider/Definition/scope 绑定不一致');
|
|
117
|
+
}
|
|
118
|
+
if (manifest.authority?.profile !== provider.authority.profile ||
|
|
119
|
+
manifest.authority?.expectedUserId !== provider.authority.expectedUserId ||
|
|
120
|
+
manifest.authority?.actualUserId !== provider.authority.expectedUserId) {
|
|
121
|
+
throw new Error('Remote Semantic State manifest 身份绑定不一致');
|
|
122
|
+
}
|
|
123
|
+
assertManifestLayer(manifest.layers?.l1, 'l1', provider.layers.l1, memory.mount.source, relativeCachePath(stateDir, memory.mount.path));
|
|
124
|
+
assertManifestLayer(manifest.layers?.l2, 'l2', provider.layers.l2, `dingtalk-aitable:${provider.layers.l2.baseId}/${provider.layers.l2.tableId}/${provider.layers.l2.recordId}`, join('cache', 'remote-semantic-state', provider.id, 'l2', 'record.json'));
|
|
125
|
+
assertManifestLayer(manifest.layers?.l3, 'l3', provider.layers.l3, knowledge.mount.source, relativeCachePath(stateDir, knowledge.mount.path));
|
|
126
|
+
const paths = Object.values(manifest.layers).map((item) => item.cachePath);
|
|
127
|
+
if (new Set(paths).size !== paths.length) {
|
|
128
|
+
throw new Error('Remote Semantic State slot cachePath 串线');
|
|
129
|
+
}
|
|
130
|
+
const cacheBodies = { l1: '', l2: '', l3: '' };
|
|
131
|
+
for (const slot of ['l1', 'l2', 'l3']) {
|
|
132
|
+
const layer = manifest.layers[slot];
|
|
133
|
+
const path = safeCachePath(stateDir, layer.cachePath);
|
|
134
|
+
const body = readFileSync(path, 'utf8');
|
|
135
|
+
const cacheHash = digest(body);
|
|
136
|
+
if (cacheHash !== layer.cacheHash || cacheHash !== layer.remoteHash) {
|
|
137
|
+
throw new Error(`Remote Semantic State ${slot} 缓存与远端 hash 不一致`);
|
|
138
|
+
}
|
|
139
|
+
cacheBodies[slot] = body;
|
|
140
|
+
}
|
|
141
|
+
assertRemoteMarkdownSafe('l1', cacheBodies.l1);
|
|
142
|
+
assertRemoteMarkdownSafe('l3', cacheBodies.l3);
|
|
143
|
+
const structured = validateCachedStructuredState(readJsonText(cacheBodies.l2), provider);
|
|
144
|
+
if (manifest.nextAction !== structured.nextAction) {
|
|
145
|
+
throw new Error('Remote Semantic State manifest nextAction 与 l2 缓存不一致');
|
|
146
|
+
}
|
|
147
|
+
const stateHash = semanticStateHash(providerHash, bootstrap.definition.hash, provider.scopeId, manifest.layers, structured.nextAction);
|
|
148
|
+
if (manifest.stateHash !== stateHash) {
|
|
149
|
+
throw new Error('Remote Semantic State stateHash 不一致');
|
|
150
|
+
}
|
|
151
|
+
if (manifest.controlState?.provider !== 'host-atomic-store' ||
|
|
152
|
+
manifest.controlState?.remoteProjection !== false ||
|
|
153
|
+
stableStringify(manifest.controlState.excludedFromRemoteMarkdown) !==
|
|
154
|
+
stableStringify([...REMOTE_MARKDOWN_FORBIDDEN_FIELDS])) {
|
|
155
|
+
throw new Error('Remote Semantic State control state 边界不一致');
|
|
156
|
+
}
|
|
157
|
+
const { hash, ...unsigned } = manifest;
|
|
158
|
+
if (!hash || digest(stableStringify(unsigned)) !== hash) {
|
|
159
|
+
throw new Error('Remote Semantic State manifest hash 不一致');
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
$schema: 'dingtalk-agent/remote-semantic-state-rehydration@1',
|
|
163
|
+
stateDir,
|
|
164
|
+
manifestPath,
|
|
165
|
+
definitionHash: bootstrap.definition.hash,
|
|
166
|
+
providerHash,
|
|
167
|
+
memoryHash: manifest.layers.l1.remoteHash,
|
|
168
|
+
structuredStateHash: manifest.layers.l2.remoteHash,
|
|
169
|
+
knowledgeHash: manifest.layers.l3.remoteHash,
|
|
170
|
+
stateHash,
|
|
171
|
+
nextAction: structured.nextAction,
|
|
172
|
+
manifest,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
function validateProvider(value) {
|
|
176
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
177
|
+
throw new Error('Remote Semantic State Provider 必须是 JSON object');
|
|
178
|
+
}
|
|
179
|
+
const input = value;
|
|
180
|
+
assertKeys(input, ['$schema', 'id', 'scopeId', 'authority', 'layers', 'controlState'], 'Provider');
|
|
181
|
+
if (input.$schema !== 'dingtalk-agent/remote-semantic-state-provider@1' ||
|
|
182
|
+
!/^[a-z0-9][a-z0-9._-]*$/.test(clean(input.id)) || !clean(input.scopeId)) {
|
|
183
|
+
throw new Error('Remote Semantic State Provider schema/id/scopeId 非法');
|
|
184
|
+
}
|
|
185
|
+
assertKeys(input.authority, ['profile', 'expectedUserId'], 'authority');
|
|
186
|
+
if (!clean(input.authority?.profile) || clean(input.authority?.profile).includes(',') ||
|
|
187
|
+
!clean(input.authority?.expectedUserId)) {
|
|
188
|
+
throw new Error('Remote Semantic State Provider 必须固定单一 profile 和 expectedUserId');
|
|
189
|
+
}
|
|
190
|
+
assertKeys(input.layers, ['l1', 'l2', 'l3'], 'layers');
|
|
191
|
+
validateDocLayer(input.layers?.l1, 'l1', 'session-working-memory', 'semantic-read-only-mirror');
|
|
192
|
+
validateDocLayer(input.layers?.l3, 'l3', 'long-term-knowledge', 'reviewed-knowledge-source');
|
|
193
|
+
const l2 = input.layers?.l2;
|
|
194
|
+
assertKeys(l2, [
|
|
195
|
+
'provider', 'semanticRole', 'mode', 'baseId', 'tableId', 'recordId', 'expected', 'fields',
|
|
196
|
+
], 'l2');
|
|
197
|
+
if (l2?.provider !== 'dingtalk-aitable' || l2?.semanticRole !== 'structured-hot-state' ||
|
|
198
|
+
l2?.mode !== 'business-fact-source') {
|
|
199
|
+
throw new Error('Remote Semantic State l2 必须是结构化 AI 表格业务事实源');
|
|
200
|
+
}
|
|
201
|
+
for (const key of ['baseId', 'tableId', 'recordId']) {
|
|
202
|
+
if (!clean(l2?.[key]))
|
|
203
|
+
throw new Error(`Remote Semantic State l2 缺少 ${key}`);
|
|
204
|
+
}
|
|
205
|
+
assertKeys(l2?.expected, ['key', 'scopeId'], 'l2.expected');
|
|
206
|
+
if (!clean(l2?.expected?.key) || clean(l2?.expected?.scopeId) !== clean(input.scopeId)) {
|
|
207
|
+
throw new Error('Remote Semantic State l2 expected key/scopeId 非法');
|
|
208
|
+
}
|
|
209
|
+
const fieldNames = ['key', 'scopeId', 'status', 'nextAction', 'summary', 'sourceRefs'];
|
|
210
|
+
assertKeys(l2?.fields, fieldNames, 'l2.fields');
|
|
211
|
+
const fieldIds = fieldNames.map((name) => clean(l2?.fields?.[name]));
|
|
212
|
+
if (fieldIds.some((item) => !item) || new Set(fieldIds).size !== fieldIds.length) {
|
|
213
|
+
throw new Error('Remote Semantic State l2 fields 必须是互不复用的显式 fieldId');
|
|
214
|
+
}
|
|
215
|
+
assertKeys(input.controlState, ['provider', 'remoteProjection'], 'controlState');
|
|
216
|
+
if (input.controlState?.provider !== 'host-atomic-store' ||
|
|
217
|
+
input.controlState?.remoteProjection !== false) {
|
|
218
|
+
throw new Error('Remote Semantic State control state 必须留在宿主原子存储且禁止远端投影');
|
|
219
|
+
}
|
|
220
|
+
return JSON.parse(JSON.stringify(input));
|
|
221
|
+
}
|
|
222
|
+
function validateDocLayer(value, slot, semanticRole, mode) {
|
|
223
|
+
assertKeys(value, ['provider', 'semanticRole', 'mode', 'uri'], slot);
|
|
224
|
+
if (value?.provider !== 'dingtalk-doc' || value?.semanticRole !== semanticRole ||
|
|
225
|
+
value?.mode !== mode || !clean(value?.uri).startsWith('dingtalk-doc:') ||
|
|
226
|
+
!clean(value?.uri).slice('dingtalk-doc:'.length)) {
|
|
227
|
+
throw new Error(`Remote Semantic State ${slot} 文档 Provider 合同非法`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
function validateDefinitionBinding(bootstrap, provider) {
|
|
231
|
+
const definition = bootstrap.definition;
|
|
232
|
+
if (definition.status !== 'ready' ||
|
|
233
|
+
definition.authority.dwsProfile !== provider.authority.profile ||
|
|
234
|
+
definition.authority.expectedUserId !== provider.authority.expectedUserId ||
|
|
235
|
+
definition.storage.memory !== provider.layers.l1.uri ||
|
|
236
|
+
definition.storage.knowledge !== provider.layers.l3.uri ||
|
|
237
|
+
bootstrap.scopeId !== provider.scopeId) {
|
|
238
|
+
throw new Error('Remote Semantic State 与本地 Definition/authority/storage/scope 绑定不一致');
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
function validateBootstrapMount(root, stateDir, bootstrap, provider, slot, source) {
|
|
242
|
+
const mount = bootstrap.mounts.find((item) => item.slot === slot);
|
|
243
|
+
if (!mount || mount.provider !== 'dingtalk-doc' || mount.source !== source) {
|
|
244
|
+
throw new Error(`Remote Semantic State ${slot} mount 与 Provider slot 串线`);
|
|
245
|
+
}
|
|
246
|
+
const path = safeExistingPath(root, stateDir, mount.path, `${slot} cache`);
|
|
247
|
+
const content = readFileSync(path, 'utf8');
|
|
248
|
+
if (digest(content) !== mount.hash) {
|
|
249
|
+
throw new Error(`Remote Semantic State ${slot} mount/cache hash 不一致`);
|
|
250
|
+
}
|
|
251
|
+
const cacheManifestPath = join(dirname(path), 'manifest.json');
|
|
252
|
+
const cacheManifest = readJson(cacheManifestPath);
|
|
253
|
+
if (cacheManifest.$schema !== 'dingtalk-agent/bootstrap-cache@1' ||
|
|
254
|
+
cacheManifest.source !== source || cacheManifest.profile !== provider.authority.profile ||
|
|
255
|
+
cacheManifest.hash !== mount.hash ||
|
|
256
|
+
realpathSync(cacheManifest.path) !== path) {
|
|
257
|
+
throw new Error(`Remote Semantic State ${slot} bootstrap manifest 不一致`);
|
|
258
|
+
}
|
|
259
|
+
return { mount, content };
|
|
260
|
+
}
|
|
261
|
+
function readRemoteDocument(uri, profile, slot) {
|
|
262
|
+
const ref = uri.slice('dingtalk-doc:'.length);
|
|
263
|
+
const info = dws.docInfo(ref, profile);
|
|
264
|
+
const contentType = String(info?.contentType || '').toUpperCase();
|
|
265
|
+
const extension = String(info?.extension || '').toLowerCase();
|
|
266
|
+
if (contentType !== 'ALIDOC' || extension !== 'adoc') {
|
|
267
|
+
throw new Error(`Remote Semantic State ${slot} 只接受在线文档 adoc;` +
|
|
268
|
+
`实际 contentType=${contentType || '?'} extension=${extension || '?'}`);
|
|
269
|
+
}
|
|
270
|
+
const body = String(dws.readDoc(ref, profile));
|
|
271
|
+
assertRemoteMarkdownSafe(slot, body);
|
|
272
|
+
return body;
|
|
273
|
+
}
|
|
274
|
+
function readStructuredHotState(provider) {
|
|
275
|
+
const layer = provider.layers.l2;
|
|
276
|
+
const rows = dws.queryAiTableRecords({
|
|
277
|
+
baseId: layer.baseId,
|
|
278
|
+
tableId: layer.tableId,
|
|
279
|
+
recordIds: [layer.recordId],
|
|
280
|
+
profile: provider.authority.profile,
|
|
281
|
+
});
|
|
282
|
+
if (rows.length !== 1 || clean(rows[0]?.recordId) !== layer.recordId) {
|
|
283
|
+
throw new Error(`Remote Semantic State l2 recordId=${layer.recordId} 必须精确回读一条记录`);
|
|
284
|
+
}
|
|
285
|
+
const cells = rows[0]?.cells;
|
|
286
|
+
if (!cells || typeof cells !== 'object' || Array.isArray(cells)) {
|
|
287
|
+
throw new Error('Remote Semantic State l2 回读缺少 cells');
|
|
288
|
+
}
|
|
289
|
+
const fields = layer.fields;
|
|
290
|
+
return validateStructuredState({
|
|
291
|
+
recordId: layer.recordId,
|
|
292
|
+
key: textCell(cells[fields.key]),
|
|
293
|
+
scopeId: textCell(cells[fields.scopeId]),
|
|
294
|
+
status: textCell(cells[fields.status]),
|
|
295
|
+
nextAction: textCell(cells[fields.nextAction]),
|
|
296
|
+
summary: textCell(cells[fields.summary]),
|
|
297
|
+
sourceRefs: textCell(cells[fields.sourceRefs]),
|
|
298
|
+
}, provider);
|
|
299
|
+
}
|
|
300
|
+
function validateCachedStructuredState(value, provider) {
|
|
301
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
302
|
+
throw new Error('Remote Semantic State l2 cache 必须是 JSON object');
|
|
303
|
+
}
|
|
304
|
+
assertKeys(value, [
|
|
305
|
+
'recordId', 'key', 'scopeId', 'status', 'nextAction', 'summary', 'sourceRefs',
|
|
306
|
+
], 'l2 cache');
|
|
307
|
+
const input = value;
|
|
308
|
+
return validateStructuredState({
|
|
309
|
+
recordId: clean(input.recordId),
|
|
310
|
+
key: clean(input.key),
|
|
311
|
+
scopeId: clean(input.scopeId),
|
|
312
|
+
status: clean(input.status),
|
|
313
|
+
nextAction: clean(input.nextAction),
|
|
314
|
+
summary: clean(input.summary),
|
|
315
|
+
sourceRefs: clean(input.sourceRefs),
|
|
316
|
+
}, provider);
|
|
317
|
+
}
|
|
318
|
+
function validateStructuredState(state, provider) {
|
|
319
|
+
if (state.recordId !== provider.layers.l2.recordId ||
|
|
320
|
+
state.key !== provider.layers.l2.expected.key ||
|
|
321
|
+
state.scopeId !== provider.scopeId) {
|
|
322
|
+
throw new Error('Remote Semantic State l2 recordId/key/scopeId 绑定不一致');
|
|
323
|
+
}
|
|
324
|
+
for (const key of ['status', 'nextAction', 'summary', 'sourceRefs']) {
|
|
325
|
+
if (!state[key])
|
|
326
|
+
throw new Error(`Remote Semantic State l2 缺少可恢复 ${key}`);
|
|
327
|
+
}
|
|
328
|
+
return state;
|
|
329
|
+
}
|
|
330
|
+
function manifestLayer(slot, layer, source, mediaType, cachePath, hash) {
|
|
331
|
+
return {
|
|
332
|
+
slot,
|
|
333
|
+
semanticRole: layer.semanticRole,
|
|
334
|
+
provider: layer.provider,
|
|
335
|
+
mode: layer.mode,
|
|
336
|
+
source,
|
|
337
|
+
mediaType,
|
|
338
|
+
cachePath,
|
|
339
|
+
remoteHash: hash,
|
|
340
|
+
cacheHash: hash,
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
function assertManifestLayer(value, slot, providerLayer, source, cachePath) {
|
|
344
|
+
if (!value || value.slot !== slot || value.provider !== providerLayer.provider ||
|
|
345
|
+
value.semanticRole !== providerLayer.semanticRole || value.mode !== providerLayer.mode ||
|
|
346
|
+
value.source !== source || value.cachePath !== cachePath) {
|
|
347
|
+
throw new Error(`Remote Semantic State manifest ${slot} slot/source/cachePath 串线`);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
function semanticStateHash(providerHash, definitionHash, scopeId, layers, nextAction) {
|
|
351
|
+
return digest(stableStringify({
|
|
352
|
+
$schema: 'dingtalk-agent/remote-semantic-state@1',
|
|
353
|
+
providerHash,
|
|
354
|
+
definitionHash,
|
|
355
|
+
scopeId,
|
|
356
|
+
layers: {
|
|
357
|
+
l1: { source: layers.l1.source, hash: layers.l1.remoteHash },
|
|
358
|
+
l2: { source: layers.l2.source, hash: layers.l2.remoteHash },
|
|
359
|
+
l3: { source: layers.l3.source, hash: layers.l3.remoteHash },
|
|
360
|
+
},
|
|
361
|
+
nextAction,
|
|
362
|
+
}));
|
|
363
|
+
}
|
|
364
|
+
function assertRemoteMarkdownSafe(slot, body) {
|
|
365
|
+
const found = FORBIDDEN_MARKDOWN_PATTERNS
|
|
366
|
+
.filter(([, pattern]) => pattern.test(body))
|
|
367
|
+
.map(([name]) => name);
|
|
368
|
+
if (found.length) {
|
|
369
|
+
throw new Error(`Remote Semantic State ${slot} Markdown 含宿主 control state/凭据字段: ${found.join(', ')}`);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
function validateStateDir(root, input) {
|
|
373
|
+
if (!input)
|
|
374
|
+
throw new Error('Remote Semantic State 需要 bootstrap stateDir');
|
|
375
|
+
const rootReal = realpathSync(resolve(root));
|
|
376
|
+
const stateDir = realpathSync(resolve(input));
|
|
377
|
+
assertInside(rootReal, stateDir, 'stateDir');
|
|
378
|
+
return stateDir;
|
|
379
|
+
}
|
|
380
|
+
function relativeCachePath(stateDir, path) {
|
|
381
|
+
const rel = relative(stateDir, realpathSync(path));
|
|
382
|
+
if (!rel || rel === '..' || rel.startsWith(`..${process.platform === 'win32' ? '\\' : '/'}`)) {
|
|
383
|
+
throw new Error('Remote Semantic State cache 必须位于 stateDir 内');
|
|
384
|
+
}
|
|
385
|
+
return rel;
|
|
386
|
+
}
|
|
387
|
+
function safeCachePath(stateDir, input) {
|
|
388
|
+
if (!input || isAbsolute(input) || input.split(/[\\/]/).includes('..')) {
|
|
389
|
+
throw new Error(`Remote Semantic State cachePath 非法: ${input || '-'}`);
|
|
390
|
+
}
|
|
391
|
+
const path = realpathSync(resolve(stateDir, input));
|
|
392
|
+
assertInside(stateDir, path, 'cachePath');
|
|
393
|
+
if (!lstatSync(path).isFile() || lstatSync(path).isSymbolicLink()) {
|
|
394
|
+
throw new Error(`Remote Semantic State cache 必须是普通文件: ${input}`);
|
|
395
|
+
}
|
|
396
|
+
return path;
|
|
397
|
+
}
|
|
398
|
+
function safeExistingPath(root, stateDir, input, label) {
|
|
399
|
+
const path = realpathSync(resolve(input));
|
|
400
|
+
assertInside(realpathSync(resolve(root)), path, label);
|
|
401
|
+
assertInside(stateDir, path, label);
|
|
402
|
+
if (!lstatSync(path).isFile() || lstatSync(path).isSymbolicLink()) {
|
|
403
|
+
throw new Error(`Remote Semantic State ${label} 必须是普通文件`);
|
|
404
|
+
}
|
|
405
|
+
return path;
|
|
406
|
+
}
|
|
407
|
+
function assertInside(root, path, label) {
|
|
408
|
+
const rel = relative(resolve(root), resolve(path));
|
|
409
|
+
if (rel === '..' || rel.startsWith(`..${process.platform === 'win32' ? '\\' : '/'}`)) {
|
|
410
|
+
throw new Error(`Remote Semantic State ${label} 越界`);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
function textCell(value) {
|
|
414
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
415
|
+
const input = value;
|
|
416
|
+
return clean(input.name ?? input.text ?? input.value);
|
|
417
|
+
}
|
|
418
|
+
return clean(value);
|
|
419
|
+
}
|
|
420
|
+
function findValue(value, keys) {
|
|
421
|
+
if (!value || typeof value !== 'object')
|
|
422
|
+
return undefined;
|
|
423
|
+
if (Array.isArray(value)) {
|
|
424
|
+
for (const item of value) {
|
|
425
|
+
const found = findValue(item, keys);
|
|
426
|
+
if (found !== undefined)
|
|
427
|
+
return found;
|
|
428
|
+
}
|
|
429
|
+
return undefined;
|
|
430
|
+
}
|
|
431
|
+
const input = value;
|
|
432
|
+
for (const key of keys)
|
|
433
|
+
if (input[key] !== undefined)
|
|
434
|
+
return input[key];
|
|
435
|
+
for (const item of Object.values(input)) {
|
|
436
|
+
const found = findValue(item, keys);
|
|
437
|
+
if (found !== undefined)
|
|
438
|
+
return found;
|
|
439
|
+
}
|
|
440
|
+
return undefined;
|
|
441
|
+
}
|
|
442
|
+
function assertKeys(value, allowed, label) {
|
|
443
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
444
|
+
throw new Error(`Remote Semantic State ${label} 必须是 object`);
|
|
445
|
+
}
|
|
446
|
+
const extras = Object.keys(value).filter((key) => !allowed.includes(key));
|
|
447
|
+
if (extras.length) {
|
|
448
|
+
throw new Error(`Remote Semantic State ${label} 含未知字段: ${extras.join(', ')}`);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
function readJson(path) {
|
|
452
|
+
if (!existsSync(path))
|
|
453
|
+
throw new Error(`Remote Semantic State 文件不存在: ${path}`);
|
|
454
|
+
try {
|
|
455
|
+
return JSON.parse(readFileSync(path, 'utf8'));
|
|
456
|
+
}
|
|
457
|
+
catch (error) {
|
|
458
|
+
throw new Error(`Remote Semantic State JSON 非法: ${error.message}`);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
function readJsonText(text) {
|
|
462
|
+
try {
|
|
463
|
+
return JSON.parse(text);
|
|
464
|
+
}
|
|
465
|
+
catch (error) {
|
|
466
|
+
throw new Error(`Remote Semantic State cache JSON 非法: ${error.message}`);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
function writeAtomic(path, value) {
|
|
470
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
471
|
+
const temporary = `${path}.${process.pid}.${Date.now()}.tmp`;
|
|
472
|
+
writeFileSync(temporary, value, { flag: 'wx' });
|
|
473
|
+
renameSync(temporary, path);
|
|
474
|
+
}
|
|
475
|
+
function clean(value) {
|
|
476
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
477
|
+
}
|
|
478
|
+
//# sourceMappingURL=remote-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-state.js","sourceRoot":"","sources":["../../../src/memory/remote-state.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n existsSync, lstatSync, mkdirSync, readFileSync, realpathSync, renameSync, writeFileSync,\n} from 'node:fs'\nimport { dirname, isAbsolute, join, relative, resolve } from 'node:path'\nimport type { BootstrapMount, BootstrapResult } from '../bootstrap.js'\nimport * as dws from '../dws.js'\nimport { digest, stableStringify } from '../events.js'\n\ntype SemanticLayer = 'l1' | 'l2' | 'l3'\n\nexport const REMOTE_MARKDOWN_FORBIDDEN_FIELDS = [\n 'waitId', 'generation', 'idempotencyKey', 'lease', 'Action Receipt', 'credentials',\n] as const\n\nconst FORBIDDEN_MARKDOWN_PATTERNS: Array<[string, RegExp]> = [\n ['waitId', /\\bwait[-_ ]?id\\b/i],\n ['generation', /\\bgeneration\\b/i],\n ['idempotencyKey', /\\bidempotency[-_ ]?key\\b/i],\n ['lease', /\\blease\\b/i],\n ['Action Receipt', /\\baction[-_ ]?receipt\\b/i],\n ['credentials', /\\b(?:credential|client[-_ ]?secret|access[-_ ]?token|refresh[-_ ]?token|password)s?\\b/i],\n]\n\nexport interface RemoteSemanticStateProvider {\n $schema: 'dingtalk-agent/remote-semantic-state-provider@1'\n id: string\n scopeId: string\n authority: { profile: string; expectedUserId: string }\n layers: {\n l1: {\n provider: 'dingtalk-doc'\n semanticRole: 'session-working-memory'\n mode: 'semantic-read-only-mirror'\n uri: string\n }\n l2: {\n provider: 'dingtalk-aitable'\n semanticRole: 'structured-hot-state'\n mode: 'business-fact-source'\n baseId: string\n tableId: string\n recordId: string\n expected: { key: string; scopeId: string }\n fields: {\n key: string\n scopeId: string\n status: string\n nextAction: string\n summary: string\n sourceRefs: string\n }\n }\n l3: {\n provider: 'dingtalk-doc'\n semanticRole: 'long-term-knowledge'\n mode: 'reviewed-knowledge-source'\n uri: string\n }\n }\n controlState: {\n provider: 'host-atomic-store'\n remoteProjection: false\n }\n}\n\ninterface StructuredHotState {\n recordId: string\n key: string\n scopeId: string\n status: string\n nextAction: string\n summary: string\n sourceRefs: string\n}\n\ninterface ManifestLayer {\n slot: SemanticLayer\n semanticRole: string\n provider: 'dingtalk-doc' | 'dingtalk-aitable'\n mode: string\n source: string\n mediaType: 'ALIDOC/adoc' | 'application/json'\n cachePath: string\n remoteHash: string\n cacheHash: string\n}\n\nexport interface RemoteSemanticStateManifest {\n $schema: 'dingtalk-agent/remote-semantic-state-manifest@1'\n providerId: string\n providerHash: string\n scopeId: string\n definitionHash: string\n authority: { profile: string; expectedUserId: string; actualUserId: string }\n layers: { l1: ManifestLayer; l2: ManifestLayer; l3: ManifestLayer }\n nextAction: string\n stateHash: string\n controlState: {\n provider: 'host-atomic-store'\n remoteProjection: false\n excludedFromRemoteMarkdown: string[]\n }\n pulledAt: string\n hash: string\n}\n\nexport interface RemoteSemanticStateResult {\n $schema: 'dingtalk-agent/remote-semantic-state-rehydration@1'\n stateDir: string\n manifestPath: string\n definitionHash: string\n providerHash: string\n memoryHash: string\n structuredStateHash: string\n knowledgeHash: string\n stateHash: string\n nextAction: string\n manifest: RemoteSemanticStateManifest\n}\n\nexport function planRemoteSemanticState(value: unknown): Record<string, unknown> {\n const provider = validateProvider(value)\n return {\n $schema: 'dingtalk-agent/remote-semantic-state-plan@1',\n providerId: provider.id,\n providerHash: digest(stableStringify(provider)),\n scopeId: provider.scopeId,\n sideEffect: false,\n remoteRead: false,\n layers: {\n l1: { provider: provider.layers.l1.provider, mode: provider.layers.l1.mode },\n l2: { provider: provider.layers.l2.provider, mode: provider.layers.l2.mode },\n l3: { provider: provider.layers.l3.provider, mode: provider.layers.l3.mode },\n },\n controlState: provider.controlState,\n }\n}\n\nexport function rehydrateRemoteSemanticState(\n root: string,\n bootstrap: BootstrapResult,\n value: unknown,\n): RemoteSemanticStateResult {\n const provider = validateProvider(value)\n validateDefinitionBinding(bootstrap, provider)\n const stateDir = validateStateDir(root, bootstrap.stateDir)\n const providerHash = digest(stableStringify(provider))\n const memory = validateBootstrapMount(\n root, stateDir, bootstrap, provider, 'memory', provider.layers.l1.uri,\n )\n const knowledge = validateBootstrapMount(\n root, stateDir, bootstrap, provider, 'knowledge', provider.layers.l3.uri,\n )\n\n const identity = dws.getSelf(provider.authority.profile)\n const actualUserId = String(findValue(identity, ['userId', 'user_id', 'userid']) || '')\n if (!actualUserId || actualUserId !== provider.authority.expectedUserId) {\n throw new Error(\n `Remote Semantic State DWS 身份不符:expected=${provider.authority.expectedUserId}, ` +\n `actual=${actualUserId || '-'}`,\n )\n }\n\n assertRemoteMarkdownSafe('l1', memory.content)\n assertRemoteMarkdownSafe('l3', knowledge.content)\n const memoryReadback = readRemoteDocument(provider.layers.l1.uri, provider.authority.profile, 'l1')\n const knowledgeReadback = readRemoteDocument(provider.layers.l3.uri, provider.authority.profile, 'l3')\n if (digest(memoryReadback) !== memory.mount.hash) {\n throw new Error('Remote Semantic State l1 远端状态在 bootstrap 后发生漂移')\n }\n if (digest(knowledgeReadback) !== knowledge.mount.hash) {\n throw new Error('Remote Semantic State l3 远端状态在 bootstrap 后发生漂移')\n }\n\n const structured = readStructuredHotState(provider)\n const structuredReadback = readStructuredHotState(provider)\n const structuredBody = stableStringify(structured)\n if (structuredBody !== stableStringify(structuredReadback)) {\n throw new Error('Remote Semantic State l2 AI 表格在独立回读时发生漂移')\n }\n const aggregateRoot = join(stateDir, 'cache', 'remote-semantic-state', provider.id)\n const structuredPath = join(aggregateRoot, 'l2', 'record.json')\n writeAtomic(structuredPath, structuredBody)\n\n const layers = {\n l1: manifestLayer('l1', provider.layers.l1, memory.mount.source, 'ALIDOC/adoc',\n relativeCachePath(stateDir, memory.mount.path), memory.mount.hash),\n l2: manifestLayer('l2', provider.layers.l2,\n `dingtalk-aitable:${provider.layers.l2.baseId}/${provider.layers.l2.tableId}/${provider.layers.l2.recordId}`,\n 'application/json', relativeCachePath(stateDir, structuredPath), digest(structuredBody)),\n l3: manifestLayer('l3', provider.layers.l3, knowledge.mount.source, 'ALIDOC/adoc',\n relativeCachePath(stateDir, knowledge.mount.path), knowledge.mount.hash),\n }\n const stateHash = semanticStateHash(\n providerHash, bootstrap.definition.hash, provider.scopeId, layers, structured.nextAction,\n )\n const unsigned: Omit<RemoteSemanticStateManifest, 'hash'> = {\n $schema: 'dingtalk-agent/remote-semantic-state-manifest@1',\n providerId: provider.id,\n providerHash,\n scopeId: provider.scopeId,\n definitionHash: bootstrap.definition.hash,\n authority: {\n profile: provider.authority.profile,\n expectedUserId: provider.authority.expectedUserId,\n actualUserId,\n },\n layers,\n nextAction: structured.nextAction,\n stateHash,\n controlState: {\n provider: 'host-atomic-store',\n remoteProjection: false,\n excludedFromRemoteMarkdown: [...REMOTE_MARKDOWN_FORBIDDEN_FIELDS],\n },\n pulledAt: new Date().toISOString(),\n }\n const manifest: RemoteSemanticStateManifest = {\n ...unsigned,\n hash: digest(stableStringify(unsigned)),\n }\n writeAtomic(join(aggregateRoot, 'manifest.json'), JSON.stringify(manifest, null, 2) + '\\n')\n return verifyRemoteSemanticStateCache(root, bootstrap, provider)\n}\n\nexport function verifyRemoteSemanticStateCache(\n root: string,\n bootstrap: BootstrapResult,\n value: unknown,\n): RemoteSemanticStateResult {\n const provider = validateProvider(value)\n validateDefinitionBinding(bootstrap, provider)\n const stateDir = validateStateDir(root, bootstrap.stateDir)\n const providerHash = digest(stableStringify(provider))\n const memory = validateBootstrapMount(\n root, stateDir, bootstrap, provider, 'memory', provider.layers.l1.uri,\n )\n const knowledge = validateBootstrapMount(\n root, stateDir, bootstrap, provider, 'knowledge', provider.layers.l3.uri,\n )\n const manifestPath = join(\n stateDir, 'cache', 'remote-semantic-state', provider.id, 'manifest.json',\n )\n if (!existsSync(manifestPath)) throw new Error('Remote Semantic State 缺少聚合 manifest')\n const manifest = readJson(manifestPath) as RemoteSemanticStateManifest\n if (manifest.$schema !== 'dingtalk-agent/remote-semantic-state-manifest@1') {\n throw new Error('Remote Semantic State manifest schema 非法')\n }\n if (manifest.providerId !== provider.id || manifest.providerHash !== providerHash ||\n manifest.scopeId !== provider.scopeId ||\n manifest.definitionHash !== bootstrap.definition.hash) {\n throw new Error('Remote Semantic State manifest Provider/Definition/scope 绑定不一致')\n }\n if (manifest.authority?.profile !== provider.authority.profile ||\n manifest.authority?.expectedUserId !== provider.authority.expectedUserId ||\n manifest.authority?.actualUserId !== provider.authority.expectedUserId) {\n throw new Error('Remote Semantic State manifest 身份绑定不一致')\n }\n\n assertManifestLayer(manifest.layers?.l1, 'l1', provider.layers.l1, memory.mount.source,\n relativeCachePath(stateDir, memory.mount.path))\n assertManifestLayer(manifest.layers?.l2, 'l2', provider.layers.l2,\n `dingtalk-aitable:${provider.layers.l2.baseId}/${provider.layers.l2.tableId}/${provider.layers.l2.recordId}`,\n join('cache', 'remote-semantic-state', provider.id, 'l2', 'record.json'))\n assertManifestLayer(manifest.layers?.l3, 'l3', provider.layers.l3, knowledge.mount.source,\n relativeCachePath(stateDir, knowledge.mount.path))\n const paths = Object.values(manifest.layers).map((item) => item.cachePath)\n if (new Set(paths).size !== paths.length) {\n throw new Error('Remote Semantic State slot cachePath 串线')\n }\n\n const cacheBodies: Record<SemanticLayer, string> = { l1: '', l2: '', l3: '' }\n for (const slot of ['l1', 'l2', 'l3'] as const) {\n const layer = manifest.layers[slot]\n const path = safeCachePath(stateDir, layer.cachePath)\n const body = readFileSync(path, 'utf8')\n const cacheHash = digest(body)\n if (cacheHash !== layer.cacheHash || cacheHash !== layer.remoteHash) {\n throw new Error(`Remote Semantic State ${slot} 缓存与远端 hash 不一致`)\n }\n cacheBodies[slot] = body\n }\n assertRemoteMarkdownSafe('l1', cacheBodies.l1)\n assertRemoteMarkdownSafe('l3', cacheBodies.l3)\n const structured = validateCachedStructuredState(readJsonText(cacheBodies.l2), provider)\n if (manifest.nextAction !== structured.nextAction) {\n throw new Error('Remote Semantic State manifest nextAction 与 l2 缓存不一致')\n }\n const stateHash = semanticStateHash(\n providerHash, bootstrap.definition.hash, provider.scopeId, manifest.layers,\n structured.nextAction,\n )\n if (manifest.stateHash !== stateHash) {\n throw new Error('Remote Semantic State stateHash 不一致')\n }\n if (manifest.controlState?.provider !== 'host-atomic-store' ||\n manifest.controlState?.remoteProjection !== false ||\n stableStringify(manifest.controlState.excludedFromRemoteMarkdown) !==\n stableStringify([...REMOTE_MARKDOWN_FORBIDDEN_FIELDS])) {\n throw new Error('Remote Semantic State control state 边界不一致')\n }\n const { hash, ...unsigned } = manifest\n if (!hash || digest(stableStringify(unsigned)) !== hash) {\n throw new Error('Remote Semantic State manifest hash 不一致')\n }\n return {\n $schema: 'dingtalk-agent/remote-semantic-state-rehydration@1',\n stateDir,\n manifestPath,\n definitionHash: bootstrap.definition.hash,\n providerHash,\n memoryHash: manifest.layers.l1.remoteHash,\n structuredStateHash: manifest.layers.l2.remoteHash,\n knowledgeHash: manifest.layers.l3.remoteHash,\n stateHash,\n nextAction: structured.nextAction,\n manifest,\n }\n}\n\nfunction validateProvider(value: unknown): RemoteSemanticStateProvider {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error('Remote Semantic State Provider 必须是 JSON object')\n }\n const input = value as Record<string, any>\n assertKeys(input, ['$schema', 'id', 'scopeId', 'authority', 'layers', 'controlState'], 'Provider')\n if (input.$schema !== 'dingtalk-agent/remote-semantic-state-provider@1' ||\n !/^[a-z0-9][a-z0-9._-]*$/.test(clean(input.id)) || !clean(input.scopeId)) {\n throw new Error('Remote Semantic State Provider schema/id/scopeId 非法')\n }\n assertKeys(input.authority, ['profile', 'expectedUserId'], 'authority')\n if (!clean(input.authority?.profile) || clean(input.authority?.profile).includes(',') ||\n !clean(input.authority?.expectedUserId)) {\n throw new Error('Remote Semantic State Provider 必须固定单一 profile 和 expectedUserId')\n }\n assertKeys(input.layers, ['l1', 'l2', 'l3'], 'layers')\n validateDocLayer(input.layers?.l1, 'l1', 'session-working-memory', 'semantic-read-only-mirror')\n validateDocLayer(input.layers?.l3, 'l3', 'long-term-knowledge', 'reviewed-knowledge-source')\n const l2 = input.layers?.l2\n assertKeys(l2, [\n 'provider', 'semanticRole', 'mode', 'baseId', 'tableId', 'recordId', 'expected', 'fields',\n ], 'l2')\n if (l2?.provider !== 'dingtalk-aitable' || l2?.semanticRole !== 'structured-hot-state' ||\n l2?.mode !== 'business-fact-source') {\n throw new Error('Remote Semantic State l2 必须是结构化 AI 表格业务事实源')\n }\n for (const key of ['baseId', 'tableId', 'recordId']) {\n if (!clean(l2?.[key])) throw new Error(`Remote Semantic State l2 缺少 ${key}`)\n }\n assertKeys(l2?.expected, ['key', 'scopeId'], 'l2.expected')\n if (!clean(l2?.expected?.key) || clean(l2?.expected?.scopeId) !== clean(input.scopeId)) {\n throw new Error('Remote Semantic State l2 expected key/scopeId 非法')\n }\n const fieldNames = ['key', 'scopeId', 'status', 'nextAction', 'summary', 'sourceRefs']\n assertKeys(l2?.fields, fieldNames, 'l2.fields')\n const fieldIds = fieldNames.map((name) => clean(l2?.fields?.[name]))\n if (fieldIds.some((item) => !item) || new Set(fieldIds).size !== fieldIds.length) {\n throw new Error('Remote Semantic State l2 fields 必须是互不复用的显式 fieldId')\n }\n assertKeys(input.controlState, ['provider', 'remoteProjection'], 'controlState')\n if (input.controlState?.provider !== 'host-atomic-store' ||\n input.controlState?.remoteProjection !== false) {\n throw new Error('Remote Semantic State control state 必须留在宿主原子存储且禁止远端投影')\n }\n return JSON.parse(JSON.stringify(input)) as RemoteSemanticStateProvider\n}\n\nfunction validateDocLayer(\n value: Record<string, any>,\n slot: 'l1' | 'l3',\n semanticRole: string,\n mode: string,\n): void {\n assertKeys(value, ['provider', 'semanticRole', 'mode', 'uri'], slot)\n if (value?.provider !== 'dingtalk-doc' || value?.semanticRole !== semanticRole ||\n value?.mode !== mode || !clean(value?.uri).startsWith('dingtalk-doc:') ||\n !clean(value?.uri).slice('dingtalk-doc:'.length)) {\n throw new Error(`Remote Semantic State ${slot} 文档 Provider 合同非法`)\n }\n}\n\nfunction validateDefinitionBinding(\n bootstrap: BootstrapResult,\n provider: RemoteSemanticStateProvider,\n): void {\n const definition = bootstrap.definition\n if (definition.status !== 'ready' ||\n definition.authority.dwsProfile !== provider.authority.profile ||\n definition.authority.expectedUserId !== provider.authority.expectedUserId ||\n definition.storage.memory !== provider.layers.l1.uri ||\n definition.storage.knowledge !== provider.layers.l3.uri ||\n bootstrap.scopeId !== provider.scopeId) {\n throw new Error('Remote Semantic State 与本地 Definition/authority/storage/scope 绑定不一致')\n }\n}\n\nfunction validateBootstrapMount(\n root: string,\n stateDir: string,\n bootstrap: BootstrapResult,\n provider: RemoteSemanticStateProvider,\n slot: 'memory' | 'knowledge',\n source: string,\n): { mount: BootstrapMount; content: string } {\n const mount = bootstrap.mounts.find((item) => item.slot === slot)\n if (!mount || mount.provider !== 'dingtalk-doc' || mount.source !== source) {\n throw new Error(`Remote Semantic State ${slot} mount 与 Provider slot 串线`)\n }\n const path = safeExistingPath(root, stateDir, mount.path, `${slot} cache`)\n const content = readFileSync(path, 'utf8')\n if (digest(content) !== mount.hash) {\n throw new Error(`Remote Semantic State ${slot} mount/cache hash 不一致`)\n }\n const cacheManifestPath = join(dirname(path), 'manifest.json')\n const cacheManifest = readJson(cacheManifestPath) as Record<string, any>\n if (cacheManifest.$schema !== 'dingtalk-agent/bootstrap-cache@1' ||\n cacheManifest.source !== source || cacheManifest.profile !== provider.authority.profile ||\n cacheManifest.hash !== mount.hash ||\n realpathSync(cacheManifest.path) !== path) {\n throw new Error(`Remote Semantic State ${slot} bootstrap manifest 不一致`)\n }\n return { mount, content }\n}\n\nfunction readRemoteDocument(uri: string, profile: string, slot: 'l1' | 'l3'): string {\n const ref = uri.slice('dingtalk-doc:'.length)\n const info = dws.docInfo(ref, profile)\n const contentType = String(info?.contentType || '').toUpperCase()\n const extension = String(info?.extension || '').toLowerCase()\n if (contentType !== 'ALIDOC' || extension !== 'adoc') {\n throw new Error(\n `Remote Semantic State ${slot} 只接受在线文档 adoc;` +\n `实际 contentType=${contentType || '?'} extension=${extension || '?'}`,\n )\n }\n const body = String(dws.readDoc(ref, profile))\n assertRemoteMarkdownSafe(slot, body)\n return body\n}\n\nfunction readStructuredHotState(provider: RemoteSemanticStateProvider): StructuredHotState {\n const layer = provider.layers.l2\n const rows = dws.queryAiTableRecords({\n baseId: layer.baseId,\n tableId: layer.tableId,\n recordIds: [layer.recordId],\n profile: provider.authority.profile,\n })\n if (rows.length !== 1 || clean(rows[0]?.recordId) !== layer.recordId) {\n throw new Error(`Remote Semantic State l2 recordId=${layer.recordId} 必须精确回读一条记录`)\n }\n const cells = rows[0]?.cells\n if (!cells || typeof cells !== 'object' || Array.isArray(cells)) {\n throw new Error('Remote Semantic State l2 回读缺少 cells')\n }\n const fields = layer.fields\n return validateStructuredState({\n recordId: layer.recordId,\n key: textCell(cells[fields.key]),\n scopeId: textCell(cells[fields.scopeId]),\n status: textCell(cells[fields.status]),\n nextAction: textCell(cells[fields.nextAction]),\n summary: textCell(cells[fields.summary]),\n sourceRefs: textCell(cells[fields.sourceRefs]),\n }, provider)\n}\n\nfunction validateCachedStructuredState(\n value: unknown,\n provider: RemoteSemanticStateProvider,\n): StructuredHotState {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error('Remote Semantic State l2 cache 必须是 JSON object')\n }\n assertKeys(value as Record<string, any>, [\n 'recordId', 'key', 'scopeId', 'status', 'nextAction', 'summary', 'sourceRefs',\n ], 'l2 cache')\n const input = value as Record<string, unknown>\n return validateStructuredState({\n recordId: clean(input.recordId),\n key: clean(input.key),\n scopeId: clean(input.scopeId),\n status: clean(input.status),\n nextAction: clean(input.nextAction),\n summary: clean(input.summary),\n sourceRefs: clean(input.sourceRefs),\n }, provider)\n}\n\nfunction validateStructuredState(\n state: StructuredHotState,\n provider: RemoteSemanticStateProvider,\n): StructuredHotState {\n if (state.recordId !== provider.layers.l2.recordId ||\n state.key !== provider.layers.l2.expected.key ||\n state.scopeId !== provider.scopeId) {\n throw new Error('Remote Semantic State l2 recordId/key/scopeId 绑定不一致')\n }\n for (const key of ['status', 'nextAction', 'summary', 'sourceRefs'] as const) {\n if (!state[key]) throw new Error(`Remote Semantic State l2 缺少可恢复 ${key}`)\n }\n return state\n}\n\nfunction manifestLayer(\n slot: SemanticLayer,\n layer: Record<string, any>,\n source: string,\n mediaType: ManifestLayer['mediaType'],\n cachePath: string,\n hash: string,\n): ManifestLayer {\n return {\n slot,\n semanticRole: layer.semanticRole,\n provider: layer.provider,\n mode: layer.mode,\n source,\n mediaType,\n cachePath,\n remoteHash: hash,\n cacheHash: hash,\n }\n}\n\nfunction assertManifestLayer(\n value: ManifestLayer,\n slot: SemanticLayer,\n providerLayer: Record<string, any>,\n source: string,\n cachePath: string,\n): void {\n if (!value || value.slot !== slot || value.provider !== providerLayer.provider ||\n value.semanticRole !== providerLayer.semanticRole || value.mode !== providerLayer.mode ||\n value.source !== source || value.cachePath !== cachePath) {\n throw new Error(`Remote Semantic State manifest ${slot} slot/source/cachePath 串线`)\n }\n}\n\nfunction semanticStateHash(\n providerHash: string,\n definitionHash: string,\n scopeId: string,\n layers: RemoteSemanticStateManifest['layers'],\n nextAction: string,\n): string {\n return digest(stableStringify({\n $schema: 'dingtalk-agent/remote-semantic-state@1',\n providerHash,\n definitionHash,\n scopeId,\n layers: {\n l1: { source: layers.l1.source, hash: layers.l1.remoteHash },\n l2: { source: layers.l2.source, hash: layers.l2.remoteHash },\n l3: { source: layers.l3.source, hash: layers.l3.remoteHash },\n },\n nextAction,\n }))\n}\n\nfunction assertRemoteMarkdownSafe(slot: 'l1' | 'l3', body: string): void {\n const found = FORBIDDEN_MARKDOWN_PATTERNS\n .filter(([, pattern]) => pattern.test(body))\n .map(([name]) => name)\n if (found.length) {\n throw new Error(\n `Remote Semantic State ${slot} Markdown 含宿主 control state/凭据字段: ${found.join(', ')}`,\n )\n }\n}\n\nfunction validateStateDir(root: string, input: string): string {\n if (!input) throw new Error('Remote Semantic State 需要 bootstrap stateDir')\n const rootReal = realpathSync(resolve(root))\n const stateDir = realpathSync(resolve(input))\n assertInside(rootReal, stateDir, 'stateDir')\n return stateDir\n}\n\nfunction relativeCachePath(stateDir: string, path: string): string {\n const rel = relative(stateDir, realpathSync(path))\n if (!rel || rel === '..' || rel.startsWith(`..${process.platform === 'win32' ? '\\\\' : '/'}`)) {\n throw new Error('Remote Semantic State cache 必须位于 stateDir 内')\n }\n return rel\n}\n\nfunction safeCachePath(stateDir: string, input: string): string {\n if (!input || isAbsolute(input) || input.split(/[\\\\/]/).includes('..')) {\n throw new Error(`Remote Semantic State cachePath 非法: ${input || '-'}`)\n }\n const path = realpathSync(resolve(stateDir, input))\n assertInside(stateDir, path, 'cachePath')\n if (!lstatSync(path).isFile() || lstatSync(path).isSymbolicLink()) {\n throw new Error(`Remote Semantic State cache 必须是普通文件: ${input}`)\n }\n return path\n}\n\nfunction safeExistingPath(root: string, stateDir: string, input: string, label: string): string {\n const path = realpathSync(resolve(input))\n assertInside(realpathSync(resolve(root)), path, label)\n assertInside(stateDir, path, label)\n if (!lstatSync(path).isFile() || lstatSync(path).isSymbolicLink()) {\n throw new Error(`Remote Semantic State ${label} 必须是普通文件`)\n }\n return path\n}\n\nfunction assertInside(root: string, path: string, label: string): void {\n const rel = relative(resolve(root), resolve(path))\n if (rel === '..' || rel.startsWith(`..${process.platform === 'win32' ? '\\\\' : '/'}`)) {\n throw new Error(`Remote Semantic State ${label} 越界`)\n }\n}\n\nfunction textCell(value: unknown): string {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const input = value as Record<string, unknown>\n return clean(input.name ?? input.text ?? input.value)\n }\n return clean(value)\n}\n\nfunction findValue(value: unknown, keys: string[]): unknown {\n if (!value || typeof value !== 'object') return undefined\n if (Array.isArray(value)) {\n for (const item of value) {\n const found = findValue(item, keys)\n if (found !== undefined) return found\n }\n return undefined\n }\n const input = value as Record<string, unknown>\n for (const key of keys) if (input[key] !== undefined) return input[key]\n for (const item of Object.values(input)) {\n const found = findValue(item, keys)\n if (found !== undefined) return found\n }\n return undefined\n}\n\nfunction assertKeys(value: unknown, allowed: string[], label: string): void {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error(`Remote Semantic State ${label} 必须是 object`)\n }\n const extras = Object.keys(value).filter((key) => !allowed.includes(key))\n if (extras.length) {\n throw new Error(`Remote Semantic State ${label} 含未知字段: ${extras.join(', ')}`)\n }\n}\n\nfunction readJson(path: string): unknown {\n if (!existsSync(path)) throw new Error(`Remote Semantic State 文件不存在: ${path}`)\n try { return JSON.parse(readFileSync(path, 'utf8')) }\n catch (error) { throw new Error(`Remote Semantic State JSON 非法: ${(error as Error).message}`) }\n}\n\nfunction readJsonText(text: string): unknown {\n try { return JSON.parse(text) }\n catch (error) { throw new Error(`Remote Semantic State cache JSON 非法: ${(error as Error).message}`) }\n}\n\nfunction writeAtomic(path: string, value: string): void {\n mkdirSync(dirname(path), { recursive: true })\n const temporary = `${path}.${process.pid}.${Date.now()}.tmp`\n writeFileSync(temporary, value, { flag: 'wx' })\n renameSync(temporary, path)\n}\n\nfunction clean(value: unknown): string {\n return typeof value === 'string' ? value.trim() : ''\n}\n"]}
|