@ftai/dsh-plugin-acn 0.0.0-stage → 0.1.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/CHANGELOG.md +90 -0
- package/LICENSE-APACHE +201 -0
- package/LICENSE-MIT +19 -0
- package/README.md +82 -2
- package/README_EN.md +83 -0
- package/cordis.patch.yml +29 -0
- package/docs/acn-compat.md +33 -0
- package/docs/architecture.md +130 -0
- package/docs/assets/acn-claim-reuse.png +0 -0
- package/docs/assets/activity-view.png +0 -0
- package/docs/assets/install-package.png +0 -0
- package/docs/assets/knowledge-model.png +0 -0
- package/docs/assets/knowledge-view.png +0 -0
- package/docs/assets/personal-configuration.png +0 -0
- package/docs/assets/session-upstream.png +0 -0
- package/docs/assets/upstream-settings.png +0 -0
- package/docs/assets/upstream-team.png +0 -0
- package/docs/command-reference.md +201 -0
- package/docs/config.md +253 -0
- package/docs/development.md +197 -0
- package/docs/dsh-compat.md +59 -0
- package/docs/index.md +16 -0
- package/docs/outstanding-issues.md +61 -0
- package/docs/user_guide.md +185 -0
- package/icon.svg +8 -0
- package/lib/activities-B8U-iW4-.js +407 -0
- package/lib/alignment-CwH0nBf-.js +80 -0
- package/lib/auth-DFI9yowX.js +71 -0
- package/lib/checkpoint-CPFPOxBM.js +188 -0
- package/lib/checkpoint-c7aI4D-X.js +318 -0
- package/lib/claim-DOAGe8ZK.js +168 -0
- package/lib/client.js +18417 -0
- package/lib/deliver-C-dmhkfm.js +168 -0
- package/lib/delivery-status-M7-Rwoyj.js +89 -0
- package/lib/dispute-CtrInHzf.js +20 -0
- package/lib/disputes-ByEmi43j.js +51 -0
- package/lib/dream-agent-BVqxbKFc.js +249 -0
- package/lib/dream.js +4 -0
- package/lib/effects-DX1iy6FM.js +268 -0
- package/lib/errors-Bp_2WXBr.js +19 -0
- package/lib/errors-pPumDOGD.js +18 -0
- package/lib/evidence-store-DW7kj20i.js +1030 -0
- package/lib/formation-D4LO31WW.js +187 -0
- package/lib/formation-replay-Bf4TSBiz.js +87 -0
- package/lib/formation.js +9 -0
- package/lib/history-DPMHX3ZE.js +214 -0
- package/lib/inbox-2CugZZQm.js +188 -0
- package/lib/inbox-DFtE2fOp.js +71 -0
- package/lib/inbox.js +3 -0
- package/lib/index.js +1373 -0
- package/lib/lock-DbmlKOoX.js +332 -0
- package/lib/pages-BEWC3kmZ.js +51 -0
- package/lib/paths-B7NI9Ano.js +157 -0
- package/lib/plugins/commands.js +590 -0
- package/lib/plugins/dream.js +66 -0
- package/lib/plugins/formation.js +66 -0
- package/lib/plugins/inbox.js +53 -0
- package/lib/plugins/knowledge.js +1109 -0
- package/lib/plugins/prompt.js +102 -0
- package/lib/plugins/tools.js +280 -0
- package/lib/policy-DnyHh7Bl.js +16 -0
- package/lib/prepare-CGXwBEcu.js +134 -0
- package/lib/protocol.js +8 -0
- package/lib/queue-M917xHPS.js +153 -0
- package/lib/regular-file-BFpqMoub.js +136 -0
- package/lib/render-CJaVcKKC.js +48 -0
- package/lib/reported-sets-DdEKdeVb.js +122 -0
- package/lib/revision-DeoL_IUN.js +11 -0
- package/lib/scheduler-BfJSY1eq.js +64 -0
- package/lib/service-BPwaZzFF.js +1106 -0
- package/lib/service-BQaszW_v.js +344 -0
- package/lib/service-BhniAHLo.js +305 -0
- package/lib/service-C2lXoygJ.js +505 -0
- package/lib/session-binding-zCSuizHs.js +342 -0
- package/lib/session-state-CYqUhC95.js +38 -0
- package/lib/sessions-C2xuPFQv.js +218 -0
- package/lib/store.js +16 -0
- package/lib/structured-C9byFuzm.js +453 -0
- package/lib/subagent-yJsFxHmH.js +9 -0
- package/lib/team.js +3 -0
- package/lib/tool-schema-3b4gH1zf.js +28 -0
- package/lib/trace-Da0RnL5R.js +14 -0
- package/lib/traces-CHBo8y1z.js +11 -0
- package/lib/types/activities.d.ts +73 -0
- package/lib/types/advanced-configuration.d.ts +11 -0
- package/lib/types/client/ActivityCard.d.ts +14 -0
- package/lib/types/client/ActivityDetails.d.ts +18 -0
- package/lib/types/client/AdvancedPreferences.d.ts +8 -0
- package/lib/types/client/BlankCommandFeedback.d.ts +10 -0
- package/lib/types/client/ComposerMenu.d.ts +24 -0
- package/lib/types/client/ConfigurationPage.d.ts +11 -0
- package/lib/types/client/ConnectionCheckDialog.d.ts +12 -0
- package/lib/types/client/KnowledgeDetail.d.ts +6 -0
- package/lib/types/client/KnowledgeDirectoryField.d.ts +11 -0
- package/lib/types/client/KnowledgePanel.d.ts +12 -0
- package/lib/types/client/KnowledgeReference.d.ts +13 -0
- package/lib/types/client/SessionToolbar.d.ts +16 -0
- package/lib/types/client/SettingsToast.d.ts +3 -0
- package/lib/types/client/SourceSessionLink.d.ts +16 -0
- package/lib/types/client/TeamCredentialField.d.ts +16 -0
- package/lib/types/client/TeamSettingsPage.d.ts +28 -0
- package/lib/types/client/configuration-errors.d.ts +2 -0
- package/lib/types/client/interaction-styles.d.ts +1 -0
- package/lib/types/client/interaction-ui.d.ts +30 -0
- package/lib/types/client/knowledge-labels.d.ts +5 -0
- package/lib/types/client/locales.d.ts +51 -0
- package/lib/types/commands/claim.d.ts +4 -0
- package/lib/types/commands/import.d.ts +10 -0
- package/lib/types/commands/status.d.ts +5 -0
- package/lib/types/config.d.ts +111 -0
- package/lib/types/configuration.d.ts +235 -0
- package/lib/types/credentials.d.ts +59 -0
- package/lib/types/dream/audit.d.ts +4 -0
- package/lib/types/dream/autonomous.d.ts +185 -0
- package/lib/types/dream/candidates.d.ts +34 -0
- package/lib/types/dream/checkpoint.d.ts +35 -0
- package/lib/types/dream/evidence-files.d.ts +10 -0
- package/lib/types/dream/evidence-store.d.ts +103 -0
- package/lib/types/dream/evidence.d.ts +30 -0
- package/lib/types/dream/index.d.ts +10 -0
- package/lib/types/dream/plan.d.ts +18 -0
- package/lib/types/dream/preservation.d.ts +6 -0
- package/lib/types/dream/review.d.ts +10 -0
- package/lib/types/dream/schema.d.ts +1475 -0
- package/lib/types/dream/service.d.ts +56 -0
- package/lib/types/dream/sync.d.ts +147 -0
- package/lib/types/dsh-adapter/configuration-remote.d.ts +1 -0
- package/lib/types/dsh-adapter/configuration-service.d.ts +28 -0
- package/lib/types/dsh-adapter/dream-agent.d.ts +4 -0
- package/lib/types/dsh-adapter/dream-evidence.d.ts +3 -0
- package/lib/types/dsh-adapter/formation-archive.d.ts +3 -0
- package/lib/types/dsh-adapter/formation-replay.d.ts +5 -0
- package/lib/types/dsh-adapter/formation.d.ts +4 -0
- package/lib/types/dsh-adapter/interaction-service.d.ts +13 -0
- package/lib/types/dsh-adapter/knowledge-paths.d.ts +3 -0
- package/lib/types/dsh-adapter/llm.d.ts +10 -0
- package/lib/types/dsh-adapter/project-upstream.d.ts +4 -0
- package/lib/types/dsh-adapter/runtime-pool.d.ts +110 -0
- package/lib/types/dsh-adapter/session-binding.d.ts +43 -0
- package/lib/types/dsh-adapter/source-sessions.d.ts +3 -0
- package/lib/types/dsh-adapter/team-credentials.d.ts +5 -0
- package/lib/types/dsh-adapter/tool-schema.d.ts +4 -0
- package/lib/types/dsh-adapter/tools.d.ts +5 -0
- package/lib/types/formation/capture.d.ts +19 -0
- package/lib/types/formation/checkpoint.d.ts +136 -0
- package/lib/types/formation/index.d.ts +10 -0
- package/lib/types/formation/prepare.d.ts +16 -0
- package/lib/types/formation/schema.d.ts +45 -0
- package/lib/types/formation/service.d.ts +58 -0
- package/lib/types/formation/transcript.d.ts +75 -0
- package/lib/types/formation/triggers.d.ts +3 -0
- package/lib/types/inbox/cascade.d.ts +3 -0
- package/lib/types/inbox/effects.d.ts +275 -0
- package/lib/types/inbox/index.d.ts +5 -0
- package/lib/types/inbox/prepare.d.ts +380 -0
- package/lib/types/inbox/service.d.ts +26 -0
- package/lib/types/inbox/sync.d.ts +9 -0
- package/lib/types/index.d.ts +1 -0
- package/lib/types/interaction-messages.d.ts +69 -0
- package/lib/types/interaction.d.ts +541 -0
- package/lib/types/knowledge/alignment.d.ts +49 -0
- package/lib/types/knowledge/catalog.d.ts +5 -0
- package/lib/types/knowledge/changes.d.ts +32 -0
- package/lib/types/knowledge/disputes.d.ts +3 -0
- package/lib/types/knowledge/errors.d.ts +9 -0
- package/lib/types/knowledge/ordering.d.ts +7 -0
- package/lib/types/knowledge/pages.d.ts +7 -0
- package/lib/types/knowledge/safety.d.ts +2 -0
- package/lib/types/knowledge/service.d.ts +52 -0
- package/lib/types/knowledge/sessions.d.ts +59 -0
- package/lib/types/knowledge/sources.d.ts +2 -0
- package/lib/types/knowledge/timestamps.d.ts +1 -0
- package/lib/types/knowledge/types.d.ts +84 -0
- package/lib/types/llm/response.d.ts +1 -0
- package/lib/types/llm/structured.d.ts +27 -0
- package/lib/types/local-name.d.ts +1 -0
- package/lib/types/plugins/client.d.ts +9 -0
- package/lib/types/plugins/commands.d.ts +11 -0
- package/lib/types/plugins/configuration.d.ts +8 -0
- package/lib/types/plugins/dream.d.ts +16 -0
- package/lib/types/plugins/formation.d.ts +16 -0
- package/lib/types/plugins/inbox.d.ts +16 -0
- package/lib/types/plugins/knowledge.d.ts +19 -0
- package/lib/types/plugins/prompt.d.ts +17 -0
- package/lib/types/plugins/tools.d.ts +10 -0
- package/lib/types/prompt/render.d.ts +2 -0
- package/lib/types/protocol/arbitration.d.ts +154 -0
- package/lib/types/protocol/auth.d.ts +31 -0
- package/lib/types/protocol/claim.d.ts +36 -0
- package/lib/types/protocol/dispute.d.ts +17 -0
- package/lib/types/protocol/ids.d.ts +20 -0
- package/lib/types/protocol/inbox.d.ts +141 -0
- package/lib/types/protocol/index.d.ts +11 -0
- package/lib/types/protocol/policy.d.ts +21 -0
- package/lib/types/protocol/revision.d.ts +2 -0
- package/lib/types/protocol/router.d.ts +114 -0
- package/lib/types/protocol/schema.d.ts +4 -0
- package/lib/types/protocol/time.d.ts +5 -0
- package/lib/types/protocol/trace.d.ts +11 -0
- package/lib/types/store/atomic.d.ts +8 -0
- package/lib/types/store/claim-edits.d.ts +33 -0
- package/lib/types/store/claims.d.ts +7 -0
- package/lib/types/store/context.d.ts +13 -0
- package/lib/types/store/delivery-status.d.ts +48 -0
- package/lib/types/store/disputes.d.ts +6 -0
- package/lib/types/store/entities.d.ts +16 -0
- package/lib/types/store/errors.d.ts +8 -0
- package/lib/types/store/history.d.ts +65 -0
- package/lib/types/store/inbox.d.ts +27 -0
- package/lib/types/store/index.d.ts +16 -0
- package/lib/types/store/jobs.d.ts +5 -0
- package/lib/types/store/library-directory.d.ts +4 -0
- package/lib/types/store/lock.d.ts +11 -0
- package/lib/types/store/path-names.d.ts +2 -0
- package/lib/types/store/paths.d.ts +45 -0
- package/lib/types/store/presentation.d.ts +13 -0
- package/lib/types/store/regular-file.d.ts +2 -0
- package/lib/types/store/rejected-disputes.d.ts +18 -0
- package/lib/types/store/rename.d.ts +1 -0
- package/lib/types/store/reported-sets.d.ts +24 -0
- package/lib/types/store/session-state.d.ts +17 -0
- package/lib/types/store/traces.d.ts +6 -0
- package/lib/types/store/uploads.d.ts +312 -0
- package/lib/types/store/yaml.d.ts +8 -0
- package/lib/types/team/errors.d.ts +10 -0
- package/lib/types/team/http.d.ts +20 -0
- package/lib/types/team/index.d.ts +5 -0
- package/lib/types/team/maintainer-client.d.ts +18 -0
- package/lib/types/team/router-client.d.ts +14 -0
- package/lib/types/team/service.d.ts +28 -0
- package/lib/types/team/system-proxy.d.ts +9 -0
- package/lib/types/tools/claim.d.ts +63 -0
- package/lib/types/tools/consult-router.d.ts +11 -0
- package/lib/types/tools/subagent.d.ts +8 -0
- package/lib/types/tools/validation.d.ts +2 -0
- package/lib/types/upload/consolidation.d.ts +63 -0
- package/lib/types/upload/deliver.d.ts +15 -0
- package/lib/types/upload/index.d.ts +2 -0
- package/lib/types/upload/scheduler.d.ts +19 -0
- package/lib/types/upstreams.d.ts +5 -0
- package/lib/types/worker/queue.d.ts +17 -0
- package/lib/types/worker/types.d.ts +51 -0
- package/lib/types/worker/worker.d.ts +39 -0
- package/lib/types-C2ST2Zdg.js +17 -0
- package/lib/upload.js +3 -0
- package/lib/uploads-BCA2p92b.js +210 -0
- package/lib/upstreams-DEi-56tD.js +495 -0
- package/lib/worker-HMGzJFWd.js +185 -0
- package/locale/commands/en.json +1 -0
- package/locale/commands/zh.json +1 -0
- package/locale/dream/en.json +1 -0
- package/locale/dream/zh.json +1 -0
- package/locale/en.json +7 -0
- package/locale/formation/en.json +1 -0
- package/locale/formation/zh.json +1 -0
- package/locale/inbox/en.json +1 -0
- package/locale/inbox/zh.json +1 -0
- package/locale/knowledge/en.json +1 -0
- package/locale/knowledge/zh.json +1 -0
- package/locale/prompt/en.json +1 -0
- package/locale/prompt/zh.json +1 -0
- package/locale/tools/en.json +1 -0
- package/locale/tools/zh.json +1 -0
- package/locale/zh.json +7 -0
- package/package.json +262 -3
- package/prompts/claim_dream.j2 +77 -0
- package/prompts/claim_dream_legacy.j2 +63 -0
- package/prompts/dream_compaction.j2 +11 -0
- package/prompts/dream_evidence.j2 +5 -0
- package/prompts/inbox_claim_attribute_update_internalize.j2 +112 -0
- package/prompts/inbox_policy_update_internalize.j2 +87 -0
- package/prompts/knowledge.j2 +38 -0
- package/prompts/session_recap.j2 +113 -0
- package/prompts/what_is_claim.j2 +51 -0
- package/prompts/what_is_dispute.j2 +21 -0
- package/prompts/what_is_policy.j2 +22 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { randomBytes } from "node:crypto";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
5
|
+
import { parse, stringify } from "yaml";
|
|
6
|
+
import { setTimeout } from "node:timers/promises";
|
|
7
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
8
|
+
import { performance } from "node:perf_hooks";
|
|
9
|
+
import lockfile from "proper-lockfile";
|
|
10
|
+
//#region src/store/errors.ts
|
|
11
|
+
var StoreError = class extends Error {
|
|
12
|
+
kind;
|
|
13
|
+
constructor(kind, message, options) {
|
|
14
|
+
super(message, options);
|
|
15
|
+
this.kind = kind;
|
|
16
|
+
this.name = "StoreError";
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
var LockTimeoutError = class extends StoreError {
|
|
20
|
+
constructor(path) {
|
|
21
|
+
super("lock_timeout", `Timed out acquiring lock: ${path}`);
|
|
22
|
+
this.name = "LockTimeoutError";
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
function hasCode(error, code) {
|
|
26
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
//#region src/worker/types.ts
|
|
30
|
+
const JobKindSchema = z.enum([
|
|
31
|
+
"finalize",
|
|
32
|
+
"recap",
|
|
33
|
+
"inbox",
|
|
34
|
+
"dream"
|
|
35
|
+
]);
|
|
36
|
+
const JobSchema = z.strictObject({
|
|
37
|
+
schemaVersion: z.literal(1),
|
|
38
|
+
id: z.string().regex(/^[a-zA-Z0-9_-]+$/),
|
|
39
|
+
kind: JobKindSchema,
|
|
40
|
+
sessionId: z.string().regex(/^[a-zA-Z0-9_-]+$/).optional(),
|
|
41
|
+
payload: z.record(z.string(), z.json()),
|
|
42
|
+
state: z.enum([
|
|
43
|
+
"queued",
|
|
44
|
+
"running",
|
|
45
|
+
"succeeded",
|
|
46
|
+
"failed"
|
|
47
|
+
]),
|
|
48
|
+
attempts: z.number().int().nonnegative(),
|
|
49
|
+
createdAt: z.number().int().nonnegative(),
|
|
50
|
+
updatedAt: z.number().int().nonnegative(),
|
|
51
|
+
ordinal: z.number().int().nonnegative().optional(),
|
|
52
|
+
nextRunAt: z.number().int().nonnegative().optional(),
|
|
53
|
+
lastError: z.string().optional(),
|
|
54
|
+
lastErrorKind: z.string().optional(),
|
|
55
|
+
result: z.json().optional()
|
|
56
|
+
});
|
|
57
|
+
const jobPriority = {
|
|
58
|
+
finalize: 0,
|
|
59
|
+
recap: 1,
|
|
60
|
+
inbox: 2,
|
|
61
|
+
dream: 3
|
|
62
|
+
};
|
|
63
|
+
var JobError = class extends Error {
|
|
64
|
+
kind;
|
|
65
|
+
retryable;
|
|
66
|
+
retryAfterMs;
|
|
67
|
+
constructor(kind, message, retryable = false, retryAfterMs) {
|
|
68
|
+
super(message);
|
|
69
|
+
this.kind = kind;
|
|
70
|
+
this.retryable = retryable;
|
|
71
|
+
this.retryAfterMs = retryAfterMs;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
var Preempted = class extends JobError {
|
|
75
|
+
constructor() {
|
|
76
|
+
super("preempted", "Recap superseded by Finalize before prepared.");
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
var DreamStopped = class extends JobError {
|
|
80
|
+
constructor() {
|
|
81
|
+
super("dream_stopped", "Dream 已停在可恢复边界,已生效修改保留。");
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
var DreamYield = class extends JobError {
|
|
85
|
+
constructor() {
|
|
86
|
+
super("dream_yield", "Dream 已让位给高优先级任务,草稿和进度保留。");
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
//#endregion
|
|
90
|
+
//#region src/store/rename.ts
|
|
91
|
+
async function renameFile(source, destination) {
|
|
92
|
+
for (let attempt = 0;; attempt += 1) try {
|
|
93
|
+
await fs.rename(source, destination);
|
|
94
|
+
return;
|
|
95
|
+
} catch (error) {
|
|
96
|
+
if (process.platform !== "win32" || attempt >= 5 || ![
|
|
97
|
+
"EPERM",
|
|
98
|
+
"EACCES",
|
|
99
|
+
"EBUSY"
|
|
100
|
+
].some((code) => hasCode(error, code))) throw error;
|
|
101
|
+
await setTimeout(10 * 2 ** attempt);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region src/store/atomic.ts
|
|
106
|
+
async function syncDirectory(path, logger) {
|
|
107
|
+
try {
|
|
108
|
+
const directory = await fs.open(path, "r");
|
|
109
|
+
try {
|
|
110
|
+
await directory.sync();
|
|
111
|
+
} finally {
|
|
112
|
+
await directory.close();
|
|
113
|
+
}
|
|
114
|
+
} catch {
|
|
115
|
+
logger.debug(`Parent directory sync unavailable: ${path}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async function writeTextAtomic(path, content, logger) {
|
|
119
|
+
await publishText(path, content, logger, false);
|
|
120
|
+
}
|
|
121
|
+
function writeTextAtomicIfAbsent(path, content, logger) {
|
|
122
|
+
return publishText(path, content, logger, true);
|
|
123
|
+
}
|
|
124
|
+
async function publishText(path, content, logger, exclusive) {
|
|
125
|
+
let temporary;
|
|
126
|
+
try {
|
|
127
|
+
await fs.mkdir(dirname(path), { recursive: true });
|
|
128
|
+
for (let attempt = 0; attempt < 16; attempt += 1) {
|
|
129
|
+
const candidate = join(dirname(path), `${basename(path)}.tmp.${process.pid}.${randomBytes(8).toString("hex")}`);
|
|
130
|
+
let file;
|
|
131
|
+
try {
|
|
132
|
+
file = await fs.open(candidate, "wx", 384);
|
|
133
|
+
} catch (error) {
|
|
134
|
+
if (hasCode(error, "EEXIST")) continue;
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
137
|
+
temporary = candidate;
|
|
138
|
+
try {
|
|
139
|
+
await file.writeFile(content, "utf8");
|
|
140
|
+
await file.sync();
|
|
141
|
+
} finally {
|
|
142
|
+
await file.close();
|
|
143
|
+
}
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
if (temporary === void 0) throw new StoreError("io", "Could not create an exclusive temporary file.");
|
|
147
|
+
if (exclusive) {
|
|
148
|
+
try {
|
|
149
|
+
await fs.link(temporary, path);
|
|
150
|
+
} catch (error) {
|
|
151
|
+
if (!hasCode(error, "EEXIST")) throw error;
|
|
152
|
+
await fs.unlink(temporary);
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
await fs.unlink(temporary);
|
|
156
|
+
} else await renameFile(temporary, path);
|
|
157
|
+
await syncDirectory(dirname(path), logger);
|
|
158
|
+
return true;
|
|
159
|
+
} catch (error) {
|
|
160
|
+
if (temporary !== void 0) await fs.rm(temporary, { force: true }).catch(() => {
|
|
161
|
+
logger.debug(`Could not remove temporary file: ${temporary}`);
|
|
162
|
+
});
|
|
163
|
+
throw new StoreError("io", `Atomic write failed: ${path}`, { cause: error });
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async function removeFile(path, logger) {
|
|
167
|
+
try {
|
|
168
|
+
await fs.unlink(path);
|
|
169
|
+
await syncDirectory(dirname(path), logger);
|
|
170
|
+
} catch (error) {
|
|
171
|
+
if (!hasCode(error, "ENOENT")) throw new StoreError("io", `Cannot remove file: ${path}`, { cause: error });
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
async function cleanupAtomicTemps(root, logger, options = {}) {
|
|
175
|
+
const cutoff = (options.nowMs ?? Date.now()) - (options.olderThanMs ?? 36e5);
|
|
176
|
+
let entries;
|
|
177
|
+
try {
|
|
178
|
+
entries = await fs.readdir(root, { withFileTypes: true });
|
|
179
|
+
} catch (error) {
|
|
180
|
+
if (hasCode(error, "ENOENT")) return 0;
|
|
181
|
+
throw error;
|
|
182
|
+
}
|
|
183
|
+
let removed = 0;
|
|
184
|
+
for (const entry of entries) {
|
|
185
|
+
const path = join(root, entry.name);
|
|
186
|
+
if (entry.isDirectory() && !entry.name.endsWith(".lock")) removed += await cleanupAtomicTemps(path, logger, options);
|
|
187
|
+
else if (entry.isFile() && entry.name.includes(".tmp.")) try {
|
|
188
|
+
if ((await fs.stat(path)).mtimeMs <= cutoff) {
|
|
189
|
+
await removeFile(path, logger);
|
|
190
|
+
removed += 1;
|
|
191
|
+
}
|
|
192
|
+
} catch (error) {
|
|
193
|
+
if (!hasCode(error, "ENOENT")) throw error;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return removed;
|
|
197
|
+
}
|
|
198
|
+
//#endregion
|
|
199
|
+
//#region src/store/yaml.ts
|
|
200
|
+
function encodeJson(schema, value) {
|
|
201
|
+
return JSON.stringify(schema.parse(value));
|
|
202
|
+
}
|
|
203
|
+
function encodeYaml(schema, value) {
|
|
204
|
+
try {
|
|
205
|
+
return stringify(JSON.parse(encodeJson(schema, value)), {
|
|
206
|
+
indent: 2,
|
|
207
|
+
indentSeq: false,
|
|
208
|
+
lineWidth: 0
|
|
209
|
+
});
|
|
210
|
+
} catch {
|
|
211
|
+
throw new StoreError("encode", "Cannot encode YAML value.");
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
function decodeYaml(schema, text) {
|
|
215
|
+
try {
|
|
216
|
+
const value = parse(text, { maxAliasCount: 100 });
|
|
217
|
+
return schema.parse(value);
|
|
218
|
+
} catch {
|
|
219
|
+
throw new StoreError("decode", "Invalid YAML document.");
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
async function readYaml(path, schema) {
|
|
223
|
+
let text;
|
|
224
|
+
try {
|
|
225
|
+
text = await fs.readFile(path, "utf8");
|
|
226
|
+
} catch (error) {
|
|
227
|
+
throw new StoreError("io", `Cannot read file: ${path}`, { cause: error });
|
|
228
|
+
}
|
|
229
|
+
try {
|
|
230
|
+
return decodeYaml(schema, text);
|
|
231
|
+
} catch {
|
|
232
|
+
throw new StoreError("decode", `Invalid YAML document: ${path}`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
async function readYamlOr(path, schema, fallback) {
|
|
236
|
+
try {
|
|
237
|
+
return await readYaml(path, schema);
|
|
238
|
+
} catch (error) {
|
|
239
|
+
if (error instanceof StoreError && hasCode(error.cause, "ENOENT")) return fallback();
|
|
240
|
+
throw error;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
async function writeYamlAtomic(path, value, schema, logger) {
|
|
244
|
+
await writeTextAtomic(path, encodeYaml(schema, value), logger);
|
|
245
|
+
}
|
|
246
|
+
//#endregion
|
|
247
|
+
//#region src/store/lock.ts
|
|
248
|
+
const heldLocks = new AsyncLocalStorage();
|
|
249
|
+
async function acquireFileLease(path, options = {}) {
|
|
250
|
+
options.signal?.throwIfAborted();
|
|
251
|
+
const lockPath = resolve(path);
|
|
252
|
+
const timeout = options.timeoutMs ?? 3e4;
|
|
253
|
+
const stale = options.staleMs ?? 3e4;
|
|
254
|
+
if (!Number.isFinite(timeout) || timeout < 0 || !Number.isFinite(stale) || stale < 5e3) throw new StoreError("lock_order", "Invalid lock timing options.");
|
|
255
|
+
await fs.mkdir(dirname(lockPath), { recursive: true });
|
|
256
|
+
const deadline = performance.now() + timeout;
|
|
257
|
+
let compromised;
|
|
258
|
+
let pendingDeleteRetries = 0;
|
|
259
|
+
for (;;) {
|
|
260
|
+
options.signal?.throwIfAborted();
|
|
261
|
+
try {
|
|
262
|
+
const release = await lockfile.lock(lockPath, {
|
|
263
|
+
realpath: false,
|
|
264
|
+
lockfilePath: lockPath,
|
|
265
|
+
stale,
|
|
266
|
+
retries: 0,
|
|
267
|
+
onCompromised: (error) => {
|
|
268
|
+
compromised = error;
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
if (options.signal?.aborted) {
|
|
272
|
+
await release();
|
|
273
|
+
options.signal.throwIfAborted();
|
|
274
|
+
}
|
|
275
|
+
return {
|
|
276
|
+
check: () => {
|
|
277
|
+
if (compromised !== void 0) throw new StoreError("lock_compromised", "Lock ownership was lost.", { cause: compromised });
|
|
278
|
+
},
|
|
279
|
+
release
|
|
280
|
+
};
|
|
281
|
+
} catch (error) {
|
|
282
|
+
options.signal?.throwIfAborted();
|
|
283
|
+
if (process.platform === "win32" && hasCode(error, "EPERM") && typeof error === "object" && error !== null && "syscall" in error && error.syscall === "mkdir" && pendingDeleteRetries < 5 && performance.now() < deadline) {
|
|
284
|
+
await setTimeout(Math.min(10 * 2 ** pendingDeleteRetries++, Math.max(1, deadline - performance.now())), void 0, { signal: options.signal });
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
if (!hasCode(error, "ELOCKED")) throw new StoreError("io", `Cannot acquire lock: ${lockPath}`, { cause: error });
|
|
288
|
+
if (performance.now() >= deadline) throw new LockTimeoutError(lockPath);
|
|
289
|
+
await setTimeout(Math.min(25, Math.max(1, deadline - performance.now())), void 0, { signal: options.signal });
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
async function withFileLock(path, action, options = {}) {
|
|
294
|
+
const lockPath = resolve(path);
|
|
295
|
+
const held = heldLocks.getStore() ?? [];
|
|
296
|
+
if (held.some((previous) => previous >= lockPath)) throw new StoreError("lock_order", `Lock order violation: ${lockPath}`);
|
|
297
|
+
const lease = await acquireFileLease(lockPath, options);
|
|
298
|
+
let outcome;
|
|
299
|
+
try {
|
|
300
|
+
const result = await heldLocks.run([...held, lockPath], action);
|
|
301
|
+
lease.check();
|
|
302
|
+
outcome = {
|
|
303
|
+
ok: true,
|
|
304
|
+
value: result
|
|
305
|
+
};
|
|
306
|
+
} catch (error) {
|
|
307
|
+
outcome = {
|
|
308
|
+
ok: false,
|
|
309
|
+
error
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
try {
|
|
313
|
+
await lease.release();
|
|
314
|
+
} catch (error) {
|
|
315
|
+
if (outcome.ok) outcome = {
|
|
316
|
+
ok: false,
|
|
317
|
+
error: new StoreError("lock_compromised", `Cannot release lock: ${lockPath}`, { cause: error })
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
if (!outcome.ok) throw outcome.error;
|
|
321
|
+
return outcome.value;
|
|
322
|
+
}
|
|
323
|
+
function withFileLocks(paths, action, options = {}) {
|
|
324
|
+
const ordered = [...new Set(paths.map((path) => resolve(path)))].sort();
|
|
325
|
+
const acquire = (index) => {
|
|
326
|
+
const path = ordered[index];
|
|
327
|
+
return path === void 0 ? action() : withFileLock(path, () => acquire(index + 1), options);
|
|
328
|
+
};
|
|
329
|
+
return acquire(0);
|
|
330
|
+
}
|
|
331
|
+
//#endregion
|
|
332
|
+
export { StoreError as C, LockTimeoutError as S, JobError as _, encodeJson as a, Preempted as b, readYamlOr as c, removeFile as d, writeTextAtomic as f, DreamYield as g, DreamStopped as h, decodeYaml as i, writeYamlAtomic as l, renameFile as m, withFileLock as n, encodeYaml as o, writeTextAtomicIfAbsent as p, withFileLocks as r, readYaml as s, acquireFileLease as t, cleanupAtomicTemps as u, JobKindSchema as v, hasCode as w, jobPriority as x, JobSchema as y };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { S as timestampNanos, i as effectiveUpdatedAt } from "./claim-DOAGe8ZK.js";
|
|
2
|
+
import { t as KnowledgeError } from "./errors-Bp_2WXBr.js";
|
|
3
|
+
import "./types-C2ST2Zdg.js";
|
|
4
|
+
//#region src/knowledge/pages.ts
|
|
5
|
+
function boundedText(value, limit) {
|
|
6
|
+
const chars = Array.from(value);
|
|
7
|
+
return {
|
|
8
|
+
text: chars.slice(0, limit).join(""),
|
|
9
|
+
truncated: chars.length > limit
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function validatePage(offset, limit, maximum = 100) {
|
|
13
|
+
if (!Number.isSafeInteger(offset) || offset < 0 || !Number.isSafeInteger(limit) || limit < 1 || limit > maximum) throw new KnowledgeError("validation", `Offset must be nonnegative and limit must be within 1..${maximum}.`);
|
|
14
|
+
}
|
|
15
|
+
function page(items, offset, limit) {
|
|
16
|
+
const selected = items.slice(offset, offset + limit);
|
|
17
|
+
const end = Math.min(offset + selected.length, items.length);
|
|
18
|
+
return {
|
|
19
|
+
items: selected,
|
|
20
|
+
offset,
|
|
21
|
+
limit,
|
|
22
|
+
omitted: items.length - end,
|
|
23
|
+
next_offset: end < items.length ? end : null
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function sortClaims(claims) {
|
|
27
|
+
return [...claims].sort((a, b) => {
|
|
28
|
+
const delta = timestampNanos(effectiveUpdatedAt(b)) - timestampNanos(effectiveUpdatedAt(a));
|
|
29
|
+
return delta === 0n ? a.id < b.id ? -1 : a.id > b.id ? 1 : 0 : delta > 0n ? 1 : -1;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function claimListPage(claims, query) {
|
|
33
|
+
const offset = query.offset ?? 0;
|
|
34
|
+
const limit = query.limit ?? 20;
|
|
35
|
+
validatePage(offset, limit);
|
|
36
|
+
const term = query.query?.trim().toLowerCase();
|
|
37
|
+
return page(sortClaims(claims.filter((claim) => (query.includeDeprecated || claim.status !== "deprecated") && (!term || [
|
|
38
|
+
claim.name,
|
|
39
|
+
claim.scope,
|
|
40
|
+
claim.statement
|
|
41
|
+
].some((value) => value.toLowerCase().includes(term))))).map((claim) => ({
|
|
42
|
+
id: claim.id,
|
|
43
|
+
name: boundedText(claim.name, 120),
|
|
44
|
+
scope: boundedText(claim.scope, 240),
|
|
45
|
+
confidence: claim.confidence,
|
|
46
|
+
status: claim.status,
|
|
47
|
+
updated_at: effectiveUpdatedAt(claim)
|
|
48
|
+
})), offset, limit);
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { validatePage as a, sortClaims as i, claimListPage as n, page as r, boundedText as t };
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { c as AgentIdSchema, d as InboxIdSchema, h as TraceIdSchema, l as ClaimIdSchema, u as DisputeIdSchema } from "./claim-DOAGe8ZK.js";
|
|
2
|
+
import { C as StoreError } from "./lock-DbmlKOoX.js";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
import { join, resolve } from "node:path";
|
|
5
|
+
import { homedir } from "node:os";
|
|
6
|
+
//#region src/local-name.ts
|
|
7
|
+
function portableLocalName(value) {
|
|
8
|
+
return !/^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i.test(value);
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/store/path-names.ts
|
|
12
|
+
function invalidStorageName(name, platform = process.platform) {
|
|
13
|
+
return platform === "win32" && !portableLocalName(name);
|
|
14
|
+
}
|
|
15
|
+
function assertStorageName(name) {
|
|
16
|
+
if (invalidStorageName(name)) throw new StoreError("io", "Windows reserved names cannot be used for an Agent ID or upstream directory.");
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/store/paths.ts
|
|
20
|
+
function expandHomePath(home) {
|
|
21
|
+
return home === "~" ? homedir() : /^~[/\\]/.test(home) ? join(homedir(), home.slice(2)) : home;
|
|
22
|
+
}
|
|
23
|
+
function agentHomePath(home, agentId, upstream = "personal") {
|
|
24
|
+
const id = AgentIdSchema.parse(agentId);
|
|
25
|
+
if (!/^[a-z0-9_-]+$/.test(upstream)) throw new Error("Invalid upstream identifier.");
|
|
26
|
+
assertStorageName(upstream);
|
|
27
|
+
const directory = createHash("sha256").update("agent").update(Uint8Array.of(0)).update(id).digest("hex");
|
|
28
|
+
return join(resolve(expandHomePath(home)), "upstreams", upstream, "agents", directory);
|
|
29
|
+
}
|
|
30
|
+
function safeKey(value) {
|
|
31
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(value)) throw new Error("Invalid local document identifier.");
|
|
32
|
+
assertStorageName(value);
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
var AgentPaths = class {
|
|
36
|
+
root;
|
|
37
|
+
constructor(agentHome) {
|
|
38
|
+
this.root = resolve(agentHome);
|
|
39
|
+
}
|
|
40
|
+
get claims() {
|
|
41
|
+
return join(this.root, "claims");
|
|
42
|
+
}
|
|
43
|
+
get traces() {
|
|
44
|
+
return join(this.root, "traces");
|
|
45
|
+
}
|
|
46
|
+
get disputes() {
|
|
47
|
+
return join(this.root, "disputes");
|
|
48
|
+
}
|
|
49
|
+
get inbox() {
|
|
50
|
+
return join(this.root, "inbox");
|
|
51
|
+
}
|
|
52
|
+
get uploads() {
|
|
53
|
+
return join(this.root, "maintainer_uploads");
|
|
54
|
+
}
|
|
55
|
+
get pendingUploads() {
|
|
56
|
+
return join(this.uploads, "pending.yaml");
|
|
57
|
+
}
|
|
58
|
+
get pendingUploadsLock() {
|
|
59
|
+
return join(this.uploads, "pending.lock");
|
|
60
|
+
}
|
|
61
|
+
get rejectedDisputes() {
|
|
62
|
+
return join(this.uploads, "rejected_disputes.yaml");
|
|
63
|
+
}
|
|
64
|
+
get deliveryStatus() {
|
|
65
|
+
return join(this.uploads, "delivery_status.yaml");
|
|
66
|
+
}
|
|
67
|
+
get deliveryLock() {
|
|
68
|
+
return join(this.uploads, "delivery.lock");
|
|
69
|
+
}
|
|
70
|
+
get knowledgeLock() {
|
|
71
|
+
return join(this.root, "knowledge_apply.lock");
|
|
72
|
+
}
|
|
73
|
+
get claimEditPending() {
|
|
74
|
+
return join(this.root, "claim_edit_pending.yaml");
|
|
75
|
+
}
|
|
76
|
+
get reportedSets() {
|
|
77
|
+
return join(this.disputes, "reported_claim_sets.yaml");
|
|
78
|
+
}
|
|
79
|
+
get jobs() {
|
|
80
|
+
return join(this.root, "jobs");
|
|
81
|
+
}
|
|
82
|
+
get workerLock() {
|
|
83
|
+
return join(this.jobs, "worker.lock");
|
|
84
|
+
}
|
|
85
|
+
get jobQueueLock() {
|
|
86
|
+
return join(this.jobs, "queue.lock");
|
|
87
|
+
}
|
|
88
|
+
get sessions() {
|
|
89
|
+
return join(this.root, "sessions");
|
|
90
|
+
}
|
|
91
|
+
get lastRoute() {
|
|
92
|
+
return join(this.root, "runtime", "last_route.yaml");
|
|
93
|
+
}
|
|
94
|
+
get dreamWorkspace() {
|
|
95
|
+
return join(this.root, "runtime", "dream_workspace.yaml");
|
|
96
|
+
}
|
|
97
|
+
get llmCalls() {
|
|
98
|
+
return join(this.root, "runtime", "llm-calls");
|
|
99
|
+
}
|
|
100
|
+
get dreamRoot() {
|
|
101
|
+
return join(this.root, "dream");
|
|
102
|
+
}
|
|
103
|
+
get dreamState() {
|
|
104
|
+
return join(this.root, "runtime", "supervisor", "dream_state.yaml");
|
|
105
|
+
}
|
|
106
|
+
get dreamPending() {
|
|
107
|
+
return join(this.root, "runtime", "supervisor", "dream_pending.yaml");
|
|
108
|
+
}
|
|
109
|
+
dreamJob(id) {
|
|
110
|
+
return join(this.dreamRoot, safeKey(id));
|
|
111
|
+
}
|
|
112
|
+
dreamFinal(id) {
|
|
113
|
+
return join(this.root, "runtime", "supervisor", "dream", `${safeKey(id)}.yaml`);
|
|
114
|
+
}
|
|
115
|
+
dreamExecution(id, validation) {
|
|
116
|
+
if (!/^[0-9a-f]{64}$/.test(validation)) throw new Error("Invalid Dream validation identifier.");
|
|
117
|
+
return join(this.dreamJob(id), "executions", `${validation}.yaml`);
|
|
118
|
+
}
|
|
119
|
+
transcript(id) {
|
|
120
|
+
return join(this.session(id), "transcript.jsonl");
|
|
121
|
+
}
|
|
122
|
+
transcriptPending(id) {
|
|
123
|
+
return join(this.session(id), "transcript-pending");
|
|
124
|
+
}
|
|
125
|
+
claim(id) {
|
|
126
|
+
return join(this.claims, `${ClaimIdSchema.parse(id)}.yaml`);
|
|
127
|
+
}
|
|
128
|
+
trace(id) {
|
|
129
|
+
return join(this.traces, `${TraceIdSchema.parse(id)}.yaml`);
|
|
130
|
+
}
|
|
131
|
+
dispute(id) {
|
|
132
|
+
return join(this.disputes, `${DisputeIdSchema.parse(id)}.yaml`);
|
|
133
|
+
}
|
|
134
|
+
pendingInbox(id) {
|
|
135
|
+
return join(this.inbox, `${InboxIdSchema.parse(id)}.yaml`);
|
|
136
|
+
}
|
|
137
|
+
doneInbox(id) {
|
|
138
|
+
return join(this.inbox, `${InboxIdSchema.parse(id)}.done.yaml`);
|
|
139
|
+
}
|
|
140
|
+
inboxEffect(id) {
|
|
141
|
+
return join(this.inbox, "effects", `${InboxIdSchema.parse(id)}.yaml`);
|
|
142
|
+
}
|
|
143
|
+
session(id) {
|
|
144
|
+
return join(this.root, "sessions", safeKey(id));
|
|
145
|
+
}
|
|
146
|
+
sessionState(id) {
|
|
147
|
+
return join(this.session(id), "state.yaml");
|
|
148
|
+
}
|
|
149
|
+
finalizeCheckpoint(id) {
|
|
150
|
+
return join(this.session(id), "finalize_checkpoint.yaml");
|
|
151
|
+
}
|
|
152
|
+
job(id) {
|
|
153
|
+
return join(this.jobs, `${safeKey(id)}.yaml`);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
//#endregion
|
|
157
|
+
export { assertStorageName as a, safeKey as i, agentHomePath as n, invalidStorageName as o, expandHomePath as r, AgentPaths as t };
|